water action fixes
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
# )
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -79,9 +82,3 @@ 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
|
||||
|
||||
@@ -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
|
||||
# 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.
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user