Compare commits

...

4 Commits

Author SHA1 Message Date
Andrey
ad2501ca8c add proxy support 2021-02-19 10:32:28 +03:00
Andrey
5681f7315c add proxy support 2021-02-19 10:06:56 +03:00
Andrey
da87c24db9 add proxy support 2021-02-19 09:50:31 +03:00
Andrey
a0dcfa4b9c fix force_d 2021-02-18 20:09:45 +03:00
13 changed files with 56 additions and 55 deletions

View File

@@ -1,56 +1,30 @@
import asyncio
from urllib.parse import urlparse, parse_qsl
from asyncio import Event, FIRST_COMPLETED
import signal
import typing
from logging import getLogger, DEBUG
stop = Event()
loop = asyncio.get_event_loop()
lg = getLogger(__name__)
lg.setLevel(DEBUG)
def make_handler(get_ans: typing.Callable[[dict], str]):
async def handler(
reader: asyncio.StreamReader,
writer: asyncio.StreamWriter,
):
data = await reader.read(200)
print(data)
message = data.decode()
addr = writer.get_extra_info('peername')
lg.debug('process msg "%s" from %s', message, addr)
try:
(_, p, *_) = message.split(' ')
p = dict(parse_qsl(urlparse(p).query))
lg.debug('query %s', p)
ans = get_ans(p)
ans = f'''HTTP/1.1 200 OK\nContent-Length: {len(ans)}\n\n{ans}'''.encode() # \nContent-Length: 6
ans = b'HTTP/1.1 200 OK\r\n\r\n7:2'
print(ans)
except Exception as exc:
print(exc)
lg.exception('process msg "%s" from %s', message, addr)
ans = '''HTTP/1.1 500\n\n'''.encode()
writer.write(ans)
await writer.drain()
# writer.transport.close()
writer.close()
await writer.wait_closed()
return handler
async def handler(
reader: asyncio.StreamReader,
writer: asyncio.StreamWriter,
):
await reader.read(100)
ans = b'HTTP/1.1 200 OK\r\nContent-Length:1\r\n\r\nd'
writer.write(ans)
await writer.drain()
writer.close()
await writer.wait_closed()
async def serve():
server = await asyncio.start_server(
make_handler(lambda x: '7:2'),
handler,
host='0.0.0.0',
port=1111,
port=8888,
)
addr = server.sockets[0].getsockname()
print(f'Serving on {addr}')
async with server:
await asyncio.wait((server.serve_forever(), stop.wait()), return_when=FIRST_COMPLETED)
@@ -58,4 +32,4 @@ if __name__ == '__main__':
loop.add_signal_handler(
signal.SIGINT, stop.set
)
loop.run_until_complete(serve())
loop.run_until_complete(serve())

View File

@@ -7,11 +7,10 @@ import voluptuous as vol
from homeassistant.const import (
CONF_SCAN_INTERVAL, CONF_ID, CONF_NAME, CONF_DOMAIN,
CONF_UNIT_OF_MEASUREMENT, CONF_HOST
CONF_UNIT_OF_MEASUREMENT, CONF_HOST, CONF_VALUE_TEMPLATE
)
from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.helpers.service import bind_hass
from homeassistant.helpers.template import Template
from homeassistant.helpers import config_validation as cv
from homeassistant.components import mqtt
from homeassistant.config_entries import ConfigEntry
@@ -41,7 +40,8 @@ CUSTOMIZE_PORT = {
'сообщение из меги '): cv.template,
vol.Optional(CONF_ACTION): cv.script_action, # пока не реализовано
vol.Optional(CONF_GET_VALUE, default=True): bool,
vol.Optional(CONF_CONV_TEMPLATE): cv.template
vol.Optional(CONF_CONV_TEMPLATE): cv.template,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
}
CUSTOMIZE_DS2413 = {
vol.Optional(str.lower, description='адрес и индекс устройства'): CUSTOMIZE_PORT

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, CONF_POLL_OUTS # pylint:disable=unused-import
CONF_NPORTS, CONF_UPDATE_ALL, CONF_POLL_OUTS, CONF_FAKE_RESPONSE # pylint:disable=unused-import
from .hub import MegaD
from . import exceptions
@@ -27,6 +27,7 @@ STEP_USER_DATA_SCHEMA = vol.Schema(
vol.Optional(CONF_MQTT_INPUTS, default=True): bool,
vol.Optional(CONF_NPORTS, default=37): int,
vol.Optional(CONF_UPDATE_ALL, default=True): bool,
vol.Optional(CONF_FAKE_RESPONSE, default=True): bool,
},
)
@@ -138,6 +139,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
vol.Optional(CONF_NPORTS, default=e.get(CONF_NPORTS, 37)): int,
vol.Optional(CONF_RELOAD, default=False): bool,
vol.Optional(CONF_UPDATE_ALL, default=e.get(CONF_UPDATE_ALL, True)): bool,
vol.Optional(CONF_FAKE_RESPONSE, default=e.get(CONF_FAKE_RESPONSE, True)): bool,
# vol.Optional(CONF_INVERT, default=''): str,
}),
)

View File

@@ -23,6 +23,7 @@ CONF_NPORTS = 'nports'
CONF_RESPONSE_TEMPLATE = 'response_template'
CONF_ACTION = 'action'
CONF_UPDATE_ALL = 'update_all'
CONF_FAKE_RESPONSE = 'fake_response'
CONF_GET_VALUE = 'get_value'
CONF_ALLOW_HOSTS = 'allow_hosts'
CONF_CONV_TEMPLATE = 'conv_template'

View File

@@ -24,7 +24,7 @@ class MegaView(HomeAssistantView):
def __init__(self, cfg: dict):
self._try = 0
self.allowed_hosts = {'::1'}
self.allowed_hosts = {'::1', '127.0.0.1'}
self.callbacks = defaultdict(lambda: defaultdict(list))
self.templates: typing.Dict[str, typing.Dict[str, Template]] = {
mid: {
@@ -78,11 +78,13 @@ class MegaView(HomeAssistantView):
template.hass = hass
ret = template.async_render(data)
_LOGGER.debug('response %s', ret)
Response(body='', content_type='text/plain', headers={'Server': 's', 'Date': 'n'})
if 'd' in ret:
await hub.request(pt=port, cmd=ret)
else:
await hub.request(cmd=ret)
Response(body='' if hub.fake_response else ret, content_type='text/plain')
if hub.fake_response:
if 'd' in ret:
await hub.request(pt=port, cmd=ret)
else:
await hub.request(cmd=ret)
return ret
async def later_update(self, hub):

View File

@@ -75,6 +75,7 @@ class MegaD:
inverted: typing.List[int] = None,
update_all=True,
poll_outs=False,
fake_response=True,
**kwargs,
):
"""Initialize."""
@@ -87,6 +88,7 @@ class MegaD:
self.poll_outs = poll_outs
self.update_all = update_all if update_all is not None else True
self.nports = nports
self.fake_response = fake_response
self.mqtt_inputs = mqtt_inputs
self.loop: asyncio.AbstractEventLoop = None
self.hass = hass

View File

@@ -15,5 +15,5 @@
"@andvikt"
],
"issue_tracker": "https://github.com/andvikt/mega_hacs/issues",
"version": "v0.4.1b7"
"version": "v0.4.2b1"
}

View File

@@ -13,7 +13,7 @@ from homeassistant.const import (
CONF_PORT,
CONF_UNIQUE_ID,
CONF_ID,
CONF_TYPE, CONF_UNIT_OF_MEASUREMENT,
CONF_TYPE, CONF_UNIT_OF_MEASUREMENT, CONF_VALUE_TEMPLATE,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.template import Template
@@ -163,7 +163,7 @@ class Mega1WSensor(MegaPushEntity):
ret = str(ret)
except:
ret = None
tmpl: Template = self.customize.get(CONF_CONV_TEMPLATE)
tmpl: Template = self.customize.get(CONF_CONV_TEMPLATE, self.customize.get(CONF_VALUE_TEMPLATE))
if tmpl is not None and self.hass is not None:
tmpl.hass = self.hass
ret = tmpl.async_render({'value': ret})

View File

@@ -15,6 +15,7 @@
"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%]",
"fake_response": "[%key:common::config_flow::data::fake_response%]",
"poll_outs": "[%key:common::config_flow::data::poll_outs%]"
}
}

View File

@@ -23,6 +23,7 @@
"nports": "Number of ports",
"update_all": "Update all outs when input",
"mqtt_inputs": "Use MQTT",
"fake_response": "Fake response",
"poll_outs": "Poll outs"
}
}
@@ -37,6 +38,7 @@
"reload": "Reload objects",
"mqtt_inputs": "Use MQTT",
"update_all": "Update all outs when input",
"fake_response": "Fake response",
"poll_outs": "Poll outs"
}
}

View File

@@ -22,6 +22,7 @@
"mqtt_inputs": "Использовать MQTT",
"nports": "Кол-во портов",
"update_all": "Обновить все выходы когда срабатывает вход",
"fake_response": "Имитация http-ответа",
"poll_outs": "Обновлять выходы (регулярно)"
}
}
@@ -36,6 +37,7 @@
"reload": "Обновить объекты",
"invert": "Список портов (через ,) с инвертированной логикой",
"mqtt_inputs": "Использовать MQTT",
"fake_response": "Имитация http-ответа",
"nports": "Кол-во портов",
"update_all": "Обновить все выходы когда срабатывает вход",
"poll_outs": "Обновлять выходы (регулярно)"

View File

@@ -22,6 +22,7 @@
"mqtt_inputs": "Використовувати MQTT",
"nports": "Кількість портів",
"update_all": "Оновити всі виходи коли спрацьовує вхід",
"fake_response": "Имитация http-ответа",
"poll_outs": "Оновити виходи"
}
}
@@ -37,6 +38,7 @@
"invert": "Список портів з інвертованою логікою (через ,)",
"mqtt_inputs": "Використовувати MQTT",
"nports": "Кількість портів",
"fake_response": "Имитация http-ответа",
"update_all": "Оновити всі виходи коли спрацьовує вхід",
"poll_outs": "Оновити виходи"
}

View File

@@ -21,7 +21,8 @@
`light`, для шим - `light` с поддержкой яркости, для цифровых входов `binary_sensor`, для датчиков
`sensor`)
- Возможность работы с несколькими megad
- Обратная связь по mqtt или http (на выбор)
- Обратная связь по http или mqtt (`deprecated`, поддержка mqtt будет выключена в версиях >= 1.0.0, тк в нем нет
необходимости)
- События на двойные/долгие нажатия
- Команды выполняются друг за другом без конкурентного доступа к ресурсам megad, это дает гарантии надежного исполнения
большого кол-ва команд (например в сценах). Каждая следующая команда отправляется только после получения ответа о
@@ -52,7 +53,19 @@ wget -q -O - https://raw.githubusercontent.com/andvikt/mega_hacs/master/install.
Все имеющиеся у вас порты будут настроены автоматически. Вы можете менять названия, иконки и entity_id так же из интерфейса.
В самой меге необходимо прописать настройки:
```yaml
srv: "192.168.1.4:8123" # ip:port вашего HA
script: "mega" # это api интеграции, к которому будет обращаться контроллер
```
## Зависимости
Для совместимости c mqtt необходимо настроить интеграцию [mqtt](https://www.home-assistant.io/integrations/mqtt/)
в HomeAssistant, а так же обновить ваш контроллер до последней версии, обновление прошивки MegaD можно делать прямо
Для максимальной скорости реакции на команды сервера, рекомендуется выключить `имитацию http-ответа` в
настройках интеграции и настроить proxy_pass к HA, самый простой способ сделать это - воспользоваться
[специальным аддоном](https://github.com/andvikt/mega_addon/tree/master/mega-updater)
Обновить ваш контроллер до последней версии, обновление прошивки MegaD можно делать
из HA с помощью [аддона](https://github.com/andvikt/mega_addon.git)
Подробная документация по [ссылке](https://github.com/andvikt/mega_hacs/wiki)