From 75ab9b96fc3c94227c3ff77f8871d769a9ab79c8 Mon Sep 17 00:00:00 2001 From: avollkopf <43980694+avollkopf@users.noreply.github.com> Date: Mon, 22 Nov 2021 16:09:09 +0100 Subject: [PATCH] Added MQTT Actor and power setting --- cbpi/__init__.py | 2 +- cbpi/controller/actor_controller.py | 2 + cbpi/controller/satellite_controller.py | 26 ++++++++-- cbpi/extension/mqtt_actor/__init__.py | 65 +++++++++++++++++++++++++ cbpi/extension/mqtt_actor/config.yaml | 3 ++ 5 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 cbpi/extension/mqtt_actor/__init__.py create mode 100644 cbpi/extension/mqtt_actor/config.yaml diff --git a/cbpi/__init__.py b/cbpi/__init__.py index 7455d4e..3cf324b 100644 --- a/cbpi/__init__.py +++ b/cbpi/__init__.py @@ -1 +1 @@ -__version__ = "4.0.0.47" +__version__ = "4.0.0.49" diff --git a/cbpi/controller/actor_controller.py b/cbpi/controller/actor_controller.py index 6ecfcbe..aade888 100644 --- a/cbpi/controller/actor_controller.py +++ b/cbpi/controller/actor_controller.py @@ -11,6 +11,8 @@ class ActorController(BasicController): async def on(self, id, power=None): try: item = self.find_by_id(id) + if item.power: + power = item.power if item.instance.state is False: await item.instance.on(power) await self.push_udpate() diff --git a/cbpi/controller/satellite_controller.py b/cbpi/controller/satellite_controller.py index 6cd47b7..cb3a46f 100644 --- a/cbpi/controller/satellite_controller.py +++ b/cbpi/controller/satellite_controller.py @@ -21,7 +21,8 @@ class SatelliteController: self.client = None self.topic_filters = [ ("cbpi/actor/+/on", self._actor_on), - ("cbpi/actor/+/off", self._actor_off) + ("cbpi/actor/+/off", self._actor_off), + ("cbpi/actor/+/power", self._actor_power), ] self.tasks = set() @@ -33,7 +34,7 @@ class SatelliteController: try: await self.client.publish(topic, message, qos=1, retain=retain) except: - self.logger.warning("Faild to push data via mqtt") + self.logger.warning("Failed to push data via mqtt") async def _actor_on(self, messages): async for message in messages: @@ -41,7 +42,7 @@ class SatelliteController: topic_key = message.topic.split("/") await self.cbpi.actor.on(topic_key[2]) except: - self.logger.warning("Faild to process actor on via mqtt") + self.logger.warning("Failed to process actor on via mqtt") async def _actor_off(self, messages): async for message in messages: @@ -49,7 +50,24 @@ class SatelliteController: topic_key = message.topic.split("/") await self.cbpi.actor.off(topic_key[2]) except: - self.logger.warning("Faild to process actor off via mqtt") + self.logger.warning("Failed to process actor off via mqtt") + + async def _actor_power(self, messages): + async for message in messages: + try: + topic_key = message.topic.split("/") + try: + power=int(message.payload.decode()) + if power > 100: + power = 100 + if power < 0: + power = 0 + await self.cbpi.actor.set_power(topic_key[2],power) + await self.cbpi.actor.actor_update(topic_key[2],power) + except: + self.logger.warning("Failed to set actor power via mqtt. No valid power in message") + except: + self.logger.warning("Failed to set actor power via mqtt") def subcribe(self, topic, method): task = asyncio.create_task(self._subcribe(topic, method)) diff --git a/cbpi/extension/mqtt_actor/__init__.py b/cbpi/extension/mqtt_actor/__init__.py new file mode 100644 index 0000000..3b3453d --- /dev/null +++ b/cbpi/extension/mqtt_actor/__init__.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +import asyncio +import json +from cbpi.api import parameters, Property, CBPiActor +from cbpi.api import * + +@parameters([Property.Text(label="Topic", configurable=True, description = "MQTT Topic")]) +class MQTTActor(CBPiActor): + + # Custom property which can be configured by the user + @action("Set Power", parameters=[Property.Number(label="Power", configurable=True,description="Power Setting [0-100]")]) + async def setpower(self,Power = 100 ,**kwargs): + self.power=int(Power) + if self.power < 0: + self.power = 0 + if self.power > 100: + self.power = 100 + await self.set_power(self.power) + + def __init__(self, cbpi, id, props): + super(MQTTActor, self).__init__(cbpi, id, props) + + async def on_start(self): + self.topic = self.props.get("Topic", None) + self.power = 100 + + async def on(self, power=None): + if power is not None: + if power != self.power: + power = min(100, power) + power = max(0, power) + self.power = int(power) + await self.cbpi.satellite.publish(self.topic, json.dumps( + {"state": "on", "power": self.power}), True) + self.state = True + pass + + async def off(self): + self.state = False + await self.cbpi.satellite.publish(self.topic, json.dumps( + {"state": "off"}), True) + pass + + async def run(self): + while self.running: + await asyncio.sleep(1) + + def get_state(self): + return self.state + + async def set_power(self, power): + await self.on(power) + await self.cbpi.actor.actor_update(self.id,power) + pass + +def setup(cbpi): + ''' + This method is called by the server during startup + Here you need to register your plugins at the server + + :param cbpi: the cbpi core + :return: + ''' + if cbpi.static_config.get("mqtt", False) is True: + cbpi.plugin.register("MQTTActor", MQTTActor) diff --git a/cbpi/extension/mqtt_actor/config.yaml b/cbpi/extension/mqtt_actor/config.yaml new file mode 100644 index 0000000..7f0aa15 --- /dev/null +++ b/cbpi/extension/mqtt_actor/config.yaml @@ -0,0 +1,3 @@ +name: DummySensor +version: 4 +active: true \ No newline at end of file