Compare commits

..

62 Commits

Author SHA1 Message Date
Викторов Андрей Германович
4145eebbdd Bump version: 1.0.10b6 → 1.0.10b7 2021-10-28 15:02:18 +03:00
Викторов Андрей Германович
d4dddc61fd add sensor filters 2021-10-28 15:02:11 +03:00
Викторов Андрей Германович
bc34c1a0b3 add sensor filters 2021-09-21 17:49:43 +03:00
Викторов Андрей Германович
2662b9c3bd Bump version: 1.0.10b5 → 1.0.10b6 2021-09-21 17:33:30 +03:00
Викторов Андрей Германович
8399bbd1de fix focs about i2c id 2021-09-21 17:33:22 +03:00
Викторов Андрей Германович
975b2e8a38 Bump version: 1.0.10b4 → 1.0.10b5 2021-09-21 14:51:36 +03:00
Викторов Андрей Германович
919f1ceb12 add sensor filters 2021-09-21 14:51:33 +03:00
Викторов Андрей Германович
2c58f8e67e add sensor filters 2021-09-21 14:41:32 +03:00
Викторов Андрей Германович
1c65c341b7 add sensor filters 2021-09-21 14:38:31 +03:00
Викторов Андрей Германович
2ef0ebf702 add sensor filters 2021-09-21 14:34:44 +03:00
Викторов Андрей Германович
b8ceec0386 Bump version: 1.0.10b3 → 1.0.10b4 2021-09-21 14:26:04 +03:00
Викторов Андрей Германович
496713cfec add sensor filters 2021-09-21 14:26:00 +03:00
andvikt
1512238763 Bump version: 1.0.10b2 → 1.0.10b3 2021-09-18 22:22:20 +03:00
andvikt
ce1987d0c0 Merge pull request #59 from andvikt/feature/adc328
Feature/adc328
2021-09-18 22:21:30 +03:00
andvikt
b4521a93bb Merge branch 'master' into feature/adc328 2021-09-18 22:21:10 +03:00
andvikt
9322f9cae1 Bump version: 1.0.10b1 → 1.0.10b2 2021-09-18 22:11:56 +03:00
andvikt
52ace90600 add adc support for 328 mega 2021-09-18 22:11:52 +03:00
andvikt
8738a936fe Bump version: 1.0.10b0 → 1.0.10b1 2021-09-18 22:10:50 +03:00
andvikt
2490e09748 add adc support for 328 mega 2021-09-18 22:10:47 +03:00
andvikt
e134a874fa add adc support for 328 mega 2021-09-18 22:08:52 +03:00
andvikt
6fc5391490 Update index.md 2021-09-15 14:09:21 +03:00
andvikt
d37fa11ab3 Merge pull request #58 from andvikt/fix/57
Fix/57
2021-09-15 14:02:52 +03:00
andvikt
1db5670cfd fix #57 2021-09-15 13:59:30 +03:00
andvikt
74b6e200a5 add bumb2version 2021-09-15 13:58:22 +03:00
andvikt
3737bf91a3 Bump version: 1.0.9 → 1.0.10b0 2021-09-15 13:56:37 +03:00
andvikt
747b8e6c36 add bumb2version 2021-09-15 13:56:33 +03:00
andvikt
fec5cef05c add bumb2version 2021-09-15 13:54:34 +03:00
Викторов Андрей Германович
1ec581b08b fix #54 2021-08-26 11:49:26 +03:00
Викторов Андрей Германович
c62a5a2d92 fix formating 2021-08-26 11:16:57 +03:00
Викторов Андрей Германович
b6349eece8 fix formating 2021-08-26 08:40:35 +03:00
Andrey
4300676c23 Merge remote-tracking branch 'origin/master' 2021-08-25 18:39:30 +03:00
Andrey
a78a87662b fix #54 2021-08-25 18:39:15 +03:00
andvikt
530daea77c Update index.md 2021-08-15 16:23:08 +03:00
andvikt
0a72dd0f24 Update mkdocs.yml 2021-08-03 13:26:10 +03:00
andvikt
4ccc0618ce Update index.md 2021-08-03 12:17:25 +03:00
Andrey
eadfc5dce0 add enhance type issue 2021-08-03 12:12:43 +03:00
Andrey
eb7926057f Merge remote-tracking branch 'origin/master' 2021-08-03 12:10:56 +03:00
Andrey
c635cc9b36 add enhance type issue 2021-08-03 12:10:45 +03:00
andvikt
bb73c35f2e Update bug-report.md 2021-08-03 12:06:31 +03:00
andvikt
11c8eba6cb Update main.yml 2021-08-03 11:56:28 +03:00
Andrey
c1029d146c add mkdocs.yml 2021-08-03 11:51:56 +03:00
andvikt
693e2e9901 Update main.yml 2021-08-03 11:50:22 +03:00
andvikt
5795c943f5 Update index.md 2021-08-03 11:48:56 +03:00
andvikt
641531f8dc add mkdocs action 2021-08-03 11:34:07 +03:00
Andrey
7b953d06d5 add new docs 2021-08-03 11:27:19 +03:00
Andrey
912440c079 add new docs 2021-08-03 11:23:53 +03:00
Andrey
54f1ebeda3 fix some issues with brightness after restart 2021-07-29 21:30:41 +03:00
Andrey
87492be38f fix dimmer_scale for PCA9685 2021-07-25 08:36:12 +03:00
Andrey
0fab2384b0 fix patt 2021-04-21 10:08:28 +03:00
Andrey
70a2e5bbb0 fix patt 2021-04-20 17:00:31 +03:00
Andrey
83c843d722 fix validation error 2021-04-20 09:23:36 +03:00
Andrey
af684a6c00 fix validation error 2021-04-20 09:19:37 +03:00
Andrey
d94efbe1a7 add ADS1115
add DEVICE_CLASS_CO2
2021-04-20 09:11:00 +03:00
Andrey
eaa46a99ae fix fw pattern
add dps368 support
fix docs url
2021-04-20 07:37:39 +03:00
Andrey
e65598fe63 fix int mega id 2021-04-20 07:35:59 +03:00
Andrey
e12ab45c04 fix int mega id 2021-04-20 07:35:06 +03:00
Andrey
7fb72be646 add skip sensors 2021-04-19 22:03:30 +03:00
Andrey
f9f97a91b6 add timeouts 2021-04-19 21:46:12 +03:00
Andrey
ad1210d5cc fix some timeouts 2021-03-29 21:43:25 +03:00
Andrey Viktorov
687e80f729 fix empty config while first setup 2021-03-29 19:54:48 +03:00
Andrey Viktorov
7d777c9e82 fix sensors 2021-03-24 18:14:15 +03:00
Andrey Viktorov
c9f0e85f6a edit readme 2021-03-24 17:04:37 +03:00
25 changed files with 892 additions and 119 deletions

21
.bumpversion.cfg Normal file
View File

@@ -0,0 +1,21 @@
[bumpversion]
current_version = 1.0.10b7
parse = (?P<major>\d+)(\.(?P<minor>\d+))(\.(?P<patch>\d+))(?P<release>[bf]*)(?P<build>\d*)
commit = True
tag = True
serialize =
{major}.{minor}.{patch}{release}{build}
{major}.{minor}.{patch}
[bumpversion:part:release]
optional_value = f
values =
b
f
[bumpversion:part:build]
first_value = 0
[bumpversion:file:custom_components/mega/manifest.json]
search = "version": "v{current_version}"
replace = "version": "v{new_version}"

View File

@@ -1,6 +1,6 @@
--- ---
name: Bug report name: Проблема
about: Create a report to help us improve about: Обнаружен баг/проблема
title: '' title: ''
labels: '' labels: ''
assignees: '' assignees: ''
@@ -24,4 +24,4 @@ megad firmware version:
If applicable, add screenshots to help explain your problem. If applicable, add screenshots to help explain your problem.
**LOG** **LOG**
Просьба прикладывать детальный лог, подробная инструкция как включать отладку по [ссылке](https://github.com/andvikt/mega_hacs/wiki/Отладка) Просьба прикладывать детальный лог, подробная инструкция как включать отладку по [ссылке](https://andvikt.github.io/mega_hacs/debug/)

9
.github/ISSUE_TEMPLATE/enhance.md vendored Normal file
View File

@@ -0,0 +1,9 @@
---
name: Улучшение
about: Идея на улучшение интеграции
title: ''
labels: 'enhancement'
assignees: ''
---
**Описание**

17
.github/workflows/main.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
name: Publish docs via GitHub Pages
on:
push:
jobs:
build:
name: Deploy docs
runs-on: ubuntu-latest
steps:
- name: Checkout main
uses: actions/checkout@v2
- name: Deploy docs
uses: mhausenblas/mkdocs-deploy-gh-pages@master
# Or use mhausenblas/mkdocs-deploy-gh-pages@nomaterial to build without the mkdocs-material theme
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -16,7 +16,8 @@ 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, \ 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_MQTT_INPUTS, CONF_HTTP, CONF_RESPONSE_TEMPLATE, CONF_ACTION, CONF_GET_VALUE, CONF_ALLOW_HOSTS, \
CONF_CONV_TEMPLATE, CONF_ALL, CONF_FORCE_D, CONF_DEF_RESPONSE, CONF_FORCE_I2C_SCAN, CONF_HEX_TO_FLOAT, \ CONF_CONV_TEMPLATE, CONF_ALL, CONF_FORCE_D, CONF_DEF_RESPONSE, CONF_FORCE_I2C_SCAN, CONF_HEX_TO_FLOAT, \
RGB_COMBINATIONS, CONF_WS28XX, CONF_ORDER, CONF_SMOOTH, CONF_LED, CONF_WHITE_SEP, CONF_CHIP, CONF_RANGE RGB_COMBINATIONS, CONF_WS28XX, CONF_ORDER, CONF_SMOOTH, CONF_LED, CONF_WHITE_SEP, CONF_CHIP, CONF_RANGE, \
CONF_FILTER_VALUES, CONF_FILTER_SCALE, CONF_FILTER_LOW, CONF_FILTER_HIGH
from .hub import MegaD from .hub import MegaD
from .config_flow import ConfigFlow from .config_flow import ConfigFlow
from .http import MegaView from .http import MegaView
@@ -74,6 +75,10 @@ CUSTOMIZE_PORT = {
vol.Optional(CONF_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_FORCE_I2C_SCAN): bool, vol.Optional(CONF_FORCE_I2C_SCAN): bool,
vol.Optional(CONF_HEX_TO_FLOAT): bool, vol.Optional(CONF_HEX_TO_FLOAT): bool,
vol.Optional(CONF_FILTER_VALUES): [cv.positive_float],
vol.Optional(CONF_FILTER_SCALE): cv.positive_float,
vol.Optional(CONF_FILTER_LOW): cv.positive_float,
vol.Optional(CONF_FILTER_HIGH): cv.positive_float,
vol.Optional(CONF_SMOOTH): cv.time_period_seconds, vol.Optional(CONF_SMOOTH): cv.time_period_seconds,
# vol.Optional(CONF_RANGE): vol.ExactSequence([int, int]), TODO: сделать отбрасывание "плохих" значений # vol.Optional(CONF_RANGE): vol.ExactSequence([int, int]), TODO: сделать отбрасывание "плохих" значений
vol.Optional(str): { vol.Optional(str): {
@@ -99,7 +104,7 @@ CONFIG_SCHEMA = vol.Schema(
{ {
DOMAIN: { DOMAIN: {
vol.Optional(CONF_ALLOW_HOSTS): [str], vol.Optional(CONF_ALLOW_HOSTS): [str],
vol.Required(str, description='id меги из веб-интерфейса'): { vol.Optional(vol.Any(str, int), description='id меги из веб-интерфейса'): {
vol.Optional(CONF_FORCE_D, description='Принудительно слать d после срабатывания входа', default=False): bool, vol.Optional(CONF_FORCE_D, description='Принудительно слать d после срабатывания входа', default=False): bool,
vol.Optional( vol.Optional(
CONF_DEF_RESPONSE, CONF_DEF_RESPONSE,
@@ -111,6 +116,10 @@ CONFIG_SCHEMA = vol.Schema(
CUSTOMIZE_PORT, CUSTOMIZE_PORT,
CUSTOMIZE_DS2413, CUSTOMIZE_DS2413,
), ),
vol.Optional(CONF_FILTER_VALUES): [cv.positive_float],
vol.Optional(CONF_FILTER_SCALE): cv.positive_float,
vol.Optional(CONF_FILTER_LOW): cv.positive_float,
vol.Optional(CONF_FILTER_HIGH): cv.positive_float,
} }
} }
}, },
@@ -210,7 +219,7 @@ async def async_remove_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
id = entry.data.get('id', entry.entry_id) id = entry.data.get('id', entry.entry_id)
hub: MegaD = hass.data[DOMAIN].get(id) hub: MegaD = hass.data[DOMAIN].get(id)
if hub is None: if hub is None:
return return True
_LOGGER.debug(f'remove {id}') _LOGGER.debug(f'remove {id}')
_hubs.pop(id, None) _hubs.pop(id, None)
hass.data[DOMAIN].pop(id, None) hass.data[DOMAIN].pop(id, None)
@@ -221,7 +230,7 @@ async def async_remove_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
if task is not None: if task is not None:
task.cancel() task.cancel()
if hub is None: if hub is None:
return return True
await hub.stop() await hub.stop()
return True return True

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 = 24 VERSION = 25
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):

View File

@@ -45,6 +45,10 @@ CONF_SMOOTH = 'smooth'
CONF_WHITE_SEP = 'white_sep' CONF_WHITE_SEP = 'white_sep'
CONF_CHIP = 'chip' CONF_CHIP = 'chip'
CONF_RANGE = 'range' CONF_RANGE = 'range'
CONF_FILTER_VALUES = 'filter_values'
CONF_FILTER_SCALE = 'filter_scale'
CONF_FILTER_LOW = 'filter_low'
CONF_FILTER_HIGH = 'filter_high'
PLATFORMS = [ PLATFORMS = [
"light", "light",
"switch", "switch",
@@ -64,7 +68,7 @@ LUX = 'lux'
SINGLE_CLICK = 'single' SINGLE_CLICK = 'single'
DOUBLE_CLICK = 'double' DOUBLE_CLICK = 'double'
PATT_FW = re.compile(r'fw:\s(.+)\)') PATT_FW = re.compile(r'fw:\s(.+?)\)')
REMOVE_CONFIG = [ REMOVE_CONFIG = [
'extenders', 'extenders',

View File

@@ -296,7 +296,7 @@ class MegaOutPort(MegaPushEntity):
def max_dim(self): def max_dim(self):
if self.dimmer_scale == 1: if self.dimmer_scale == 1:
return 255 return 255
elif self.dimmer == 16: elif self.dimmer_scale == 16:
return 4095 return 4095
else: else:
return 255 return 255
@@ -421,7 +421,7 @@ class MegaOutPort(MegaPushEntity):
self._last_called = time.time() self._last_called = time.time()
if not self.dimmer: if not self.dimmer:
transition = None transition = None
if not self.is_on: if not self.is_on and (brightness is None or brightness == 0):
brightness = self._restore_brightness brightness = self._restore_brightness
brightness = brightness or self.brightness or 255 brightness = brightness or self.brightness or 255
_prev = safe_int(self.brightness) or 0 _prev = safe_int(self.brightness) or 0

View File

@@ -117,7 +117,7 @@ class MegaView(HomeAssistantView):
_data = data.copy() _data = data.copy()
if e.startswith('ext'): if e.startswith('ext'):
idx = e[3:] idx = e[3:]
pt = f'{pt_orig}e{idx}' pt = f'{pt_orig}e{idx}' if not hub.new_naming else f'{int(pt_orig):02d}e{int(idx):02d}'
_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 # имитация поведения обычного входа, чтобы события обрабатывались аналогично

View File

@@ -91,6 +91,7 @@ class MegaD:
**kwargs, **kwargs,
): ):
"""Initialize.""" """Initialize."""
self.skip_ports = set()
if config is not None: if config is not None:
lg.debug(f'load config: %s', config.data) lg.debug(f'load config: %s', config.data)
self.config = config self.config = config
@@ -157,11 +158,10 @@ class MegaD:
if force_d is not None: if force_d is not None:
self.customize[CONF_FORCE_D] = force_d self.customize[CONF_FORCE_D] = force_d
try: try:
if allow_hosts is not None: if allow_hosts is not None and DOMAIN in hass.data:
allow_hosts = set(allow_hosts.split(';')) allow_hosts = set(allow_hosts.split(';'))
hass.data[DOMAIN][CONF_HTTP].allowed_hosts |= allow_hosts hass.data[DOMAIN][CONF_HTTP].allowed_hosts |= allow_hosts
hass.data[DOMAIN][CONF_HTTP].protected = protected hass.data[DOMAIN][CONF_HTTP].protected = protected
except Exception: except Exception:
self.lg.exception('while setting allowed hosts') self.lg.exception('while setting allowed hosts')
@@ -186,7 +186,10 @@ class MegaD:
continue continue
if x.port in ports: if x.port in ports:
continue continue
await self.get_port(x.port, force_http=True, http_cmd=x.http_cmd) try:
await self.get_port(x.port, force_http=True, http_cmd=x.http_cmd)
except asyncio.TimeoutError:
continue
ports.append(x.port) ports.append(x.port)
@property @property
@@ -233,12 +236,15 @@ class MegaD:
""" """
for x in self.ds2413_ports: for x in self.ds2413_ports:
self.lg.debug(f'poll ds2413 for %s', x) self.lg.debug(f'poll ds2413 for %s', x)
await self.get_port( try:
port=x, await self.get_port(
force_http=True, port=x,
http_cmd='list', force_http=True,
conv=False http_cmd='list',
) conv=False
)
except asyncio.TimeoutError:
continue
async def poll(self): async def poll(self):
""" """
@@ -253,6 +259,7 @@ class MegaD:
ret = await self._update_i2c(x) ret = await self._update_i2c(x)
if isinstance(ret, dict): if isinstance(ret, dict):
self.values.update(ret) self.values.update(ret)
for x in self.extenders: for x in self.extenders:
ret = await self._update_extender(x) ret = await self._update_extender(x)
if not isinstance(ret, dict): if not isinstance(ret, dict):
@@ -290,14 +297,21 @@ class MegaD:
url = f"{url}/?{cmd}" url = f"{url}/?{cmd}"
self.lg.debug('request: %s', url) self.lg.debug('request: %s', url)
async with self._http_lck(priority): async with self._http_lck(priority):
async with aiohttp.request("get", url=url) as req: for _ntry in range(3):
if req.status != 200: try:
self.lg.warning('%s returned %s (%s)', url, req.status, await req.text()) async with aiohttp.request("get", url=url, timeout=aiohttp.ClientTimeout(total=5)) as req:
return None if req.status != 200:
else: self.lg.warning('%s returned %s (%s)', url, req.status, await req.text())
ret = await req.text() return None
self.lg.debug('response %s', ret) else:
return ret ret = await req.text()
self.lg.debug('response %s', ret)
return ret
except asyncio.TimeoutError:
self.lg.warning(f'timeout while requesting {url}')
raise
# await asyncio.sleep(1)
raise asyncio.TimeoutError('after 3 tries')
async def save(self): async def save(self):
await self.send_command(cmd='s') await self.send_command(cmd='s')
@@ -350,7 +364,10 @@ class MegaD:
return {e.port for e in self.entities} return {e.port for e in self.entities}
async def get_all_ports(self, only_out=False, check_skip=False): async def get_all_ports(self, only_out=False, check_skip=False):
ret = await self.request(cmd='all') try:
ret = await self.request(cmd='all')
except asyncio.TimeoutError:
return
for port, x in enumerate(ret.split(';')): for port, x in enumerate(ret.split(';')):
if port in self.ds2413_ports: if port in self.ds2413_ports:
continue continue
@@ -446,7 +463,10 @@ class MegaD:
:param port: :param port:
:return: :return:
""" """
values = await self.request(pt=port, cmd='get') try:
values = await self.request(pt=port, cmd='get')
except asyncio.TimeoutError:
return
ret = {} ret = {}
for i, x in enumerate(values.split(';')): for i, x in enumerate(values.split(';')):
ret[f'{port}e{i}'] = x ret[f'{port}e{i}'] = x
@@ -458,13 +478,21 @@ class MegaD:
:param params: параметры url :param params: параметры url
:return: :return:
""" """
pt = params.get('pt')
if pt in self.skip_ports:
return
if pt is not None:
pass
_params = tuple(params.items()) _params = tuple(params.items())
delay = None delay = None
if 'delay' in params: if 'delay' in params:
delay = params.pop('delay') delay = params.pop('delay')
ret = { try:
_params: await self.request(**params) ret = {
} _params: await self.request(**params)
}
except asyncio.TimeoutError:
return
self.lg.debug('i2c response: %s', ret) self.lg.debug('i2c response: %s', ret)
if delay: if delay:
self.lg.debug('delay %s', delay) self.lg.debug('delay %s', delay)
@@ -510,7 +538,7 @@ class MegaD:
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 not self.new_naming else f'{port:02}e{n:02}' pt = f'{port}e{n}' if not self.new_naming else f'{port:02d}e{n:02d}'
if ext_cfg.ety == '1': if ext_cfg.ety == '1':
ret['light'][pt].append({}) ret['light'][pt].append({})
elif ext_cfg.ety == '0': elif ext_cfg.ety == '0':
@@ -538,6 +566,9 @@ class MegaD:
elif cfg.pty == '4' and cfg.m == '2': elif cfg.pty == '4' and cfg.m == '2':
# scl исключаем из сканирования # scl исключаем из сканирования
continue continue
elif cfg.pty is None and nports < 30:
# вроде как это ADC на 328 меге
ret['sensor'][port].append(dict())
elif cfg.pty in ('3', '2', '4'): elif cfg.pty in ('3', '2', '4'):
http_cmd = 'get' http_cmd = 'get'
if cfg.d == '5' and cfg.pty == '3': if cfg.d == '5' and cfg.pty == '3':

View File

@@ -6,6 +6,7 @@ from homeassistant.const import (
DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_TEMPERATURE,
DEVICE_CLASS_ILLUMINANCE, DEVICE_CLASS_ILLUMINANCE,
DEVICE_CLASS_PRESSURE, DEVICE_CLASS_PRESSURE,
DEVICE_CLASS_CO2,
PERCENTAGE, PERCENTAGE,
LIGHT_LUX, LIGHT_LUX,
TEMP_CELSIUS, TEMP_CELSIUS,
@@ -103,6 +104,10 @@ i2c_classes = {
DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, None), DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, None),
DeviceType(DEVICE_CLASS_HUMIDITY, PERCENTAGE, None) DeviceType(DEVICE_CLASS_HUMIDITY, PERCENTAGE, None)
], ],
'dps368': [
DeviceType(DEVICE_CLASS_PRESSURE, PRESSURE_BAR, None),
DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, None),
],
'mlx90614': [ 'mlx90614': [
Skip, Skip,
DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, 'temp'), DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, 'temp'),
@@ -119,9 +124,21 @@ i2c_classes = {
DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, None), # сенсор встроенный в микросхему DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, None), # сенсор встроенный в микросхему
], ],
't67xx': [ 't67xx': [
DeviceType(None, CONCENTRATION_PARTS_PER_MILLION, None) # для co2 нет класса в HA DeviceType(DEVICE_CLASS_CO2, CONCENTRATION_PARTS_PER_MILLION, None)
], ],
'tmp117': [ 'tmp117': [
DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, None), DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, None),
] ],
'ads1115': [
DeviceType(None, None, 'ch0'),
DeviceType(None, None, 'ch1'),
DeviceType(None, None, 'ch2'),
DeviceType(None, None, 'ch3'),
],
'ads1015': [
DeviceType(None, None, 'ch0'),
DeviceType(None, None, 'ch1'),
DeviceType(None, None, 'ch2'),
DeviceType(None, None, 'ch3'),
],
} }

View File

@@ -2,7 +2,7 @@
"domain": "mega", "domain": "mega",
"name": "mega", "name": "mega",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/mega_hacs", "documentation": "https://github.com/andvikt/mega_hacs",
"requirements": [ "requirements": [
"beautifulsoup4", "beautifulsoup4",
"lxml" "lxml"
@@ -15,5 +15,5 @@
"@andvikt" "@andvikt"
], ],
"issue_tracker": "https://github.com/andvikt/mega_hacs/issues", "issue_tracker": "https://github.com/andvikt/mega_hacs/issues",
"version": "v1.0.1" "version": "v1.0.10b7"
} }

View File

@@ -20,7 +20,8 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.template import Template from homeassistant.helpers.template import Template
from .entities import MegaPushEntity from .entities import MegaPushEntity
from .const import CONF_KEY, TEMP, HUM, W1, W1BUS, CONF_CONV_TEMPLATE, CONF_HEX_TO_FLOAT from .const import CONF_KEY, TEMP, HUM, W1, W1BUS, CONF_CONV_TEMPLATE, CONF_HEX_TO_FLOAT, DOMAIN, CONF_CUSTOM, \
CONF_SKIP, CONF_FILTER_VALUES, CONF_FILTER_SCALE, CONF_FILTER_LOW, CONF_FILTER_HIGH
from .hub import MegaD from .hub import MegaD
import re import re
@@ -84,9 +85,14 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry, asyn
mid = config_entry.data[CONF_ID] mid = config_entry.data[CONF_ID]
hub: MegaD = hass.data['mega'][mid] hub: MegaD = hass.data['mega'][mid]
devices = [] devices = []
customize = hass.data.get(DOMAIN, {}).get(CONF_CUSTOM, {}).get(mid, {})
for tp in ['sensor', 'i2c']: for tp in ['sensor', 'i2c']:
for port, cfg in config_entry.data.get(tp, {}).items(): for port, cfg in config_entry.data.get(tp, {}).items():
port = int_ignore(port) port = int_ignore(port)
c = customize.get(port, {})
if c.get(CONF_SKIP):
hub.skip_ports |= {port}
continue
for data in cfg: for data in cfg:
hub.lg.debug(f'add sensor on port %s with data %s', port, data) hub.lg.debug(f'add sensor on port %s with data %s', port, data)
sensor = _constructors[tp]( sensor = _constructors[tp](
@@ -102,7 +108,45 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry, asyn
async_add_devices(devices) async_add_devices(devices)
class MegaI2C(MegaPushEntity): class FilterBadValues(MegaPushEntity):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._prev_value = None
def filter_value(self, value):
if value in self.filter_values \
or (self.filter_low is not None and value < self.filter_low) \
or (self.filter_high is not None and value > self.filter_high) \
or (
self._prev_value is not None
and self.filter_scale is not None
and (
abs(value - self._prev_value) / self._prev_value > self.filter_scale
)
):
value = self._prev_value
self._prev_value = value
return value
@property
def filter_values(self):
return self.customize.get(CONF_FILTER_VALUES, self.mega.customize.get(CONF_FILTER_VALUES, []))
@property
def filter_scale(self):
return self.customize.get(CONF_FILTER_SCALE, self.mega.customize.get(CONF_FILTER_SCALE, None))
@property
def filter_low(self):
return self.customize.get(CONF_FILTER_LOW, self.mega.customize.get(CONF_FILTER_LOW, None))
@property
def filter_high(self):
return self.customize.get(CONF_FILTER_HIGH, self.mega.customize.get(CONF_FILTER_HIGH, None))
class MegaI2C(FilterBadValues):
def __init__( def __init__(
self, self,
@@ -121,6 +165,14 @@ class MegaI2C(MegaPushEntity):
def customize(self): def customize(self):
return super().customize.get(self.id_suffix, {}) or {} return super().customize.get(self.id_suffix, {}) or {}
@property
def extra_state_attributes(self):
attrs = super().extra_state_attributes or {}
attrs.update({
'i2c_id': self.id_suffix,
})
return attrs
@property @property
def device_class(self): def device_class(self):
return self._device_class return self._device_class
@@ -135,7 +187,7 @@ class MegaI2C(MegaPushEntity):
ret = self.mega.values.get(self._params) ret = self.mega.values.get(self._params)
if self.customize.get(CONF_HEX_TO_FLOAT): if self.customize.get(CONF_HEX_TO_FLOAT):
try: try:
ret = struct.unpack('!f', bytes.fromhex('41973333'))[0] ret = struct.unpack('!f', bytes.fromhex(ret))[0]
except: except:
self.lg.warning(f'could not convert {ret} form hex to float') self.lg.warning(f'could not convert {ret} form hex to float')
tmpl: Template = self.customize.get(CONF_CONV_TEMPLATE, self.customize.get(CONF_VALUE_TEMPLATE)) tmpl: Template = self.customize.get(CONF_CONV_TEMPLATE, self.customize.get(CONF_VALUE_TEMPLATE))
@@ -146,14 +198,15 @@ class MegaI2C(MegaPushEntity):
ret = tmpl.async_render({'value': ret}) ret = tmpl.async_render({'value': ret})
except: except:
ret = ret ret = ret
return ret ret = self.filter_value(ret)
return str(ret)
@property @property
def device_class(self): def device_class(self):
return self._device_class return self._device_class
class Mega1WSensor(MegaPushEntity): class Mega1WSensor(FilterBadValues):
def __init__( def __init__(
self, self,
@@ -175,6 +228,7 @@ class Mega1WSensor(MegaPushEntity):
self._device_class = device_class self._device_class = device_class
self._unit_of_measurement = unit_of_measurement self._unit_of_measurement = unit_of_measurement
self.mega.sensors.append(self) self.mega.sensors.append(self)
self.prev_value = None
@property @property
def unit_of_measurement(self): def unit_of_measurement(self):
@@ -228,7 +282,8 @@ class Mega1WSensor(MegaPushEntity):
ret = float(ret) ret = float(ret)
ret = str(ret) ret = str(ret)
except: except:
ret = None self.lg.warning(f'could not convert to float "{ret}"')
ret = self.prev_value
if self.customize.get(CONF_HEX_TO_FLOAT): if self.customize.get(CONF_HEX_TO_FLOAT):
try: try:
ret = struct.unpack('!f', bytes.fromhex(ret))[0] ret = struct.unpack('!f', bytes.fromhex(ret))[0]
@@ -242,7 +297,9 @@ class Mega1WSensor(MegaPushEntity):
ret = tmpl.async_render({'value': ret}) ret = tmpl.async_render({'value': ret})
except: except:
pass pass
return ret ret = self.filter_value(ret)
self.prev_value = ret
return str(ret)
@property @property
def name(self): def name(self):

58
docs/blueprints.md Normal file
View File

@@ -0,0 +1,58 @@
**blueprints** - это удобные шаблоны автоматизаций, которые помогают строить автоматизацию из
интерфейса и ими легко делиться. Все ваши шаблоны доступны из специального меню.
[![Open your Home Assistant instance and show your blueprints.](https://my.home-assistant.io/badges/blueprints.svg)](https://my.home-assistant.io/redirect/blueprints/)
[Официальная документация по blueprints](https://www.home-assistant.io/docs/blueprint/)
## Общее
Здесь я делюсь шаблонами, в которых используются события из моей интеграции.
Если вы хотите сделать что-то подобное своими руками, то можно использовать мои шаблоны как отправную точку.
Во всех шаблонах в качестве триггера используется событие **mega.binary** и доступен выбор типа,
[подробное описание типов здесь](events.md#binary).
## Включить что-то
Этот шаблон лучше всего подходит для включения сценариев/сцен или любых других объектов по нажатию какой-то кнопки или
обнаружению движения.
!!! note "Движение"
Датчики движения - это такие же *binary_sensor* как и обычные выключатели. В зависимости от настроек контроллера
будут приходить события либо типа **single** (если настроен режим click), либо **press**
Опционально так же доступна настройка автоматического выключения по таймеру, если указан 0 (по умолчанию), таймер не
будет использован.
Опционально доступен так же *блокирующий объект* и *период блокировки*. Например, если в одной комнате с датчиком
движения есть выключатель, тогда его можно указать как *блокирующий объект* и в течении *периода блокировки*
после нажатия выключателя события с датчика движения будут игнорироваться.
[![Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.](https://my.home-assistant.io/badges/blueprint_import.svg)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgist.github.com%2Fandvikt%2Fb78459f4f43862d04c7fbba20d6893c7)
[Исходный код](https://gist.github.com/andvikt/b78459f4f43862d04c7fbba20d6893c7)
## Переключить состояние
Классическое управление светом с кнопки без фиксации: нажали кнопку - свет выключился, если он сейчас включен, и наоборот.
Если вам нужно управлять несколькими светильниками, то необходимо будет
[создать группу света](https://www.home-assistant.io/integrations/light.group/)
[![Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.](https://my.home-assistant.io/badges/blueprint_import.svg)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgist.github.com%2Fandvikt%2Fefb48535b1b9d998fe3dbe9a3efcea2c)
[Исходный код](https://gist.github.com/andvikt/efb48535b1b9d998fe3dbe9a3efcea2c)
## Выключатель с фиксацией
Если выбран тип "нестрогий", то при каждом переключении состояния выключателя состоянии целевого объекта так же будет
меняться. Этот режим рекомендуется, тк в случае переключения состояния с сервера, в случае со строгим типом будет
"рассинхрон" - вам придется сначала выключатель привести в соответствие с текущим состоянием света.
Если выбран тип "строгий", то будет строгое соответсвие состояний, те выкл==выкл и наоборот.
[![Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.](https://my.home-assistant.io/badges/blueprint_import.svg)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgist.github.com%2Fandvikt%2F9addf966db75d0964143177963f40bb9)
[Исходный код](https://gist.github.com/andvikt/9addf966db75d0964143177963f40bb9)
## Универсальный шаблон
Универсальный шаблон, с помощью которого можно выбрать любое событие меги, привязать
к нему набор произвольных действий
[![Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.](https://my.home-assistant.io/badges/blueprint_import.svg)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgist.github.com%2Fandvikt%2Fbe1f683d308050b8972f9efa8aec465f)
[Исходный код](https://gist.github.com/andvikt/be1f683d308050b8972f9efa8aec465f)

15
docs/debug.md Normal file
View File

@@ -0,0 +1,15 @@
[Сообщить о проблеме](https://github.com/andvikt/mega_hacs/issues/new?assignees=&labels=&template=bug-report.md&title=){ .md-button .md-button--primary }
В первую очередь проверьте лог на наличие ошибок, доступ к логу возможен по кнопке ниже.
[![Open your Home Assistant instance and show your Home Assistant logs.](https://my.home-assistant.io/badges/logs.svg)](https://my.home-assistant.io/redirect/logs/)
Так же будет очень полезно прикладывать детальный лог, который можно включить в конфиге так:
```yaml
logger:
default: info
logs:
custom_components.mega: debug
```
Для просмотра логов рекомендуется использовать [logviewer](https://github.com/hassio-addons/addon-log-viewer)

66
docs/events.md Normal file
View File

@@ -0,0 +1,66 @@
Для быстрого старта рекомендую попробовать [мои шаблоны автоматизаций](blueprints.md)
## mega.binary {: #binary}
События можно использовать только в автоматизациях как триггер типа *event*
```yaml
- alias: some long click
trigger:
- platform: event
event_type: mega.binary
event_data:
entity_id: binary_sensor.some_id
type: long
action:
- service: light.toggle
entity_id: light.some_light
```
!!! note "Возможные варианты поля type"
- **press**: замыкание
- **release**: размыкание (с гарантией, что не было долгого нажатия)
*Эти типы доступны только в режиме click (настраивается на контроллере):*
- **long**: долгое нажатие
- **long_release**: размыкание после долгого нажатия
- **single**: одинарный клик (в режиме кликов)
- **double**: двойной клик
## mega.sensor
Этот вид событий более "технический", им имеет смысл пользоваться только если функциональности *mega.binary* не
достаточно.
```yaml
# событие при перезагрузке меги
- alias: mega restart
trigger:
- platform: event
event_type: mega.sensor
event_data:
st: 1
action:
# какой-то экшн
# Пример события с полями как есть прямо из меги
- alias: some double click
trigger:
- platform: event
event_type: mega.sensor
event_data:
pt: 1
click: 2
action:
- service: light.toggle
entity_id: light.some_light
```
!!! note "События могут содержать следующие поля в event_data"
- **mega_id**: id как в конфиге HA
- **pt**: номер порта
- **cnt**: счетчик срабатываний
- **mdid**: id как в конфиге контроллера
- **click**: клик (подробнее в документации меги)
- **port**: номер порта
## Отладка
Чтобы понять, какие события приходят, лучше всего воспользоваться панелью разработчика (кнопка ниже) и подписаться
на вкладке события на событие `mega.binary` или `mega.sensor`, понажимать физические кнопки на меге.
[![Open your Home Assistant instance and show your event developer tools.](https://my.home-assistant.io/badges/developer_events.svg)](https://my.home-assistant.io/redirect/developer_events/)

64
docs/http.md Normal file
View File

@@ -0,0 +1,64 @@
Контроллер оповещает сервер о своих событиях, например, нажали кнопку выключателя или сработал датчик движения,
для этого в интеграции реализован http-сервер, для его работы необходимо прописать
в настройках меги следующие параметры:
```yaml
srv: "192.168.1.4:8123" # ip:port вашего HA
script: "mega" # это api интеграции, к которому будет обращаться контроллер
```
!!! note "Внимание!"
Не используйте **srv loop** на контроллере - это может приводить к ложным срабатываниям входов. Вместо srv loop
интеграция будет сама обновлять все состояния портов с заданным интервалом
За события будут отвечать объекты типа *binary_sensor* - их статус будет меняться на **on** при замыкании
контакта, на **off** при размыкании, а так же для более сложного контроля (двойные, долгие нажатия) предусмотрены
события с типом *mega.binary*, [об этом подробнее в разделе события](events.md)
Так же вы можете [воспользоваться моими шаблонами автоматизаций](blueprints.md) для быстрого понимания, как всем этим
пользоваться.
## Ответ на входящие события от контроллера
Контроллер ожидает ответ от сервера, который может быть сценарием (по умолчанию интеграция отвечает `d`, что означает
запустить то что прописано в поле act в настройках порта).
*Внимание!* По умолчанию в настройках интеграции стоит опция `имитация ответа` - это означает, что сервер вместо ответа
делает запрос к меге с необходимой командой - это вынужденная мера, тк встроенный в HA сервер разбивает пакет на части,
а контроллер не работает с такими пакетами. В целом, `имитация ответа` полностью закрывает эту проблему, единственный
недостаток - это небольшая задержка в ответе.
Для максимальной скорости реакции, можно воспользоваться
[аддоном](https://github.com/andvikt/mega_addon/tree/master/mega-proxy), подробности в документации аддона.
[Поддерживаются шаблоны HA.](yaml.md#binary) Это может быть использовано, например, для запоминания яркости (тк сам контроллер этого не
умеет).
## Отладка шаблонов {: #temp-debug }
Отладку шаблонов рекомендуется проводить в специальном меню HA, которое находится в `Панель разработчика` - `Шаблоны`
Вот пример, с которого можно начать:
```yaml
{## Переменные, которые передает контроллер, указываются только в тесте ##}
{% set m = 1%}
{% set pt = 2%}
{% set mdid = 'mega'%}
{## Шаблон ответа ##}
{% if m in [0, 1] %}d{% endif %}
```
## Отладка ответов http-сервера {: #http-response }
Для отладки ответов сервера можно самим имитировать запросы контроллера, если у вас есть доступ к консоли HA:
```shell
curl -v -X GET 'http://localhost:8123/mega?pt=5&m=1&mdid=mymega1'
```
Где mymega1 - id устройства mega, который нужно узнать по url `http://192.168.1.14/sec/?cf=2`
При этом необходимо так же в настройках интеграции прописать хост, с которого вы будете обращаться,
[подробнее](yaml.md#allow_hosts)
И тогда можно с локальной машины делать запросы на ваш сервер HA:
```shell
curl -v -X GET 'http://192.168.88.1.4:8123/mega?pt=5&m=1&mdid=mymega1'
```
В ответ будет приходить либо d, либо скрипт, который вы настроили

29
docs/i2c.md Normal file
View File

@@ -0,0 +1,29 @@
I2C-датчики будут добавлены автоматически в HA с названием, соответствующим порту, типу и адресу
(если необходим), название и entity_id вы всегда можете поменять из интерфейса HA, [а также дополнительно их
кастомизировать с помощью yaml](yaml.md#sensors).
Как и все остальные датчики, i2c подчиняется единому интервалу обновления, который указывается в меню интеграции.
## Список i2c-датчиков, поддерживаемых интеграцией: {: #list}
!!! note ""
Под поддерживаемыми подразумеваются те датчики, у которых учтены все возможные
дополнительные значения, а так же корректно определены типы
Неподдерживаемые датчики все равно будут работать, но будет отображаться только основное значение (i2c_par=0),
а тип будет определен как общий, универсальный для всех датчиков.
- HTU21D/Si7021
- SHT31
- MAX44009
- BH1750
- TSL2591
- BMP180
- BME280
- T6703/T67xx
- MLX90614
- PTsensor
- MCP9600
- DPS368
- ADS1115/ADS1015
Так же заводите issue если какой-то датчик отсутсвует в этом списке, но поддерживается контроллером.

71
docs/index.md Normal file
View File

@@ -0,0 +1,71 @@
# MegaD HomeAssistant integration
[![hacs_badge](https://img.shields.io/badge/HACS-Custom-orange.svg)](https://github.com/custom-components/hacs)
[![Donate](https://img.shields.io/badge/donate-Yandex-red.svg)](https://yoomoney.ru/to/410013955329136)
<a class="github-button" href="https://github.com/andvikt/mega_hacs" data-icon="octicon-star" data-show-count="true" aria-label="Star andvikt/mega_hacs on GitHub">Star</a>
[Сообщить о проблеме](https://github.com/andvikt/mega_hacs/issues/new?assignees=&labels=&template=bug-report.md&title=){ .md-button .md-button--primary }
[Предложение об улучшении](https://github.com/andvikt/mega_hacs/issues/new?assignees=&labels=enhancement&template=enhance.md&title=){ .md-button .md-button--primary }
Интеграция с [MegaD-2561, MegaD-328](https://www.ab-log.ru/smart-house/ethernet/megad-2561)
Если вам понравилась интеграция, не забудьте поставить звезду на гитхабе - вам не сложно, а мне приятно ) А если
интеграция очень понравилась - еще приятнее, если вы воспользуетесь кнопкой доната )
Обновление прошивки MegaD можно делать прямо из HA с помощью [аддона](https://github.com/andvikt/mega_addon.git)
## Основные особенности {: #mains }
- Настройка в [веб-интерфейсе](settings.md) + [yaml](yaml.md)
- Все порты автоматически добавляются как устройства (для обычных релейных выходов создается
`light`, для шим - `light` с поддержкой яркости, для цифровых входов `binary_sensor`, для датчиков
`sensor`)
- Поддержка rgb+w лент как с использованием диммеров, так и адресных лент на чипах ws28xx и подобных,
[подробнее про rgbw](yaml.md#rgb)
- Плавное диммирование для любых диммируемых объектов (в том числе с аппаратной поддержкой и без),
[подробнее про smooth](smooth.md)
- Возможность работы с несколькими megad
- Обратная связь по [http](http.md)
- Автоматическое восстановление состояний выходов после перезагрузки контроллера
- Автоматическое добавление/изменение объектов после перезагрузки контроллера
- [События](events.md) на двойные/долгие нажатия
- Команды выполняются друг за другом без конкурентного доступа к ресурсам megad, это дает гарантии надежного исполнения
большого кол-ва команд (например в сценах). Каждая следующая команда отправляется только после получения ответа о
выполнении предыдущей.
- поддержка [ds2413](https://www.ab-log.ru/smart-house/ethernet/megad-2w) в том числе несколько шиной (начиная с версии 0.4.1)
- поддержка расширителей MegaD-16I-XT, MegaD-16R-XT, MegaD-16PWM (начиная с версии 0.5.1)
- поддержка всех возможных датчиков в режиме I2C-ANY, полный список поддерживаемых датчиков
[по ссылке](i2c.md) (начиная с версии 0.6.1)
## Установка {: #install}
Если вы уже раньше устанавливали HACS, то просто поищите в списке интеграций HACS MegaD, если нет, то сначла необходимо
установить HACS - это витрина сторонних интеграций. [Инструкция по установке](https://hacs.xyz/docs/installation/installation)
Далее внутри интерфейса HACS ищем MegaD: `HACS - Integrations - Explore`, в поиске ищем MegaD.
На этом установка не закончена, вам потребуется прописать настройки каждого контроллера, [подробнее](settings.md)
!!! note "Альтернативный способ установки"
Откройте терминал (стандартный аддон Terminal & SSH, если у вас есть supervisor, если нет то терминал вашей системы)
```shell
# из папки с конфигом
wget -q -O - https://raw.githubusercontent.com/andvikt/mega_hacs/master/install.sh | bash -
```
Не забываем перезагрузить HA
## Обновления
Обновления выполняются так же в меню HACS.
Информация об обновлениях приходит с некоторым интервалом, чтобы вручную проверить наличие обновлений
нажмите три точки возле интеграции в меню HACS и нажмите `обновить информацию`
## Беты {: #beta }
Иногда я буду выпускать бета-версии, в стабильности которых пока не уверен и не готов раскатывать на всех, поэтому в целях тестирвоания
нужно принудительно включать поддержку бет, для этого зайдите в HACS, найдите интеграцию MegaD, нажмите три точки,
там кнопка "переустановить" или reinstall, дальше нужно нажать галку "показывать бета-версии"
## Зависимости {: #deps }
Для максимальной скорости реакции на команды сервера, рекомендуется выключить `имитацию http-ответа` в
настройках интеграции и настроить proxy_pass к HA, самый простой способ сделать это - воспользоваться
[специальным аддоном](https://github.com/andvikt/mega_addon/tree/master/mega-proxy)
Обновить ваш контроллер до последней версии, обновление прошивки MegaD можно делать
из HA с помощью [аддона](https://github.com/andvikt/mega_addon.git)

32
docs/services.md Normal file
View File

@@ -0,0 +1,32 @@
Все сервисы доступны в меню разработчика с описанием и примерами использования
```yaml
mega.save:
description: Сохраняет текущее состояние портов (?cmd=s)
fields:
mega_id:
description: ID меги, можно оставить пустым, тогда будут сохранены все зарегистрированные меги
example: "mega"
mega.get_port:
description: Запросить текущий статус порта (или всех)
fields:
mega_id:
description: ID меги, можно оставить пустым, тогда будут порты всех зарегистрированных мег
example: "mega"
port:
description: Номер порта (если не заполнять, будут запрошены все порты сразу)
example: 1
mega.run_cmd:
description: Выполнить любую произвольную команду
fields:
mega_id:
description: ID меги
example: "mega"
port:
description: Номер порта (это не порт, которым мы управляем, а порт с которого шлем команду)
example: 1
cmd:
description: Любая поддерживаемая мегой команда
example: "1:0"
```

16
docs/settings.md Normal file
View File

@@ -0,0 +1,16 @@
[После успешной установки интеграции в HACS](index.md#install), необходимо настроить
каждый контроллер, проще всего сделать это по этой кнопке:
[![Добавить интеграцию](https://my.home-assistant.io/badges/config_flow_start.svg)](https://my.home-assistant.io/redirect/config_flow_start/?domain=mega)
Все имеющиеся у вас порты будут настроены автоматически. Вы можете менять названия, иконки и entity_id так же из интерфейса.
В самой меге необходимо прописать настройки:
```yaml
srv: "192.168.1.4:8123" # ip:port вашего HA
script: "mega" # это api интеграции, к которому будет обращаться контроллер
```
Так же необходимо настроить Mega-ID в настройках контроллера, для каждой меги id должен быть разным.
При любых изменениях настроек контроллера (типы входов, id и тд) необходимо в настройках интеграции нажать `Обновить
объекты`

50
docs/smooth.md Normal file
View File

@@ -0,0 +1,50 @@
Начиная с версии `1.0.0` интеграция поддерживает плавные переходы. Функция реализована
как на аппаратном уровне, так и на программном.
Для аппаратной поддержки в настройках контроллера диммируемого порта необходимо включить опцию smooth.
В чем разница между аппаратной и программной реализацией? Контроллер на аппаратном уровне умеет медленно
менять значение pwm-порта, рекомендуется для всех портов с поддержкой этого режима использовать именно его,
тк будет обеспечена максимальная плавность для любого числа устройств одновременно.
Плавность программного диммирования ограничена ресурсами вашего сервера и скоростью ответа контроллера,
если вы будете довольно быстро (за пару секунд) диммировать сразу группу
света из нескольких светильков, то в программной реализации возможно увидеть скачки.
Тем не менее, pwm-расширитель не умеет аппаратно сглаживать диммирование, поэтому для него есть смысл воспользоваться
программной реализацией
Для запуска плавного перехода можно воспользоваться штатными сервисами, например:
```yaml
action:
service: light.turn_on
entity_id: light.some_light
data:
# свет будет плавно включаться в течении 30 секунд
brightness_pct: 50
transition: 10 # кол-во секунд на переход
```
Так же любые диммируемые каналы могут участвовать в сценах, а эти сцены в свою очередь будут поддерживать опцию transition:
```yaml
action:
service: scene.turn_on
target:
entity_id: scene.romantic
data:
transition: 2.5
```
Плавность реализована в любых диммируемых объектах: свет, rgb-ленты.
Кроме того, возможно установить плавность по-умолчанию (имеет смысл использовать на pwm-расширителе), для этого в yaml-конфиге
следует добавить опцию smooth:
```yaml
mega:
mega1:
10e1:
smooth: 1 # если указать, то порт будет диммироваться плавно (от 0 до 100% за <smooth> секунд)
# опцию smooth можно использовать и на обычном pwm-порте, но в этом мало необходимости, лучше использовать
# встроенный в контроллер механизм smooth
```
Для светодиодных лент smooth по умолчанию установлен в 1 секунду,
подробнее [тут](yaml.md#rgb)

245
docs/yaml.md Normal file
View File

@@ -0,0 +1,245 @@
С помощью yaml-конфигурации можно кастомизировать ваши устройства.
## Основное
Конфиг записывается стандартным образом в файл `configuration.yaml`, начинаем с
указания названия интеграции:
```yaml hl_lines="1"
mega:
megaid1:
10:
domain: switch
invert: true
megaid2:
14:
hex_to_float: true
```
Далее каждый новый контроллер добавляется с помощью указания его id, который вы
придумали при установке интеграции
```yaml hl_lines="2 6"
mega:
megaid1:
10:
domain: switch
invert: true
megaid2:
14:
hex_to_float: true
```
Далее конфигурируются порты:
```yaml hl_lines="3 4 5 7 8"
mega:
megaid1:
10:
domain: switch
invert: true
megaid2:
14:
hex_to_float: true
```
## Параметры устройств
В зависимости от типа порта доступны разные параметры. Все параметры опциональные, в скобках приведены типы и дефолтные
значения.
### Стандартный набор параметров
Все устройства вне зависимости от типа
!!! note ""
- **skip** (bool, false): пропустить или нет. Если true - устройство будет исключено из списка
- **name** (str): имя, используется в интерфейсе
### Реле
!!! note ""
- **domain** (str, light): тип устройства. Можно выбрать light или switch
- **invert** (bool, false): инвертировать или нет.
### ds2413
Те же параметры, что у реле, но записываются иначе:
```yaml
10:
c6c439000000_a: #c6c439000000 - это адрес ds2413, a-первый канал
# параметры
c6c439000000_b: #b-второй канал
```
### Диммеры
!!! note ""
- **smooth** (float, 0): программное плавное диммирование. Это поле отвечает за кол-во секунд, за которое яркость
диммера набирает от 0 до 100%
- **limits** (list[int, int], [0, 255]), *начиная с версии 1.1.0*: границы диммирования в абсолютных единицах контроллера. При диммировании 1%
будет равен левой границе, 100% - правой.
[Подробнее про плавное диммирование](smooth.md)
### MegaD-16R-XT, MegaD-16PWM
Порты расширителей MegaD-16R-XT, MegaD-16PWM конфигурируются аналогично обычным реле и диммерам, но адресация порта
выглядит так:
```yaml
33e1: # 33-основной порт, на котором сидит расширитель, e1-дополнительный порт расширителя
# стандартный конфиг порта
33e2:
```
### RGB+W {: #rgb}
Для настройки rgb(w) лент существует специальный раздел `led` в настройках каждого контроллера:
```yaml hl_lines="3"
mega:
megaid1:
led:
ledid1: # id, который вы придумываете сами
# конфиг
```
Далее интеграция имеет поддержку двух типов лент
#### На диммерах
Интеграция может превратить любые 3 (или 4) диммера (актуально для мосфетов на pwm-расширителе или моноблоке)
в rgb(w) контроллер с интерфейсом выбора цвета. Конфиг для такого типа ленты будет выглядеть так:
!!! note ""
- **ports** (list\[str\]): список номеров портов, из которых составлять ленту, все порты должны быть типа PWM.
Порядок цветов строго \[R, G, B, W\]. W указывается опционально
- **white_sep** (bool, true): яркостью белого можно управлять в двух режимах - синхронно с яркостью RGB, либо
отдельно, по умолчанию стоит отдельно (true)
- **smooth** (float, 1): скорость диммирования, от 0 до 100% за <smooth> секунд.
Пример:
```yaml
some_led1:
ports: [10, 12, 15, 16]
white_sep: true
smooth: 2
```
#### Адресные ленты на WS281X
Подробно про поддержку контроллера таких лент рассказано в [инструкции](https://www.ab-log.ru/smart-house/ethernet/megad-2561#ws).
Интеграция не привносит ничего нового - только помогает "пробросить" такие ленты в интерфейс HA.
Конфиг таких лент выглядит так:
!!! note ""
- **ws28xx** (bool, false): обязательное поле, необходимо установить true.
- **port** (int): номер порта, на котором настроена лента.
- **order** (str, "rgb"): последовательность каналов, допускаются любые комбинации букв r,g,b: rbg, bgr и тд
- **chip** (int, 100): кол-во чипов в ленте, по умолчанию 100, если их меньше емеет смысл указать правильное кол-во
для увеличения скорости плавного диммирования
- **smooth** (float, 1): скорость диммирования, от 0 до 100% за <smooth> секунд.
Пример:
```yaml
some_led2:
ws28xx: true
port: 36
order: bgr
smooth: 2
```
### Бинарные сенсоры {: #binary}
Или по-другому цифровые входы. Как правило используются для выключателей, кнопок, датчиков движения и тд.
!!! note ""
- **response_template** (str): шаблон ответа на команды сервера. По-умолчанию d.
Про формат ответа подробно описано [тут](https://www.ab-log.ru/smart-house/ethernet/megad-2561#conf-in-act).
В шаблоне можно использовать параметры, которые передает контроллер (m, click, pt, mdid, mega_id).
Про отладку шаблонов подробнее [тут](http.md#temp-debug)
!!! note "на меге"
Для корректной работы binary_sensor имеет смысл использовать режим P&R в настройках порта меги
Бинарные сенсоры так же отвечают за события типа *mega.binary*, [об этом подробнее в разделе события](events.md)
Примеры шаблонов ответа:
```yaml
4:
response_template: "5:2" # простейший пример без шаблона. Каждый раз когда будет приходить сообщение на этот порт,
# будем менять состояние на противоположное
5:
# пример с использованием шаблона, порт 1 будет выключен если он сейчас включен и включен с последней сохраненной
# яркостью если он сейчас выключен
response_template: >-
{% if is_state('light.some_port_1', 'on') %}
1:0
{% else %}
1:{{state_attr('light.some_port_1', 'brightness')}}
{% endif %}
6:
# в шаблон так же передаются все параметры, которые передает контроллер (pt, cnt, m, click)
# эти параметры можно использовать в условиях или непосредственно в шаблоне в виде {{pt}}
response_template: >-
{% if m==2 %}1:0{% else %}d{% endif %}
```
### Датчики {: #sensors }
Любой датчик будь то i2c или аналоговый или 1-wire
!!! note ""
- **unit_of_measurement** (str): единицы измерения, [список доступных](https://developers.home-assistant.io/docs/core/entity/sensor#available-device-classes)
- **value_template** (str): шаблон для конвертации, например `{{(value|float)/100}}`
- **device_class** (str): класс устройства, [список доступных](https://developers.home-assistant.io/docs/core/entity/sensor#available-device-classes)
- **hex_to_float** (bool, false): если ваш датчик возвращает float запакованный в HEX, интеграция его распакует (перед применением темплейта)
- **filter_high** (float, none): верхняя граница значений, выше нее значения будут считаться ошибочными и отбрасываться. [Доступно так же глобальное значение](#filter_high)
- **filter_low** (float, none): нижняя граница значений, ниже нее значения будут считаться ошибочными и отбрасываться. [Доступно так же глобальное значение](#filter_low)
- **filter_values** ([float], none): список значений, которые считаются ошибочными. [Доступно так же глобальное значение](#filter_values)
- **filter_scale** (float, none): значение отклонения от текущего значения, которое будет считаться выбросом и отфильтруется, например если
установить 1, то это означает, что при росте показателя сенсора на 100% и больше или падении на 100% и больше, такое значение не будет отображаться.
[Доступно так же глобальное значение](#filter_scale)
При этом есть так же особенности адресации, так для сенсора на одном порте с одним значением:
```yaml
36:
# конфиг
```
#### DHT11/22
На этих сенсорах два значения, одно для температуры, второе для влажности, поэтому для них применяется
особый вид адресации:
```yaml
35:
name:
hum: "влажность"
temp: "температура"
# и так далее для любого параметра сенсоров
```
Логика так себе ) Но так повелось в первых версиях.
#### 1W-BUS
Для датчиков установленных в шину 1-wire адресация кастомизации такая:
```yaml
35:
addr: # адрес датчика, по-умолчанию entity_id будет состоять из адреса и типа
# конфиг
```
#### i2c {: #i2c}
Для сенсоров i2c нужно так же указать id сенсора, который можно посмотреть в атрибутах объекта на [странице разработчика](https://my.home-assistant.io/redirect/developer_states/).
```yaml
36:
htu21d_humidity: # i2c_id
# конфиг
```
[Подробнее про i2c](i2c.md)
## Параметры контроллера
Некоторые параметры применяются для всего контроллера (одна мега)
### def_response
Шаблон ответа сервера по умолчанию. Если этот параметр указан, то настройка "d по умолчанию"
в UI игнорируется.
Пример:
```yaml
mega:
megaid1:
def_response: >-
{% if m in [0, 1] %}d{% endif %}
```
## Параметры интеграции
### allow_hosts {: #allow_hosts }
Отвечает за список хостов, с которых интеграция "слушает" сообщения. По умолчанию, в этот список
входят все настроенные меги, а так же все запросы с локального хоста.
Иногда, в целях отладки, требуется расширить этот список, что можно сделать следующим оьразом:
```yaml
mega:
allow_hosts:
- 192.168.1.20
```
### filter_high {: #filter_high}
Верхняя граница значений датчиков по-умолчанию, выше нее значения будут считаться ошибочными и отбрасываться
### filter_low {: #filter_low}
Нижняя граница значений датчиков по-умолчанию, ниже нее значения будут считаться ошибочными и отбрасываться
### filter_values {: #filter_values }
Список значений, которые считаются ошибочными, настройка по-умолчанию для всех датчиков. Удобно, если у вас много
однотипных датчиков
```yaml
mega:
filter_values: [-82, - 150]
```
### filter_scale {: #filter_scale }
Значение отклонения от текущего значения, которое будет считаться выбросом и отфильтруется, например если
установить 1, то это означает, что при росте показателя сенсора на 100% и больше или падении на 100% и больше, такое значение не будет отображаться.
```yaml
mega:
filter_scale: 1 # 100%
```

34
mkdocs.yml Normal file
View File

@@ -0,0 +1,34 @@
site_name: MegaD HomeAssistant integration
repo_url: https://github.com/andvikt/mega_hacs
site_url: http://127.0.0.1:8000
extra:
disqus: mega-hacs
analytics:
provider: google
property: G-E3LX9D6959
theme:
name: material
markdown_extensions:
- toc:
permalink: "#"
- attr_list:
- pymdownx.highlight
- pymdownx.superfences
- admonition
plugins:
- search
nav:
- Главное: index.md
- Конфигурация:
- В интерфейсе: settings.md
- Настройка обратной связи: http.md
- YAML-конфиг: yaml.md
- i2c: i2c.md
- Плавные переходы: smooth.md
- Автоматизация:
- Шаблоны (Blueprints): blueprints.md
- События: events.md
- Сервисы: services.md
- Неполадки: debug.md
extra_javascript:
- "https://buttons.github.io/buttons.js"

View File

@@ -9,76 +9,4 @@
Если вам понравилась интеграция, не забудьте поставить звезду на гитхабе - вам не сложно, а мне приятно ) А если Если вам понравилась интеграция, не забудьте поставить звезду на гитхабе - вам не сложно, а мне приятно ) А если
интеграция очень понравилась - еще приятнее, если вы воспользуетесь кнопкой доната ) интеграция очень понравилась - еще приятнее, если вы воспользуетесь кнопкой доната )
Обновление прошивки MegaD можно делать прямо из HA с помощью [аддона](https://github.com/andvikt/mega_addon.git) [Подробная документация](https://andvikt.github.io/mega_hacs/)
Подробная документация по [ссылке](https://github.com/andvikt/mega_hacs/wiki)
Предложения по доработкам просьба писать в [discussions](https://github.com/andvikt/mega_hacs/discussions), о проблемах
создавать [issue](https://github.com/andvikt/mega_hacs/issues/new/choose)
## Основные особенности:
- Настройка в веб-интерфейсе + [yaml](https://github.com/andvikt/mega_hacs/wiki/Кастомизация)
- Все порты автоматически добавляются как устройства (для обычных релейных выходов создается
`light`, для шим - `light` с поддержкой яркости, для цифровых входов `binary_sensor`, для датчиков
`sensor`)
- Поддержка rgb+w лент как с использованием диммеров, так и адресных лент на чипах ws28xx и подобных,
[подробнее про rgbw](https://github.com/andvikt/mega_hacs/wiki/rgbw)
- Плавное диммирование для любых диммируемых объектов (в том числе с аппаратной поддержкой и без),
[подробнее про smooth](https://github.com/andvikt/mega_hacs/wiki/smooth)
- Возможность работы с несколькими megad
- Обратная связь по [http](https://github.com/andvikt/mega_hacs/wiki/http)
будет выключена в версиях >= 1.0.0, тк в нем нет необходимости)
- Автоматическое восстановление состояний выходов после перезагрузки контроллера
- Автоматическое добавление/изменение объектов после перезагрузки контроллера
- [События](https://github.com/andvikt/mega_hacs/wiki/События) на двойные/долгие нажатия
- Команды выполняются друг за другом без конкурентного доступа к ресурсам megad, это дает гарантии надежного исполнения
большого кол-ва команд (например в сценах). Каждая следующая команда отправляется только после получения ответа о
выполнении предыдущей.
- поддержка [ds2413](https://www.ab-log.ru/smart-house/ethernet/megad-2w) в том числе несколько шиной (начиная с версии 0.4.1)
- поддержка расширителей MegaD-16I-XT, MegaD-16R-XT, MegaD-16PWM (начиная с версии 0.5.1)
- поддержка всех возможных датчиков в режиме I2C-ANY, полный список поддерживаемых датчиков
[по ссылке](https://github.com/andvikt/mega_hacs/wiki/i2c) (начиная с версии 0.6.1)
## Установка
Рекомендованный способ с поддержкой обновлений - [HACS](https://hacs.xyz/docs/installation/installation):
HACS - Integrations - Explore, в поиске ищем MegaD.
Чтобы включить возможность использования бета-версий, зайдите в HACS, найдите интеграцию MegaD, нажмите три точки,
там кнопка "переустановить" или reinstall, дальше нужно нажать галку "показывать бета-версии"
Обновления выполняются так же в меню HACS.
Информация об обновлениях приходит с некоторым интервалом, чтобы вручную проверить наличие обновлений
нажмите три точки возле интеграции в меню HACS и нажмите `обновить информацию`
Альтернативный способ установки:
```shell
# из папки с конфигом
wget -q -O - https://raw.githubusercontent.com/andvikt/mega_hacs/master/install.sh | bash -
```
Не забываем перезагрузить HA
## Настройка
`Настройки` -> `Интеграции` -> `Добавить интеграцию` в поиске ищем mega
Все имеющиеся у вас порты будут настроены автоматически. Вы можете менять названия, иконки и entity_id так же из интерфейса.
В самой меге необходимо прописать настройки:
```yaml
srv: "192.168.1.4:8123" # ip:port вашего HA
script: "mega" # это api интеграции, к которому будет обращаться контроллер
```
Так же необходимо настроить Mega-ID в настройках контроллера, для каждой меги id должен быть разным.
При любых изменениях настроек контроллера (типы входов, id и тд) необходимо в настройках интеграции нажать `Обновить
объекты`
## Зависимости
Для максимальной скорости реакции на команды сервера, рекомендуется выключить `имитацию http-ответа` в
настройках интеграции и настроить proxy_pass к HA, самый простой способ сделать это - воспользоваться
[специальным аддоном](https://github.com/andvikt/mega_addon/tree/master/mega-proxy)
Обновить ваш контроллер до последней версии, обновление прошивки MegaD можно делать
из HA с помощью [аддона](https://github.com/andvikt/mega_addon.git)
Подробная документация по [ссылке](https://github.com/andvikt/mega_hacs/wiki)