Skip to content
Snippets Groups Projects
Commit ddb07cae authored by jkerdreu's avatar jkerdreu
Browse files

- rework on EntityFactory to handle multiples Entities for a given xAAL

device (this is really rare, but will cause pain if occurs)

git-svn-id: https://redmine.imt-atlantique.fr/svn/xaal/code/Python/branches/0.7@3012 b32b6428-25c9-4566-ad07-03861ab6144f
parent b96cbd6b
Branches
No related tags found
No related merge requests found
......@@ -24,26 +24,12 @@ async def async_setup_entry(
class Factory(EntityFactory):
def new_entity(self, device: MonitorDevice) -> bool:
entity = None
if device.dev_type.startswith('motion.'):
entity = Motion(device, self._bridge)
if device.dev_type.startswith('contact.'):
entity = Contact(device, self._bridge)
if device.dev_type.startswith('switch.'):
entity = Switch(device, self._bridge)
if device.dev_type.startswith('button.'):
entity = Button(device, self._bridge)
if entity:
self.add_entity(entity, device.address)
return True
return False
@property
def mapping(self):
return {'motion.' : [Motion],
'contact.': [Contact],
'switch.' : [Switch],
'button.' : [Button], }
class XAALBinarySensorEntity(XAALEntity, BinarySensorEntity):
......
......@@ -17,7 +17,7 @@ _LOGGER = logging.getLogger(__name__)
#DB_SERVER = tools.get_uuid('d28fbc27-190f-4ee5-815a-fe05233400a2')
DB_SERVER = tools.get_uuid('9064ccbc-84ea-11e8-80cc-82ed25e6aaaa')
UNSUPPORTED_TYPES = ['cli','hmi','windgauge','barometer','soundmeter']
UNSUPPORTED_TYPES = ['cli','hmi','windgauge',]
def filter_msg(msg: Message) -> bool:
......@@ -69,18 +69,18 @@ class Bridge(object):
#####################################################
# Entities
#####################################################
def new_entity(self,dev: MonitorDevice) -> None:
def build_entities(self,dev: MonitorDevice) -> None:
"""search factories to build a new entities"""
cnt = 0
for fact in self._factories:
r = fact.new_entity(dev)
r = fact.build_entities(dev)
if r:
cnt = cnt + 1
if cnt==0:
self.warm_once(f"Unable to find entity for {dev.address} {dev.dev_type} ")
def add_entity(self, addr: bindings.UUID, entity: XAALEntity) -> None:
"""register a new entity (called from factories"""
"""register a new entity (called from factories)"""
_LOGGER.debug(f"new Entity {addr} {entity}")
self._entities.update({addr: entity})
......@@ -101,7 +101,7 @@ class Bridge(object):
self._factories.remove(klass)
#####################################################
# xAAL stuffs
# xAAL
#####################################################
def setup_device(self) -> Device:
"""setup a new device need by the Monitor"""
......@@ -130,7 +130,7 @@ class Bridge(object):
return
# Not found, so it's a new entity
if entity is None and dev.is_ready():
self.new_entity(dev)
self.build_entities(dev)
def monitor_notification(self, msg: Message):
# right now the monitor doesn't send event on notification, so the bridge deals w/
......
from asyncio import proactor_events
import logging
from typing import Any, Dict, TYPE_CHECKING
......@@ -20,7 +21,7 @@ if TYPE_CHECKING:
_LOGGER = logging.getLogger(__name__)
class XAALEntity(Entity):
# _attr_has_entity_name = True
#_attr_has_entity_name = True
_attr_available: bool = False
def __init__(self, dev: MonitorDevice, bridge: "Bridge") -> None:
......@@ -68,7 +69,8 @@ class XAALEntity(Entity):
@property
def name(self) -> str | None:
dev_class = self.device_class or self.short_type()
force_name = getattr(self,'_force_name',None)
dev_class = force_name or self.device_class or self.short_type()
return f"{dev_class} {self._dev.display_name}"
@property
......@@ -88,10 +90,27 @@ class EntityFactory(object):
self._async_add_entitites = async_add_entitites
self._bridge.add_factory(self)
def add_entities(self, entities: Entity, address: bindings.UUID) -> None:
self._async_add_entitites(entities)
self._bridge.add_entity(address, entities[0])
def build_entities(self, device: MonitorDevice) -> bool:
""" return True if this factory managed to build some entities"""
result = []
for type_ in self.mapping.keys():
if device.dev_type.startswith(type_):
for k in self.mapping[type_]:
entity = k(device, self._bridge)
result.append(entity)
# an factory can match only one dev_type
self.add_entities(result, device.address)
return True
return False
def add_entity(self, entity: Entity, address: bindings.UUID) -> None:
self._async_add_entitites([entity])
self._bridge.add_entity(address, entity)
@property
def mapping(self) -> dict:
"""return an ordered dict containing dev_type to platform class"""
return {}
def async_setup_factory(
......
......@@ -21,19 +21,10 @@ async def async_setup_entry(
class Factory(EntityFactory):
def new_entity(self, device: MonitorDevice) -> bool:
entity = None
if device.dev_type == 'shutter.basic':
entity = Shutter(device, self._bridge)
if device.dev_type == 'shutter.position':
entity = ShutterPosition(device, self._bridge)
if entity:
self.add_entity(entity,device.address)
return True
return False
@property
def mapping(self):
return { 'shutter.position' : [ShutterPosition],
'shutter.' : [Shutter,], }
class Shutter(XAALEntity, CoverEntity):
......
......@@ -21,12 +21,9 @@ async def async_setup_entry(
class Factory(EntityFactory):
def new_entity(self, device: MonitorDevice) -> bool:
if device.dev_type.startswith('lamp.'):
entity = Lamp(device, self._bridge)
self.add_entity(entity,device.address)
return True
return False
@property
def mapping(self):
return {'lamp.' : [Lamp]}
class Lamp(XAALEntity, LightEntity):
......
......@@ -29,6 +29,9 @@ class Factory(EntityFactory):
if device.dev_type.startswith('hygrometer.'):
entity = Hygrometer(device, self._bridge)
if device.dev_type.startswith('barometer.'):
entity = Barometer(device, self._bridge)
if device.dev_type.startswith('battery.'):
entity = Battery(device, self._bridge)
......@@ -44,6 +47,9 @@ class Factory(EntityFactory):
if device.dev_type.startswith('co2meter.'):
entity = CO2Meter(device, self._bridge)
if device.dev_type.startswith('soundmeter.'):
entity = SoundMeter(device, self._bridge)
if device.dev_type.startswith('gateway.'):
entity = Gateway(device, self._bridge)
......@@ -53,6 +59,19 @@ class Factory(EntityFactory):
return False
@property
def mapping(self):
return {'thermometer.' : [Thermometer ],
'hygrometer.' : [Hygrometer],
'barometer.' : [Barometer],
'battery.' : [Battery],
'powermeter.' : [PowerMeter],
'wifimeter.' : [WifiMeter],
'luxmeter.' : [LuxMeter],
'co2meter.' : [CO2Meter],
'soundmeter.' : [SoundMeter],
'gateway.' : [Gateway], }
class XAALSensorEntity(XAALEntity, SensorEntity):
@property
......@@ -73,6 +92,12 @@ class Hygrometer(XAALSensorEntity):
_xaal_attribute = 'humidity'
class Barometer(XAALSensorEntity):
_attr_device_class = SensorDeviceClass.PRESSURE
_attr_native_unit_of_measurement = const.PRESSURE_HPA
_xaal_attribute = 'pressure'
class Battery(XAALSensorEntity):
_attr_device_class = SensorDeviceClass.BATTERY
_attr_unit_of_measurement = const.PERCENTAGE
......@@ -102,7 +127,15 @@ class CO2Meter(XAALSensorEntity):
_attr_native_unit_of_measurement = const.CONCENTRATION_PARTS_PER_MILLION
_xaal_attribute = 'co2'
class SoundMeter(XAALSensorEntity):
_attr_device_class = SensorDeviceClass.SIGNAL_STRENGTH
_attr_native_unit_of_measurement = const.SIGNAL_STRENGTH_DECIBELS
_force_name = 'sound'
_xaal_attribute = 'sound'
_attr_icon: str | None = "mdi:music-circle-outline"
class Gateway(XAALEntity, SensorEntity):
_attr_native_unit_of_measurement = "embedded"
_attr_icon: str | None = "mdi:swap-horizontal"
......@@ -112,3 +145,6 @@ class Gateway(XAALEntity, SensorEntity):
embs = self.get_attribute("embedded")
return len(embs) if embs else 0
@property
def name(self) -> str | None:
return self._dev.description.get('product_id','gateway')
\ No newline at end of file
......@@ -7,7 +7,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.components.siren import SirenEntity, SirenEntityFeature, ATTR_DURATION
from .core import XAALEntity, EntityFactory, MonitorDevice, async_setup_factory
from .core import XAALEntity, EntityFactory, async_setup_factory
_LOGGER = logging.getLogger(__name__)
......@@ -22,12 +22,9 @@ async def async_setup_entry(
class Factory(EntityFactory):
def new_entity(self, device: MonitorDevice) -> bool:
if device.dev_type.startswith('siren.'):
entity = Siren(device, self._bridge)
self.add_entity(entity,device.address)
return True
return False
@property
def mapping(self) -> dict:
return {'siren.': [Siren]}
class Siren(XAALEntity, SirenEntity):
......
......@@ -20,12 +20,9 @@ async def async_setup_entry(
class Factory(EntityFactory):
def new_entity(self, device: MonitorDevice) -> bool:
if device.dev_type.startswith('powerrelay.'):
entity = PowerRelay(device, self._bridge)
self.add_entity(entity,device.address)
return True
return False
@property
def mapping(self):
return {'powerrelay.' : [PowerRelay],}
class PowerRelay(XAALEntity, SwitchEntity):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment