Compare commits

..

2 Commits

Author SHA1 Message Date
Andrey
a7d7738a5c fix mqtt 2021-01-26 08:34:27 +03:00
Andrey
c0b1247b9e smaller headers 2021-01-25 21:35:06 +03:00
5 changed files with 65 additions and 19 deletions

View File

@@ -155,10 +155,12 @@ class MegaOutPort(MegaPushEntity):
@property @property
def is_on(self) -> bool: def is_on(self) -> bool:
val = self.mega.values.get(self.port, {}).get("value") val = self.mega.values.get(self.port, {})
if val is None and self._state is not None: if val is None and self._state is not None:
return self._state == 'ON' return self._state == 'ON'
elif val is not None: elif val is not None:
val = val.get("value")
if not self.invert: if not self.invert:
return val == 'ON' or str(val) == '1' or (safe_int(val) is not None and safe_int(val) > 0) return val == 'ON' or str(val) == '1' or (safe_int(val) is not None and safe_int(val) > 0)
else: else:
@@ -186,10 +188,11 @@ class MegaOutPort(MegaPushEntity):
self.mega.values[self.port] = {'value': cmd} self.mega.values[self.port] = {'value': cmd}
await self.get_state() await self.get_state()
def safe_int(v): def safe_int(v):
if v in ['ON', 'OFF']: if v in ['ON', 'OFF']:
return None return None
try: try:
return int(v) return int(v)
except ValueError: except (ValueError, TypeError):
return None return None

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')
@@ -61,6 +61,7 @@ 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[hub.id][port]: for cb in self.callbacks[hub.id][port]:
@@ -72,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):
@@ -82,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\.]+)')
@@ -290,9 +291,18 @@ class MegaD:
value = None value = None
try: try:
value = json.loads(msg.payload) value = json.loads(msg.payload)
if isinstance(value, dict):
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)
if isinstance(value, dict):
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

View File

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

View File

@@ -81,18 +81,42 @@ script: "mega" # это api интеграции, к которому будет
event_type: mega.sensor event_type: mega.sensor
event_data: event_data:
pt: 1 pt: 1
click: 2
action: action:
- service: light.toggle - service: light.toggle
entity_id: light.some_light entity_id: light.some_light
``` ```
Для binary_sensor имеет смысл использовать режим P&R, для остальных режимов - лучше пользоваться событиями. Для binary_sensor имеет смысл использовать режим P&R, для остальных режимов - лучше пользоваться событиями.
Примеры использования binary_sensor:
```yaml
- alias: обработка долгих/коротких нажатий
trigger:
- platform: state
entity_id: binary_sensor.some_sensor
to: on
for: 1 # задержка на секунду
action:
- choose:
# если кнопка все еще нажата - значит это долгое нажатие
- conditions: "{{ is_state('binary_sensor.some_sensor', 'on')}}"
sequence:
- service: light.turn_on
entity_id: light.some_light
# если кнопка уже не нажата - значит это короткое нажатие
- conditions: "{{ is_state('binary_sensor.some_sensor', 'off')}}"
sequence:
- service: light.turn_off
entity_id: light.some_light
```
## Ответ на входящие события от контроллера ## Ответ на входящие события от контроллера
Контроллер ожидает ответ от сервера, который может быть сценарием (по умолчанию интеграция отвечает `d`, что означает Контроллер ожидает ответ от сервера, который может быть сценарием (по умолчанию интеграция отвечает `d`, что означает
запустить то что прописано в поле act в настройках порта). запустить то что прописано в поле act в настройках порта).
Поддерживаеются шаблоны HA. Это может быть использовано, например, для запоминания яркости (тк сам контроллер этого не Поддерживаеются шаблоны HA. Это может быть использовано, например, для запоминания яркости (тк сам контроллер этого не
умеет). В шаблоне можно использовать параметры, которые передает контроллер (m, click, pt, value) умеет). В шаблоне можно использовать параметры, которые передает контроллер (m, click, pt, mdid, mega_id)
Примеры: Примеры:
```yaml ```yaml
@@ -154,6 +178,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`, понажимать кнопки.