homekit/bin/pump_mqtt_bot.py
2024-02-27 00:01:50 +03:00

169 lines
5.5 KiB
Python
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
import datetime
import include_homekit
from enum import Enum
from typing import Optional
from telegram import ReplyKeyboardMarkup, User
from homekit.config import config
from homekit.telegram import bot
from homekit.telegram._botutil import user_any_name
from homekit.mqtt import MqttNode, MqttPayload
from homekit.mqtt.module.relay import MqttRelayState
from homekit.mqtt.module.diagnostics import InitialDiagnosticsPayload, DiagnosticsPayload
config.load_app('pump_mqtt_bot')
bot.initialize()
bot.lang.ru(
start_message="Выберите команду на клавиатуре",
start_message_no_access="Доступ запрещён. Вы можете отправить заявку на получение доступа.",
unknown_command="Неизвестная команда",
send_access_request="Отправить заявку",
management="Админка",
enable="Включить",
enabled="Включен ✅",
disable="Выключить",
disabled="Выключен ❌",
status="Статус",
status_updated=' (обновлено %s)',
done="Готово 👌",
user_action_notification='Пользователь <a href="tg://user?id=%d">%s</a> <b>%s</b> насос.',
user_action_on="включил",
user_action_off="выключил",
date_yday="вчера",
date_yyday="позавчера",
date_at="в"
)
bot.lang.en(
start_message="Select command on the keyboard",
start_message_no_access="You have no access.",
unknown_command="Unknown command",
send_access_request="Send request",
management="Admin options",
enable="Turn ON",
enable_silently="Turn ON silently",
enabled="Turned ON ✅",
disable="Turn OFF",
disable_silently="Turn OFF silently",
disabled="Turned OFF ❌",
status="Status",
status_updated=' (updated %s)',
done="Done 👌",
user_action_notification='User <a href="tg://user?id=%d">%s</a> turned the pump <b>%s</b>.',
user_action_on="ON",
user_action_off="OFF",
date_yday="yesterday",
date_yyday="the day before yesterday",
date_at="at"
)
mqtt: Optional[MqttNode] = None
relay_state = MqttRelayState()
class UserAction(Enum):
ON = 'on'
OFF = 'off'
def on_mqtt_message(home_id, message: MqttPayload):
if isinstance(message, InitialDiagnosticsPayload) or isinstance(message, DiagnosticsPayload):
kwargs = dict(rssi=message.rssi, enabled=message.flags.state)
if isinstance(message, InitialDiagnosticsPayload):
kwargs['fw_version'] = message.fw_version
relay_state.update(**kwargs)
def notify(user: User, action: UserAction) -> None:
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,
user.id, user_name, action_name)
bot.notify_all(text_getter, exclude=(user.id,))
@bot.handler(message='enable')
def enable_handler(ctx: bot.Context) -> None:
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.set_power(config['mqtt']['home_id'], False)
ctx.reply(ctx.lang('done'))
notify(ctx.user, UserAction.OFF)
@bot.handler(message='status')
def status(ctx: bot.Context) -> None:
label = ctx.lang('enabled') if relay_state.enabled else ctx.lang('disabled')
if relay_state.ever_updated:
date_label = ''
today = datetime.date.today()
if today != relay_state.update_time.date():
yday = today - datetime.timedelta(days=1)
yyday = today - datetime.timedelta(days=2)
if yday == relay_state.update_time.date():
date_label = ctx.lang('date_yday')
elif yyday == relay_state.update_time.date():
date_label = ctx.lang('date_yyday')
else:
date_label = relay_state.update_time.strftime('%d.%m.%Y')
date_label += ' '
date_label += ctx.lang('date_at') + ' '
date_label += relay_state.update_time.strftime('%H:%M')
label += ctx.lang('status_updated', date_label)
ctx.reply(label)
def start(ctx: bot.Context) -> None:
if ctx.user_id in config['bot']['users'] or ctx.user_id in config['bot']['admin_users']:
ctx.reply(ctx.lang('start_message'))
else:
buttons = [
[ctx.lang('send_access_request')]
]
ctx.reply(ctx.lang('start_message_no_access'), markup=ReplyKeyboardMarkup(buttons, one_time_keyboard=False))
@bot.exceptionhandler
def exception_handler(e: Exception, ctx: bot.Context) -> bool:
return False
@bot.defaultreplymarkup
def markup(ctx: Optional[bot.Context]) -> Optional[ReplyKeyboardMarkup]:
buttons = [[ctx.lang('enable'), ctx.lang('disable')], [ctx.lang('status')]]
if ctx.user_id in config['bot']['admin_users']:
buttons.append([ctx.lang('management')])
return ReplyKeyboardMarkup(buttons, one_time_keyboard=False)
if __name__ == '__main__':
mqtt = MqttRelay(devices=MqttEspDevice(id=config['mqtt']['home_id'],
secret=config['mqtt']['home_secret']))
mqtt.set_message_callback(on_mqtt_message)
mqtt.connect_and_loop(loop_forever=False)
# bot.enable_logging(BotType.PUMP_MQTT)
bot.run(start_handler=start)
mqtt.disconnect()