forked from platypush/platypush
- Fixed switchbot.status
to handle virtual devices
- Fixed StrippedString schema field serialize handler - Fixed rendering of lists in documentation schemas
This commit is contained in:
parent
952a2a9379
commit
6db070db1c
5 changed files with 66 additions and 15 deletions
|
@ -3,6 +3,12 @@
|
|||
All notable changes to this project will be documented in this file.
|
||||
Given the high speed of development in the first phase, changes are being reported only starting from v0.20.2.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed `switchbot.status` method in case of virtual devices.
|
||||
|
||||
## [0.22.4] - 2021-10-19
|
||||
|
||||
### Added
|
||||
|
|
|
@ -38,6 +38,13 @@ class SchemaDirective(Directive):
|
|||
return bool(randint(0, 1))
|
||||
if isinstance(field, fields.URL):
|
||||
return 'https://example.org'
|
||||
if isinstance(field, fields.List):
|
||||
return [cls._get_field_value(field.inner)]
|
||||
if isinstance(field, fields.Dict):
|
||||
return {
|
||||
cls._get_field_value(field.key_field) if field.key_field else 'key':
|
||||
cls._get_field_value(field.value_field) if field.value_field else 'value'
|
||||
}
|
||||
if isinstance(field, fields.Nested):
|
||||
ret = {
|
||||
name: cls._get_field_value(f)
|
||||
|
|
|
@ -96,10 +96,15 @@ class SwitchbotPlugin(SwitchPlugin):
|
|||
|
||||
return devices
|
||||
|
||||
def _worker(self, q: queue.Queue, method: str = 'get', *args, device=None, **kwargs):
|
||||
def _worker(self, q: queue.Queue, method: str = 'get', *args, device: Optional[dict] = None, **kwargs):
|
||||
schema = DeviceStatusSchema()
|
||||
try:
|
||||
res = self._run(method, *args, device=device, **kwargs)
|
||||
q.put(DeviceStatusSchema().dump(res))
|
||||
if method == 'get' and args and args[0] == 'status' and device and device.get('is_virtual'):
|
||||
res = schema.load(device)
|
||||
else:
|
||||
res = self._run(method, *args, device=device, **kwargs)
|
||||
|
||||
q.put(schema.dump(res))
|
||||
except Exception as e:
|
||||
self.logger.exception(e)
|
||||
q.put(e)
|
||||
|
@ -115,15 +120,21 @@ class SwitchbotPlugin(SwitchPlugin):
|
|||
# noinspection PyUnresolvedReferences
|
||||
devices = self.devices().output
|
||||
if device:
|
||||
device_info = self._get_device(device)
|
||||
status = {} if device_info['is_virtual'] else self._run('get', 'status', device=device_info)
|
||||
return {
|
||||
**device,
|
||||
**self._run('get', 'status', device=self._get_device(device)),
|
||||
**device_info,
|
||||
**status,
|
||||
}
|
||||
|
||||
devices_by_id = {dev['id']: dev for dev in devices}
|
||||
queues = [queue.Queue()] * len(devices)
|
||||
workers = [
|
||||
threading.Thread(target=self._worker, args=(queues[i], 'get', 'status'), kwargs={'device': dev})
|
||||
threading.Thread(
|
||||
target=self._worker,
|
||||
args=(queues[i], 'get', 'status'),
|
||||
kwargs={'device': dev}
|
||||
)
|
||||
for i, dev in enumerate(devices)
|
||||
]
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from datetime import datetime
|
||||
from datetime import datetime, date
|
||||
from typing import Optional, Union
|
||||
|
||||
from dateutil.parser import isoparse
|
||||
|
@ -12,6 +12,10 @@ class StrippedString(fields.Function): # lgtm [py/missing-call-to-init]
|
|||
kwargs['deserialize'] = self._strip
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def _serialize(self, value, attr, obj, **kwargs) -> Optional[str]:
|
||||
if obj.get(attr) is not None:
|
||||
return self._strip(obj.get(attr))
|
||||
|
||||
@staticmethod
|
||||
def _strip(value: str):
|
||||
return value.strip()
|
||||
|
@ -34,9 +38,32 @@ class DateTime(fields.Function):
|
|||
return normalize_datetime(value)
|
||||
|
||||
|
||||
def normalize_datetime(dt: Union[str, datetime]) -> Optional[datetime]:
|
||||
class Date(fields.Function):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.metadata = {
|
||||
'example': date.today().isoformat(),
|
||||
**(self.metadata or {}),
|
||||
}
|
||||
|
||||
def _serialize(self, value, attr, obj, **kwargs) -> Optional[str]:
|
||||
value = normalize_datetime(obj.get(attr))
|
||||
if value:
|
||||
return date(value.year, value.month, value.day).isoformat()
|
||||
|
||||
def _deserialize(self, value, attr, data, **kwargs) -> Optional[date]:
|
||||
dt = normalize_datetime(value)
|
||||
return date.fromtimestamp(dt.timestamp())
|
||||
|
||||
|
||||
def normalize_datetime(dt: Union[str, date, datetime]) -> Optional[Union[date, datetime]]:
|
||||
if not dt:
|
||||
return
|
||||
if isinstance(dt, datetime):
|
||||
if isinstance(dt, datetime) or isinstance(dt, date):
|
||||
return dt
|
||||
return isoparse(dt)
|
||||
|
||||
try:
|
||||
dt = float(dt)
|
||||
return datetime.fromtimestamp(dt)
|
||||
except (TypeError, ValueError):
|
||||
return isoparse(dt)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
from marshmallow import fields
|
||||
from marshmallow.schema import Schema
|
||||
from marshmallow.validate import OneOf
|
||||
|
||||
|
||||
device_types = [
|
||||
|
@ -26,6 +25,7 @@ device_types = [
|
|||
'Speaker',
|
||||
'Water Heater',
|
||||
'Vacuum Cleaner',
|
||||
'Remote',
|
||||
'Others',
|
||||
]
|
||||
|
||||
|
@ -51,12 +51,12 @@ class DeviceSchema(Schema):
|
|||
id = fields.String(attribute='deviceId', required=True, metadata=dict(description='Device unique ID'))
|
||||
name = fields.String(attribute='deviceName', metadata=dict(description='Device name'))
|
||||
device_type = fields.String(
|
||||
attribute='deviceType', validate=OneOf(device_types),
|
||||
metadata=dict(description=f'Supported types: [{", ".join(device_types)}]')
|
||||
attribute='deviceType',
|
||||
metadata=dict(description=f'Default types: [{", ".join(device_types)}]')
|
||||
)
|
||||
remote_type = fields.String(
|
||||
attribute='remoteType', validate=OneOf(remote_types),
|
||||
metadata=dict(description=f'Supported types: [{", ".join(remote_types)}]')
|
||||
attribute='remoteType',
|
||||
metadata=dict(description=f'Default types: [{", ".join(remote_types)}]')
|
||||
)
|
||||
hub_id = fields.String(attribute='hubDeviceId', metadata=dict(description='Parent hub device unique ID'))
|
||||
cloud_service_enabled = fields.Boolean(
|
||||
|
|
Loading…
Reference in a new issue