Compare commits

..

4 Commits

Author SHA1 Message Date
Andrey
59443989a0 add poll outs 2021-02-06 09:43:10 +03:00
Andrey
5b86ceefe4 Merge remote-tracking branch 'origin/master' 2021-02-05 21:06:40 +03:00
Andrey
8cf000beae fix get_port 2021-02-05 21:06:27 +03:00
andvikt
99317da9f6 Update bug-report.md 2021-02-05 20:47:58 +03:00
10 changed files with 62 additions and 28 deletions

View File

@@ -8,19 +8,26 @@ assignees: ''
---
**Описание**
A clear and concise description of what the bug is.
Описание проблемы
**Версии систем**
Enviroment: raspberry/linux/windows/macos/docker
HA version:
mega_hacs version:
megad firmware version:
используется mqtt: true/false
**Ожидаемое поведение**
A clear and concise description of what you expected to happen.
Описание правильного поведения
**Screenshots**
If applicable, add screenshots to help explain your problem.
**LOG**
Прочитайте в документации как включить подробный лог интеграции и приложите его здесь
Просьба прикладывать детальный лог, который можно включить в конфиге так:
```yaml
logger:
default: info
logs:
custom_components.mega: debug
```

View File

@@ -17,7 +17,7 @@ from homeassistant.components import mqtt
from homeassistant.config_entries import ConfigEntry
from .const import DOMAIN, CONF_INVERT, CONF_RELOAD, PLATFORMS, CONF_PORTS, CONF_CUSTOM, CONF_SKIP, CONF_PORT_TO_SCAN, \
CONF_MQTT_INPUTS, CONF_HTTP, CONF_RESPONSE_TEMPLATE, CONF_ACTION, CONF_GET_VALUE, CONF_ALLOW_HOSTS, \
CONF_CONV_TEMPLATE
CONF_CONV_TEMPLATE, CONF_ALL
from .hub import MegaD
from .config_flow import ConfigFlow
from .http import MegaView
@@ -65,6 +65,7 @@ async def async_setup(hass: HomeAssistant, config: dict):
"""YAML-конфигурация содержит только кастомизации портов"""
hass.data[DOMAIN] = {CONF_CUSTOM: config.get(DOMAIN, {})}
hass.data[DOMAIN][CONF_HTTP] = view = MegaView(cfg=config.get(DOMAIN, {}))
hass.data[DOMAIN][CONF_ALL] = {}
view.allowed_hosts |= set(config.get(DOMAIN, {}).get(CONF_ALLOW_HOSTS, []))
hass.http.register_view(view)
hass.services.async_register(
@@ -115,6 +116,7 @@ async def _add_mega(hass: HomeAssistant, entry: ConfigEntry):
hub = await get_hub(hass, entry)
hass.data[DOMAIN][id] = hass.data[DOMAIN]['__def'] = hub
hass.data[DOMAIN][entry.data.get(CONF_HOST)] = hub
hass.data[DOMAIN][CONF_ALL][id] = hub
if not await hub.authenticate():
raise Exception("not authentificated")
mid = await hub.get_mqtt_id()
@@ -164,6 +166,7 @@ async def async_remove_entry(hass, entry) -> None:
_LOGGER.debug(f'remove {id}')
_hubs.pop(id, None)
hass.data[DOMAIN].pop(id, None)
hass.data[DOMAIN][CONF_ALL].pop(id, None)
task: asyncio.Task = _POLL_TASKS.pop(id, None)
if task is not None:
task.cancel()
@@ -215,13 +218,16 @@ async def _get_port(hass: HomeAssistant, call: ServiceCall):
for x in port:
await hub.get_port(x)
else:
for hub in hass.data[DOMAIN].values():
for hub in hass.data[DOMAIN][CONF_ALL].values():
if not isinstance(hub, MegaD):
continue
if port is None:
await hub.get_all_ports()
else:
await hub.get_all_ports(check_skip=True)
elif isinstance(port, int):
await hub.get_port(port)
elif isinstance(port, list):
for x in port:
await hub.get_port(x)
@bind_hass

View File

@@ -10,7 +10,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_ID, CONF_PASSWORD, CONF_SCAN_INTERVAL
from homeassistant.core import callback, HomeAssistant
from .const import DOMAIN, CONF_PORT_TO_SCAN, CONF_RELOAD, PLATFORMS, CONF_MQTT_INPUTS, \
CONF_NPORTS, CONF_UPDATE_ALL # pylint:disable=unused-import
CONF_NPORTS, CONF_UPDATE_ALL, CONF_POLL_OUTS # pylint:disable=unused-import
from .hub import MegaD
from . import exceptions
@@ -22,6 +22,7 @@ STEP_USER_DATA_SCHEMA = vol.Schema(
vol.Required(CONF_HOST, default="192.168.0.14"): str,
vol.Required(CONF_PASSWORD, default="sec"): str,
vol.Optional(CONF_SCAN_INTERVAL, default=0): int,
vol.Optional(CONF_POLL_OUTS, default=False): bool,
vol.Optional(CONF_PORT_TO_SCAN, default=0): int,
vol.Optional(CONF_MQTT_INPUTS, default=True): bool,
vol.Optional(CONF_NPORTS, default=37): int,
@@ -131,6 +132,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
step_id="init",
data_schema=vol.Schema({
vol.Optional(CONF_SCAN_INTERVAL, default=e.get(CONF_SCAN_INTERVAL, 0)): int,
vol.Optional(CONF_POLL_OUTS, default=e.get(CONF_POLL_OUTS, False)): bool,
vol.Optional(CONF_PORT_TO_SCAN, default=e.get(CONF_PORT_TO_SCAN, 0)): int,
vol.Optional(CONF_MQTT_INPUTS, default=e.get(CONF_MQTT_INPUTS, True)): bool,
vol.Optional(CONF_NPORTS, default=e.get(CONF_NPORTS, 37)): int,

View File

@@ -16,6 +16,7 @@ CONF_INVERT = 'invert'
CONF_PORTS = 'ports'
CONF_CUSTOM = '__custom'
CONF_HTTP = '__http'
CONF_ALL = '__all'
CONF_SKIP = 'skip'
CONF_MQTT_INPUTS = 'mqtt_inputs'
CONF_NPORTS = 'nports'
@@ -25,6 +26,7 @@ CONF_UPDATE_ALL = 'update_all'
CONF_GET_VALUE = 'get_value'
CONF_ALLOW_HOSTS = 'allow_hosts'
CONF_CONV_TEMPLATE = 'conv_template'
CONF_POLL_OUTS = 'poll_outs'
PLATFORMS = [
"light",
"switch",

View File

@@ -15,7 +15,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from .const import TEMP, HUM, PATT_SPLIT, DOMAIN, CONF_HTTP, EVENT_BINARY_SENSOR, CONF_CUSTOM, CONF_SKIP
from .entities import set_events_off
from .entities import set_events_off, BaseMegaEntity
from .exceptions import CannotConnect
from .tools import make_ints
@@ -57,6 +57,7 @@ class MegaD:
nports=38,
inverted: typing.List[int] = None,
update_all=True,
poll_outs=False,
**kwargs,
):
"""Initialize."""
@@ -66,6 +67,7 @@ class MegaD:
self.http.allowed_hosts |= {host}
else:
self.http = None
self.poll_outs = poll_outs
self.update_all = update_all if update_all is not None else True
self.nports = nports
self.mqtt_inputs = mqtt_inputs
@@ -81,7 +83,7 @@ class MegaD:
self._notif_lck = asyncio.Lock()
self.cnd = asyncio.Condition()
self.online = True
self.entities: typing.List[Entity] = []
self.entities: typing.List[BaseMegaEntity] = []
self.poll_interval = scan_interval
self.subs = None
self.lg: logging.Logger = lg.getChild(self.id)
@@ -177,8 +179,9 @@ class MegaD:
if self.mqtt is None:
await self.get_all_ports()
await self.get_sensors(only_list=True)
return
if len(self.sensors) > 0:
elif self.poll_outs:
await self.get_all_ports(check_skip=True)
elif len(self.sensors) > 0:
await self.get_sensors()
else:
await self.get_port(self.port_to_scan)
@@ -268,20 +271,23 @@ class MegaD:
except asyncio.TimeoutError:
self.lg.error(f'timeout when getting port {port}')
@property
def ports(self):
return {e.port for e in self.entities}
async def get_all_ports(self, only_out=False, check_skip=False):
if not self.mqtt_inputs:
ret = await self.request(cmd='all')
for port, x in enumerate(ret.split(';')):
if check_skip:
if self.customize.get(port, {}).get(CONF_SKIP, False):
continue
if check_skip and not port in self.ports:
continue
ret = self.parse_response(x)
self.values[port] = ret
else:
elif not check_skip:
for x in range(self.nports + 1):
if check_skip:
if self.customize.get(x, {}).get(CONF_SKIP, False):
continue
await self.get_port(x)
else:
for x in self.ports:
await self.get_port(x)
async def reboot(self, save=True):

View File

@@ -14,7 +14,8 @@
"invert": "[%key:common::config_flow::data::invert%]",
"mqtt_inputs": "[%key:common::config_flow::data::mqtt_inputs%]",
"nports": "[%key:common::config_flow::data::nports%]",
"update_all": "[%key:common::config_flow::data::update_all%]"
"update_all": "[%key:common::config_flow::data::update_all%]",
"poll_outs": "[%key:common::config_flow::data::poll_outs%]"
}
}
},
@@ -38,7 +39,8 @@
"invert": "[%key:common::config_flow::data::invert%]",
"mqtt_inputs": "[%key:common::config_flow::data::mqtt_inputs%]",
"nports": "[%key:common::config_flow::data::nports%]",
"update_all": "[%key:common::config_flow::data::update_all%]"
"update_all": "[%key:common::config_flow::data::update_all%]",
"poll_outs": "[%key:common::config_flow::data::poll_outs%]"
}
}
}

View File

@@ -22,7 +22,8 @@
"port_to_scan": "Port to poll aliveness (needed only if no sensors used)",
"nports": "Number of ports",
"update_all": "Update all outs when input",
"mqtt_inputs": "Use MQTT"
"mqtt_inputs": "Use MQTT",
"poll_outs": "Poll outs"
}
}
}
@@ -35,7 +36,8 @@
"port_to_scan": "Port to poll aliveness (needed only if no sensors used)",
"reload": "Reload objects",
"mqtt_inputs": "Use MQTT",
"update_all": "Update all outs when input"
"update_all": "Update all outs when input",
"poll_outs": "Poll outs"
}
}
}

View File

@@ -21,7 +21,8 @@
"port_to_scan": "Порт, который сканируется когда нет датчиков",
"mqtt_inputs": "Использовать MQTT",
"nports": "Кол-во портов",
"update_all": "Обновить все выходы когда срабатывает вход"
"update_all": "Обновить все выходы когда срабатывает вход",
"poll_outs": "Обновлять выходы (регулярно)"
}
}
}
@@ -36,7 +37,8 @@
"invert": "Список портов (через ,) с инвертированной логикой",
"mqtt_inputs": "Использовать MQTT",
"nports": "Кол-во портов",
"update_all": "Обновить все выходы когда срабатывает вход"
"update_all": "Обновить все выходы когда срабатывает вход",
"poll_outs": "Обновлять выходы (регулярно)"
}
}
}

View File

@@ -21,7 +21,8 @@
"port_to_scan": "Порт для сканування при відсутності датчиків",
"mqtt_inputs": "Використовувати MQTT",
"nports": "Кількість портів",
"update_all": "Оновити всі виходи коли спрацьовує вхід"
"update_all": "Оновити всі виходи коли спрацьовує вхід",
"poll_outs": "Оновити виходи"
}
}
}
@@ -36,7 +37,8 @@
"invert": "Список портів з інвертованою логікою (через ,)",
"mqtt_inputs": "Використовувати MQTT",
"nports": "Кількість портів",
"update_all": "Оновити всі виходи коли спрацьовує вхід"
"update_all": "Оновити всі виходи коли спрацьовує вхід",
"poll_outs": "Оновити виходи"
}
}
}

View File

@@ -155,12 +155,15 @@ mega:
```
Возможные варианты поля `type`:
- `long`: долгое нажатие
- `release`: размыкание (с гарантией что не было долгого нажатия)
- `release`: размыкание (с гарантией** что не было долгого нажатия)
- `long_release`: размыкание после долгого нажатия
- `press`: замыкание
- `single`: одинарный клик (в режиме кликов)
- `double`: двойной клик
**гарантия есть только при использовании http-метода синхронизации, mqtt не гарантирует порядок доставки сообщений, хотя
маловероятно, что порядок будет нарушен, но все же сам протокол не дает таких гарантий.
Чтобы понять, какие события происходят, лучше всего воспользоваться панелью разработчика и подписаться
на вкладке события на событие `mega.sensor`, понажимать кнопки.