forked from platypush/platypush
serial
plugin migrated to the new SensorPlugin
interface.
This commit is contained in:
parent
bf4db76830
commit
6a5a5de03e
1 changed files with 19 additions and 58 deletions
|
@ -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):
|
||||||
|
|
Loading…
Reference in a new issue