serial plugin migrated to the new SensorPlugin interface.

This commit is contained in:
Fabio Manganiello 2023-04-01 19:29:56 +02:00
parent bf4db76830
commit 6a5a5de03e
Signed by: blacklight
GPG key ID: D90FBA7F76362774

View file

@ -1,25 +1,23 @@
import base64 import base64
from collections import namedtuple from collections import namedtuple
from collections.abc import Collection
import json import json
from typing import Any, List, Optional, Tuple, Union from typing import Dict, List, Optional, Union
import threading import threading
from typing_extensions import override from typing_extensions import override
from serial import Serial from serial import Serial
from platypush.context import get_bus from platypush.common.sensors import Numeric
from platypush.entities.devices import Device from platypush.entities.devices import Device
from platypush.entities.sensors import RawSensor, NumericSensor from platypush.entities.sensors import RawSensor, NumericSensor
from platypush.entities.managers.sensors import SensorEntityManager from platypush.plugins import action
from platypush.message.event.sensor import SensorDataChangeEvent from platypush.plugins.sensor import SensorPlugin
from platypush.plugins import RunnablePlugin, action from platypush.utils import get_lock
from platypush.utils import get_lock, get_plugin_name_by_class
_DeviceAndRate = namedtuple('_DeviceAndRate', ['device', 'baud_rate']) _DeviceAndRate = namedtuple('_DeviceAndRate', ['device', 'baud_rate'])
class SerialPlugin(RunnablePlugin, SensorEntityManager): class SerialPlugin(SensorPlugin):
""" """
The serial plugin can read data from a serial device. The serial plugin can read data from a serial device.
@ -62,6 +60,8 @@ class SerialPlugin(RunnablePlugin, SensorEntityManager):
Triggers: Triggers:
* :class:`platypush.message.event.sensor.SensorDataAboveThresholdEvent`
* :class:`platypush.message.event.sensor.SensorDataBelowThresholdEvent`
* :class:`platypush.message.event.sensor.SensorDataChangeEvent` * :class:`platypush.message.event.sensor.SensorDataChangeEvent`
""" """
@ -75,6 +75,7 @@ class SerialPlugin(RunnablePlugin, SensorEntityManager):
max_size: int = 1 << 19, max_size: int = 1 << 19,
timeout: float = _default_lock_timeout, timeout: float = _default_lock_timeout,
enable_polling: bool = True, enable_polling: bool = True,
poll_interval: float = 0.1,
**kwargs, **kwargs,
): ):
""" """
@ -94,8 +95,12 @@ class SerialPlugin(RunnablePlugin, SensorEntityManager):
programmatically interface with the device via the :meth:`.read` programmatically interface with the device via the :meth:`.read`
and :meth:`.write` methods instead of polling for updates in JSON and :meth:`.write` methods instead of polling for updates in JSON
format. format.
:param poll_interval: How often (in seconds) we should poll the device
for new data. Since we are reading JSON data from a serial
interface whenever it's ready, the default here can be quite low
(default: 0.1 seconds).
""" """
super().__init__(**kwargs) super().__init__(poll_interval=poll_interval, **kwargs)
self.device = device self.device = device
self.baud_rate = baud_rate self.baud_rate = baud_rate
@ -255,21 +260,18 @@ class SerialPlugin(RunnablePlugin, SensorEntityManager):
@override @override
@action @action
def status( def get_measurement(
self, self,
*_, *_,
device: Optional[str] = None, device: Optional[str] = None,
baud_rate: Optional[int] = None, baud_rate: Optional[int] = None,
publish_entities: bool = True,
**__, **__,
) -> dict: ) -> Dict[str, Numeric]:
""" """
Reads JSON data from the serial device and returns it as a message Reads JSON data from the serial device and returns it as a message
:param device: Device path (default: default configured device). :param device: Device path (default: default configured device).
:param baud_rate: Baud rate (default: default configured baud_rate). :param baud_rate: Baud rate (default: default configured baud_rate).
:param publish_entities: Whether to publish an event with the newly
read values (default: True).
""" """
device, baud_rate = self._get_device_and_baud_rate(device, baud_rate) device, baud_rate = self._get_device_and_baud_rate(device, baud_rate)
@ -292,20 +294,8 @@ class SerialPlugin(RunnablePlugin, SensorEntityManager):
if data: if data:
self.last_data = data self.last_data = data
if publish_entities:
self.publish_entities(self.last_data.items())
return data return data
@action
def get_measurement(
self, device: Optional[str] = None, baud_rate: Optional[int] = None
):
"""
(Deprecated) alias for :meth:`.status`.
"""
return self.status(device, baud_rate)
@action @action
def read( def read(
self, self,
@ -397,10 +387,10 @@ class SerialPlugin(RunnablePlugin, SensorEntityManager):
ser.write(data) ser.write(data)
@override @override
def transform_entities(self, entities: Tuple[str, Any]) -> List[Device]: def transform_entities(self, entities: Dict[str, Numeric]) -> List[Device]:
transformed_entities = [] transformed_entities = []
for k, v in entities: for k, v in entities.items():
sensor_id = f'serial:{k}' sensor_id = f'serial:{k}'
try: try:
value = float(v) value = float(v)
@ -425,18 +415,6 @@ class SerialPlugin(RunnablePlugin, SensorEntityManager):
) )
] ]
@override
def publish_entities(self, entities: Collection[Tuple[str, Any]], *_, **__):
ret = super().publish_entities(entities)
get_bus().post(
SensorDataChangeEvent(
data=dict(entities),
source=get_plugin_name_by_class(self.__class__),
)
)
return ret
@override @override
def main(self): def main(self):
if not self._enable_polling: if not self._enable_polling:
@ -444,24 +422,7 @@ class SerialPlugin(RunnablePlugin, SensorEntityManager):
self.wait_stop() self.wait_stop()
return return
while not self.should_stop(): super().main()
last_data = self.last_data.copy()
try:
new_data: dict = self.status(publish_entities=False).output # type: ignore
except Exception as e:
self.logger.warning('Could not update the status: %s', e)
self.wait_stop(1)
continue
updated_entries = {
k: v for k, v in new_data.items() if v != last_data.get(k)
}
self.publish_entities(updated_entries.items())
self.last_data = {
**last_data,
**new_data,
}
@override @override
def stop(self): def stop(self):