water action fixes

This commit is contained in:
Your Name
2019-11-06 09:20:11 +03:00
parent 94778c039e
commit 7a32cb74da
24 changed files with 178 additions and 44 deletions
+6 -3
View File
@@ -1,5 +1,6 @@
ARG VERSION
FROM acockburn/appdaemon:${VERSION}
ARG BASE_IMAGE
#FROM acockburn/appdaemon:${BASE_IMAGE}
FROM ${BASE_IMAGE}
RUN pip3 install \
attrs==19.1.0 \
@@ -7,4 +8,6 @@ RUN pip3 install \
packaging==16.8 \
python-Levenshtein==0.12.0 \
voluptuous==0.11.5 \
noolite==1.4.0 && apt-get update -y && apt-get install -y libusb-1.0-0-dev && apt-get clean
noolite==1.4.0 && \
apk add --no-cache libusb-dev
#apt-get update && apt-get install -y libusb-1.0.0-dev && apt-get clean
+11 -5
View File
@@ -1,17 +1,23 @@
log:
logfile: STDOUT
errorfile: STDERR
logs:
main_log:
filename: STDOUT
appdaemon:
threads: 10
latitude: !secret home_latitude
longitude: !secret home_longitude
elevation: 0
timezone: !secret timezone
api_port: 5000
api_key: !secret ha_password
time_zone: !secret timezone
narodmon_key: !secret narodmon_key
api:
plugins:
HASS:
type: hass
ha_url: !secret ha_url
#ha_key: !secret ha_password
token: !secret ha_token
token: !secret ha_token
@@ -1,5 +1,6 @@
import appdaemon.plugins.hass.hassapi as hass
import globals
import datetime
#
# Very special case, this will run sound 'alarm' on xiaomi gateway based on alarm clock event (alarmclock_trigger)
# and stop it when sensor became active.
@@ -41,7 +42,7 @@ class AlarmclockAction(hass.Hass):
def alarmclock_alarm(self, event_id, event_args, kwargs):
self.log('Alarm triggered!')
self.volume = 10
self.timer = self.run_every(self.timer_tick, self.datetime(), 17)
self.timer = self.run_every(self.timer_tick, self.datetime()+datetime.timedelta(seconds=15), 17)
def timer_tick(self, kwargs):
self.call_service("xiaomi_aqara/play_ringtone", gw_mac=self.gw_mac, ringtone_id=self.ringtone, ringtone_vol=self.volume)
@@ -1,4 +1,5 @@
import appdaemon.plugins.hass.hassapi as hass
import datetime
#
# Pre alarm event.
@@ -51,7 +52,7 @@ class AlarmclockPrealarm(hass.Hass):
self.log('Prealarm triggered!')
self.brightness = 1
self.color_temp = 588
self.timer = self.run_every(self.timer_tick, self.datetime(), 10)
self.timer = self.run_every(self.timer_tick, self.datetime()+datetime.timedelta(seconds=15), 10)
def timer_tick(self, kwargs):
attributes = self.get_state(self.args['entity'], attribute = "all")
@@ -39,11 +39,11 @@ class Doorbell(hass.Hass):
self.notify("Звонок в дверь!!!", name = self.args['notify'])
result = self.send_video()
def send_video(self):
def send_video(self):
file = '/config/www/doorbell_video.mp4'
if os.path.exists(file):
os.remove(file)
self.call_service("stream/record", stream_source=self.args['rtsp'], filename=file, duration=10)
self.timer = self.run_in(self.run_in_send_video, 20, file=file)
@@ -34,6 +34,17 @@ class LightControl(hass.Hass):
# self.log('Sun is up, and we will turn it only after sundown.')
return
vacuum_state = "docked"
ha_panel_state = ""
if "vacuum" in self.args:
vacuum_state = self.get_state(self.args["vacuum"])
if "ha_panel" in self.args:
ha_panel_state = self.get_state(self.args["ha_panel"])
#Если работает пылесос и сработал датчик движения
if ha_panel_state == "armed_away" and vacuum_state == 'cleaning':
self.log('Motion sensor is triggered, but vacuum is cleaning.')
return
#sensor is off
if new == 'off' and old == 'on':
self.log('Sensor is off - running timer for {}s.'.format(self.args['timeout']))
@@ -8,6 +8,8 @@ light_control_mainroom:
control_entity: group.mainroom_light
timeout: 60
constraint: input_boolean.mainroom_light_control
ha_panel: alarm_control_panel.ha_alarm
vacuum: vacuum.xiaomi_vacuum_cleaner
global_dependencies:
- globals
@@ -18,6 +20,8 @@ light_control_kitchen:
control_entity: group.kitchen_light
timeout: 300
constraint: input_boolean.kitchen_light_control
ha_panel: alarm_control_panel.ha_alarm
vacuum: vacuum.xiaomi_vacuum_cleaner
global_dependencies:
- globals
@@ -28,6 +32,8 @@ light_control_hall:
control_entity: group.hall_light
timeout: 120
constraint: input_boolean.hall_light_control
ha_panel: alarm_control_panel.ha_alarm
vacuum: vacuum.xiaomi_vacuum_cleaner
global_dependencies:
- globals
@@ -23,7 +23,7 @@ class Watchdog(hass.Hass):
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'])
self.timer = self.run_every(self.watchdog_check, self.datetime()+timedelta(seconds=10), self.args['update_interval'])
def watchdog_check(self, kwargs):
if 'constraint' in self.args and not self.constrain_input_boolean(self.args['constraint']):
@@ -1,4 +1,5 @@
import appdaemon.plugins.hass.hassapi as hass
import datetime
#
# Water control application.
@@ -16,6 +17,8 @@ import appdaemon.plugins.hass.hassapi as hass
class WaterValveControl(hass.Hass):
standby_power_limit = 15
current_wait_cycle = 0
wait_cycles = 3
timer = None
listen_event_handle_list = []
timers = []
@@ -51,7 +54,7 @@ class WaterValveControl(hass.Hass):
device_names += self.friendly_name(device)
self.notify('В доме остались требующие воды устройства ({}), подача воды не будет отключена.'.format(device_names), name = self.args['notify'])
self.cancel_current_timer()
self.timers.append(self.run_every(self.wait_when_device_is_done, self.datetime(), 5*60))
self.timers.append(self.run_every(self.wait_when_device_is_done, self.datetime()+datetime.timedelta(seconds=5), 5*60))
else:
self.turn_off(self.args['water_valve'])
for device in self.args['water_devices']:
@@ -62,13 +65,23 @@ class WaterValveControl(hass.Hass):
return
powered_on = self.get_turned_on_devices()
self.log('still powered on: {}'.format(powered_on))
if (len(powered_on) == 0):
# self.turn_off(self.args['water_valve'])
# for device in self.args['water_devices']:
# self.turn_off(device)
self.notify('Устройства требующие воды закончили свою работу.', name = self.args['notify'])
if len(powered_on) == 1:
self.current_wait_cycle = 0
elif len(powered_on) == 0 and self.current_wait_cycle<self.wait_cycles:
self.log("Current wait cycle: {}".format(self.current_wait_cycle))
self.current_wait_cycle = self.current_wait_cycle+1
elif len(powered_on) == 0 and self.current_wait_cycle>=self.wait_cycles:
self.current_wait_cycle = 0
self.notify('Устройства требующие воды закончили свою работу, отключаю подачу воды.', name = self.args['notify'])
self.turn_off_water_devices()
self.cancel_current_timer()
def turn_off_water_devices():
self.log("Turning off water devices.")
self.turn_off(self.args['water_valve'])
for device in self.args['water_devices']:
self.turn_off(device)
def get_turned_on_devices(self):
powered_on_devices = []
devices = self.args['water_devices']
@@ -80,8 +93,8 @@ class WaterValveControl(hass.Hass):
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:
self.log('{} state: {}, load power is: {}'.format(device, state, load_power))
if state == 'off' or load_power < self.standby_power_limit:
continue
powered_on_devices.append(device)
return powered_on_devices
@@ -24,7 +24,7 @@ class MosEnergoSbytSender(Automation):
class MosEnergoSbytUpdater(Automation):
def initialize(self):
super().initialize()
self.timer = self.run_every(self.update_sensors, self.datetime(), 1*60*60)
self.timer = self.run_every(self.update_sensors, self.datetime()+timedelta(seconds=10), 1*60*60)
# self.send_mosenergosbyt_counters({})
def update_sensors(self, args) -> None:
+1 -1
View File
@@ -161,7 +161,7 @@ class PowerCounterSensor(Automation):
class EpdBalanceSensor(Automation):
def initialize(self):
super().initialize()
self.timer = self.run_every(self.update_sensors, self.datetime(), 1*60*60)
self.timer = self.run_every(self.update_sensors, self.datetime()+timedelta(seconds=40), 1*60*60)
def update_sensors(self, args) -> None:
if 'epd_balance' in self.entity_ids:
@@ -32,7 +32,7 @@ class ToiletPresence(hass.Hass):
def distance_changed(self, entity, attribute, old, new, kwargs):
distance = int(new)
state = ""
if (distance > 1000 or distance < 850):
if (distance > 1100 or distance < 750):
self.timers_off()
self.timers.append(self.run_in(self.run_in_presense_off, self.presence_timeout))
self.log('re-setting timer for {}s.'.format(self.presence_timeout))
+7 -2
View File
@@ -1,6 +1,10 @@
# -*- coding: utf-8 -*-
import appdaemon.plugins.hass.hassapi as hass
from notification import send_notification
import datetime
import sys, locale
import logging, codecs
#import unicode
# from automation import Automation # type: ignore
"""
@@ -10,7 +14,8 @@ Arguments:
"""
class Test(hass.Hass):
def initialize(self) -> None:
self.log('test')
self.log(u"Привет")
self.log(str(u'ô'))
# id = send_notification(
# self, targets="telegram_monster", message="Repeated message", title="title", when=datetime.datetime.now(), interval=10, iterations=2
# )
@@ -23,4 +28,4 @@ class Test(hass.Hass):
self.log('terminate')
# for listen_event_handle in self.listen_event_handle_list:
# self.cancel_listen_event(listen_event_handle)
+39
View File
@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
import appdaemon.plugins.hass.hassapi as hass
from notification import send_notification
import datetime
import sys, locale
import logging
#import unicode
# from automation import Automation # type: ignore
"""
Monitor events and output changes to the verbose_log. Nice for debugging purposes.
Arguments:
- events: List of events to monitor
"""
class Test(hass.Hass):
def initialize(self) -> None:
root_logger= logging.getLogger()
root_logger.setLevel(logging.DEBUG) # or whatever
handler = logging.FileHandler('test.log', 'w', 'utf-8') # or whatever
formatter = logging.Formatter('%(name)s %(message)s') # or whatever
handler.setFormatter(formatter) # Pass handler as a parameter, not assign
root_logger.addHandler(handler)
UTF8Writer = codecs.getwriter('utf8')
sys.stdout = UTF8Writer(sys.stdout.buffer)
self.log(u"Привет")
self.log(str(u'ô'))
# id = send_notification(
# self, targets="telegram_monster", message="Repeated message", title="title", when=datetime.datetime.now(), interval=10, iterations=2
# )
# self.log("id:{}".format(id))
# id = send_notification(
# self, targets="telegram_monster", message="Dummy", title="title"
# )
def terminate(self):
self.log('terminate')
# for listen_event_handle in self.listen_event_handle_list:
# self.cancel_listen_event(listen_event_handle)
+2 -2
View File
@@ -19,7 +19,7 @@ services:
- /srv/mysql:/var/lib/mysql
hass:
image: homeassistant/home-assistant
image: homeassistant/home-assistant:0.100.2
container_name: hass
volumes:
- ./hass/settings:/config
@@ -46,7 +46,7 @@ services:
build:
context: ./appdaemon/docker
args:
VERSION: 3.0.5
BASE_IMAGE: dlashua/appdaemon:dev #acockburn/appdaemon:3.0.5
container_name: appdaemon
depends_on:
- hass
+6 -9
View File
@@ -23,6 +23,8 @@ http:
trusted_proxies:
- 172.19.0.0/24
# noolite:
# Enables the frontend
frontend:
lovelace:
@@ -44,11 +46,12 @@ logbook:
# Components
automation: !include_dir_merge_list configuration/automation
apple_tv: !include_dir_merge_list configuration/appletv
alexa: !include configuration/amazon/alexa.yaml
#apple_tv: !include_dir_merge_list configuration/appletv
#alexa: !include configuration/amazon/alexa.yaml
alarm_control_panel: !include_dir_merge_list configuration/alarm_control_panel
binary_sensor: !include_dir_merge_list configuration/binary_sensor
camera: !include_dir_merge_list configuration/camera
fan: !include_dir_merge_list configuration/fan
#climate: !include_dir_merge_list configuration/climate
group: !include_dir_merge_named configuration/group
input_boolean: !include_dir_merge_named configuration/input/input_boolean
@@ -78,10 +81,4 @@ modbus: !include configuration/modbus.yaml
utility_meter: !include_dir_merge_named configuration/utility_meter
speedtestdotnet: !include configuration/speedtest.yaml
yandex_smart_home: !include configuration/alice.yaml
# fan:
# - platform: xiaomi_miio
# host: 192.168.1.14
# token: '411cf70bb69052c0121813388f30e193'
# model: zhimi.airpurifier.mc1
yandex_smart_home: !include configuration/alice.yaml
@@ -0,0 +1,4 @@
- platform: xiaomi_miio
model: zhimi.airpurifier.mc1
host: !secret purifier_ip
token: !secret purifier_key
@@ -1,6 +1,4 @@
# - platform: noolite
# channel: 0
# name: "salt_lamp"
# scan_interval: 60
# type: dimmer
# mode: noolite
# - platform: noolite
# tx_channel: 1
# friendly_name: "salt_lamp"
# dimmable: true
@@ -0,0 +1,7 @@
- platform: template
sensors:
xiaomi_airpurifier_air_quality_pm25:
friendly_name: "Air quality"
value_template: "{{ state_attr('fan.xiaomi_miio_device', 'aqi') }}"
unit_of_measurement: "μg/m³"
icon_template: "mdi:weather-fog"
@@ -40,6 +40,10 @@
friendly_name: "Фитолампа в мес."
unit_of_measurement: '₽'
value_template: "{{ (states('sensor.fitolamp_monthly') | float * (states('sensor.power_cost') | float)) | round(2) }}"
server_money_monthly:
friendly_name: "Сервер в мес."
unit_of_measurement: '₽'
value_template: "{{ (states('sensor.server_monthly') | float * (states('sensor.power_cost') | float)) | round(2) }}"
power_money_t1_monthly:
friendly_name: "Т1 в мес."
unit_of_measurement: '₽'
@@ -98,6 +102,10 @@
friendly_name: "Фитолампа в день"
unit_of_measurement: '₽'
value_template: "{{ (states('sensor.fitolamp_daily') | float * (states('sensor.power_cost') | float)) | round(2) }}"
server_money_daily:
friendly_name: "Сервер в день"
unit_of_measurement: '₽'
value_template: "{{ (states('sensor.server_daily') | float * (states('sensor.power_cost') | float)) | round(2) }}"
counter_hot_money_hourly:
friendly_name: "Горячая в час"
@@ -139,3 +147,7 @@
friendly_name: "Фитолампа в час"
unit_of_measurement: '₽'
value_template: "{{ (states('sensor.fitolamp_hourly') | float * (states('sensor.power_cost') | float)) | round(2) }}"
server_money_hourly:
friendly_name: "Сервер в час"
unit_of_measurement: '₽'
value_template: "{{ (states('sensor.server_hourly') | float * (states('sensor.power_cost') | float)) | round(2) }}"
@@ -28,4 +28,7 @@
friendly_name: "Фитолампа потреблено"
unit_of_measurement: 'kWh'
value_template: "{{ state_attr('switch.plug_158d0002924779', 'power_consumed') / 1000 }}"
server_consumed:
friendly_name: "Сервер потреблено"
unit_of_measurement: 'kWh'
value_template: "{{ state_attr('switch.plug_158d00026ea017', 'power_consumed') / 1000 }}"
@@ -0,0 +1,9 @@
server_hourly:
source: sensor.server_consumed
cycle: hourly
server_daily:
source: sensor.server_consumed
cycle: daily
server_monthly:
source: sensor.server_consumed
cycle: monthly
Binary file not shown.
+19
View File
@@ -22,14 +22,17 @@ views:
entities:
- sensor.temperature_158d0001149b3c
- sensor.humidity_158d0001149b3c
- sensor.xiaomi_airpurifier_air_quality_pm25
- light.yeelight_color1_34ce008fe328
- light.yeelight_color1_286c071065c7
- light.yeelight_mono1_34ce0087ff33
- light.yeelight_mono1_f0b4290e5444
- light.yeelight_mono1_f0b429a8f6df
# - light.salt_lamp
- cover.curtain_158d0002b0c46a
- switch.plug_158d0001104a0c
- switch.plug_158d00010dd98d
- fan.xiaomi_miio_device
- climate.living_room
- type: entities
title: "Кухня"
@@ -285,6 +288,16 @@ views:
- sensor.fitolamp_money_hourly
- sensor.fitolamp_money_daily
- sensor.fitolamp_money_monthly
- type: entities
title: "Сервер"
show_header_toggle: false
entities:
- sensor.server_hourly
- sensor.server_daily
- sensor.server_monthly
- sensor.server_money_hourly
- sensor.server_money_daily
- sensor.server_money_monthly
- type: entities
title: "Теория трехтарифника"
show_header_toggle: false
@@ -296,6 +309,12 @@ views:
- sensor.power_money_t2_monthly
- sensor.power_money_t3_monthly
- sensor.power_theory_money_monthly
- type: history-graph
title: Качество воздуха
hours_to_show: 80
refresh_interval: 60
entities:
- sensor.xiaomi_airpurifier_air_quality_pm25
- title: "Настройки"
icon: mdi:settings
cards: