Compare commits

...

13 Commits

Author SHA1 Message Date
Andrey
22a6f8f444 fix errors 2021-02-28 22:06:36 +03:00
Andrey
9a53de1d5d fix errors 2021-02-28 22:02:22 +03:00
Andrey
bd8b07dd90 fix errors 2021-02-28 21:52:34 +03:00
Andrey
d9b6ba3a50 fix errors 2021-02-28 21:52:06 +03:00
Andrey
1042592a31 fix errors 2021-02-28 21:33:26 +03:00
Andrey
137eb8b6ba fix errors 2021-02-28 21:15:48 +03:00
Andrey
a2f412b89e fix errors 2021-02-28 20:16:04 +03:00
Andrey
8fa14cdbc5 fix errors 2021-02-28 20:15:47 +03:00
Andrey
fc17b82021 support response for extenders 2021-02-28 15:01:39 +03:00
Andrey
1aeaabfb3c fix errors 2021-02-28 14:50:47 +03:00
Andrey
a0bd8acac0 fix errors 2021-02-28 14:49:38 +03:00
andvikt
c48a3632d2 Update http.py 2021-02-28 13:04:00 +03:00
Andrey
e06ba65ead fix errors 2021-02-28 09:49:16 +03:00
6 changed files with 60 additions and 29 deletions

View File

@@ -67,6 +67,10 @@ class MegaBinarySensor(BinarySensorEntity, MegaPushEntity):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self._is_on = None self._is_on = None
self._attrs = None self._attrs = None
self._click_task = None
async def _click(self):
await self.customize.get
@property @property
def state_attributes(self): def state_attributes(self):

View File

@@ -63,7 +63,7 @@ async def validate_input(hass: core.HomeAssistant, data):
class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for mega.""" """Handle a config flow for mega."""
VERSION = 13 VERSION = 17
CONNECTION_CLASS = config_entries.CONN_CLASS_ASSUMED CONNECTION_CLASS = config_entries.CONN_CLASS_ASSUMED
async def async_step_user(self, user_input=None): async def async_step_user(self, user_input=None):
@@ -118,7 +118,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
reload = user_input.pop(CONF_RELOAD) reload = user_input.pop(CONF_RELOAD)
cfg = dict(self.config_entry.data) cfg = dict(self.config_entry.data)
cfg.update(user_input) cfg.update(user_input)
hub = await get_hub(self.hass, self.config_entry.data) hub = await get_hub(self.hass, cfg)
if reload: if reload:
await hub.start() await hub.start()
new = await hub.get_config(nports=user_input.get(CONF_NPORTS, 37)) new = await hub.get_config(nports=user_input.get(CONF_NPORTS, 37))

View File

@@ -1,6 +1,19 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
inputs = [
'eact',
'inta',
'misc',
]
selectors = [
'pty',
'm',
'gr',
'd',
'ety',
]
@dataclass(frozen=True, eq=True) @dataclass(frozen=True, eq=True)
class Config: class Config:
@@ -8,21 +21,16 @@ class Config:
m: str = None m: str = None
gr: str = None gr: str = None
d: str = None d: str = None
inta: str = field(compare=False, hash=False, default=None)
ety: str = None ety: str = None
inta: str = field(compare=False, hash=False, default=None)
misc: str = field(compare=False, hash=False, default=None) misc: str = field(compare=False, hash=False, default=None)
eact: str = field(compare=False, hash=False, default=None)
def parse_config(page: str): def parse_config(page: str):
page = BeautifulSoup(page, features="lxml") page = BeautifulSoup(page, features="lxml")
ret = {} ret = {}
for x in [ for x in selectors:
'pty',
'm',
'gr',
'd',
'ety',
]:
v = page.find('select', attrs={'name': x}) v = page.find('select', attrs={'name': x})
if v is None: if v is None:
continue continue
@@ -31,12 +39,10 @@ def parse_config(page: str):
if v: if v:
v = v['value'] v = v['value']
ret[x] = v ret[x] = v
v = page.find('input', attrs={'name': 'inta'}) for x in inputs:
if v: v = page.find('input', attrs={'name': x})
ret['inta'] = v['value'] if v:
v = page.find('input', attrs={'name': 'misc'}) ret[x] = v['value']
if v:
ret['misc'] = v.get('checked', False)
return Config(**ret) return Config(**ret)

View File

@@ -32,6 +32,8 @@ CONF_POLL_OUTS = 'poll_outs'
CONF_FORCE_D = 'force_d' CONF_FORCE_D = 'force_d'
CONF_DEF_RESPONSE = 'def_response' CONF_DEF_RESPONSE = 'def_response'
CONF_RESTORE_ON_RESTART = 'restore_on_restart' CONF_RESTORE_ON_RESTART = 'restore_on_restart'
CONF_CLICK_TIME = 'click_time'
CONF_LONG_TIME = 'long_time'
PLATFORMS = [ PLATFORMS = [
"light", "light",
"switch", "switch",

View File

@@ -100,24 +100,36 @@ class MegaView(HomeAssistantView):
ret = 'd' if hub.force_d else '' ret = 'd' if hub.force_d else ''
if port is not None: if port is not None:
if is_ext(data): if is_ext(data):
ret = '' # пока ответ всегда пустой, неясно какая будет реакция на непустой ответ # ret = '' # пока ответ всегда пустой, неясно какая будет реакция на непустой ответ
if port in hub.extenders: if port in hub.extenders:
pt_orig = port pt_orig = port
else: else:
pt_orig = hub.ext_in.get(port) pt_orig = hub.ext_in.get(port, hub.ext_in.get(str(port)))
if pt_orig is None: if pt_orig is None:
hub.lg.warning(f'can not find extender for int port {port}') hub.lg.warning(f'can not find extender for int port {port}, '
f'have ext_int: {hub.ext_in}, ext: {hub.extenders}')
return Response(status=200) return Response(status=200)
for e, v in data.items(): for e, v in data.items():
if e.startswith('ext') in data: _data = data.copy()
idx = e[-1] if e.startswith('ext'):
idx = e[3:]
pt = f'{pt_orig}e{idx}' pt = f'{pt_orig}e{idx}'
data['pt_orig'] = pt_orig _data['pt_orig'] = pt_orig
data['value'] = 'ON' if v == '1' else 'OFF' _data['value'] = 'ON' if v == '1' else 'OFF'
data['m'] = 1 if data[e] == '0' else 0 # имитация поведения обычного входа, чтобы события обрабатывались аналогично _data['m'] = 1 if _data[e] == '0' else 0 # имитация поведения обычного входа, чтобы события обрабатывались аналогично
hub.values[pt] = data hub.values[pt] = _data
for cb in self.callbacks[hub.id][pt]: for cb in self.callbacks[hub.id][pt]:
cb(data) cb(_data)
act = hub.ext_act.get(pt)
hub.lg.debug(f'act on port {pt}: {act}, all acts are: {hub.ext_act}')
template: Template = self.templates.get(hub.id, {}).get(port, hub.def_response)
if template is not None:
template.hass = hass
ret = template.async_render(_data)
hub.lg.debug(f'response={ret}, template={template}')
if ret == 'd' and act:
await hub.request(cmd=act)
ret = 'd' if hub.force_d else ''
else: else:
hub.values[port] = data hub.values[port] = data
for cb in self.callbacks[hub.id][port]: for cb in self.callbacks[hub.id][port]:

View File

@@ -82,6 +82,7 @@ class MegaD:
restore_on_restart=False, restore_on_restart=False,
extenders=None, extenders=None,
ext_in=None, ext_in=None,
ext_acts=None,
**kwargs, **kwargs,
): ):
"""Initialize.""" """Initialize."""
@@ -98,6 +99,7 @@ class MegaD:
self.http = None self.http = None
self.extenders = extenders or [] self.extenders = extenders or []
self.ext_in = ext_in or {} self.ext_in = ext_in or {}
self.ext_act = ext_acts or {}
self.poll_outs = poll_outs self.poll_outs = poll_outs
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
self.nports = nports self.nports = nports
@@ -517,6 +519,7 @@ class MegaD:
ret['mqtt_id'] = await self.get_mqtt_id() ret['mqtt_id'] = await self.get_mqtt_id()
ret['extenders'] = extenders = [] ret['extenders'] = extenders = []
ret['ext_in'] = ext_int = {} ret['ext_in'] = ext_int = {}
ret['ext_acts'] = ext_acts = {}
async for port, cfg in self.scan_ports(nports): async for port, cfg in self.scan_ports(nports):
if cfg.pty == "0": if cfg.pty == "0":
ret['binary_sensor'][port].append({}) ret['binary_sensor'][port].append({})
@@ -536,16 +539,20 @@ class MegaD:
]) ])
elif cfg == MCP230: elif cfg == MCP230:
extenders.append(port) extenders.append(port)
ext_int[int(cfg.inta)] = port if cfg.inta:
ext_int[int_ignore(cfg.inta)] = port
values = await self.request(pt=port, cmd='get') values = await self.request(pt=port, cmd='get')
values = values.split(';') values = values.split(';')
for n in range(len(values)): for n in range(len(values)):
ext_page = await self.request(pt=port, ext=n) ext_page = await self.request(pt=port, ext=n)
ext_cfg = parse_config(ext_page) ext_cfg = parse_config(ext_page)
pt = f'{port}e{n}'
if ext_cfg.ety == '1': if ext_cfg.ety == '1':
ret['light'][f'{port}e{n}'].append({}) ret['light'][pt].append({})
elif ext_cfg.ety == '0': elif ext_cfg.ety == '0':
ret['binary_sensor'][f'{port}e{n}'].append({}) if ext_cfg.eact:
ext_acts[pt] = ext_cfg.eact
ret['binary_sensor'][pt].append({})
elif cfg == PCA9685: elif cfg == PCA9685:
extenders.append(port) extenders.append(port)
values = await self.request(pt=port, cmd='get') values = await self.request(pt=port, cmd='get')