Compare commits

...

10 Commits

18 changed files with 348 additions and 9 deletions

View File

@ -0,0 +1 @@
BinarySensor.vue

View File

@ -0,0 +1 @@
Sensor.vue

View File

@ -0,0 +1 @@
BinarySensor.vue

View File

@ -0,0 +1 @@
Sensor.vue

View File

@ -0,0 +1 @@
Sensor.vue

View File

@ -0,0 +1 @@
Sensor.vue

View File

@ -87,6 +87,14 @@
}
},
"dew_point_sensor": {
"name": "Sensor",
"name_plural": "Sensors",
"icon": {
"class": "fas fa-hand-holding-droplet"
}
},
"illuminance_sensor": {
"name": "Sensor",
"name_plural": "Sensors",
@ -103,6 +111,30 @@
}
},
"contact_sensor": {
"name": "Sensor",
"name_plural": "Sensors",
"icon": {
"class": "far fa-hand"
}
},
"presence_sensor": {
"name": "Sensor",
"name_plural": "Sensors",
"icon": {
"class": "fas fa-person"
}
},
"weight_sensor": {
"name": "Sensor",
"name_plural": "Sensors",
"icon": {
"class": "fas fa-weight-scale"
}
},
"link_quality": {
"name": "Link Quality",
"name_plural": "Link Qualities",
@ -127,6 +159,38 @@
}
},
"steps_sensor": {
"name": "Sensor",
"name_plural": "Sensors",
"icon": {
"class": "fas fa-shoe-prints"
}
},
"heart_rate_sensor": {
"name": "Sensor",
"name_plural": "Sensors",
"icon": {
"class": "fas fa-heart-pulse"
}
},
"time_duration_sensor": {
"name": "Sensor",
"name_plural": "Sensors",
"icon": {
"class": "fas fa-clock"
}
},
"pressure_sensor": {
"name": "Sensor",
"name_plural": "Sensors",
"icon": {
"class": "fas fa-gauge"
}
},
"muted": {
"name": "Switch",
"name_plural": "Switches",

View File

@ -0,0 +1,23 @@
from sqlalchemy import Column, Integer, ForeignKey
from platypush.common.db import Base
from .sensors import BinarySensor
if 'contact_sensor' not in Base.metadata:
class ContactSensor(BinarySensor):
"""
A binary sensor that detects contact.
"""
__tablename__ = 'contact_sensor'
id = Column(
Integer, ForeignKey(BinarySensor.id, ondelete='CASCADE'), primary_key=True
)
__mapper_args__ = {
'polymorphic_identity': __tablename__,
}

View File

@ -0,0 +1,23 @@
from sqlalchemy import Column, Integer, ForeignKey
from platypush.common.db import Base
from .sensors import NumericSensor
if 'heart_rate_sensor' not in Base.metadata:
class HeartRateSensor(NumericSensor):
"""
A sensor that measures the heart rate.
"""
__tablename__ = 'heart_rate_sensor'
id = Column(
Integer, ForeignKey(NumericSensor.id, ondelete='CASCADE'), primary_key=True
)
__mapper_args__ = {
'polymorphic_identity': __tablename__,
}

View File

@ -8,6 +8,10 @@ from .sensors import NumericSensor
if 'humidity_sensor' not in Base.metadata:
class HumiditySensor(NumericSensor):
"""
A sensor that measures humidity.
"""
__tablename__ = 'humidity_sensor'
id = Column(
@ -17,3 +21,21 @@ if 'humidity_sensor' not in Base.metadata:
__mapper_args__ = {
'polymorphic_identity': __tablename__,
}
if 'dew_point_sensor' not in Base.metadata:
class DewPointSensor(NumericSensor):
"""
A sensor that measures the dew point.
"""
__tablename__ = 'dew_point_sensor'
id = Column(
Integer, ForeignKey(NumericSensor.id, ondelete='CASCADE'), primary_key=True
)
__mapper_args__ = {
'polymorphic_identity': __tablename__,
}

View File

@ -0,0 +1,23 @@
from sqlalchemy import Column, Integer, ForeignKey
from platypush.common.db import Base
from .sensors import BinarySensor
if 'presence_sensor' not in Base.metadata:
class PresenceSensor(BinarySensor):
"""
A binary sensor that detects presence.
"""
__tablename__ = 'presence_sensor'
id = Column(
Integer, ForeignKey(BinarySensor.id, ondelete='CASCADE'), primary_key=True
)
__mapper_args__ = {
'polymorphic_identity': __tablename__,
}

View File

@ -0,0 +1,23 @@
from sqlalchemy import Column, Integer, ForeignKey
from platypush.common.db import Base
from .sensors import NumericSensor
if 'pressure_sensor' not in Base.metadata:
class PressureSensor(NumericSensor):
"""
A sensor that measures pressure.
"""
__tablename__ = 'pressure_sensor'
id = Column(
Integer, ForeignKey(NumericSensor.id, ondelete='CASCADE'), primary_key=True
)
__mapper_args__ = {
'polymorphic_identity': __tablename__,
}

View File

@ -0,0 +1,23 @@
from sqlalchemy import Column, Integer, ForeignKey
from platypush.common.db import Base
from .sensors import NumericSensor
if 'steps_sensor' not in Base.metadata:
class StepsSensor(NumericSensor):
"""
A sensor that measures the number of steps taken.
"""
__tablename__ = 'steps_sensor'
id = Column(
Integer, ForeignKey(NumericSensor.id, ondelete='CASCADE'), primary_key=True
)
__mapper_args__ = {
'polymorphic_identity': __tablename__,
}

View File

@ -0,0 +1,23 @@
from sqlalchemy import Column, Integer, ForeignKey
from platypush.common.db import Base
from .sensors import NumericSensor
if 'time_duration_sensor' not in Base.metadata:
class TimeDurationSensor(NumericSensor):
"""
A sensor that measures a time duration.
"""
__tablename__ = 'time_duration_sensor'
id = Column(
Integer, ForeignKey(NumericSensor.id, ondelete='CASCADE'), primary_key=True
)
__mapper_args__ = {
'polymorphic_identity': __tablename__,
}

View File

@ -0,0 +1,23 @@
from sqlalchemy import Column, Integer, ForeignKey
from platypush.common.db import Base
from .sensors import NumericSensor
if 'weight_sensor' not in Base.metadata:
class WeightSensor(NumericSensor):
"""
A sensor that measures weight.
"""
__tablename__ = 'weight_sensor'
id = Column(
Integer, ForeignKey(NumericSensor.id, ondelete='CASCADE'), primary_key=True
)
__mapper_args__ = {
'polymorphic_identity': __tablename__,
}

View File

@ -14,17 +14,24 @@ from TheengsGateway._decoder import decodeBLE, getAttribute, getProperties
from platypush.entities import Entity
from platypush.entities.batteries import Battery
from platypush.entities.bluetooth import BluetoothDevice
from platypush.entities.contact import ContactSensor
from platypush.entities.electricity import (
CurrentSensor,
EnergySensor,
PowerSensor,
VoltageSensor,
)
from platypush.entities.humidity import HumiditySensor
from platypush.entities.heart import HeartRateSensor
from platypush.entities.humidity import DewPointSensor, HumiditySensor
from platypush.entities.illuminance import IlluminanceSensor
from platypush.entities.motion import MotionSensor
from platypush.entities.presence import PresenceSensor
from platypush.entities.pressure import PressureSensor
from platypush.entities.sensors import BinarySensor, NumericSensor, RawSensor
from platypush.entities.steps import StepsSensor
from platypush.entities.temperature import TemperatureSensor
from platypush.entities.time import TimeDurationSensor
from platypush.entities.weight import WeightSensor
@dataclass
@ -53,46 +60,122 @@ class NullSensor:
# Maps property names to transformer methods (first mapper choice).
_property_to_entity: Dict[str, Callable[[Any, Dict[str, Any]], Entity]] = {
'activity heart rate': lambda value, _: HeartRateSensor(value=value),
'atmospheric pressure': lambda value, conf: PressureSensor(
value=value,
unit=conf.get('unit'),
),
'battery': lambda value, conf: Battery(
value=value,
unit=conf.get('unit', '%'),
min=conf.get('min', 0),
max=conf.get('min', 100),
),
'contact': lambda value, _: ContactSensor(value=value),
'current': lambda value, conf: CurrentSensor(
value=value,
unit=conf.get('unit', 'A'),
),
'dew_point_sensor': lambda value, conf: DewPointSensor(
value=value,
unit=conf.get('unit'),
),
'duration': lambda value, conf: TimeDurationSensor(
value=value,
unit=conf.get('unit'),
),
'energy': lambda value, conf: EnergySensor(
value=value,
unit=conf.get('unit', 'kWh'),
),
'heart rate': lambda value, _: HeartRateSensor(value=value),
'humidity': lambda value, conf: HumiditySensor(
value=value,
unit=conf.get('unit', '%'),
min=conf.get('min', 0),
max=conf.get('min', 100),
),
'light level': lambda value, _: IlluminanceSensor(value=value),
'light level': lambda value, conf: IlluminanceSensor(
value=value,
unit=conf.get('unit'),
),
'luminance': lambda value, conf: IlluminanceSensor(
value=value,
unit=conf.get('unit'),
),
'moisture': lambda value, conf: HumiditySensor(
value=value,
unit=conf.get('unit'),
),
'motion': lambda value, _: MotionSensor(value=value),
'open': lambda value, _: BinarySensor(value=value),
'power': lambda value, conf: PowerSensor(
value=value,
unit=conf.get('unit', 'W'),
),
'motion': lambda value, _: MotionSensor(value=value),
'presence': lambda value, _: PresenceSensor(value=value),
'pressure': lambda value, conf: PressureSensor(
value=value,
unit=conf.get('unit'),
),
'steps': lambda value, _: StepsSensor(value=value),
'temperature': lambda value, conf: TemperatureSensor(
value=value,
unit=conf.get('unit', 'C'),
),
'temperature2': lambda value, conf: TemperatureSensor(
value=value,
unit=conf.get('unit', 'C'),
),
'temperature3': lambda value, conf: TemperatureSensor(
value=value,
unit=conf.get('unit', 'C'),
),
'temperature4': lambda value, conf: TemperatureSensor(
value=value,
unit=conf.get('unit', 'C'),
),
'temperature5': lambda value, conf: TemperatureSensor(
value=value,
unit=conf.get('unit', 'C'),
),
'temperature6': lambda value, conf: TemperatureSensor(
value=value,
unit=conf.get('unit', 'C'),
),
'temperature7': lambda value, conf: TemperatureSensor(
value=value,
unit=conf.get('unit', 'C'),
),
'temperature8': lambda value, conf: TemperatureSensor(
value=value,
unit=conf.get('unit', 'C'),
),
'volt': lambda value, conf: VoltageSensor(
value=value,
unit=conf.get('unit', 'V'),
),
'voltage': lambda value, conf: VoltageSensor(
value=value,
unit=conf.get('unit', 'V'),
),
'weight': lambda value, conf: WeightSensor(
value=value,
unit=conf.get('unit', 'kg'),
),
}
# Maps reported units to transformer methods (second mapper choice).
_unit_to_entity: Dict[str, Callable[[Any, Dict[str, Any]], Entity]] = {
'status': lambda value, _: BinarySensor(value=value),
'int': lambda value, _: NumericSensor(value=value),
'int': lambda value, conf: NumericSensor(
value=value,
unit=conf.get('unit'),
),
'float': lambda value, conf: NumericSensor(
value=value,
unit=conf.get('unit'),
),
'%': lambda value, conf: NumericSensor(
value=value,
unit='%',
@ -105,9 +188,9 @@ _unit_to_entity: Dict[str, Callable[[Any, Dict[str, Any]], Entity]] = {
# Maps value types to transformer methods (third mapper choice).
_value_type_to_entity: Dict[type, Callable[[Any, Dict[str, Any]], Entity]] = {
bool: lambda value, _: BinarySensor(value=value),
int: lambda value, _: NumericSensor(value=value),
float: lambda value, _: NumericSensor(value=value),
str: lambda value, _: RawSensor(value=value),
int: lambda value, conf: NumericSensor(value=value, unit=conf.get('unit')),
float: lambda value, conf: NumericSensor(value=value, unit=conf.get('unit')),
str: lambda value, conf: RawSensor(value=value, unit=conf.get('unit')),
bytes: lambda value, _: RawSensor(value=value),
bytearray: lambda value, _: RawSensor(value=value),
}
@ -218,7 +301,7 @@ def parse_device_args(device: BLEDevice) -> Dict[str, Any]:
object.
"""
props = device.details.get('props', {})
props = (device.details or {}).get('props', {})
return {
'name': device.name or device.address,
'connected': props.get('Connected', False),
@ -262,7 +345,8 @@ def _parse_service_data(device: BLEDevice) -> Dict[str, str]:
"""
return {
service_uuid: ''.join([f'{x:02x}' for x in value])
for service_uuid, value in device.details.get('props', {})
for service_uuid, value in (device.details or {})
.get('props', {})
.get('ServiceData', {})
.items()
}