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

- new API for EntityFactory (no-more mapping..)

- Fix TTS
- Added utils

git-svn-id: https://redmine.imt-atlantique.fr/svn/xaal/code/Python/branches/0.7@3021 b32b6428-25c9-4566-ad07-03861ab6144f
parent 8badd146
No related branches found
No related tags found
No related merge requests found
......@@ -21,3 +21,11 @@ Read carefully :
- entity_id (used in UI, script and so on) is build from unique_id or entity_name if provided
- changes in xAAL nickname only affect entity_name, entity_id will not change. This is the
way HASS works.
xALL Device => Entities / Devices
- For a given device_type you can have more than one Entity (powermeter => power/current/voltage)
- One Entity is always bounded to HASS device
- If more than one entity is used, they bellow to the same HASS device
- If xAAL group is used (ie: smart plug), the binding groups them in a HASS device.
......@@ -9,7 +9,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.components.binary_sensor import BinarySensorEntity, BinarySensorDeviceClass
from homeassistant.const import STATE_ON, STATE_OFF
from .bridge import XAALEntity, EntityFactory, async_setup_factory
from .bridge import XAALEntity, async_setup_factory
from xaal.lib import Message
_LOGGER = logging.getLogger(__name__)
......@@ -18,18 +18,14 @@ _LOGGER = logging.getLogger(__name__)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
return async_setup_factory(hass, config_entry, async_add_entities, Factory)
async_add_entities: AddEntitiesCallback) -> None:
class Factory(EntityFactory):
@property
def mapping(self):
return {'motion.' : [Motion],
binding = {'motion.' : [Motion],
'contact.': [Contact],
'switch.' : [Switch],
'button.' : [Button], }
return async_setup_factory(hass, config_entry, async_add_entities, binding)
class XAALBinarySensorEntity(XAALEntity, BinarySensorEntity):
......
import asyncio
import functools
from typing import Dict, List, Any, Type
......@@ -17,17 +16,11 @@ from xaal.monitor import Monitor, Notification
from xaal.monitor.monitor import Device as MonitorDevice
import logging
_LOGGER = logging.getLogger(__name__)
UNSUPPORTED_TYPES = ['cli','hmi','windgauge',]
def filter_msg(msg: Message) -> bool:
m_type = msg.dev_type.split('.')[0]
if m_type in UNSUPPORTED_TYPES:
return False
return True
class XAALEntity(Entity):
#_attr_has_entity_name = True
_attr_available: bool = False
......@@ -97,18 +90,19 @@ class XAALEntity(Entity):
class EntityFactory(object):
"""Class that hold binding (dev_type->Entities) and add_entities callback for each platform"""
def __init__(self, bridge: "Bridge", async_add_entitites: AddEntitiesCallback) -> None:
def __init__(self, bridge: "Bridge", async_add_entitites: AddEntitiesCallback, binding: dict) -> None:
self._bridge = bridge
self._async_add_entitites = async_add_entitites
self._bridge.add_factory(self)
self._map = binding
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_]:
for b_type in self._map.keys():
if device.dev_type.startswith(b_type):
for k in self._map[b_type]:
entity = k(device, self._bridge)
result.append(entity)
# an factory can match only one dev_type
......@@ -117,10 +111,28 @@ class EntityFactory(object):
return True
return False
@property
def mapping(self) -> dict:
"""return an ordered dict containing dev_type to platform class"""
return {}
def async_setup_factory(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
binding: dict ) -> None:
bridge: Bridge = hass.data[DOMAIN][config_entry.entry_id]
factory = EntityFactory(bridge, async_add_entities, binding)
bridge.add_factory(factory)
for dev in bridge._mon.devices:
if dev.is_ready():
factory.build_entities(dev)
def filter_msg(msg: Message) -> bool:
m_type = msg.dev_type.split('.')[0]
if m_type in UNSUPPORTED_TYPES:
return False
return True
class Bridge(object):
......@@ -203,12 +215,12 @@ class Bridge(object):
#####################################################
# Factories
#####################################################
def add_factory(self, klass: Type[EntityFactory]):
def add_factory(self, factory: EntityFactory):
""" register a new platform factory"""
self._factories.append(klass)
self._factories.append(factory)
def remove_factory(self, klass: Type[EntityFactory]):
self._factories.remove(klass)
def remove_factory(self, factory: EntityFactory):
self._factories.remove(factory)
#####################################################
# xAAL
......@@ -261,17 +273,3 @@ class Bridge(object):
@functools.lru_cache(maxsize=128)
def warm_once(self, msg: str):
_LOGGER.warning(msg)
def async_setup_factory(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
factory_class: EntityFactory
) -> None:
bridge = hass.data[DOMAIN][config_entry.entry_id]
factory = factory_class(bridge, async_add_entities)
for dev in bridge._mon.devices:
if dev.is_ready():
factory.new_entity(dev)
"""Constants for the Detailed Hello World Push integration."""
import homeassistant.helpers.config_validation as cv
import voluptuous as vol
# This is the internal name of the integration, it should also match the directory
# name for the integration.
DOMAIN = "xaal"
CONF_DB_SERVER = "db_server"
XAAL_TTS_SCHEMA = vol.Schema({
vol.Optional("title"): cv.template,
vol.Required("message"): cv.template,
})
XAAL_TTS_SCHEMA = vol.Schema({
vol.Required("message"): cv.template,
})
......@@ -6,7 +6,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.components.cover import CoverEntity, CoverDeviceClass, CoverEntityFeature, ATTR_POSITION
from .bridge import XAALEntity, EntityFactory, async_setup_factory
from .bridge import XAALEntity, async_setup_factory
_LOGGER = logging.getLogger(__name__)
......@@ -16,15 +16,9 @@ async def async_setup_entry(
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
return async_setup_factory(hass, config_entry, async_add_entities, Factory)
class Factory(EntityFactory):
@property
def mapping(self):
return { 'shutter.position' : [ShutterPosition],
'shutter.' : [Shutter,], }
binding = { 'shutter.position' : [ShutterPosition],
'shutter.' : [Shutter,] }
return async_setup_factory(hass, config_entry, async_add_entities, binding)
class Shutter(XAALEntity, CoverEntity):
......
......@@ -6,7 +6,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.components.light import LightEntity, ColorMode, ATTR_BRIGHTNESS, ATTR_HS_COLOR, ATTR_COLOR_TEMP
from homeassistant.util import color as color_util
from .bridge import XAALEntity, EntityFactory, async_setup_factory
from .bridge import XAALEntity, async_setup_factory
_LOGGER = logging.getLogger(__name__)
......@@ -14,16 +14,10 @@ _LOGGER = logging.getLogger(__name__)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
return async_setup_factory(hass, config_entry, async_add_entities, Factory)
async_add_entities: AddEntitiesCallback) -> None:
class Factory(EntityFactory):
@property
def mapping(self):
return {'lamp.' : [Lamp]}
binding = {'lamp.' : [Lamp]}
return async_setup_factory(hass, config_entry, async_add_entities, binding)
class Lamp(XAALEntity, LightEntity):
......
......@@ -7,23 +7,19 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
from homeassistant import const
from .bridge import XAALEntity, EntityFactory, async_setup_factory
from .bridge import XAALEntity, async_setup_factory
from .const import XAAL_TTS_SCHEMA
from . import utils
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
return async_setup_factory(hass, config_entry, async_add_entities, Factory)
class Factory(EntityFactory):
@property
def mapping(self):
return {'thermometer.' : [Thermometer ],
async_add_entities: AddEntitiesCallback ) -> None:
binding = {'thermometer.' : [Thermometer ],
'hygrometer.' : [Hygrometer],
'barometer.' : [Barometer],
'battery.' : [Battery],
......@@ -36,6 +32,9 @@ class Factory(EntityFactory):
'tts.' : [TTS],
}
return async_setup_factory(hass, config_entry, async_add_entities, binding)
class XAALSensorEntity(XAALEntity, SensorEntity):
@property
......@@ -110,7 +109,7 @@ class SoundMeter(XAALSensorEntity):
_attr_icon: str | None = "mdi:music-circle-outline"
class Gateway(XAALEntity, SensorEntity):
class Gateway(XAALSensorEntity):
_attr_native_unit_of_measurement = "embedded"
_attr_icon: str | None = "mdi:swap-horizontal"
......@@ -124,20 +123,17 @@ class Gateway(XAALEntity, SensorEntity):
return self._dev.description.get('product_id','gateway')
class TTS(XAALEntity,SensorEntity):
class TTS(XAALEntity):
_attr_native_value = 1
def setup(self):
import voluptuous as vol
import homeassistant.helpers.config_validation as cv
XAAL_NOTIF_SCHEMA = vol.Schema(
{
vol.Required("message"): cv.template,
vol.Optional("title"): cv.template,
}
)
self._bridge._hass.services.async_register("notify",self._dev.display_name, self.notify, schema=XAAL_NOTIF_SCHEMA)
name = utils.str_to_id(self.name)
self._bridge._hass.services.async_register("notify",name, self.say, XAAL_TTS_SCHEMA)
def notify(self, service):
def say(self, service):
msg = service.data['message'].template
self.send_request('say',{'msg':msg})
@property
def name(self) -> str | None:
return self._dev.description.get('info','tts')
\ 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 .bridge import XAALEntity, EntityFactory, async_setup_factory
from .bridge import XAALEntity, async_setup_factory
_LOGGER = logging.getLogger(__name__)
......@@ -15,16 +15,10 @@ _LOGGER = logging.getLogger(__name__)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
return async_setup_factory(hass, config_entry, async_add_entities, Factory)
async_add_entities: AddEntitiesCallback) -> None:
class Factory(EntityFactory):
@property
def mapping(self) -> dict:
return {'siren.': [Siren]}
binding = {'siren.': [Siren]}
return async_setup_factory(hass, config_entry, async_add_entities, binding)
class Siren(XAALEntity, SirenEntity):
......
......@@ -5,7 +5,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.components.switch import SwitchEntity, DEVICE_CLASS_OUTLET
from .bridge import EntityFactory, XAALEntity, async_setup_factory
from .bridge import XAALEntity, async_setup_factory
_LOGGER = logging.getLogger(__name__)
......@@ -13,16 +13,10 @@ _LOGGER = logging.getLogger(__name__)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
return async_setup_factory(hass, config_entry, async_add_entities, Factory)
async_add_entities: AddEntitiesCallback ) -> None:
class Factory(EntityFactory):
@property
def mapping(self):
return {'powerrelay.' : [PowerRelay],}
binding = {'powerrelay.' : [PowerRelay]}
return async_setup_factory(hass, config_entry, async_add_entities, binding)
class PowerRelay(XAALEntity, SwitchEntity):
......
def str_to_id(value: str):
return value.translate ({ord(c): "_" for c in "!@#$%^&*()[]{};:,./<>?\|`~-=_+ "})
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment