Source code for juham_automation.ts.forecast_ts
import json
from typing import Any
from typing_extensions import override
from masterpiece.mqtt import MqttMsg
from juham_core import JuhamTs
from juham_core.timeutils import epoc2utc
[docs]
class ForecastTs(JuhamTs):
"""Forecast database record.
This class listens the forecast topic and writes to the time series
database.
"""
def __init__(self, name: str = "forecast_ts") -> None:
"""Construct forecast record object with the given name."""
super().__init__(name)
self.forecast_topic = self.make_topic_name("forecast")
[docs]
@override
def on_connect(self, client: object, userdata: Any, flags: int, rc: int) -> None:
"""Standard mqtt connect notification.
This method is called when the client connection with the MQTT
broker is established.
"""
super().on_connect(client, userdata, flags, rc)
self.subscribe(self.forecast_topic)
self.debug(f"Subscribed to {self.forecast_topic}")
[docs]
@override
def on_message(self, client: object, userdata: Any, msg: MqttMsg) -> None:
"""Standard mqtt message notification method.
This method is called upon new arrived message.
"""
if msg.topic == self.forecast_topic:
m = json.loads(msg.payload.decode())
self.on_forecast(m)
else:
super().on_message(client, userdata, msg)
[docs]
def on_forecast(self, em: dict[Any, Any]) -> None:
"""Handle weather forecast data. Writes the received hourly forecast
data to timeseries database.
Args:
em (dict): forecast
"""
# List of fields you want to add
fields = [
"ts",
"day",
"solarradiation",
"solarenergy",
"cloudcover",
"snowdepth",
"uvindex",
"pressure",
"humidity",
"windspeed",
"winddir",
"temp",
"feels",
]
days: int = 0
for m in em:
senderid: str = "unknown"
if "id" in m:
senderid = m["id"]
if not "hour" in m:
self.error(
f"No hour key in forecast record from {senderid}, skipped", str(m)
)
else:
point = (
self.measurement("forecast")
.tag("hour", m.get("hour"))
.tag("source", senderid)
.field("hr", str(m["hour"]))
)
# Conditionally add each field
for field in fields:
if field in m:
if field == "day" or field == "ts":
point = point.field(field, m[field])
else:
point = point.field(field, float(m[field]))
point = point.time(epoc2utc(m["ts"]))
self.write(point)
days = days + 1
self.info(
f"Forecast from {senderid} for the next {days} days written to time series database"
)