Compare commits

...

5 Commits

Author SHA1 Message Date
Andrey
c0b1247b9e smaller headers 2021-01-25 21:35:06 +03:00
Andrey
1548e8c364 fix multiple megas 2021-01-25 20:17:15 +03:00
Andrey
39c4ab0e3b fix device name 2021-01-25 18:45:23 +03:00
Andrey
a002e48e04 fix old mega out type 0 2021-01-25 18:13:25 +03:00
Andrey
dc6bdfc8f4 fix yaml exclusion 2021-01-25 17:56:47 +03:00
5 changed files with 41 additions and 24 deletions

View File

@@ -59,7 +59,7 @@ class BaseMegaEntity(CoordinatorEntity, RestoreEntity):
"config_entries": [ "config_entries": [
self.config_entry, self.config_entry,
], ],
"name": f'port {self.port}', "name": f'{self._mega_id} port {self.port}',
"manufacturer": 'ab-log.ru', "manufacturer": 'ab-log.ru',
# "model": self.light.productname, # "model": self.light.productname,
# "sw_version": self.light.swversion, # "sw_version": self.light.swversion,

View File

@@ -8,10 +8,10 @@ from aiohttp.web_request import Request
from aiohttp.web_response import Response from aiohttp.web_response import Response
from homeassistant.helpers.template import Template from homeassistant.helpers.template import Template
from .const import EVENT_BINARY_SENSOR, CONF_HTTP, DOMAIN, CONF_CUSTOM, CONF_RESPONSE_TEMPLATE from .const import EVENT_BINARY_SENSOR, DOMAIN, CONF_RESPONSE_TEMPLATE
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.core import callback, HomeAssistant from homeassistant.core import HomeAssistant
from . import hub from .tools import make_ints
_LOGGER = logging.getLogger(__name__).getChild('http') _LOGGER = logging.getLogger(__name__).getChild('http')
@@ -26,8 +26,7 @@ class MegaView(HomeAssistantView):
def __init__(self, cfg: dict): def __init__(self, cfg: dict):
self._try = 0 self._try = 0
self.allowed_hosts = {'::1'} self.allowed_hosts = {'::1'}
self.callbacks: typing.DefaultDict[int, typing.List[typing.Callable[[dict], typing.Coroutine]]] \ self.callbacks = defaultdict(lambda: defaultdict(list))
= defaultdict(list)
self.templates: typing.Dict[str, typing.Dict[str, Template]] = { self.templates: typing.Dict[str, typing.Dict[str, Template]] = {
mid: { mid: {
pt: cfg[mid][pt][CONF_RESPONSE_TEMPLATE] pt: cfg[mid][pt][CONF_RESPONSE_TEMPLATE]
@@ -62,9 +61,10 @@ class MegaView(HomeAssistantView):
make_ints(data) make_ints(data)
port = data.get('pt') port = data.get('pt')
data = data.copy() data = data.copy()
data['mega_id'] = hub.id
ret = 'd' ret = 'd'
if port is not None: if port is not None:
for cb in self.callbacks[port]: for cb in self.callbacks[hub.id][port]:
cb(data) cb(data)
template: Template = self.templates.get(hub.id, {}).get(port) template: Template = self.templates.get(hub.id, {}).get(port)
if hub.update_all: if hub.update_all:
@@ -73,8 +73,7 @@ class MegaView(HomeAssistantView):
template.hass = hass template.hass = hass
ret = template.async_render(data) ret = template.async_render(data)
_LOGGER.debug('response %s', ret) _LOGGER.debug('response %s', ret)
ret = Response(body=ret or 'd', content_type='text/plain', headers={}) ret = Response(body=ret or 'd', content_type='text/plain', headers={'Server': 's', 'Date': 'n'})
ret.headers.clear()
return ret return ret
async def later_update(self, hub): async def later_update(self, hub):
@@ -83,13 +82,3 @@ class MegaView(HomeAssistantView):
await hub.updater.async_refresh() await hub.updater.async_refresh()
def make_ints(d: dict):
for x in d:
try:
d[x] = float(d[x])
except ValueError:
pass
if 'm' not in d:
d['m'] = 0
if 'click' not in d:
d['click'] = 0

View File

@@ -14,9 +14,10 @@ from homeassistant.const import DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_HUMIDITY
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from .const import TEMP, HUM, PATT_SPLIT, DOMAIN, CONF_HTTP from .const import TEMP, HUM, PATT_SPLIT, DOMAIN, CONF_HTTP, EVENT_BINARY_SENSOR
from .exceptions import CannotConnect, MqttNotConfigured from .exceptions import CannotConnect, MqttNotConfigured
from .http import MegaView from .http import MegaView
from .tools import make_ints
TEMP_PATT = re.compile(r'temp:([01234567890\.]+)') TEMP_PATT = re.compile(r'temp:([01234567890\.]+)')
HUM_PATT = re.compile(r'hum:([01234567890\.]+)') HUM_PATT = re.compile(r'hum:([01234567890\.]+)')
@@ -61,7 +62,8 @@ class MegaD:
"""Initialize.""" """Initialize."""
if mqtt_inputs is None or mqtt_inputs == 'None' or mqtt_inputs is False: if mqtt_inputs is None or mqtt_inputs == 'None' or mqtt_inputs is False:
self.http = hass.data.get(DOMAIN, {}).get(CONF_HTTP) self.http = hass.data.get(DOMAIN, {}).get(CONF_HTTP)
self.http.allowed_hosts |= {host} if not self.http is None:
self.http.allowed_hosts |= {host}
else: else:
self.http = None self.http = None
self.update_all = update_all if update_all is not None else True self.update_all = update_all if update_all is not None else True
@@ -289,9 +291,16 @@ class MegaD:
value = None value = None
try: try:
value = json.loads(msg.payload) value = json.loads(msg.payload)
value = make_ints(value)
self.values[port] = value self.values[port] = value
for cb in self._callbacks[port]: for cb in self._callbacks[port]:
cb(value) cb(value)
value = value.copy()
value['mega_id'] = self.id
self.hass.bus.async_fire(
EVENT_BINARY_SENSOR,
value,
)
except Exception as exc: except Exception as exc:
self.lg.warning(f'could not parse json ({msg.payload}): {exc}') self.lg.warning(f'could not parse json ({msg.payload}): {exc}')
return return
@@ -306,7 +315,7 @@ class MegaD:
if self.mqtt_inputs: if self.mqtt_inputs:
self._callbacks[port].append(callback) self._callbacks[port].append(callback)
else: else:
self.http.callbacks[port].append(callback) self.http.callbacks[self.id][port].append(callback)
async def authenticate(self) -> bool: async def authenticate(self) -> bool:
"""Test if we can authenticate with the host.""" """Test if we can authenticate with the host."""
@@ -371,7 +380,7 @@ class MegaD:
async for port, pty, m in self.scan_ports(nports): async for port, pty, m in self.scan_ports(nports):
if pty == "0": if pty == "0":
ret['binary_sensor'][port].append({}) ret['binary_sensor'][port].append({})
elif pty == "1" and m in ['0', '1', '3']: elif pty == "1" and (m in ['0', '1', '3'] or m is None):
ret['light'][port].append({'dimmer': m == '1'}) ret['light'][port].append({'dimmer': m == '1'})
elif pty == '3': elif pty == '3':
try: try:

View File

@@ -0,0 +1,10 @@
def make_ints(d: dict):
for x in d:
try:
d[x] = float(d[x])
except ValueError:
pass
if 'm' not in d:
d['m'] = 0
if 'click' not in d:
d['click'] = 0

View File

@@ -92,7 +92,7 @@ script: "mega" # это api интеграции, к которому будет
запустить то что прописано в поле act в настройках порта). запустить то что прописано в поле act в настройках порта).
Поддерживаеются шаблоны HA. Это может быть использовано, например, для запоминания яркости (тк сам контроллер этого не Поддерживаеются шаблоны HA. Это может быть использовано, например, для запоминания яркости (тк сам контроллер этого не
умеет). В шаблоне можно использовать параметры, которые передает контроллер (m, click, pt, value) умеет). В шаблоне можно использовать параметры, которые передает контроллер (m, click, pt, mdid, mega_id)
Примеры: Примеры:
```yaml ```yaml
@@ -154,6 +154,15 @@ curl -v -X GET 'http://192.168.88.1.4:8123/mega?pt=5&m=1'
- service: light.toggle - service: light.toggle
entity_id: light.some_light entity_id: light.some_light
``` ```
События могут содержать следующие поля:
- mega_id: id как в конфиге HA
- pt: номер порта
- cnt: счетчик срабатываний
- mdid: if как в конфиге контроллера
- click: клик (подробнее в документации меги)
- value: текущее значение (только для mqtt)
- port: номер порта
Чтобы понять, какие события происходят, лучше всего воспользоваться панелью разработчика и подписаться Чтобы понять, какие события происходят, лучше всего воспользоваться панелью разработчика и подписаться
на вкладке события на событие `mega.sensor`, понажимать кнопки. на вкладке события на событие `mega.sensor`, понажимать кнопки.