Source code for juham_automation.automation.spothintafi

from datetime import datetime
import time
import json
from typing import Any, Dict, Optional, cast
from typing_extensions import override

from masterpiece.mqtt import Mqtt, MqttMsg
from juham_core import JuhamCloudThread, JuhamThread


class SpotHintaFiThread(JuhamCloudThread):
    """Thread running SpotHinta.fi.

    Periodically fetches the spot electricity prices and publishes them
    to  'spot' topic.
    """

    _spot_topic: str = ""
    _url: str = ""
    _interval: float = 12 * 3600

    def __init__(self, client: Optional[Mqtt] = None) -> None:
        super().__init__(client)
        self._interval = 60

    def init(self, topic: str, url: str, interval: float) -> None:
        self._spot_topic = topic
        self._url = url
        self._interval = interval

    @override
    def make_weburl(self) -> str:
        return self._url

    @override
    def update_interval(self) -> float:
        return self._interval

    @override
    def process_data(self, rawdata: Any) -> None:
        """Publish electricity price message to Juham topic.

        Args:
            rawdata (dict): electricity prices
        """

        super().process_data(rawdata)
        data = rawdata.json()

        spot = []
        for e in data:
            ts = time.mktime(time.strptime(e["DateTime"], "%Y-%m-%dT%H:%M:%S%z"))
            hour = datetime.utcfromtimestamp(ts).strftime("%H")
            h = {
                "Timestamp": ts,
                "hour": hour,
                "Rank": e["Rank"],
                "PriceWithTax": e["PriceWithTax"],
            }
            spot.append(h)
        self.publish(self._spot_topic, json.dumps(spot), 1, True)
        self.info(f"Spot electricity prices published for the next {len(spot)} days")


[docs] class SpotHintaFi(JuhamThread): """Spot electricity price for reading hourly electricity prices from https://api.spot-hinta.fi site. """ worker_thread_id = SpotHintaFiThread.get_class_id() url = "https://api.spot-hinta.fi/TodayAndDayForward" update_interval = 12 * 3600 def __init__(self, name: str = "rspothintafi") -> None: super().__init__(name) self.active_liter_lpm = -1 self.update_ts = None self.spot_topic = self.make_topic_name("spot")
[docs] @override def on_connect(self, client: object, userdata: Any, flags: int, rc: int) -> None: super().on_connect(client, userdata, flags, rc) if rc == 0: self.subscribe(self.spot_topic)
[docs] @override def on_message(self, client: object, userdata: Any, msg: MqttMsg) -> None: if msg.topic == self.spot_topic: em = json.loads(msg.payload.decode()) self.on_spot(em) else: super().on_message(client, userdata, msg)
[docs] def on_spot(self, m: dict[Any, Any]) -> None: """Write hourly spot electricity prices to time series database. Args: m (dict): holding hourly spot electricity prices """ pass
[docs] @override def run(self) -> None: self.worker = cast(SpotHintaFiThread, self.instantiate(self.worker_thread_id)) self.worker.init(self.spot_topic, self.url, self.update_interval) super().run()
[docs] @override def to_dict(self) -> Dict[str, Any]: data: Dict[str, Any] = super().to_dict() data["_spothintafi"] = { "topic": self.spot_topic, "url": self.url, "interval": self.update_interval, } return data
[docs] @override def from_dict(self, data: Dict[str, Any]) -> None: super().from_dict(data) if "_spothintafi" in data: for key, value in data["_spothintafi"].items(): setattr(self, key, value)