Source code for juham.shelly.shellymotion

import json
from typing import Any, Dict
from typing_extensions import override
from influxdb_client_3 import Point
from juham.base import Base, MqttMsg
from juham.base.jmqtt import JMqtt
from juham.base.time import epoc2utc, timestampstr
from juham.shelly.jshelly import JShelly


[docs] class ShellyMotion(JShelly): """Shelly Motion 2 - a wifi motion sensor with light and temperature metering.""" shelly_topic = "shellies/shellymotion2/info" # source topic def __init__(self, name: str = "shellymotion") -> None: super().__init__(name) self.motion_topic = self.make_topic_name("motion")
[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.shelly_topic) self.debug("Topic " + self.shelly_topic + " subscribed")
[docs] @override def on_message(self, client: object, userdata: Any, msg: MqttMsg) -> None: if msg.topic == self.shelly_topic: m = json.loads(msg.payload.decode()) self.on_sensor(m) else: super().on_message(client, userdata, msg)
[docs] def on_sensor(self, m: dict[str, Any]) -> None: """Handle motion sensor event. This method reads the incoming event, translates it, and publishes it to the Juham topic. It also writes the attributes to the time series database. Args: m (dict): MQTT event from Shelly motion sensor """ tmp = m["tmp"] sensor_id = "motion" roomtemperature = tmp["value"] sensor = m["sensor"] vibration = sensor["vibration"] motion = sensor["motion"] timestamp = m["unixtime"] self.debug(f"Motion sensor event {timestampstr(timestamp)}") msg = { "sensor": sensor_id, "timestamp": timestamp, "temperature": int(roomtemperature), "motion": motion, "vibration": vibration, } self.publish(self.motion_topic, json.dumps(msg), 1, True) point = ( Point("motion") .tag("sensor", sensor_id) .field("motion", motion) .field("vibration", vibration) .field("roomtemp", roomtemperature) .field("timestamp", int(timestamp)) .time(epoc2utc(timestamp)) ) self.write(point)
[docs] @override def to_dict(self) -> Dict[str, Any]: data: Dict[str, Any] = super().to_dict() data["_shellymotion"] = { "shelly_topic": self.shelly_topic, "motion_topic": self.motion_topic, } return data
[docs] @override def from_dict(self, data: Dict[str, Any]) -> None: super().from_dict(data) if "_shellymotion" in data: for key, value in data["_shellymotion"].items(): setattr(self, key, value)