diff --git a/platypush/backend/http/webapp/src/components/panels/Entities/BinarySensor.vue b/platypush/backend/http/webapp/src/components/panels/Entities/BinarySensor.vue
new file mode 100644
index 0000000000..1962533289
--- /dev/null
+++ b/platypush/backend/http/webapp/src/components/panels/Entities/BinarySensor.vue
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
diff --git a/platypush/backend/http/webapp/src/components/panels/Entities/meta.json b/platypush/backend/http/webapp/src/components/panels/Entities/meta.json
index abdfd3667f..4fba884441 100644
--- a/platypush/backend/http/webapp/src/components/panels/Entities/meta.json
+++ b/platypush/backend/http/webapp/src/components/panels/Entities/meta.json
@@ -71,14 +71,6 @@
}
},
- "numeric_sensor": {
- "name": "Sensor",
- "name_plural": "Sensors",
- "icon": {
- "class": "fas fa-thermometer"
- }
- },
-
"power_sensor": {
"name": "Sensor",
"name_plural": "Sensors",
@@ -109,5 +101,29 @@
"icon": {
"class": "fas fa-car-battery"
}
+ },
+
+ "binary_sensor": {
+ "name": "Sensor",
+ "name_plural": "Sensors",
+ "icon": {
+ "class": "fas fa-thermometer"
+ }
+ },
+
+ "numeric_sensor": {
+ "name": "Sensor",
+ "name_plural": "Sensors",
+ "icon": {
+ "class": "fas fa-thermometer"
+ }
+ },
+
+ "sensor": {
+ "name": "Sensor",
+ "name_plural": "Sensors",
+ "icon": {
+ "class": "fas fa-thermometer"
+ }
}
}
diff --git a/platypush/entities/sensors.py b/platypush/entities/sensors.py
index afd2d46378..efcf3e57f6 100644
--- a/platypush/entities/sensors.py
+++ b/platypush/entities/sensors.py
@@ -1,7 +1,11 @@
-from sqlalchemy import Column, Integer, ForeignKey, Numeric, String
+import logging
+
+from sqlalchemy import Column, Integer, ForeignKey, Boolean, Numeric, String
from .devices import Device, entity_types_registry
+logger = logging.getLogger(__name__)
+
class Sensor(Device):
__abstract__ = True
@@ -46,3 +50,36 @@ if not entity_types_registry.get('NumericSensor'):
entity_types_registry['NumericSensor'] = NumericSensor
else:
NumericSensor = entity_types_registry['NumericSensor']
+
+
+if not entity_types_registry.get('BinarySensor'):
+
+ class BinarySensor(Sensor):
+ __tablename__ = 'binary_sensor'
+
+ def __init__(self, *args, value=None, **kwargs):
+ if isinstance(value, str):
+ value = value.lower()
+
+ if value in {True, 1, '1', 't', 'true', 'on'}:
+ value = True
+ elif value in {False, 0, '0', 'f', 'false', 'off'}:
+ value = False
+ elif value is not None:
+ logger.warning(f'Unsupported value for BinarySensor type: {value}')
+ value = None
+
+ super().__init__(*args, value=value, **kwargs)
+
+ id = Column(
+ Integer, ForeignKey(Device.id, ondelete='CASCADE'), primary_key=True
+ )
+ value = Column(Boolean)
+
+ __mapper_args__ = {
+ 'polymorphic_identity': __tablename__,
+ }
+
+ entity_types_registry['BinarySensor'] = BinarySensor
+else:
+ BinarySensor = entity_types_registry['BinarySensor']
diff --git a/platypush/plugins/zigbee/mqtt/__init__.py b/platypush/plugins/zigbee/mqtt/__init__.py
index 2271ceddb9..9fe0970fcc 100644
--- a/platypush/plugins/zigbee/mqtt/__init__.py
+++ b/platypush/plugins/zigbee/mqtt/__init__.py
@@ -16,7 +16,7 @@ from platypush.entities.electricity import (
from platypush.entities.humidity import HumiditySensor
from platypush.entities.lights import Light
from platypush.entities.linkquality import LinkQuality
-from platypush.entities.sensors import Sensor, NumericSensor
+from platypush.entities.sensors import Sensor, BinarySensor, NumericSensor
from platypush.entities.switches import Switch
from platypush.entities.temperature import TemperatureSensor
from platypush.message import Mapping
@@ -1495,14 +1495,20 @@ class ZigbeeMqttPlugin(MqttPlugin): # lgtm [py/missing-call-to-init]
),
'value': device_info.get('state', {}).get(exposed['property']),
'description': exposed.get('description'),
- 'min': exposed.get('value_min'),
- 'max': exposed.get('value_max'),
- 'unit': exposed.get('unit'),
'is_read_only': cls._is_read_only(exposed),
- 'is_write_only': cls._is_read_only(exposed),
+ 'is_write_only': cls._is_write_only(exposed),
'data': device_info,
}
+ if exposed.get('type') == 'numeric':
+ sensor_args.update(
+ {
+ 'min': exposed.get('value_min'),
+ 'max': exposed.get('value_max'),
+ 'unit': exposed.get('unit'),
+ }
+ )
+
if exposed.get('property') == 'battery':
entity_type = Battery
elif exposed.get('property') == 'linkquality':
@@ -1519,6 +1525,11 @@ class ZigbeeMqttPlugin(MqttPlugin): # lgtm [py/missing-call-to-init]
entity_type = TemperatureSensor
elif exposed.get('property', '').endswith('humidity'):
entity_type = HumiditySensor
+ elif exposed.get('type') == 'binary':
+ entity_type = BinarySensor
+ sensor_args['value'] = sensor_args['value'] == exposed.get(
+ 'value_on', True
+ )
elif exposed.get('type') == 'numeric':
entity_type = NumericSensor