diff options
-rw-r--r-- | src/home/mqtt/__init__.py | 3 | ||||
-rw-r--r-- | src/home/mqtt/util.py | 14 | ||||
-rwxr-xr-x | src/pump_bot.py | 60 | ||||
-rwxr-xr-x | src/pump_mqtt_bot.py | 20 | ||||
-rw-r--r-- | systemd/ipcam_rtsp2hls@.service | 2 |
5 files changed, 85 insertions, 14 deletions
diff --git a/src/home/mqtt/__init__.py b/src/home/mqtt/__init__.py index 3fbd744..c95061f 100644 --- a/src/home/mqtt/__init__.py +++ b/src/home/mqtt/__init__.py @@ -4,5 +4,6 @@ from ._module import MqttModule from .util import ( poll_tick, get_modules as get_mqtt_modules, - import_module as import_mqtt_module + import_module as import_mqtt_module, + add_module as add_mqtt_module )
\ No newline at end of file diff --git a/src/home/mqtt/util.py b/src/home/mqtt/util.py index 78cbcaa..91b6baf 100644 --- a/src/home/mqtt/util.py +++ b/src/home/mqtt/util.py @@ -3,6 +3,8 @@ import os import re import importlib +from ._node import MqttNode +from . import MqttModule from typing import List @@ -23,4 +25,14 @@ def get_modules() -> List[str]: def import_module(module: str): return importlib.import_module( - f'..module.{module}', __name__)
\ No newline at end of file + f'..module.{module}', __name__) + + +def add_module(mqtt_node: MqttNode, module: str) -> MqttModule: + module = import_module(module) + if not hasattr(module, 'MODULE_NAME'): + raise RuntimeError(f'MODULE_NAME not found in module {module}') + cl = getattr(module, getattr(module, 'MODULE_NAME')) + instance = cl() + mqtt_node.add_module(instance) + return instance
\ No newline at end of file diff --git a/src/pump_bot.py b/src/pump_bot.py index de925db..1996dfb 100755 --- a/src/pump_bot.py +++ b/src/pump_bot.py @@ -3,14 +3,18 @@ from enum import Enum from typing import Optional from telegram import ReplyKeyboardMarkup, User -from home.config import config +from home.config import config, is_development_mode from home.telegram import bot from home.telegram._botutil import user_any_name from home.relay.sunxi_h3_client import RelayClient from home.api.types import BotType +from home.mqtt import MqttNode, MqttModule, add_mqtt_module config.load('pump_bot') +mqtt: Optional[MqttNode] = None +mqtt_relay_module: Optional[MqttModule] = None + bot.initialize() bot.lang.ru( start_message="Выберите команду на клавиатуре", @@ -24,11 +28,17 @@ bot.lang.ru( disable_silently="Выключить тихо", disabled="Выключен ❌", + start_watering="Включить полив", + stop_watering="Отключить полив", + status="Статус", done="Готово 👌", user_action_notification='Пользователь <a href="tg://user?id=%d">%s</a> <b>%s</b> насос.', + user_watering_notification='Пользователь <a href="tg://user?id=%d">%s</a> <b>%s</b> полив.', user_action_on="включил", user_action_off="выключил", + user_action_watering_on="включил", + user_action_watering_off="выключил", ) bot.lang.en( start_message="Select command on the keyboard", @@ -42,17 +52,25 @@ bot.lang.en( disable_silently="Turn OFF silently", disabled="Turned OFF ❌", + start_watering="Start watering", + stop_watering="Stop watering", + status="Status", done="Done 👌", user_action_notification='User <a href="tg://user?id=%d">%s</a> turned the pump <b>%s</b>.', + user_watering_notification='User <a href="tg://user?id=%d">%s</a> <b>%s</b> the watering.', user_action_on="ON", user_action_off="OFF", + user_action_watering_on="started", + user_action_watering_off="stopped", ) class UserAction(Enum): ON = 'on' OFF = 'off' + WATERING_ON = 'watering_on' + WATERING_OFF = 'watering_off' def get_relay() -> RelayClient: @@ -75,11 +93,24 @@ def off(ctx: bot.Context, silent=False) -> None: notify(ctx.user, UserAction.OFF) +def watering_on(ctx: bot.Context) -> None: + mqtt_relay_module.switchpower(mqtt, True, config.get('mqtt_water_relay.secret')) + ctx.reply(ctx.lang('done')) + notify(ctx.user, UserAction.WATERING_ON) + + +def watering_off(ctx: bot.Context) -> None: + mqtt_relay_module.switchpower(mqtt, False, config.get('mqtt_water_relay.secret')) + ctx.reply(ctx.lang('done')) + notify(ctx.user, UserAction.WATERING_OFF) + + def notify(user: User, action: UserAction) -> None: + notification_key = 'user_watering_notification' if action in (UserAction.WATERING_ON, UserAction.WATERING_OFF) else 'user_action_notification' def text_getter(lang: str): action_name = bot.lang.get(f'user_action_{action.value}', lang) user_name = user_any_name(user) - return 'ℹ ' + bot.lang.get('user_action_notification', lang, + return 'ℹ ' + bot.lang.get(notification_key, lang, user.id, user_name, action_name) bot.notify_all(text_getter, exclude=(user.id,)) @@ -100,6 +131,16 @@ def disable_handler(ctx: bot.Context) -> None: off(ctx) +@bot.handler(message='start_watering') +def start_watering(ctx: bot.Context) -> None: + watering_on(ctx) + + +@bot.handler(message='stop_watering') +def stop_watering(ctx: bot.Context) -> None: + watering_off(ctx) + + @bot.handler(message='disable_silently') def disable_s_handler(ctx: bot.Context) -> None: off(ctx, True) @@ -121,11 +162,26 @@ def markup(ctx: Optional[bot.Context]) -> Optional[ReplyKeyboardMarkup]: if ctx.user_id in config['bot']['silent_users']: buttons.append([ctx.lang('enable_silently'), ctx.lang('disable_silently')]) + buttons.append([ctx.lang('start_watering'), ctx.lang('stop_watering')]) buttons.append([ctx.lang('status')]) return ReplyKeyboardMarkup(buttons, one_time_keyboard=False) if __name__ == '__main__': + mqtt = MqttNode(node_id=config.get('mqtt_water_relay.node_id')) + if is_development_mode(): + add_mqtt_module(mqtt, 'diagnostics') + mqtt_relay_module = add_mqtt_module(mqtt, 'relay') + + mqtt.configure_tls() + mqtt.connect_and_loop(loop_forever=False) + bot.enable_logging(BotType.PUMP) bot.run() + + try: + mqtt.disconnect() + except: + pass + diff --git a/src/pump_mqtt_bot.py b/src/pump_mqtt_bot.py index 86d87d3..6a63caf 100755 --- a/src/pump_mqtt_bot.py +++ b/src/pump_mqtt_bot.py @@ -8,7 +8,7 @@ from telegram import ReplyKeyboardMarkup, User from home.config import config from home.telegram import bot from home.telegram._botutil import user_any_name -from home.mqtt import MqttEspDevice, MqttPayload +from home.mqtt import MqttNode, MqttPayload from home.mqtt.module.relay import MqttRelayState from home.mqtt.module.diagnostics import InitialDiagnosticsPayload, DiagnosticsPayload @@ -69,7 +69,7 @@ bot.lang.en( ) -mqtt_relay: Optional[MqttRelay] = None +mqtt: Optional[MqttNode] = None relay_state = MqttRelayState() @@ -98,14 +98,14 @@ def notify(user: User, action: UserAction) -> None: @bot.handler(message='enable') def enable_handler(ctx: bot.Context) -> None: - mqtt_relay.set_power(config['mqtt']['home_id'], True) + mqtt.set_power(config['mqtt']['home_id'], True) ctx.reply(ctx.lang('done')) notify(ctx.user, UserAction.ON) @bot.handler(message='disable') def disable_handler(ctx: bot.Context) -> None: - mqtt_relay.set_power(config['mqtt']['home_id'], False) + mqtt.set_power(config['mqtt']['home_id'], False) ctx.reply(ctx.lang('done')) notify(ctx.user, UserAction.OFF) @@ -156,13 +156,13 @@ def markup(ctx: Optional[bot.Context]) -> Optional[ReplyKeyboardMarkup]: if __name__ == '__main__': - mqtt_relay = MqttRelay(devices=MqttEspDevice(id=config['mqtt']['home_id'], - secret=config['mqtt']['home_secret'])) - mqtt_relay.set_message_callback(on_mqtt_message) - mqtt_relay.configure_tls() - mqtt_relay.connect_and_loop(loop_forever=False) + mqtt = MqttRelay(devices=MqttEspDevice(id=config['mqtt']['home_id'], + secret=config['mqtt']['home_secret'])) + mqtt.set_message_callback(on_mqtt_message) + mqtt.configure_tls() + mqtt.connect_and_loop(loop_forever=False) # bot.enable_logging(BotType.PUMP_MQTT) bot.run(start_handler=start) - mqtt_relay.disconnect() + mqtt.disconnect() diff --git a/systemd/ipcam_rtsp2hls@.service b/systemd/ipcam_rtsp2hls@.service index 244a192..4d5e59d 100644 --- a/systemd/ipcam_rtsp2hls@.service +++ b/systemd/ipcam_rtsp2hls@.service @@ -8,6 +8,8 @@ User=user Group=user EnvironmentFile=/etc/ipcam_rtsp2hls.conf.d/%i.conf ExecStart=/home/user/homekit/tools/ipcam_rtsp2hls.sh --name %i --user $USER --password $PASSWORD --ip $IP --port $PORT $ARGS +Restart=on-failure +RestartSec=3 [Install] WantedBy=multi-user.target |