Init
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import datetime
|
||||
from automation import Automation, Base # type: ignore
|
||||
|
||||
#
|
||||
# App to send email report for low balance
|
||||
#
|
||||
# Args:
|
||||
#
|
||||
# threshold = value below which battery levels are reported and email is sent
|
||||
# always_send = set to 1 to override threshold and force send
|
||||
#
|
||||
# None
|
||||
#
|
||||
# Release Notes
|
||||
#
|
||||
# Version 1.0:
|
||||
# Initial Version
|
||||
|
||||
class Balance(Base):
|
||||
|
||||
def initialize(self):
|
||||
super().initialize()
|
||||
self.check_balance({"force": 1})
|
||||
self.run_daily(self.check_balance, datetime.time(10, 0, 0))
|
||||
|
||||
def check_balance(self, kwargs):
|
||||
if 'constraint' in self.args and not self.constrain_input_boolean(self.args['constraint']):
|
||||
return
|
||||
|
||||
values = {}
|
||||
low = []
|
||||
for key in self.entity_ids:
|
||||
device = self.entity_ids[key]
|
||||
balance = self.get_state(device)
|
||||
if balance != None and self.is_number(balance):
|
||||
if float(balance) < self.args["threshold"]:
|
||||
low.append(device)
|
||||
values[device] = balance
|
||||
|
||||
message=""
|
||||
if low:
|
||||
message += "Пожалуйста пополните баланс: (< {}) \n".format(self.args["threshold"])
|
||||
for device in low:
|
||||
message += " - {}: {}\n".format(self.friendly_name(device), values[device])
|
||||
message += "\n\n"
|
||||
|
||||
if low or ("always_send" in self.args and self.args["always_send"] == 1) or ("force" in kwargs and kwargs["force"] == 1):
|
||||
if message != "":
|
||||
self.notify(message, name = "telegram_monster")
|
||||
|
||||
def is_number(self, s):
|
||||
try:
|
||||
float(s)
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
@@ -0,0 +1,15 @@
|
||||
#################################
|
||||
# SENSOR BATTERY LOW REMINDER #
|
||||
#################################
|
||||
balance_low_report:
|
||||
class: Balance
|
||||
module: balance
|
||||
entity_ids:
|
||||
mosenergosbyt_balance: sensor.power_mosenergosbyt_balance
|
||||
epd_balance: sensor.epd_balance
|
||||
|
||||
always_send: 0
|
||||
threshold: -100
|
||||
notify: telegram_monster
|
||||
global_dependencies:
|
||||
- globals
|
||||
@@ -0,0 +1,54 @@
|
||||
import appdaemon.plugins.hass.hassapi as hass
|
||||
import datetime
|
||||
|
||||
#
|
||||
# App to send email report for devices running low on battery
|
||||
#
|
||||
# Args:
|
||||
#
|
||||
# threshold = value below which battery levels are reported and email is sent
|
||||
# always_send = set to 1 to override threshold and force send
|
||||
#
|
||||
# None
|
||||
#
|
||||
# Release Notes
|
||||
#
|
||||
# Version 1.0:
|
||||
# Initial Version
|
||||
|
||||
class Battery(hass.Hass):
|
||||
|
||||
def initialize(self):
|
||||
#self.check_batteries({"force": 1})
|
||||
time = datetime.time(10, 0, 0)
|
||||
self.run_daily(self.check_batteries, time)
|
||||
|
||||
def check_batteries(self, kwargs):
|
||||
if 'constraint' in self.args and not self.constrain_input_boolean(self.args['constraint']):
|
||||
return
|
||||
|
||||
devices = self.get_state()
|
||||
values = {}
|
||||
low = []
|
||||
for device in devices:
|
||||
battery = None
|
||||
if "attributes" in devices[device]:
|
||||
if "battery" in devices[device]["attributes"]:
|
||||
battery = devices[device]["attributes"]["battery"]
|
||||
if "battery_level" in devices[device]["attributes"]:
|
||||
battery = devices[device]["attributes"]["battery_level"]
|
||||
if battery != None:
|
||||
if battery < self.args["threshold"]:
|
||||
low.append(device)
|
||||
values[device] = battery
|
||||
|
||||
message=""
|
||||
if low:
|
||||
message += "У следующих датчиков садится батарея: (< {}) \n".format(self.args["threshold"])
|
||||
for device in low:
|
||||
message += "{}: {}%\n".format(self.friendly_name(device), values[device])
|
||||
message += "\n\n"
|
||||
|
||||
if low or ("always_send" in self.args and self.args["always_send"] == 1) or ("force" in kwargs and kwargs["force"] == 1):
|
||||
if message != "":
|
||||
self.notify(message, name = "telegram")
|
||||
@@ -0,0 +1,11 @@
|
||||
#################################
|
||||
# SENSOR BATTERY LOW REMINDER #
|
||||
#################################
|
||||
sensor_battery_low_report:
|
||||
class: Battery
|
||||
module: battery
|
||||
constraint: input_boolean.battery_report
|
||||
always_send: 0
|
||||
threshold: 10
|
||||
global_dependencies:
|
||||
- globals
|
||||
@@ -0,0 +1,55 @@
|
||||
import appdaemon.plugins.hass.hassapi as hass
|
||||
from datetime import timedelta
|
||||
import datetime
|
||||
import globals
|
||||
|
||||
#
|
||||
# App to monitor high power usage when away.
|
||||
#
|
||||
# Args:
|
||||
#
|
||||
#
|
||||
# None
|
||||
#
|
||||
# Release Notes
|
||||
#
|
||||
# Version 1.0:
|
||||
# Initial Version
|
||||
|
||||
class PowerWatchdog(hass.Hass):
|
||||
listen_event_handle_list = []
|
||||
notified_today = False
|
||||
standby_power_limit = 10
|
||||
|
||||
def initialize(self):
|
||||
if not globals.check_args(self, ['entity', 'thresold', 'ha_panel', 'water_devices']):
|
||||
return
|
||||
self.listen_event_handle_list.append(self.listen_state(self.power_changed, self.args['entity']))
|
||||
|
||||
def power_changed(self, entity, attribute, old, new, kwargs):
|
||||
if 'constraint' in self.args and not self.constrain_input_boolean(self.args['constraint']):
|
||||
return
|
||||
|
||||
ha_panel_state = self.get_state(self.args['ha_panel'])
|
||||
if (ha_panel_state != "armed_away"):
|
||||
return
|
||||
# self.log('Power usage changed - {}kWh.'.format(new))
|
||||
|
||||
# if water devices is on - then skipping this alert
|
||||
devices = self.args['water_devices']
|
||||
for device in devices:
|
||||
state = self.get_state(device)
|
||||
attributes = self.get_state(device, attribute = "all")['attributes']
|
||||
if 'load_power' not in attributes:
|
||||
continue
|
||||
load_power = attributes['load_power']
|
||||
# self.log('{} load power is: {}'.format(device, load_power))
|
||||
if state == 'on' and load_power > self.standby_power_limit:
|
||||
return
|
||||
|
||||
power = float(new)
|
||||
if power > self.args['thresold']:
|
||||
if not self.notified_today:
|
||||
self.notified_today = True
|
||||
self.log('Power usage too much when away - {}kWh.'.format(new))
|
||||
self.notify('В ваше отсутствие наблюдается высокое потребление электроэнергии ({}), не оставили ли вы работающие устройства?'.format(power), name = 'telegram')
|
||||
@@ -0,0 +1,15 @@
|
||||
#################################
|
||||
# SENSOR BATTERY LOW REMINDER #
|
||||
#################################
|
||||
watchdog_power:
|
||||
class: PowerWatchdog
|
||||
module: power
|
||||
entity: sensor.power_active_power
|
||||
ha_panel: alarm_control_panel.ha_alarm
|
||||
thresold: 0.6
|
||||
water_devices:
|
||||
- switch.plug_158d0001a68c64 # Посудомойка
|
||||
- switch.plug_158d0001a4cfb4 # стиралка
|
||||
|
||||
global_dependencies:
|
||||
- globals
|
||||
@@ -0,0 +1,43 @@
|
||||
import appdaemon.plugins.hass.hassapi as hass
|
||||
from datetime import timedelta
|
||||
import datetime
|
||||
import globals
|
||||
|
||||
#
|
||||
# App to monitor entity update time.
|
||||
#
|
||||
# Args:
|
||||
#
|
||||
#
|
||||
# None
|
||||
#
|
||||
# Release Notes
|
||||
#
|
||||
# Version 1.0:
|
||||
# Initial Version
|
||||
|
||||
class Watchdog(hass.Hass):
|
||||
listen_event_handle_list = []
|
||||
timezone = 3
|
||||
def initialize(self):
|
||||
if not globals.check_args(self, ['entity','update_interval', 'timeout']):
|
||||
return
|
||||
self.timer = self.run_every(self.watchdog_check, self.datetime(), self.args['update_interval'])
|
||||
|
||||
def watchdog_check(self, kwargs):
|
||||
if 'constraint' in self.args and not self.constrain_input_boolean(self.args['constraint']):
|
||||
return
|
||||
|
||||
entity = self.args['entity']
|
||||
attributes = self.get_state(entity, attribute='all')
|
||||
if not 'last_changed' in attributes:
|
||||
return
|
||||
last_changed = attributes['last_changed']
|
||||
last_changed_date = datetime.datetime.strptime(last_changed, '%Y-%m-%dT%H:%M:%S.%f+00:00') + timedelta(hours=self.timezone)
|
||||
time_diff = datetime.datetime.now() - last_changed_date
|
||||
if time_diff.seconds > self.args['timeout']:
|
||||
self.log('Entity {} was changed {} seconds ago.'.format(entity, time_diff.seconds))
|
||||
|
||||
friendly_name = self.friendly_name(entity)
|
||||
message = "Датчик {} ({}) не обновлялся в течении {} секунд.".format(friendly_name, entity, self.args['timeout'])
|
||||
self.notify(message, name = "telegram")
|
||||
@@ -0,0 +1,11 @@
|
||||
#################################
|
||||
# SENSOR BATTERY LOW REMINDER #
|
||||
#################################
|
||||
watchdog_sensor_power_active_power:
|
||||
class: Watchdog
|
||||
module: watchdog
|
||||
entity: sensor.power_active_power
|
||||
update_interval: 60
|
||||
timeout: 360
|
||||
global_dependencies:
|
||||
- globals
|
||||
@@ -0,0 +1,97 @@
|
||||
import appdaemon.plugins.hass.hassapi as hass
|
||||
import datetime
|
||||
import globals
|
||||
|
||||
#
|
||||
# App to send notifications when counters state needs attention
|
||||
#
|
||||
# Args:
|
||||
#
|
||||
#
|
||||
# None
|
||||
#
|
||||
# Release Notes
|
||||
#
|
||||
# Version 1.0:
|
||||
# Initial Version
|
||||
|
||||
class WaterCountersAlarm(hass.Hass):
|
||||
checkup_threasold = 31
|
||||
send_threasold = 31
|
||||
|
||||
def initialize(self):
|
||||
if not globals.check_args(self, ['checkup_threasold', 'send_threasold']):
|
||||
return
|
||||
self.checkup_threasold = self.args['checkup_threasold']
|
||||
self.send_threasold = self.args['send_threasold']
|
||||
|
||||
self.check_send_dates({"force": 1})
|
||||
time = datetime.time(10, 0, 0)
|
||||
self.run_daily(self.check_checkup_dates, time)
|
||||
self.run_daily(self.check_send_dates, time)
|
||||
|
||||
def check_send_dates(self, kwargs):
|
||||
if 'constraint' in self.args and not self.constrain_input_boolean(self.args['constraint']):
|
||||
return
|
||||
devices = self.get_state()
|
||||
values = {}
|
||||
send_devices = []
|
||||
for device in devices:
|
||||
send_date = None
|
||||
if "attributes" in devices[device]:
|
||||
if "date" in devices[device]["attributes"]:
|
||||
send_date = devices[device]["attributes"]["date"]
|
||||
if send_date != None:
|
||||
self.log('found device {} with send date {}'.format(device, send_date))
|
||||
if send_date == "":
|
||||
send_devices.append(device)
|
||||
else:
|
||||
send_date_date = None
|
||||
if '-' in send_date:
|
||||
send_date_date = datetime.datetime.strptime(send_date, '%Y-%m-%d')
|
||||
else:
|
||||
send_date_date = datetime.datetime.strptime(send_date, '%d.%m.%Y')
|
||||
if send_date_date < (datetime.datetime.now() - datetime.timedelta(days=self.send_threasold)):
|
||||
send_devices.append(device)
|
||||
values[device] = send_date
|
||||
|
||||
message=""
|
||||
if send_devices:
|
||||
message += "ВНИМАНИЕ! У вас есть счетчики, показания по которым давно не передавались:\n"
|
||||
for device in send_devices:
|
||||
message += "- {}: {}\n".format(self.friendly_name(device), values[device])
|
||||
message += "\n\n"
|
||||
|
||||
if send_devices or ("always_send" in self.args and self.args["always_send"] == 1) or ("force" in kwargs and kwargs["force"] == 1):
|
||||
if message != "":
|
||||
self.notify(message, name = "telegram")
|
||||
|
||||
def check_checkup_dates(self, kwargs):
|
||||
if 'constraint' in self.args and not self.constrain_input_boolean(self.args['constraint']):
|
||||
return
|
||||
|
||||
devices = self.get_state()
|
||||
values = {}
|
||||
checkup_devices = []
|
||||
for device in devices:
|
||||
checkup = None
|
||||
if "attributes" in devices[device]:
|
||||
if "checkup" in devices[device]["attributes"]:
|
||||
checkup = devices[device]["attributes"]["checkup"]
|
||||
if checkup != None:
|
||||
self.log('found device {} with checkup date {}'.format(device, checkup))
|
||||
checkup_date = datetime.datetime.strptime(checkup, '%Y-%m-%d')
|
||||
if (checkup_date - datetime.timedelta(days=self.checkup_threasold)) < datetime.datetime.now():
|
||||
checkup_devices.append(device)
|
||||
values[device] = checkup
|
||||
|
||||
message=""
|
||||
if checkup_devices:
|
||||
message += "ВНИМАНИЕ! У вас есть счетчик, нуждающийся в поверке:\n"
|
||||
for device in checkup_devices:
|
||||
message += "- {}: {}\n".format(self.friendly_name(device), values[device])
|
||||
message += "\n\n"
|
||||
|
||||
if checkup_devices or ("always_send" in self.args and self.args["always_send"] == 1) or ("force" in kwargs and kwargs["force"] == 1):
|
||||
if message != "":
|
||||
self.notify(message, name = "telegram")
|
||||
@@ -0,0 +1,11 @@
|
||||
#################################
|
||||
# WATER COUNTERS ALARM #
|
||||
#################################
|
||||
water_counters:
|
||||
class: WaterCountersAlarm
|
||||
module: water_counters
|
||||
constraint: input_boolean.water_counters_report
|
||||
checkup_threasold: 31
|
||||
send_threasold: 31
|
||||
global_dependencies:
|
||||
- globals
|
||||
Reference in New Issue
Block a user