Home Assistant Git Exporter
parent
448b6a3be5
commit
bb3a77ba75
|
@ -1,7 +1,3 @@
|
||||||
Add-On Repository for Cloudflare:
|
|
||||||
maintainer: Tobia Brenner <https://github.com/brenner-tobias/>
|
|
||||||
slug: 9074a9fa
|
|
||||||
source: https://github.com/brenner-tobias/ha-addons
|
|
||||||
Alex's Add-ons Shack:
|
Alex's Add-ons Shack:
|
||||||
maintainer: Alex van den Hoogen <homeassistant@alxx.nl>
|
maintainer: Alex van den Hoogen <homeassistant@alxx.nl>
|
||||||
slug: 2ca71ec5
|
slug: 2ca71ec5
|
||||||
|
@ -10,6 +6,10 @@ B Tasker HomeAssistant Addons:
|
||||||
maintainer: B Tasker
|
maintainer: B Tasker
|
||||||
slug: 93f0ddc5
|
slug: 93f0ddc5
|
||||||
source: https://github.com/bentasker/HomeAssistantAddons
|
source: https://github.com/bentasker/HomeAssistantAddons
|
||||||
|
Cloudflared:
|
||||||
|
maintainer: Tobia Brenner <https://github.com/brenner-tobias/>
|
||||||
|
slug: 9074a9fa
|
||||||
|
source: https://github.com/brenner-tobias/ha-addons
|
||||||
EMHASS Add-on Energy Management for Home Assistant:
|
EMHASS Add-on Energy Management for Home Assistant:
|
||||||
maintainer: David HERNANDEZ <davidusb@gmail.com>
|
maintainer: David HERNANDEZ <davidusb@gmail.com>
|
||||||
slug: 5b918bf2
|
slug: 5b918bf2
|
||||||
|
@ -42,6 +42,10 @@ Home Assistant Google Drive Backup Repository:
|
||||||
maintainer: Stephen Beechen <stephen@beechens.com>
|
maintainer: Stephen Beechen <stephen@beechens.com>
|
||||||
slug: cebe7a76
|
slug: cebe7a76
|
||||||
source: https://github.com/sabeechen/hassio-google-drive-backup
|
source: https://github.com/sabeechen/hassio-google-drive-backup
|
||||||
|
MatterVN Hass.io Add-ons:
|
||||||
|
maintainer: TTVTien <ttvtien@gmail.com>
|
||||||
|
slug: 4ee6ccd4
|
||||||
|
source: https://github.com/TenySmart/HassioAddon
|
||||||
MickMake Hass.io Add-ons:
|
MickMake Hass.io Add-ons:
|
||||||
maintainer: MickMake <embed@mickmake.com>
|
maintainer: MickMake <embed@mickmake.com>
|
||||||
slug: ba22da74
|
slug: ba22da74
|
||||||
|
@ -54,10 +58,6 @@ Shortumations:
|
||||||
maintainer: Ari Sosnovsky <ariel@sosnovsky.ca>
|
maintainer: Ari Sosnovsky <ariel@sosnovsky.ca>
|
||||||
slug: 04377e81
|
slug: 04377e81
|
||||||
source: https://github.com/asosnovsky/Shortumation
|
source: https://github.com/asosnovsky/Shortumation
|
||||||
TenySmart Hass.io Add-ons:
|
|
||||||
maintainer: TTVTien <ttvtien@gmail.com>
|
|
||||||
slug: 4ee6ccd4
|
|
||||||
source: https://github.com/TenySmart/HassioAddon
|
|
||||||
bjeanes Home Assistant add-on repository:
|
bjeanes Home Assistant add-on repository:
|
||||||
maintainer: Bo Jeanes <hassio@bjeanes.com>
|
maintainer: Bo Jeanes <hassio@bjeanes.com>
|
||||||
slug: 9c51689a
|
slug: 9c51689a
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
2022.8.5
|
2023.4.6
|
|
@ -68,3 +68,44 @@
|
||||||
before: sunset
|
before: sunset
|
||||||
action:
|
action:
|
||||||
service: openuv.update_data
|
service: openuv.update_data
|
||||||
|
- id: '1661989262917'
|
||||||
|
alias: Control Living Room Lights
|
||||||
|
description: ''
|
||||||
|
trigger:
|
||||||
|
- id: brightness
|
||||||
|
platform: state
|
||||||
|
entity_id:
|
||||||
|
- sensor.living_room_light_dimmer_action
|
||||||
|
to:
|
||||||
|
- brightness_move_down
|
||||||
|
- brightness_move_up
|
||||||
|
- brightness_stop
|
||||||
|
- id: toggle
|
||||||
|
platform: state
|
||||||
|
to: toggle
|
||||||
|
entity_id:
|
||||||
|
- sensor.living_room_light_dimmer_action
|
||||||
|
condition: []
|
||||||
|
action:
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: '{{ trigger.id == ''toggle'' }}'
|
||||||
|
sequence:
|
||||||
|
- service: light.toggle
|
||||||
|
target:
|
||||||
|
area_id: living_room
|
||||||
|
data:
|
||||||
|
transition: 1
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: '{{ trigger.id == ''brightness'' }}'
|
||||||
|
sequence:
|
||||||
|
- service: light.turn_on
|
||||||
|
data:
|
||||||
|
transition: 0.1
|
||||||
|
brightness: '{{ state_attr(''sensor.living_room_light_dimmer_action'', ''brightness'')
|
||||||
|
| int }}'
|
||||||
|
target:
|
||||||
|
area_id: living_room
|
||||||
|
mode: queued
|
||||||
|
|
|
@ -17,7 +17,7 @@ homeassistant:
|
||||||
recorder:
|
recorder:
|
||||||
db_url: !secret recorder_db
|
db_url: !secret recorder_db
|
||||||
commit_interval: 30
|
commit_interval: 30
|
||||||
purge_keep_days: 60
|
purge_keep_days: 14
|
||||||
|
|
||||||
http:
|
http:
|
||||||
use_x_forwarded_for: true
|
use_x_forwarded_for: true
|
||||||
|
|
|
@ -1,8 +1 @@
|
||||||
sensor.rtorrent_all_torrents:
|
{}
|
||||||
unit_of_measurement: torrents
|
|
||||||
sensor.rtorrent_active_torrents:
|
|
||||||
unit_of_measurement: torrents
|
|
||||||
sensor.rtorrent_downloading_torrents:
|
|
||||||
unit_of_measurement: torrents
|
|
||||||
sensor.rtorrent_uploading_torrents:
|
|
||||||
unit_of_measurement: torrents
|
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,26 @@
|
||||||
|
# TODO:
|
||||||
|
#
|
||||||
|
# * Turn on AC when: someone is home, weather outside is cold, and are out of bed or about to get out of bed
|
||||||
|
# - maybe can change the logic that manages the blinds using the sleep/wake logic to be backed by a schedule state that multiple things can key off?
|
||||||
|
automation:
|
||||||
|
- alias: "Living Room AC Ionizer"
|
||||||
|
trigger:
|
||||||
|
platform: state
|
||||||
|
entity_id: climate.living_room_a_c
|
||||||
|
not_to:
|
||||||
|
- unavailable
|
||||||
|
- unknown
|
||||||
|
not_from:
|
||||||
|
- unavailable
|
||||||
|
- unknown
|
||||||
|
condition:
|
||||||
|
condition: template
|
||||||
|
value_template: '{{ trigger.to_state.state != "off" }}'
|
||||||
|
action:
|
||||||
|
- service: switch.turn_on
|
||||||
|
entity_id: switch.living_room_a_c_ionizer
|
||||||
|
- service: climate.set_fan_mode
|
||||||
|
data:
|
||||||
|
fan_mode: NATURE
|
||||||
|
target:
|
||||||
|
entity_id: climate.living_room_a_c
|
|
@ -6,6 +6,8 @@ sensor:
|
||||||
- platform: statistics # Force statistics integration to be loaded (even if no other sensors) so I can reload without restarting HA
|
- platform: statistics # Force statistics integration to be loaded (even if no other sensors) so I can reload without restarting HA
|
||||||
name: "dummy_statistics"
|
name: "dummy_statistics"
|
||||||
unique_id: dummy
|
unique_id: dummy
|
||||||
|
sampling_size: 20
|
||||||
|
state_characteristic: mean
|
||||||
entity_id: sensor.energy_production_tomorrow
|
entity_id: sensor.energy_production_tomorrow
|
||||||
|
|
||||||
- platform: filter # Force filter integration to be loaded (even if no other sensors) so I can reload without restarting HA
|
- platform: filter # Force filter integration to be loaded (even if no other sensors) so I can reload without restarting HA
|
||||||
|
|
|
@ -31,6 +31,23 @@ utility_meter:
|
||||||
name: Energy exported
|
name: Energy exported
|
||||||
cycle: daily
|
cycle: daily
|
||||||
|
|
||||||
|
# daily_supply_charge:
|
||||||
|
# unique_id: 31887b27e2ecd837328b
|
||||||
|
|
||||||
|
template:
|
||||||
|
- trigger:
|
||||||
|
- platform: time_pattern
|
||||||
|
hours: "*" # calculate hourly should be fine
|
||||||
|
sensor:
|
||||||
|
# Increases every day by 1W to fake a daily supply charge in energy dashboard.
|
||||||
|
- state: >-
|
||||||
|
{{ 0.001 * (now() - "2022-09-26" | as_datetime | as_local).days }}
|
||||||
|
unit_of_measurement: kWh
|
||||||
|
state_class: total_increasing
|
||||||
|
device_class: energy
|
||||||
|
unique_id: 3970c65019ebd336b074
|
||||||
|
name: "Days for daily supply charge"
|
||||||
|
|
||||||
automation:
|
automation:
|
||||||
- id: b508954f792ff8483254
|
- id: b508954f792ff8483254
|
||||||
alias: Change electricity tariff
|
alias: Change electricity tariff
|
||||||
|
@ -73,39 +90,23 @@ rest_command:
|
||||||
User-Agent: HomeAssistant
|
User-Agent: HomeAssistant
|
||||||
X-Pvoutput-Apikey: !secret pvoutput_api_key
|
X-Pvoutput-Apikey: !secret pvoutput_api_key
|
||||||
X-Pvoutput-SystemId: !secret pvoutput_system_id
|
X-Pvoutput-SystemId: !secret pvoutput_system_id
|
||||||
payload: >-
|
payload: "{{ states('sensor.pvoutput_payload') }}"
|
||||||
d={{now().strftime("%Y%m%d")}} {#- date -#}
|
|
||||||
&t={{now().strftime("%H:%M")}} {#- time -#}
|
|
||||||
&c1=2 {#- cumulative mode -#}
|
|
||||||
&v1={{(states('sensor.inverter_pv_generation_today')|float * 1000)|round(0) }}
|
|
||||||
{#- energy generation (Wh) -#}
|
|
||||||
&v2={{states('sensor.inverter_active_power')|float|round(0)}} {#- power generation (W) -#}
|
|
||||||
&v3= {#- energy consumption (Wh) -#}
|
|
||||||
&v4={{states('sensor.household_power_demand')|float|round(0)}} {#- power consumption (W) -#}
|
|
||||||
{#- &v5={{states('sensor.home_weather_temperature')|float|round(1)}} {#- panel temperature? -#}
|
|
||||||
&v6={{states('sensor.inverter_phase_a_voltage')|float|round(1)}} {#- voltage -#}
|
|
||||||
content_type: "application/x-www-form-urlencoded"
|
content_type: "application/x-www-form-urlencoded"
|
||||||
|
|
||||||
sensor:
|
sensor:
|
||||||
- platform: template
|
- platform: template
|
||||||
sensors:
|
sensors:
|
||||||
# energy_import_price:
|
pvoutput_payload:
|
||||||
# unique_id: 2b80f57455c84e873952
|
unique_id: pvoutput_payload
|
||||||
# friendly_name: Energy import price
|
friendly_name: PVOutput payload
|
||||||
# value_template: >-
|
value_template: >-
|
||||||
# {%- if is_state('select.daily_energy_import', 'peak') -%}
|
d={{now().strftime("%Y%m%d")}} {#- date -#}
|
||||||
# 0.23320
|
&t={{now().strftime("%H:%M")}} {#- time -#}
|
||||||
# {%- else -%}
|
&c1=2 {#- cumulative mode -#}
|
||||||
# 0.15235
|
&v1={{states('sensor.inverter_pv_generation_today') | int * 1000 }} {#- energy generation -#}
|
||||||
# {%- endif -%}
|
&v2={{states('sensor.inverter_pv_power')|float|round(0)}} {#- power generation (W) -#}
|
||||||
# unit_of_measurement: AUD
|
&v4={{states('sensor.inverter_load_power')|float|round(0)}} {#- power consumption (W) -#}
|
||||||
# device_class: monetary
|
&v6={{states('sensor.inverter_phase_a_voltage')|float|round(1)}} {#- voltage -#}
|
||||||
# energy_export_price:
|
|
||||||
# unique_id: a661839f99fbc85e23d9
|
|
||||||
# friendly_name: Energy export price
|
|
||||||
# value_template: "0.067"
|
|
||||||
# unit_of_measurement: AUD
|
|
||||||
# device_class: monetary
|
|
||||||
|
|
||||||
eagle_200_meter_power_demand_w:
|
eagle_200_meter_power_demand_w:
|
||||||
unique_id: 528a94ffdd069f6f5dcd
|
unique_id: 528a94ffdd069f6f5dcd
|
||||||
|
@ -130,288 +131,3 @@ sensor:
|
||||||
unit_of_measurement: $/hr
|
unit_of_measurement: $/hr
|
||||||
device_class: monetary
|
device_class: monetary
|
||||||
friendly_name: Current electricity cost
|
friendly_name: Current electricity cost
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# SunGather (used internally by ModbusTCP2MQTT add-on) produces this payload, but doesn't create sensors for everything I want to monitor:
|
|
||||||
# {
|
|
||||||
# "device_type_code": "SH5.0RS",
|
|
||||||
# "run_state": "OFF",
|
|
||||||
# "protocol_number": 1094856704,
|
|
||||||
# "protocol_version": 16781568,
|
|
||||||
# "arm_software_version": 16722,
|
|
||||||
# "dsp_software_version": 19780,
|
|
||||||
# "serial_number": 16690,
|
|
||||||
# "nominal_active_power": 5.0,
|
|
||||||
# "output_type": "2P",
|
|
||||||
# "daily_power_yields": 6.1,
|
|
||||||
# "total_power_yields": 0.0,
|
|
||||||
# "total_running_time": 0,
|
|
||||||
# "internal_temperature": 22.6,
|
|
||||||
# "total_apparent_power": 1234,
|
|
||||||
# "mppt_1_voltage": 433.4,
|
|
||||||
# "mppt_1_current": 1.2,
|
|
||||||
# "mppt_2_voltage": 213.8,
|
|
||||||
# "mppt_2_current": 0.7,
|
|
||||||
# "mppt_3_voltage": 0.0,
|
|
||||||
# "mppt_3_current": 0.0,
|
|
||||||
# "total_dc_power": 711,
|
|
||||||
# "phase_a_voltage": 243.7,
|
|
||||||
# "phase_b_voltage": 0.0,
|
|
||||||
# "phase_c_voltage": 0.0,
|
|
||||||
# "phase_a_current": 5.3,
|
|
||||||
# "phase_b_current": 0.0,
|
|
||||||
# "phase_c_current": 0.0,
|
|
||||||
# "total_active_power": 1084,
|
|
||||||
# "total_reactive_power": 509,
|
|
||||||
# "power_factor": 0.91,
|
|
||||||
# "grid_frequency": 49.97,
|
|
||||||
# "work_state_1": 0,
|
|
||||||
# "nominal_reactive_power": 3.0,
|
|
||||||
# "array_insulation_resistance": 1124,
|
|
||||||
# "active_power_regulation_setpoint": 0,
|
|
||||||
# "reactive_power_regulation_setpoint": 0,
|
|
||||||
# "work_state_2": 0,
|
|
||||||
# "meter_power": 0,
|
|
||||||
# "meter_a_phase_power": 0,
|
|
||||||
# "meter_b_phase_power": 80936959,
|
|
||||||
# "meter_c_phase_power": -65536,
|
|
||||||
# "load_power": 1084,
|
|
||||||
# "daily_export_energy": 0.1,
|
|
||||||
# "total_export_energy": 2.6,
|
|
||||||
# "daily_import_energy": 0.0,
|
|
||||||
# "total_import_energy": 192.3,
|
|
||||||
# "daily_direct_energy_consumption": 0.3,
|
|
||||||
# "total_direct_energy_consumption": 12.3,
|
|
||||||
# "daily_running_time": 0,
|
|
||||||
# "mppt_4_voltage": 0.0,
|
|
||||||
# "mppt_4_current": 0.0,
|
|
||||||
# "mppt_5_voltage": 0.0,
|
|
||||||
# "mppt_5_current": 0.0,
|
|
||||||
# "mppt_6_voltage": 0.0,
|
|
||||||
# "mppt_6_current": 0.0,
|
|
||||||
# "mppt_7_voltage": 0.0,
|
|
||||||
# "mppt_7_current": 0.0,
|
|
||||||
# "mppt_8_voltage": 0.0,
|
|
||||||
# "mppt_8_current": 0.0,
|
|
||||||
# "monthly_power_yields": 0.0,
|
|
||||||
# "mppt_9_voltage": 0.0,
|
|
||||||
# "mppt_9_current": 0.0,
|
|
||||||
# "mppt_10_voltage": 0.0,
|
|
||||||
# "mppt_10_current": 0.0,
|
|
||||||
# "mppt_11_voltage": 0.0,
|
|
||||||
# "mppt_11_current": 0.0,
|
|
||||||
# "mppt_12_voltage": 0.0,
|
|
||||||
# "mppt_12_current": 0.0,
|
|
||||||
# "negative_voltage_to_the_ground": 0.0,
|
|
||||||
# "bus_voltage": 458.0,
|
|
||||||
# "pid_work_state": 0,
|
|
||||||
# "pid_alarm_code": 0,
|
|
||||||
# "export_power": -7,
|
|
||||||
# "power_meter": 1090,
|
|
||||||
# "pv_power_of_today": 0,
|
|
||||||
# "daily_pv_energy_yields": 0.0,
|
|
||||||
# "monthly_pv_energy_yields": 0,
|
|
||||||
# "yearly_pv_energy_yields": 0.0,
|
|
||||||
# "direct_power_consumption_today_pv": 0,
|
|
||||||
# "direct_power_consumption_pv": 0.0,
|
|
||||||
# "direct_power_consumption_monthly_pv": 0.0,
|
|
||||||
# "direct_power_consumption_yearly_pv": 0.0,
|
|
||||||
# "export_power_from_pv_today": 0,
|
|
||||||
# "export_power_from_pv": 0.0,
|
|
||||||
# "export_power_from_pv_monthly": 0.0,
|
|
||||||
# "export_power_from_pv_yearly": 0.0,
|
|
||||||
# "battery_charge_power_from_pv_today": 0.0,
|
|
||||||
# "battery_charge_power_from_pv": 0.0,
|
|
||||||
# "battery_charge_power_from_pv_monthly": 0.0,
|
|
||||||
# "battery_charge_power_from_pv_yearly": 0.0,
|
|
||||||
# "string_1_current": 0.0,
|
|
||||||
# "string_2_current": 0.0,
|
|
||||||
# "string_3_current": 0.0,
|
|
||||||
# "string_4_current": 0.0,
|
|
||||||
# "string_5_current": 0.0,
|
|
||||||
# "string_6_current": 0.0,
|
|
||||||
# "string_7_current": 0.0,
|
|
||||||
# "string_8_current": 0.0,
|
|
||||||
# "string_9_current": 0.0,
|
|
||||||
# "string_10_current": 0.0,
|
|
||||||
# "string_11_current": 0.0,
|
|
||||||
# "string_12_current": 0.0,
|
|
||||||
# "string_13_current": 0.0,
|
|
||||||
# "string_14_current": 0.0,
|
|
||||||
# "string_15_current": 0.0,
|
|
||||||
# "string_16_current": 0.0,
|
|
||||||
# "string_17_current": 0.0,
|
|
||||||
# "string_18_current": 0.0,
|
|
||||||
# "string_19_current": 0.0,
|
|
||||||
# "string_20_current": 0.0,
|
|
||||||
# "string_21_current": 0.0,
|
|
||||||
# "string_22_current": 0.0,
|
|
||||||
# "string_23_current": 0.0,
|
|
||||||
# "string_24_current": 0.0,
|
|
||||||
# "system_state": 0,
|
|
||||||
# "running_state": 45,
|
|
||||||
# "daily_pv_generation": 0.3,
|
|
||||||
# "total_pv_generation": 38.5,
|
|
||||||
# "daily_pv_export": 0.0,
|
|
||||||
# "total_pv_export": 2.5,
|
|
||||||
# "load_power_hybrid": 1094,
|
|
||||||
# "export_power_hybrid": -10,
|
|
||||||
# "daily_battery_charge_from_pv": 0.0,
|
|
||||||
# "total_battery_charge_from_pv": 23.7,
|
|
||||||
# "co2_reduction": 26.9,
|
|
||||||
# "battery_voltage": 0.0,
|
|
||||||
# "battery_current": 0,
|
|
||||||
# "battery_power": 465,
|
|
||||||
# "battery_level": 5.8,
|
|
||||||
# "battery_state_of_healthy": 10.0,
|
|
||||||
# "battery_temperature": 10.8,
|
|
||||||
# "daily_battery_discharge_energy": 5.7,
|
|
||||||
# "total_battery_discharge_energy": 11.2,
|
|
||||||
# "self_consumption_of_day": 100.0,
|
|
||||||
# "grid_state": 0,
|
|
||||||
# "battery_capacity": 12.8,
|
|
||||||
# "daily_charge_energy": 0.0,
|
|
||||||
# "total_charge_energy": 10.3,
|
|
||||||
# "drm_state": 255,
|
|
||||||
# "inverter_alarm": 0.0,
|
|
||||||
# "grid-side_fault": 0.0,
|
|
||||||
# "system_fault1": 0.0,
|
|
||||||
# "system_fault2": 0.0,
|
|
||||||
# "dc-side_fault": 0.0,
|
|
||||||
# "permanent_fault": 0.0,
|
|
||||||
# "bdc-side_fault": 0.0,
|
|
||||||
# "bdc-side_permanent_fault": 0.0,
|
|
||||||
# "battery_fault": 0.0,
|
|
||||||
# "battery_alarm": 0.0,
|
|
||||||
# "bms_alarm": 0,
|
|
||||||
# "bms_protection": 0,
|
|
||||||
# "bms_fault1": 0,
|
|
||||||
# "bms_fault2": 0,
|
|
||||||
# "bms_alarm2": 0,
|
|
||||||
# "bms_status": 0,
|
|
||||||
# "max_charging_current": 0,
|
|
||||||
# "max_discharging_current": 0,
|
|
||||||
# "warning": 0,
|
|
||||||
# "protection": 0,
|
|
||||||
# "fault1": 0,
|
|
||||||
# "fault2": 0,
|
|
||||||
# "soc": 0,
|
|
||||||
# "soh": 0,
|
|
||||||
# "cycle_count": 0.0,
|
|
||||||
# "average_cell_voltage": 0,
|
|
||||||
# "max_cell_voltage": 0,
|
|
||||||
# "min_cell_voltage": 0,
|
|
||||||
# "battery_pack_voltage": 0,
|
|
||||||
# "average_cell_temp": 0,
|
|
||||||
# "max_cell_temp": 0,
|
|
||||||
# "min_cell_temp": 0,
|
|
||||||
# "start_stop": "Start",
|
|
||||||
# "power_limitation_switch": "Enable",
|
|
||||||
# "power_limitation_setting": 100.0,
|
|
||||||
# "export_power_limitation": 0,
|
|
||||||
# "export_power_limitation_value": 0,
|
|
||||||
# "current_transformer_output_current": 0,
|
|
||||||
# "current_transformer_range": 0,
|
|
||||||
# "current_transformer": 0,
|
|
||||||
# "export_power_limitation_percentage": 0.0,
|
|
||||||
# "installed_pv_power": 0.0,
|
|
||||||
# "power_factor_setting": 0.0,
|
|
||||||
# "night_svg_switch": 0,
|
|
||||||
# "reactive_power_adjustment_mode": "Enable Q(U)",
|
|
||||||
# "reactive_power_percentage_setting": 0.0,
|
|
||||||
# "power_limitation_adjustment": 0.0,
|
|
||||||
# "reactive_power_adjustment": 0.0,
|
|
||||||
# "pid_recovery": 0,
|
|
||||||
# "anti_pid": 0,
|
|
||||||
# "fullday_pid_suppression": 0,
|
|
||||||
# "export_to_grid": 0,
|
|
||||||
# "import_from_grid": 0,
|
|
||||||
# "timestamp": "2022-7-8 8:59:15"
|
|
||||||
# }
|
|
||||||
# mqtt:
|
|
||||||
# # https://github.com/bohdan-s/SunGather/blob/main/SunGather/registers-sungrow.yaml
|
|
||||||
# sensor:
|
|
||||||
# - &inverter_sensor
|
|
||||||
# state_topic: "inverter/SH50RS/registers"
|
|
||||||
# json_attributes_topic: "inverter/SH50RS/registers"
|
|
||||||
# unique_id: inverter_battery_level
|
|
||||||
# object_id: inverter_battery_level
|
|
||||||
# name: "Inverter battery level"
|
|
||||||
# value_template: "{{ value_json.battery_level }}"
|
|
||||||
# device_class: battery
|
|
||||||
# unit_of_measurement: "%"
|
|
||||||
# device: &inverter_device
|
|
||||||
# name: Solar Inverter
|
|
||||||
# manufacturer: Sungrow
|
|
||||||
# model: SH5.0RS
|
|
||||||
# via_device: 07bec9a1e7f11660c94ac9b707f6ea66
|
|
||||||
# connections:
|
|
||||||
# - - address
|
|
||||||
# - !secret solar_inverter_ip
|
|
||||||
# - <<: *inverter_sensor
|
|
||||||
# unique_id: inverter_battery_power
|
|
||||||
# object_id: inverter_battery_power
|
|
||||||
# name: Inverter battery power
|
|
||||||
# value_template: "{{ value_json.battery_power }}"
|
|
||||||
# device_class: power
|
|
||||||
# unit_of_measurement: W
|
|
||||||
# - <<: *inverter_sensor
|
|
||||||
# unique_id: inverter_grid_current
|
|
||||||
# object_id: inverter_grid_current
|
|
||||||
# name: Inverter grid current
|
|
||||||
# value_template: "{{ value_json.phase_a_current }}"
|
|
||||||
# device_class: current
|
|
||||||
# unit_of_measurement: A
|
|
||||||
# - <<: *inverter_sensor
|
|
||||||
# unique_id: inverter_grid_voltage
|
|
||||||
# object_id: inverter_grid_voltage
|
|
||||||
# name: Inverter grid voltage
|
|
||||||
# value_template: "{{ value_json.phase_a_voltage }}"
|
|
||||||
# device_class: voltage
|
|
||||||
# unit_of_measurement: V
|
|
||||||
# - <<: *inverter_sensor
|
|
||||||
# unique_id: inverter_grid_frequency
|
|
||||||
# object_id: inverter_grid_frequency
|
|
||||||
# name: Inverter grid frequency
|
|
||||||
# value_template: "{{ value_json.grid_frequency }}"
|
|
||||||
# unit_of_measurement: Hz
|
|
||||||
# - <<: *inverter_sensor
|
|
||||||
# unique_id: inverter_total_battery_discharge
|
|
||||||
# object_id: inverter_total_battery_discharge
|
|
||||||
# name: Inverter total battery discharge
|
|
||||||
# value_template: "{{ value_json.total_battery_discharge_energy }}"
|
|
||||||
# device_class: energy
|
|
||||||
# unit_of_measurement: kWh
|
|
||||||
# state_class: total_increasing
|
|
||||||
# - <<: *inverter_sensor
|
|
||||||
# unique_id: inverter_total_battery_charge
|
|
||||||
# object_id: inverter_total_battery_charge
|
|
||||||
# name: Inverter total battery charge
|
|
||||||
# value_template: "{{ value_json.total_battery_charge_from_pv }}"
|
|
||||||
# device_class: energy
|
|
||||||
# unit_of_measurement: kWh
|
|
||||||
# state_class: total_increasing
|
|
||||||
# - <<: *inverter_sensor
|
|
||||||
# unique_id: inverter_total_pv_generation
|
|
||||||
# object_id: inverter_total_pv_generation
|
|
||||||
# name: Inverter total PV generation
|
|
||||||
# value_template: "{{ value_json.total_pv_generation }}"
|
|
||||||
# device_class: energy
|
|
||||||
# unit_of_measurement: kWh
|
|
||||||
# state_class: total_increasing
|
|
||||||
# - <<: *inverter_sensor
|
|
||||||
# unique_id: inverter_total_pv_export
|
|
||||||
# object_id: inverter_total_pv_export
|
|
||||||
# name: Inverter total PV export
|
|
||||||
# value_template: "{{ value_json.total_pv_export }}"
|
|
||||||
# device_class: energy
|
|
||||||
# unit_of_measurement: kWh
|
|
||||||
# state_class: total_increasing
|
|
||||||
# - <<: *inverter_sensor
|
|
||||||
# unique_id: inverter_pv_power
|
|
||||||
# object_id: inverter_pv_power
|
|
||||||
# name: Inverter PV power
|
|
||||||
# value_template: "{{ value_json.total_dc_power }}"
|
|
||||||
# device_class: power
|
|
||||||
# unit_of_measurement: W
|
|
||||||
|
|
|
@ -1,62 +1,54 @@
|
||||||
android_ip_webcam:
|
|
||||||
- host: 10.10.10.112
|
|
||||||
name: Tent Cam
|
|
||||||
sensors:
|
|
||||||
- battery_level
|
|
||||||
- battery_temp
|
|
||||||
- light
|
|
||||||
- proximity
|
|
||||||
switches:
|
|
||||||
- exposure_lock
|
|
||||||
- ffc
|
|
||||||
- focus
|
|
||||||
- night_vision
|
|
||||||
- overlay
|
|
||||||
|
|
||||||
camera:
|
camera:
|
||||||
- platform: mjpeg_timelapse
|
- platform: mjpeg_timelapse
|
||||||
image_url: http://10.10.10.112:8080/shot.jpg
|
image_url: http://10.10.10.112:8080/shot.jpg
|
||||||
name: Tent Timelapse
|
name: Tent Timelapse
|
||||||
fetch_interval: 3600
|
fetch_interval: 3600
|
||||||
max_frames: 36
|
max_frames: 1000
|
||||||
framerate: 10
|
framerate: 5
|
||||||
quality: 80
|
quality: 80
|
||||||
loop: true
|
loop: true
|
||||||
|
# - platform: mjpeg_timelapse
|
||||||
|
# image_url: http://10.10.10.112:8080/shot.jpg
|
||||||
|
# name: Tent Timelapse (Daily, )
|
||||||
|
# fetch_interval:
|
||||||
|
# max_frames: 365
|
||||||
|
# framerate: 10
|
||||||
|
# quality: 80
|
||||||
|
# loop: true
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: schedule_state
|
||||||
|
name: Tent light schedule
|
||||||
|
|
||||||
template:
|
template:
|
||||||
- binary_sensor:
|
- binary_sensor:
|
||||||
- unique_id: tent_lights_status
|
- unique_id: tent_lights_status
|
||||||
name: Tent lights status
|
name: Tent lights status
|
||||||
delay_on: "0:00:05"
|
|
||||||
delay_off: "0:00:05"
|
|
||||||
state: |
|
state: |
|
||||||
{{ states('sensor.tent_wattage') | float > 150 }}
|
{{ 500 < [states('sensor.ble_illuminance_tent_c47c8d6dd13f') | int(default=0), states('sensor.ble_illuminance_tent_c47c8d6dd155') | int(default=0)] | max }}
|
||||||
attributes:
|
# trigger:
|
||||||
device_class: power
|
# - platform: numeric_state
|
||||||
|
# entity_id:
|
||||||
|
# # - sensor.ble_illuminance_tent_c47c8d6dd155
|
||||||
|
# - sensor.ble_illuminance_tent_c47c8d6dd13f
|
||||||
|
# below: 700
|
||||||
|
# variables:
|
||||||
|
# state: false
|
||||||
|
# - platform: numeric_state
|
||||||
|
# entity_id:
|
||||||
|
# # - sensor.ble_illuminance_tent_c47c8d6dd155
|
||||||
|
# - sensor.ble_illuminance_tent_c47c8d6dd13f
|
||||||
|
# above: 700
|
||||||
|
# variables:
|
||||||
|
# state: true
|
||||||
- sensor:
|
- sensor:
|
||||||
- unique_id: tent_temperature_cached
|
|
||||||
name: Tent Temperature (cached)
|
|
||||||
unit_of_measurement: °C
|
|
||||||
device_class: temperature
|
|
||||||
state_class: measurement
|
|
||||||
state: |
|
|
||||||
{{ float(states('sensor.tent_temperature'), default=states('sensor.tent_temperature_cached')) }}
|
|
||||||
|
|
||||||
- unique_id: tent_humidity_cached
|
|
||||||
name: Tent Humidity (cached)
|
|
||||||
unit_of_measurement: "%"
|
|
||||||
device_class: humidity
|
|
||||||
state_class: measurement
|
|
||||||
state: |
|
|
||||||
{{ float(states('sensor.tent_humidity'), default=states('tent_humidity_cached')) }}
|
|
||||||
|
|
||||||
- unique_id: tent_svp
|
- unique_id: tent_svp
|
||||||
name: "Tent SVP (Saturation Vapor Pressure)"
|
name: "Tent SVP (Saturation Vapor Pressure)"
|
||||||
unit_of_measurement: kPa
|
unit_of_measurement: kPa
|
||||||
device_class: pressure
|
device_class: pressure
|
||||||
state_class: measurement
|
state_class: measurement
|
||||||
state: |
|
state: |
|
||||||
{% set T = float(states('sensor.tent_temperature_cached')) %}
|
{% set T = float(states('sensor.ble_temperature_tent_a4c1385ec751')) %}
|
||||||
{% if is_number(T) %}
|
{% if is_number(T) %}
|
||||||
{{ (0.61078 * e ** (17.2694 * T / (T + 238.3))) | round(3) }}
|
{{ (0.61078 * e ** (17.2694 * T / (T + 238.3))) | round(3) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -69,7 +61,7 @@ template:
|
||||||
state_class: measurement
|
state_class: measurement
|
||||||
state: |
|
state: |
|
||||||
{% set SVP = float(states('sensor.tent_svp')) %}
|
{% set SVP = float(states('sensor.tent_svp')) %}
|
||||||
{% set RH = float(states('sensor.tent_humidity_cached')) %}
|
{% set RH = float(states('sensor.ble_humidity_tent_a4c1385ec751')) %}
|
||||||
{% if is_number(SVP) and is_number(RH) %}
|
{% if is_number(SVP) and is_number(RH) %}
|
||||||
{{ (SVP * (RH/100.0)) | round(3) }}
|
{{ (SVP * (RH/100.0)) | round(3) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -90,6 +82,20 @@ template:
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
automation:
|
automation:
|
||||||
|
- id: snapshot_camera
|
||||||
|
alias: Snapshot grow camera every 12 hours
|
||||||
|
trigger:
|
||||||
|
- platform: time_pattern
|
||||||
|
hours: "/12"
|
||||||
|
condition:
|
||||||
|
- "{{ is_state('binary_sensor.tent_lights_status', 'on') }}"
|
||||||
|
action:
|
||||||
|
- service: camera.snapshot
|
||||||
|
target:
|
||||||
|
entity_id: camera.tent_camera_mjpeg
|
||||||
|
data_template:
|
||||||
|
filename: "/config/camera/camera.tent_camera_mjpeg/{{ now().strftime('%Y%m%d-%H%M%S') }}.jpg"
|
||||||
|
|
||||||
- id: "1635395611631"
|
- id: "1635395611631"
|
||||||
alias: Tent Cam Night Mode When Light Is Off
|
alias: Tent Cam Night Mode When Light Is Off
|
||||||
description: ""
|
description: ""
|
||||||
|
@ -297,9 +303,7 @@ automation:
|
||||||
condition:
|
condition:
|
||||||
- condition: or
|
- condition: or
|
||||||
conditions:
|
conditions:
|
||||||
- condition: numeric_state
|
- "{{ is_state('binary_sensor.tent_lights_status', 'off') }}"
|
||||||
entity_id: sensor.tent_wattage
|
|
||||||
below: "150"
|
|
||||||
- condition: numeric_state
|
- condition: numeric_state
|
||||||
entity_id: sensor.tent_humidity_cached
|
entity_id: sensor.tent_humidity_cached
|
||||||
above: input_number.minimum_tent_humidity
|
above: input_number.minimum_tent_humidity
|
||||||
|
@ -311,33 +315,6 @@ automation:
|
||||||
- switch.tent_humidifier
|
- switch.tent_humidifier
|
||||||
- switch.tent_humidifier_local
|
- switch.tent_humidifier_local
|
||||||
mode: restart
|
mode: restart
|
||||||
- id: "1644716285765"
|
|
||||||
alias: Re-focus tent cam regularly
|
|
||||||
description: ""
|
|
||||||
trigger:
|
|
||||||
- platform: time_pattern
|
|
||||||
minutes: /5
|
|
||||||
seconds: "0"
|
|
||||||
hours: "*"
|
|
||||||
condition:
|
|
||||||
- condition: numeric_state
|
|
||||||
entity_id: sensor.tent_wattage
|
|
||||||
above: "150"
|
|
||||||
action:
|
|
||||||
- service: switch.toggle
|
|
||||||
data: {}
|
|
||||||
target:
|
|
||||||
entity_id: switch.tent_cam_focus
|
|
||||||
- delay:
|
|
||||||
hours: 0
|
|
||||||
minutes: 0
|
|
||||||
seconds: 3
|
|
||||||
milliseconds: 0
|
|
||||||
- service: switch.toggle
|
|
||||||
data: {}
|
|
||||||
target:
|
|
||||||
entity_id: switch.tent_cam_focus
|
|
||||||
mode: single
|
|
||||||
- id: "1645058611536"
|
- id: "1645058611536"
|
||||||
alias: Count humidifier run time
|
alias: Count humidifier run time
|
||||||
description: ""
|
description: ""
|
||||||
|
@ -382,38 +359,28 @@ automation:
|
||||||
target:
|
target:
|
||||||
entity_id: timer.humidifier_time_till_refill
|
entity_id: timer.humidifier_time_till_refill
|
||||||
mode: restart
|
mode: restart
|
||||||
- id: "1647038709985"
|
|
||||||
alias: Disable timelapse when lights off
|
- id: "b30ad63e38bec67a0207"
|
||||||
description: ""
|
alias: Timelapse tent cam only when tent lights on
|
||||||
trigger:
|
trigger:
|
||||||
- platform: numeric_state
|
- platform: state
|
||||||
entity_id: sensor.tent_wattage
|
entity_id: binary_sensor.tent_lights_status
|
||||||
for:
|
not_to:
|
||||||
hours: 0
|
- unknown
|
||||||
minutes: 0
|
- unavailable
|
||||||
seconds: 30
|
not_from:
|
||||||
below: "100"
|
- unknown
|
||||||
|
- unavailable
|
||||||
|
variables:
|
||||||
|
service: >
|
||||||
|
{% if trigger.to_state.state == 'on' %}
|
||||||
|
mjpeg_timelapse.resume_recording
|
||||||
|
{% else %}
|
||||||
|
mjpeg_timelapse.pause_recording
|
||||||
|
{% endif %}
|
||||||
condition: []
|
condition: []
|
||||||
action:
|
action:
|
||||||
- service: mjpeg_timelapse.pause_recording
|
- service: "{{ service }}"
|
||||||
data: {}
|
|
||||||
target:
|
|
||||||
entity_id: camera.tent_timelapse
|
|
||||||
mode: single
|
|
||||||
- id: "1647038771614"
|
|
||||||
alias: Enable timelapse when lights on
|
|
||||||
description: ""
|
|
||||||
trigger:
|
|
||||||
- platform: numeric_state
|
|
||||||
entity_id: sensor.tent_wattage
|
|
||||||
for:
|
|
||||||
hours: 0
|
|
||||||
minutes: 15
|
|
||||||
seconds: 0
|
|
||||||
above: "180"
|
|
||||||
condition: []
|
|
||||||
action:
|
|
||||||
- service: mjpeg_timelapse.resume_recording
|
|
||||||
data: {}
|
data: {}
|
||||||
target:
|
target:
|
||||||
entity_id: camera.tent_timelapse
|
entity_id: camera.tent_timelapse
|
||||||
|
|
|
@ -52,7 +52,17 @@ automation:
|
||||||
action:
|
action:
|
||||||
- service: light.turn_off
|
- service: light.turn_off
|
||||||
target:
|
target:
|
||||||
entity_id: all
|
area_id:
|
||||||
|
- ri_s_office
|
||||||
|
- bo_s_office
|
||||||
|
- living_room
|
||||||
|
- kitchen
|
||||||
|
- hallway
|
||||||
|
- laundry_room
|
||||||
|
- bathroom
|
||||||
|
- analog_room
|
||||||
|
- outdoors
|
||||||
|
- garden_shed
|
||||||
- service: light.turn_on
|
- service: light.turn_on
|
||||||
data:
|
data:
|
||||||
color_temp: 462
|
color_temp: 462
|
||||||
|
@ -117,6 +127,57 @@ automation:
|
||||||
data:
|
data:
|
||||||
entity_id: "{{ toggle }}"
|
entity_id: "{{ toggle }}"
|
||||||
|
|
||||||
|
- id: bedroom_blinds
|
||||||
|
alias: Manage bedroom blinds
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id: binary_sensor.in_bed
|
||||||
|
to: "on"
|
||||||
|
id: in_bed
|
||||||
|
for:
|
||||||
|
hours: 2 # proxy for "is asleep"
|
||||||
|
- id: sunset
|
||||||
|
platform: state
|
||||||
|
entity_id: sun.sun
|
||||||
|
to: below_horizon
|
||||||
|
action:
|
||||||
|
- service: cover.close_cover
|
||||||
|
target:
|
||||||
|
area_id: bedroom
|
||||||
|
# if we've gone to bed, wait for the us to get up or 8 hours to pass (whichever happens first) to then re-open
|
||||||
|
# blinds.
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
condition: trigger
|
||||||
|
id: in_bed
|
||||||
|
sequence:
|
||||||
|
- wait_for_trigger:
|
||||||
|
- platform: template
|
||||||
|
value_template: >
|
||||||
|
{{ is_state('binary_sensor.in_bed', 'off') }}
|
||||||
|
for:
|
||||||
|
minutes: 10 # _staying_ out of bed
|
||||||
|
timeout:
|
||||||
|
hours: 6 # 2 hours already part of trigger condition, for 8 hours total
|
||||||
|
- wait_for_trigger:
|
||||||
|
- platform: template
|
||||||
|
value_template: >
|
||||||
|
{{ is_state('sun.sun', 'above_horizon') and now().hour >= 7 }}
|
||||||
|
- service: cover.set_cover_position
|
||||||
|
data:
|
||||||
|
position: 20
|
||||||
|
target:
|
||||||
|
area_id: bedroom
|
||||||
|
- wait_for_trigger:
|
||||||
|
- platform: template
|
||||||
|
value_template: >
|
||||||
|
{{ is_state('binary_sensor.anyone_in_bed', 'off') }}
|
||||||
|
timeout:
|
||||||
|
hours: 2
|
||||||
|
- service: cover.open_cover
|
||||||
|
target:
|
||||||
|
area_id: bedroom
|
||||||
|
|
||||||
template:
|
template:
|
||||||
- binary_sensor:
|
- binary_sensor:
|
||||||
- unique_id: in_bed
|
- unique_id: in_bed
|
||||||
|
@ -166,7 +227,15 @@ homekit:
|
||||||
- switch.bos_office_heater
|
- switch.bos_office_heater
|
||||||
- switch.ri_s_desk_plug
|
- switch.ri_s_desk_plug
|
||||||
|
|
||||||
|
- cover.analog_room_blinds
|
||||||
|
- cover.bos_office_blinds
|
||||||
|
- cover.bedroom_blinds
|
||||||
|
- cover.front_gate
|
||||||
|
- climate.living_room_a_c
|
||||||
|
- light.fairy_lights
|
||||||
|
|
||||||
include_entity_globs:
|
include_entity_globs:
|
||||||
|
- climate.living_room*
|
||||||
- binary_sensor.*_is_occupied
|
- binary_sensor.*_is_occupied
|
||||||
- binary_sensor.*_motion
|
- binary_sensor.*_motion
|
||||||
- binary_sensor.*_presence
|
- binary_sensor.*_presence
|
||||||
|
@ -190,6 +259,23 @@ homekit:
|
||||||
- sensor.*weather*
|
- sensor.*weather*
|
||||||
- sensor.nas_*
|
- sensor.nas_*
|
||||||
- sensor.*_nas_*
|
- sensor.*_nas_*
|
||||||
|
|
||||||
|
# Magic areas entities
|
||||||
|
- light.area_*
|
||||||
|
- light.sleep_lights_*
|
||||||
|
- light.global_lights
|
||||||
|
- light.interior_lights
|
||||||
|
- light.exterior_lights
|
||||||
|
- light.overhead_lights*
|
||||||
|
- light.accent_lights*
|
||||||
|
- cover.area_*
|
||||||
|
- switch.area_light_control_*
|
||||||
|
- binary_sensor.area_battery_*
|
||||||
|
- binary_sensor.area_connectivity_*
|
||||||
|
- binary_sensor.area_door_*
|
||||||
|
- binary_sensor.area_tamper_*
|
||||||
|
- binary_sensor.area_update_*
|
||||||
|
- binary_sensor.area_global
|
||||||
exclude_domains: []
|
exclude_domains: []
|
||||||
entity_config:
|
entity_config:
|
||||||
vacuum.robot_vacuum:
|
vacuum.robot_vacuum:
|
||||||
|
|
|
@ -151,6 +151,9 @@ template:
|
||||||
{{- sources | sort | unique | list -}}
|
{{- sources | sort | unique | list -}}
|
||||||
|
|
||||||
media_player:
|
media_player:
|
||||||
|
- platform: denon
|
||||||
|
host: 10.10.20.77
|
||||||
|
|
||||||
- platform: universal
|
- platform: universal
|
||||||
name: Living Room Spotify (bjeanes) # create a media player that is only "on"/"playing"/etc when it is playing in the living room
|
name: Living Room Spotify (bjeanes) # create a media player that is only "on"/"playing"/etc when it is playing in the living room
|
||||||
children:
|
children:
|
||||||
|
@ -351,7 +354,7 @@ sensor:
|
||||||
refresh: "5:00:00"
|
refresh: "5:00:00"
|
||||||
default_state: "off"
|
default_state: "off"
|
||||||
events:
|
events:
|
||||||
- state: PBS # Default background music
|
- state: PBS 106.7FM Melbourne # Default background music
|
||||||
start: "8:00:00"
|
start: "8:00:00"
|
||||||
end: "21:00:00"
|
end: "21:00:00"
|
||||||
|
|
||||||
|
@ -369,6 +372,13 @@ sensor:
|
||||||
condition: time
|
condition: time
|
||||||
weekday: [sun]
|
weekday: [sun]
|
||||||
|
|
||||||
|
- state: Ten FM # Dad's show
|
||||||
|
start: "9:00:00"
|
||||||
|
end: "12:00:00"
|
||||||
|
condition:
|
||||||
|
condition: time
|
||||||
|
weekday: [sun]
|
||||||
|
|
||||||
- state: KLFM
|
- state: KLFM
|
||||||
start: "12:00:00"
|
start: "12:00:00"
|
||||||
end: "15:00:00"
|
end: "15:00:00"
|
||||||
|
@ -388,7 +398,7 @@ sensor:
|
||||||
entity_id: sensor.rrr_now_playing
|
entity_id: sensor.rrr_now_playing
|
||||||
state: "Stylin'"
|
state: "Stylin'"
|
||||||
|
|
||||||
- state: PBS
|
- state: PBS 106.7FM Melbourne
|
||||||
condition:
|
condition:
|
||||||
condition: state
|
condition: state
|
||||||
entity_id: sensor.pbs_now_playing
|
entity_id: sensor.pbs_now_playing
|
||||||
|
|
|
@ -9,15 +9,3 @@ template:
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ states('sensor.nzbget_speed') }}
|
{{ states('sensor.nzbget_speed') }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
sensor:
|
|
||||||
- platform: rtorrent
|
|
||||||
url: !secret rtorrent_url
|
|
||||||
monitored_variables:
|
|
||||||
- "current_status"
|
|
||||||
- "download_speed"
|
|
||||||
- "upload_speed"
|
|
||||||
- "all_torrents"
|
|
||||||
- "uploading_torrents"
|
|
||||||
- "downloading_torrents"
|
|
||||||
- "active_torrents"
|
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
input_number:
|
||||||
|
bo_s_office_target_temperature:
|
||||||
|
name: Bo's Office target temperature
|
||||||
|
min: 18
|
||||||
|
max: 24
|
||||||
|
step: 0.2
|
||||||
|
unit_of_measurement: "°C"
|
||||||
|
initial: 21
|
||||||
|
mode: box
|
||||||
|
|
||||||
# If door opens when sun is down, turn lights on
|
# If door opens when sun is down, turn lights on
|
||||||
# If sun sets and door is open or presense detected, turn lights on
|
# If sun sets and door is open or presense detected, turn lights on
|
||||||
# If lights on but no presence for one hour, turn lights off
|
# If lights on but no presence for one hour, turn lights off
|
||||||
|
@ -40,14 +50,14 @@ automation:
|
||||||
{{ is_state('binary_sensor.bo_s_office_door_contact', 'off')
|
{{ is_state('binary_sensor.bo_s_office_door_contact', 'off')
|
||||||
and (is_state('binary_sensor.bo_s_office_motion', 'on')
|
and (is_state('binary_sensor.bo_s_office_motion', 'on')
|
||||||
or is_state('binary_sensor.bo_s_office_is_occupied', 'on'))
|
or is_state('binary_sensor.bo_s_office_is_occupied', 'on'))
|
||||||
and states('sensor.ble_temperature_bos_office_a4c1380f0b98') | float < 19 }}
|
and states('sensor.ble_temperature_bos_office_a4c1380f0b98') | float < states('input_number.bo_s_office_target_temperature') | float }}
|
||||||
variables:
|
variables:
|
||||||
service: switch.turn_on
|
service: switch.turn_on
|
||||||
- platform: template
|
- platform: template
|
||||||
value_template: |
|
value_template: |
|
||||||
{{ is_state('binary_sensor.bo_s_office_door_contact', 'on')
|
{{ is_state('binary_sensor.bo_s_office_door_contact', 'on')
|
||||||
or (is_state('binary_sensor.bo_s_office_motion', 'off') and is_state('binary_sensor.bo_s_office_is_occupied', 'off'))
|
or (is_state('binary_sensor.bo_s_office_motion', 'off') and is_state('binary_sensor.bo_s_office_is_occupied', 'off'))
|
||||||
or states('sensor.ble_temperature_bos_office_a4c1380f0b98') | float > 20 }}
|
or states('sensor.ble_temperature_bos_office_a4c1380f0b98') | float >= states('input_number.bo_s_office_target_temperature') | float }}
|
||||||
variables:
|
variables:
|
||||||
service: switch.turn_off
|
service: switch.turn_off
|
||||||
action:
|
action:
|
||||||
|
|
|
@ -0,0 +1,359 @@
|
||||||
|
automation:
|
||||||
|
# The inverter can only generate 5kW of AC power. IFF the battery is not-full, it can generate 5kW of AC _and_ charge
|
||||||
|
# battery at up to 6.6kW, which saturates our 8.46 kW of PV
|
||||||
|
#
|
||||||
|
# So, preventing the battery from getting full too early on a sunny day will increase our overall yield, because the
|
||||||
|
# inverter won't have to derate the PV power to 5kW.
|
||||||
|
#
|
||||||
|
# [1]: https://discord.com/channels/936031869001158666/1008992991643455529
|
||||||
|
# [2]: https://discord.com/channels/936031869001158666/936031869001158669/1011882768021590036
|
||||||
|
- id: 05bdc8eb58714c26c2fe
|
||||||
|
alias: Inverter - maximise output
|
||||||
|
mode: restart
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id:
|
||||||
|
- sensor.inverter_pv_power
|
||||||
|
- sensor.inverter_battery_level
|
||||||
|
- sensor.inverter_active_power
|
||||||
|
- sensor.home_weather_cloud_coverage
|
||||||
|
- sensor.home_weather_forecast_cloud_coverage
|
||||||
|
- sensor.solcast_forecast_today
|
||||||
|
- sensor.solcast_forecast_this_hour
|
||||||
|
- sensor.solcast_forecast_remaining_today
|
||||||
|
# - sensor.home_weather_forecast_condition
|
||||||
|
- sensor.home_weather_condition
|
||||||
|
# - weather.home
|
||||||
|
- weather.home_hourly # can use attributes on this one to make decisions about the coming hours
|
||||||
|
# - weather.home_weather
|
||||||
|
- sun.sun # use `next_setting` attribute to ensure battery is online at least an hour before sunset
|
||||||
|
not_to:
|
||||||
|
- unavailable
|
||||||
|
- unknown
|
||||||
|
variables:
|
||||||
|
# Magic numbers
|
||||||
|
ems_self_consume: 0
|
||||||
|
ems_forced: 2
|
||||||
|
battery_charge: 0xAA
|
||||||
|
battery_discharge: 0xBB
|
||||||
|
battery_stop: 0xCC
|
||||||
|
active_power_limit: 4999 # W
|
||||||
|
active_power_buffer: 400 # W - how much below limit we want to sit
|
||||||
|
battery_upper_limit: 99.5 # % - above this, let the BMS choose the charge rate
|
||||||
|
battery_capacity: 12.8 # kWh
|
||||||
|
|
||||||
|
# Shorthands
|
||||||
|
current_active_power: "{{ states('sensor.inverter_active_power') | int(default=active_power_limit) }}"
|
||||||
|
current_pv_power: "{{ states('sensor.inverter_pv_power') | int(default=0) }}"
|
||||||
|
current_load_power: "{{ states('sensor.inverter_load_power') | int(default=current_pv_power) }}"
|
||||||
|
current_ems_mode: "{{ states('sensor.inverter_ems_mode_raw') | int(default=-1) }}"
|
||||||
|
current_battery_mode: "{{ states('sensor.inverter_forced_battery_mode_raw') | int(default=0) }}"
|
||||||
|
battery_level: "{{ states('sensor.inverter_battery_level') | float(default=100) }}"
|
||||||
|
forced_battery_power: "{{ states('sensor.inverter_battery_forced_charge_discharge_power') | int(default=0) }}"
|
||||||
|
forecast_total: "{{ states('sensor.solcast_forecast_today') | float(default=0) }}"
|
||||||
|
forecast_remaining: "{{ states('sensor.solcast_forecast_remaining_today') | float(default=0) }}"
|
||||||
|
forecast_hour: "{{ states('sensor.solcast_forecast_this_hour') | float(default=0) / 1000.0 }}"
|
||||||
|
forecast_remaining_pessimistic: "{{ [0, forecast_remaining - forecast_hour] | max }}"
|
||||||
|
# battery_lower_limit: >
|
||||||
|
# {% if is_state('sensor.home_weather_condition', 'sunny') %}
|
||||||
|
# {{ 10 }}
|
||||||
|
# {% elif is_state('sensor.home_weather_condition', 'partlycloudy') %}
|
||||||
|
# {{ 20 }}
|
||||||
|
# {% else %}
|
||||||
|
# {{ 70 }}
|
||||||
|
# {% endif %}
|
||||||
|
battery_lower_limit: 10 # ignoring above as weather forecast is too unreliable anyway
|
||||||
|
target_active_power: "{{ active_power_limit - active_power_buffer }}"
|
||||||
|
# TODO: make this scale proportionally to how far it is from target battery charge.
|
||||||
|
desired_forced_battery_power: >
|
||||||
|
{% if current_pv_power > target_active_power %}
|
||||||
|
{{ current_pv_power - target_active_power }}
|
||||||
|
{% else %}
|
||||||
|
10
|
||||||
|
{% endif %}
|
||||||
|
is_forced_charging: >
|
||||||
|
{{ current_ems_mode == ems_forced and current_battery_mode == battery_charge }}
|
||||||
|
is_forced_discharging: >
|
||||||
|
{{ current_ems_mode == ems_forced and current_battery_mode == battery_discharge }}
|
||||||
|
is_self_consuming: >
|
||||||
|
{{ current_ems_mode == ems_self_consume }}
|
||||||
|
kwh_until_full: >
|
||||||
|
{{ battery_capacity * ((100 - battery_level)/100) }}
|
||||||
|
enough_in_day: >
|
||||||
|
{{ 2.5 * kwh_until_full < forecast_remaining_pessimistic }}
|
||||||
|
generating_more_than_usage: >
|
||||||
|
{{ current_pv_power > (1.5 * current_load_power) }}
|
||||||
|
# target_battery_level: >
|
||||||
|
# {{ [[battery_lower_limit, 100.0 * (1.0 - (forecast_remaining_pessimistic/forecast_total)) | round(2)] | max, 100] | min }}
|
||||||
|
target_battery_level: >
|
||||||
|
{% if enough_in_day %}
|
||||||
|
{{ [battery_level - 10, states('input_number.inverter_battery_reserve') | int + 5] | max }}
|
||||||
|
{% else %}
|
||||||
|
{{ [battery_level, states('input_number.inverter_battery_reserve') | int + 5] | max }}
|
||||||
|
{% endif %}
|
||||||
|
battery_high_enough: "{{ battery_level >= target_battery_level }}"
|
||||||
|
battery_too_high: "{{ battery_level >= battery_upper_limit }}"
|
||||||
|
sunsetting: >
|
||||||
|
{{ now() + timedelta(hours = 2) > state_attr('sun.sun', 'next_setting') | as_datetime }}
|
||||||
|
should_slow_battery: >
|
||||||
|
{{
|
||||||
|
not sunsetting
|
||||||
|
and enough_in_day
|
||||||
|
and generating_more_than_usage
|
||||||
|
and battery_high_enough
|
||||||
|
and not battery_too_high
|
||||||
|
}}
|
||||||
|
should_discharge_battery: >
|
||||||
|
{{ should_slow_battery
|
||||||
|
and current_pv_power < (target_active_power - 500)
|
||||||
|
and battery_level < 92
|
||||||
|
}}
|
||||||
|
target_discharge_power: >
|
||||||
|
{{ [10, ((target_active_power - 500) - current_pv_power) | int] | max }}
|
||||||
|
action:
|
||||||
|
# TODO: discharge battery if too high and PV has dropped while forecast remains high
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- "{{ should_discharge_battery }}"
|
||||||
|
sequence:
|
||||||
|
- service: input_number.set_value
|
||||||
|
target:
|
||||||
|
entity_id: input_number.inverter_forced_mode_battery_power
|
||||||
|
data_template:
|
||||||
|
value: "{{ target_discharge_power }}"
|
||||||
|
- condition: "{{ not is_forced_discharging }}"
|
||||||
|
- service: script.inverter_force_battery_discharge
|
||||||
|
- conditions:
|
||||||
|
- "{{ should_slow_battery }}"
|
||||||
|
sequence:
|
||||||
|
- service: input_number.set_value
|
||||||
|
target:
|
||||||
|
entity_id: input_number.inverter_forced_mode_battery_power
|
||||||
|
data_template:
|
||||||
|
value: "{{ desired_forced_battery_power }}"
|
||||||
|
- condition: "{{ not is_forced_charging }}"
|
||||||
|
- service: script.inverter_force_battery_charge
|
||||||
|
- conditions:
|
||||||
|
- not:
|
||||||
|
- "{{ is_self_consuming }}"
|
||||||
|
sequence:
|
||||||
|
- service: script.inverter_self_consumption
|
||||||
|
default: []
|
||||||
|
|
||||||
|
- id: d5fa94e6-772a-4903-882a-4ed8cfd7854e
|
||||||
|
alias: Inverter - maximise output (new)
|
||||||
|
mode: restart
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id:
|
||||||
|
- sensor.inverter_pv_power
|
||||||
|
- sensor.inverter_battery_level
|
||||||
|
- sensor.inverter_active_power
|
||||||
|
- sensor.home_weather_cloud_coverage
|
||||||
|
- sensor.home_weather_forecast_cloud_coverage
|
||||||
|
- sensor.solcast_forecast_today
|
||||||
|
- sensor.solcast_forecast_this_hour
|
||||||
|
- sensor.solcast_forecast_remaining_today
|
||||||
|
# - sensor.home_weather_forecast_condition
|
||||||
|
- sensor.home_weather_condition
|
||||||
|
# - weather.home
|
||||||
|
- weather.home_hourly # can use attributes on this one to make decisions about the coming hours
|
||||||
|
# - weather.home_weather
|
||||||
|
- sun.sun # use `next_setting` attribute to ensure battery is online at least an hour before sunset
|
||||||
|
not_to:
|
||||||
|
- unavailable
|
||||||
|
- unknown
|
||||||
|
variables:
|
||||||
|
# Magic numbers
|
||||||
|
ems_self_consume: 0
|
||||||
|
ems_forced: 2
|
||||||
|
battery_charge: 0xAA
|
||||||
|
battery_discharge: 0xBB
|
||||||
|
battery_stop: 0xCC
|
||||||
|
active_power_limit: 4999 # W
|
||||||
|
active_power_buffer: 400 # W - how much below limit we want to sit
|
||||||
|
battery_upper_limit: 99.5 # % - above this, let the BMS choose the charge rate
|
||||||
|
battery_capacity: 12.8 # kWh
|
||||||
|
|
||||||
|
# Shorthands
|
||||||
|
current_active_power: "{{ states('sensor.inverter_active_power') | int(default=active_power_limit) }}"
|
||||||
|
current_pv_power: "{{ states('sensor.inverter_pv_power') | int(default=0) }}"
|
||||||
|
current_load_power: "{{ states('sensor.inverter_load_power') | int(default=current_pv_power) }}"
|
||||||
|
current_ems_mode: "{{ states('sensor.inverter_ems_mode_raw') | int(default=-1) }}"
|
||||||
|
current_battery_mode: "{{ states('sensor.inverter_forced_battery_mode_raw') | int(default=0) }}"
|
||||||
|
battery_level: "{{ states('sensor.inverter_battery_level') | float(default=100) }}"
|
||||||
|
forced_battery_power: "{{ states('sensor.inverter_battery_forced_charge_discharge_power') | int(default=0) }}"
|
||||||
|
forecast_total: "{{ states('sensor.solcast_forecast_today') | float(default=0) }}"
|
||||||
|
forecast_remaining: "{{ states('sensor.solcast_forecast_remaining_today') | float(default=0) }}"
|
||||||
|
forecast_hour: "{{ states('sensor.solcast_forecast_this_hour') | float(default=0) / 1000.0 }}"
|
||||||
|
forecast_remaining_pessimistic: "{{ [0, forecast_remaining - forecast_hour] | max }}"
|
||||||
|
# battery_lower_limit: >
|
||||||
|
# {% if is_state('sensor.home_weather_condition', 'sunny') %}
|
||||||
|
# {{ 10 }}
|
||||||
|
# {% elif is_state('sensor.home_weather_condition', 'partlycloudy') %}
|
||||||
|
# {{ 20 }}
|
||||||
|
# {% else %}
|
||||||
|
# {{ 70 }}
|
||||||
|
# {% endif %}
|
||||||
|
battery_lower_limit: 10 # ignoring above as weather forecast is too unreliable anyway
|
||||||
|
target_active_power: "{{ active_power_limit - active_power_buffer }}"
|
||||||
|
# TODO: make this scale proportionally to how far it is from target battery charge.
|
||||||
|
desired_forced_battery_power: >
|
||||||
|
{% if current_pv_power > target_active_power %}
|
||||||
|
{{ current_pv_power - target_active_power }}
|
||||||
|
{% else %}
|
||||||
|
10
|
||||||
|
{% endif %}
|
||||||
|
is_forced_charging: >
|
||||||
|
{{ current_ems_mode == ems_forced and current_battery_mode == battery_charge }}
|
||||||
|
is_forced_discharging: >
|
||||||
|
{{ current_ems_mode == ems_forced and current_battery_mode == battery_discharge }}
|
||||||
|
is_self_consuming: >
|
||||||
|
{{ current_ems_mode == ems_self_consume }}
|
||||||
|
kwh_until_full: >
|
||||||
|
{{ battery_capacity * ((100 - battery_level)/100) }}
|
||||||
|
enough_in_day: >
|
||||||
|
{{ 2.5 * kwh_until_full < forecast_remaining_pessimistic }}
|
||||||
|
generating_more_than_usage: >
|
||||||
|
{{ current_pv_power > (1.5 * current_load_power) }}
|
||||||
|
# target_battery_level: >
|
||||||
|
# {{ [[battery_lower_limit, 100.0 * (1.0 - (forecast_remaining_pessimistic/forecast_total)) | round(2)] | max, 100] | min }}
|
||||||
|
target_battery_level: >
|
||||||
|
{% if enough_in_day %}
|
||||||
|
{{ battery_level - 10 }}
|
||||||
|
{% else %}
|
||||||
|
{{ battery_level }}
|
||||||
|
{% endif %}
|
||||||
|
battery_high_enough: "{{ battery_level >= target_battery_level }}"
|
||||||
|
battery_too_high: "{{ battery_level >= battery_upper_limit }}"
|
||||||
|
sunsetting: >
|
||||||
|
{{ now() + timedelta(hours = 2) > state_attr('sun.sun', 'next_setting') | as_datetime }}
|
||||||
|
should_slow_battery: >
|
||||||
|
{{
|
||||||
|
not sunsetting
|
||||||
|
and enough_in_day
|
||||||
|
and generating_more_than_usage
|
||||||
|
and battery_high_enough
|
||||||
|
and not battery_too_high
|
||||||
|
}}
|
||||||
|
target_discharge_power: >
|
||||||
|
{% if (battery_level - target_battery_level) > 1 %}
|
||||||
|
{{ [6000, (battery_level - target_battery_level) * 1000 | int] | min }}
|
||||||
|
{% else %}
|
||||||
|
100
|
||||||
|
{% endif %}
|
||||||
|
action:
|
||||||
|
# TODO: discharge battery if too high and PV has dropped while forecast remains high
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- "{{ should_slow_battery }}"
|
||||||
|
sequence:
|
||||||
|
- service: input_number.set_value
|
||||||
|
target:
|
||||||
|
entity_id: input_number.inverter_forced_mode_battery_power
|
||||||
|
data_template:
|
||||||
|
value: "{{ target_discharge_power }}"
|
||||||
|
- condition: "{{ not is_forced_discharging }}"
|
||||||
|
- service: script.inverter_force_battery_discharge
|
||||||
|
- conditions:
|
||||||
|
- not:
|
||||||
|
- "{{ is_self_consuming }}"
|
||||||
|
sequence:
|
||||||
|
- service: script.inverter_self_consumption
|
||||||
|
default: []
|
||||||
|
|
||||||
|
template:
|
||||||
|
- sensor:
|
||||||
|
- unique_id: e1152f05-57d8-4821-b8fc-d6bca771a3b5
|
||||||
|
name: Inverter target active power
|
||||||
|
unit_of_measurement: W
|
||||||
|
state_class: measurement
|
||||||
|
device_class: power
|
||||||
|
attributes:
|
||||||
|
solar: "true"
|
||||||
|
state: >-
|
||||||
|
{{ 4999 - states('input_number.inverter_active_power_buffer') | int(default=400) }}
|
||||||
|
|
||||||
|
- unique_id: a59d08fc-92bb-47c6-b015-8ed0e475f2e5
|
||||||
|
name: Inverter desired forced battery power
|
||||||
|
unit_of_measurement: W
|
||||||
|
state_class: measurement
|
||||||
|
device_class: power
|
||||||
|
attributes:
|
||||||
|
solar: "true"
|
||||||
|
state: >-
|
||||||
|
{% set current_pv_power = states('sensor.inverter_pv_power') | int(default=0) %}
|
||||||
|
{% set target_active_power = states('sensor.inverter_target_active_power') | int %}
|
||||||
|
|
||||||
|
{% if current_pv_power > target_active_power %}
|
||||||
|
{{ current_pv_power - target_active_power }}
|
||||||
|
{% else %}
|
||||||
|
10
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
- unique_id: d257272c-3ac0-4d93-9ef7-00717757cef3
|
||||||
|
name: Solar forecast remaining pessimistic
|
||||||
|
state_class: measurement
|
||||||
|
device_class: energy
|
||||||
|
unit_of_measurement: kWh
|
||||||
|
attributes:
|
||||||
|
solar: "true"
|
||||||
|
state: >-
|
||||||
|
{% set forecast_remaining = states('sensor.solcast_forecast_remaining_today') | float(default=0) %}
|
||||||
|
{% set forecast_hour = states('sensor.solcast_forecast_this_hour') | float(default=0) / 1000.0 %}
|
||||||
|
{{ [0, forecast_remaining - forecast_hour] | max }}
|
||||||
|
|
||||||
|
- unique_id: 6bf7ad20-cf6a-4689-8214-13cd63de80a9
|
||||||
|
name: Inverter target battery level
|
||||||
|
state_class: measurement
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
attributes:
|
||||||
|
solar: "true"
|
||||||
|
state: >-
|
||||||
|
{% set battery_lower_limit = states('input_number.inverter_battery_reserve') | int + 5 %}
|
||||||
|
{% set forecast_remaining_pessimistic = states('sensor.solar_forecast_remaining_pessimistic') | float(default=0) %}
|
||||||
|
{% set forecast_total = states('sensor.solcast_forecast_today') | float(default=0) %}
|
||||||
|
{{ [[battery_lower_limit, 100.0 * (1.0 - (forecast_remaining_pessimistic/forecast_total)) | round(2)] | max, 100] | min }}
|
||||||
|
|
||||||
|
- unique_id: f603d8f8-92ce-4e77-b271-048110394658
|
||||||
|
name: Inverter battery mode
|
||||||
|
attributes:
|
||||||
|
solar: "true"
|
||||||
|
icon: >-
|
||||||
|
{% if this.state == 'self-consumption' %}
|
||||||
|
mdi:battery-sync
|
||||||
|
{% elif this.state == 'forced charging' %}
|
||||||
|
mdi:battery-arrow-down
|
||||||
|
{% elif this.state == 'forced discharging' %}
|
||||||
|
mdi:battery-arrow-up
|
||||||
|
{% elif this.state == 'forced stop' %}
|
||||||
|
mdi:battery-off
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
state: >-
|
||||||
|
{% set ems = states('sensor.inverter_ems_mode_raw') | int(default=-1) %}
|
||||||
|
{% set mode = states('sensor.inverter_forced_battery_mode_raw') | int(default=0) %}
|
||||||
|
{% if ems == 0 %}
|
||||||
|
self-consumption
|
||||||
|
{% elif ems == 2 %}
|
||||||
|
{% if mode == 0xAA %}
|
||||||
|
forced charging
|
||||||
|
{% elif mode == 0xBB %}
|
||||||
|
forced discharging
|
||||||
|
{% elif mode == 0xCC %}
|
||||||
|
forced stop
|
||||||
|
{% else %}
|
||||||
|
unknown
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
unknown
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
input_number:
|
||||||
|
inverter_active_power_buffer:
|
||||||
|
name: Inverter active power buffer
|
||||||
|
min: 100
|
||||||
|
max: 1000
|
||||||
|
step: 1
|
||||||
|
unit_of_measurement: W
|
||||||
|
mode: box
|
|
@ -202,7 +202,7 @@ template:
|
||||||
device_class: occupancy
|
device_class: occupancy
|
||||||
|
|
||||||
- unique_id: analog_room_is_occupied
|
- unique_id: analog_room_is_occupied
|
||||||
name: analog Room Is Occupied
|
name: analog Room As Occupied
|
||||||
state: |
|
state: |
|
||||||
{{ is_state('sensor.template_room_bo_phone', 'analog_room') or is_state('sensor.template_room_ri_phone', 'analog_room') }}
|
{{ is_state('sensor.template_room_bo_phone', 'analog_room') or is_state('sensor.template_room_ri_phone', 'analog_room') }}
|
||||||
icon: |
|
icon: |
|
||||||
|
|
|
@ -30,48 +30,39 @@
|
||||||
|
|
||||||
input_boolean:
|
input_boolean:
|
||||||
inverter_charging_schedule_enabled:
|
inverter_charging_schedule_enabled:
|
||||||
initial: true
|
|
||||||
name: Inverter charging schedule enabled
|
name: Inverter charging schedule enabled
|
||||||
inverter_charging_schedule_2_enabled:
|
inverter_charging_schedule_2_enabled:
|
||||||
initial: true
|
|
||||||
name: Inverter charging schedule 2 enabled
|
name: Inverter charging schedule 2 enabled
|
||||||
input_datetime:
|
input_datetime:
|
||||||
inverter_charging_schedule_start:
|
inverter_charging_schedule_start:
|
||||||
has_time: true
|
has_time: true
|
||||||
name: Inverter charging schedule start
|
name: Inverter charging schedule start
|
||||||
initial: "13:30:00"
|
|
||||||
inverter_charging_schedule_end:
|
inverter_charging_schedule_end:
|
||||||
has_time: true
|
has_time: true
|
||||||
name: Inverter charging schedule end
|
name: Inverter charging schedule end
|
||||||
initial: "15:00:00"
|
|
||||||
inverter_charging_schedule_2_start:
|
inverter_charging_schedule_2_start:
|
||||||
has_time: true
|
has_time: true
|
||||||
name: Inverter charging schedule 2 start
|
name: Inverter charging schedule 2 start
|
||||||
initial: "00:00:00"
|
|
||||||
inverter_charging_schedule_2_end:
|
inverter_charging_schedule_2_end:
|
||||||
has_time: true
|
has_time: true
|
||||||
name: Inverter charging schedule 2 end
|
name: Inverter charging schedule 2 end
|
||||||
initial: "00:00:00"
|
|
||||||
input_number:
|
input_number:
|
||||||
inverter_charging_schedule_target_soc:
|
inverter_charging_schedule_target_soc:
|
||||||
name: Inverter charging schedule target state of charge
|
name: Inverter charging schedule target state of charge
|
||||||
min: 0
|
min: 0
|
||||||
max: 100
|
max: 100
|
||||||
unit_of_measurement: "%"
|
unit_of_measurement: "%"
|
||||||
initial: 85
|
|
||||||
mode: box
|
mode: box
|
||||||
inverter_charging_schedule_2_target_soc:
|
inverter_charging_schedule_2_target_soc:
|
||||||
name: Inverter charging schedule 2 target state of charge
|
name: Inverter charging schedule 2 target state of charge
|
||||||
min: 0
|
min: 0
|
||||||
max: 100
|
max: 100
|
||||||
unit_of_measurement: "%"
|
unit_of_measurement: "%"
|
||||||
initial: 0
|
|
||||||
mode: box
|
mode: box
|
||||||
inverter_battery_reserve:
|
inverter_battery_reserve:
|
||||||
name: Inverter battery reserve
|
name: Inverter battery reserve
|
||||||
min: 0
|
min: 0
|
||||||
max: 100
|
max: 100
|
||||||
initial: 5
|
|
||||||
unit_of_measurement: "%"
|
unit_of_measurement: "%"
|
||||||
mode: box
|
mode: box
|
||||||
|
|
||||||
|
@ -80,7 +71,6 @@ input_number:
|
||||||
min: 10
|
min: 10
|
||||||
max: 6600
|
max: 6600
|
||||||
step: 10
|
step: 10
|
||||||
initial: 2000
|
|
||||||
mode: box
|
mode: box
|
||||||
unit_of_measurement: "W"
|
unit_of_measurement: "W"
|
||||||
|
|
||||||
|
@ -199,7 +189,7 @@ automation:
|
||||||
variables:
|
variables:
|
||||||
current_power: "{{ states('sensor.inverter_battery_forced_charge_discharge_power') | int }}"
|
current_power: "{{ states('sensor.inverter_battery_forced_charge_discharge_power') | int }}"
|
||||||
target_power: "{{ states('input_number.inverter_forced_mode_battery_power') | int }}"
|
target_power: "{{ states('input_number.inverter_forced_mode_battery_power') | int }}"
|
||||||
target_power_value: "{{ target_power / 10 }}" # undocumented register is in multiples of 10W
|
target_power_value: "{{ (target_power / 10) | round(0) | int }}" # undocumented register is in multiples of 10W
|
||||||
condition:
|
condition:
|
||||||
- "{{ current_power != target_power }}"
|
- "{{ current_power != target_power }}"
|
||||||
action:
|
action:
|
||||||
|
@ -235,98 +225,6 @@ automation:
|
||||||
data_template:
|
data_template:
|
||||||
value: "{{ states('sensor.inverter_battery_forced_charge_discharge_power') | int }}"
|
value: "{{ states('sensor.inverter_battery_forced_charge_discharge_power') | int }}"
|
||||||
|
|
||||||
# The inverter can only generate 5kW of AC power. IFF the battery is not-full, it can generate 5kW of AC _and_ charge
|
|
||||||
# battery at up to 6.6kW, which saturates our 8.46 kW of PV
|
|
||||||
#
|
|
||||||
# So, preventing the battery from getting full too early on a sunny day will increase our overall yield, because the
|
|
||||||
# inverter won't have to derate the PV power to 5kW.
|
|
||||||
#
|
|
||||||
# [1]: https://discord.com/channels/936031869001158666/1008992991643455529
|
|
||||||
# [2]: https://discord.com/channels/936031869001158666/936031869001158669/1011882768021590036
|
|
||||||
- id: 05bdc8eb58714c26c2fe
|
|
||||||
alias: Inverter - maximise output
|
|
||||||
mode: restart
|
|
||||||
trigger:
|
|
||||||
- platform: state
|
|
||||||
entity_id:
|
|
||||||
- sensor.inverter_pv_power
|
|
||||||
- sensor.inverter_battery_level
|
|
||||||
- sensor.inverter_active_power
|
|
||||||
- sensor.home_weather_cloud_coverage
|
|
||||||
- sensor.home_weather_forecast_cloud_coverage
|
|
||||||
- sensor.solcast_forecast_remaining_today
|
|
||||||
# - sensor.home_weather_forecast_condition
|
|
||||||
# - sensor.home_weather_condition
|
|
||||||
# - weather.home
|
|
||||||
- weather.home_hourly # can use attributes on this one to make decisions about the coming hours
|
|
||||||
# - weather.home_weather
|
|
||||||
- sun.sun # use `next_setting` attribute to ensure battery is online at least an hour before sunset
|
|
||||||
not_to:
|
|
||||||
- unavailable
|
|
||||||
- unknown
|
|
||||||
variables:
|
|
||||||
# Magic numbers
|
|
||||||
ems_self_consume: 0
|
|
||||||
ems_forced: 2
|
|
||||||
battery_charge: 0xAA
|
|
||||||
battery_discharge: 0xBB
|
|
||||||
battery_stop: 0xCC
|
|
||||||
active_power_limit: 4999 # W
|
|
||||||
active_power_buffer: 200 # W - how much below limit we want to sit
|
|
||||||
battery_lower_limit: 50 # %
|
|
||||||
battery_upper_limit: 98 # % - above this, let the BMS choose the charge rate
|
|
||||||
battery_capacity: 12.8 # kWh
|
|
||||||
|
|
||||||
# Shorthands
|
|
||||||
current_active_power: "{{ states('sensor.inverter_active_power') | int(default=active_power_limit) }}"
|
|
||||||
current_pv_power: "{{ states('sensor.inverter_pv_power') | int(default=0) }}"
|
|
||||||
current_ems_mode: "{{ states('sensor.inverter_ems_mode_raw') | int(default=-1) }}"
|
|
||||||
current_battery_mode: "{{ states('sensor.inverter_forced_battery_mode_raw') | int(default=0) }}"
|
|
||||||
battery_level: "{{ states('sensor.inverter_battery_level') | float(default=100) }}"
|
|
||||||
forced_battery_power: "{{ states('sensor.inverter_battery_forced_charge_discharge_power') | int(default=0) }}"
|
|
||||||
forecast_remaining: "{{ states('sensor.solcast_forecast_remaining_today') | float(default=0) }}"
|
|
||||||
|
|
||||||
target_active_power: "{{ active_power_limit - active_power_buffer }}"
|
|
||||||
desired_forced_battery_power: >
|
|
||||||
{% if current_pv_power > target_active_power %}
|
|
||||||
{{ current_pv_power - target_active_power }}
|
|
||||||
{% else %}
|
|
||||||
10
|
|
||||||
{% endif %}
|
|
||||||
is_forced_charging: >
|
|
||||||
{{ current_ems_mode == ems_forced and current_battery_mode == battery_charge }}
|
|
||||||
is_self_consuming: >
|
|
||||||
{{ current_ems_mode == ems_self_consume }}
|
|
||||||
kwh_until_full: >
|
|
||||||
{{ battery_capacity * ((100 - battery_level)/100) }}
|
|
||||||
enough_in_day: >
|
|
||||||
{{ 2.5 * kwh_until_full < forecast_remaining }}
|
|
||||||
battery_high_enough: "{{ battery_level > battery_lower_limit }}"
|
|
||||||
battery_too_high: "{{ battery_level >= battery_upper_limit }}"
|
|
||||||
sunsetting: >
|
|
||||||
{{ now() + timedelta(hours = 1) > state_attr('sun.sun', 'next_setting') | as_datetime }}
|
|
||||||
should_slow_battery: >
|
|
||||||
{{ not sunsetting and battery_high_enough and enough_in_day and not battery_too_high }}
|
|
||||||
action:
|
|
||||||
# TODO: discharge battery if too high and PV has dropped while forecast remains high
|
|
||||||
- choose:
|
|
||||||
- conditions:
|
|
||||||
- "{{ should_slow_battery }}"
|
|
||||||
sequence:
|
|
||||||
- service: input_number.set_value
|
|
||||||
target:
|
|
||||||
entity_id: input_number.inverter_forced_mode_battery_power
|
|
||||||
data_template:
|
|
||||||
value: "{{ desired_forced_battery_power }}"
|
|
||||||
- condition: "{{ is_self_consuming or not is_forced_charging }}"
|
|
||||||
- service: script.inverter_force_battery_charge
|
|
||||||
- conditions:
|
|
||||||
- not:
|
|
||||||
- "{{ is_self_consuming }}"
|
|
||||||
sequence:
|
|
||||||
- service: script.inverter_self_consumption
|
|
||||||
default: []
|
|
||||||
|
|
||||||
script:
|
script:
|
||||||
inverter_set_battery_reserve:
|
inverter_set_battery_reserve:
|
||||||
alias: "Set inverter battery reserve"
|
alias: "Set inverter battery reserve"
|
||||||
|
@ -1395,21 +1293,18 @@ sensor:
|
||||||
# input_number:
|
# input_number:
|
||||||
# set_sg_min_soc:
|
# set_sg_min_soc:
|
||||||
# name: min Soc
|
# name: min Soc
|
||||||
# #initial: 15
|
|
||||||
# min: 5
|
# min: 5
|
||||||
# max: 50
|
# max: 50
|
||||||
# step: 1
|
# step: 1
|
||||||
|
|
||||||
# set_sg_max_soc:
|
# set_sg_max_soc:
|
||||||
# name: max Soc
|
# name: max Soc
|
||||||
# #initial: 85
|
|
||||||
# min: 50
|
# min: 50
|
||||||
# max: 95
|
# max: 95
|
||||||
# step: 1
|
# step: 1
|
||||||
|
|
||||||
# set_sg_charge_discharge_power_percentage:
|
# set_sg_charge_discharge_power_percentage:
|
||||||
# name: max charge discharge power in W
|
# name: max charge discharge power in W
|
||||||
# #initial: 40
|
|
||||||
# min: 0
|
# min: 0
|
||||||
# max: 5000
|
# max: 5000
|
||||||
# step: 50
|
# step: 50
|
||||||
|
|
|
@ -11,6 +11,8 @@ automation:
|
||||||
trigger:
|
trigger:
|
||||||
- platform: state
|
- platform: state
|
||||||
entity_id: cover.front_gate
|
entity_id: cover.front_gate
|
||||||
|
for:
|
||||||
|
seconds: 2
|
||||||
from: "closed"
|
from: "closed"
|
||||||
to:
|
to:
|
||||||
- open
|
- open
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
substitutions:
|
substitutions:
|
||||||
node_name: "athom-plug-5586a8"
|
node_name: "athom-plug-5586a8"
|
||||||
friendly_name: "Tent Plug"
|
friendly_name: "Garden Shed Lights"
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
base: !include common/base.yaml
|
base: !include common/base.yaml
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
substitutions:
|
||||||
|
name: athom-smart-plug-v2-3fe952
|
||||||
|
packages:
|
||||||
|
athom.smart-plug-v2: github://athom-tech/athom-configs/athom-smart-plug-v2.yaml
|
||||||
|
esphome:
|
||||||
|
name: ${name}
|
||||||
|
name_add_mac_suffix: false
|
||||||
|
|
||||||
|
|
||||||
|
wifi:
|
||||||
|
ssid: !secret wifi_ssid
|
||||||
|
password: !secret wifi_password
|
|
@ -0,0 +1,12 @@
|
||||||
|
substitutions:
|
||||||
|
name: athom-smart-plug-v2-3feb8a
|
||||||
|
packages:
|
||||||
|
athom.smart-plug-v2: github://athom-tech/athom-configs/athom-smart-plug-v2.yaml
|
||||||
|
esphome:
|
||||||
|
name: ${name}
|
||||||
|
name_add_mac_suffix: false
|
||||||
|
|
||||||
|
|
||||||
|
wifi:
|
||||||
|
ssid: !secret wifi_ssid
|
||||||
|
password: !secret wifi_password
|
|
@ -0,0 +1,7 @@
|
||||||
|
substitutions:
|
||||||
|
node_name: "athom-smart-plug-v2-3fee17"
|
||||||
|
# friendly_name: "Tent Plug"
|
||||||
|
|
||||||
|
packages:
|
||||||
|
base: !include common/base.yaml
|
||||||
|
plug: !include common/athom-plug.yaml
|
|
@ -0,0 +1,12 @@
|
||||||
|
substitutions:
|
||||||
|
name: athom-smart-plug-v2-3fee1c
|
||||||
|
packages:
|
||||||
|
athom.smart-plug-v2: github://athom-tech/athom-configs/athom-smart-plug-v2.yaml
|
||||||
|
esphome:
|
||||||
|
name: ${name}
|
||||||
|
name_add_mac_suffix: false
|
||||||
|
|
||||||
|
|
||||||
|
wifi:
|
||||||
|
ssid: !secret wifi_ssid
|
||||||
|
password: !secret wifi_password
|
|
@ -0,0 +1,12 @@
|
||||||
|
substitutions:
|
||||||
|
name: athom-smart-plug-v2-3ff29b
|
||||||
|
packages:
|
||||||
|
athom.smart-plug-v2: github://athom-tech/athom-configs/athom-smart-plug-v2.yaml
|
||||||
|
esphome:
|
||||||
|
name: ${name}
|
||||||
|
name_add_mac_suffix: false
|
||||||
|
|
||||||
|
|
||||||
|
wifi:
|
||||||
|
ssid: !secret wifi_ssid
|
||||||
|
password: !secret wifi_password
|
|
@ -9,6 +9,7 @@ esphome:
|
||||||
packages:
|
packages:
|
||||||
base: !include common/base.yaml
|
base: !include common/base.yaml
|
||||||
ble: !include common/ble-gateway.yaml
|
ble: !include common/ble-gateway.yaml
|
||||||
|
# ph_260bd: !include common/ph_260bd.yaml
|
||||||
|
|
||||||
web_server:
|
web_server:
|
||||||
version: 2
|
version: 2
|
||||||
|
@ -16,198 +17,3 @@ web_server:
|
||||||
|
|
||||||
wifi:
|
wifi:
|
||||||
use_address: 10.10.30.82
|
use_address: 10.10.30.82
|
||||||
|
|
||||||
# JDY-08
|
|
||||||
# https://amperkot.ru/static/3236/uploads/datasheets/JDY-08.pdf
|
|
||||||
# [13:44:48][I][ble_client:085]: Attempting BLE connection to 7c:01:0a:43:4e:9e
|
|
||||||
# [13:44:49][D][ble_client_lambda:035]: Connected to BLE device
|
|
||||||
# [13:44:49][I][ble_client:161]: Service UUID: 0xFFE0
|
|
||||||
# [13:44:49][I][ble_client:162]: start_handle: 0x1 end_handle: 0x9
|
|
||||||
# [13:44:49][I][ble_client:341]: characteristic 0xFFE1, handle 0x3, properties 0x1c
|
|
||||||
# [13:44:49][I][ble_client:341]: characteristic 0xFFE2, handle 0x7, properties 0x1c
|
|
||||||
# [13:44:49][I][ble_client:161]: Service UUID: 0x1800
|
|
||||||
# [13:44:49][I][ble_client:162]: start_handle: 0xa end_handle: 0x14
|
|
||||||
# [13:44:49][I][ble_client:341]: characteristic 0x2A00, handle 0xc, properties 0x2
|
|
||||||
# [13:44:49][I][ble_client:341]: characteristic 0x2A01, handle 0xe, properties 0x2
|
|
||||||
# [13:44:49][I][ble_client:341]: characteristic 0x2A02, handle 0x10, properties 0xa
|
|
||||||
# [13:44:49][I][ble_client:341]: characteristic 0x2A05, handle 0x17, properties 0x20
|
|
||||||
ble_client:
|
|
||||||
- mac_address: "7C:01:0A:43:4E:9E"
|
|
||||||
id: ph_260bd
|
|
||||||
on_connect:
|
|
||||||
then:
|
|
||||||
- wait_until: # wait until characteristic is discovered
|
|
||||||
lambda: |-
|
|
||||||
esphome::ble_client::BLEClient* client = id(ph_260bd);
|
|
||||||
|
|
||||||
auto service_uuid = 0xFFE0; // can't get it off `sensor` because it is protected
|
|
||||||
auto char_uuid = 0xFFE1; // can't get it off `sensor` because it is protected
|
|
||||||
|
|
||||||
esphome::ble_client::BLECharacteristic* chr = client->get_characteristic(service_uuid, char_uuid);
|
|
||||||
|
|
||||||
return chr != nullptr;
|
|
||||||
- lambda: |-
|
|
||||||
ESP_LOGD("ble_client_lambda", "Connected to PH-260BD");
|
|
||||||
|
|
||||||
//esphome::ble_client::BLESensor* sensor = id(ph_260bd_sensor);
|
|
||||||
esphome::ble_client::BLEClient* client = id(ph_260bd);
|
|
||||||
|
|
||||||
auto service_uuid = 0xFFE0; // can't get it off `sensor` because it is protected
|
|
||||||
auto char_uuid = 0xFFE1; // can't get it off `sensor` because it is protected
|
|
||||||
|
|
||||||
esphome::ble_client::BLECharacteristic* chr = client->get_characteristic(service_uuid, char_uuid);
|
|
||||||
|
|
||||||
if (chr == nullptr) {
|
|
||||||
ESP_LOGW("ble_client", "[0xFFE1] Characteristic not found. State update can not be written.");
|
|
||||||
} else {
|
|
||||||
unsigned char newVal[8] = {
|
|
||||||
0x00, 0x03, 0x00, 0x00,
|
|
||||||
0x00, 0x14, 0x44, 0x14
|
|
||||||
};
|
|
||||||
int status = esp_ble_gattc_write_char(
|
|
||||||
client->gattc_if,
|
|
||||||
client->conn_id,
|
|
||||||
chr->handle,
|
|
||||||
sizeof(newVal),
|
|
||||||
newVal,
|
|
||||||
ESP_GATT_WRITE_TYPE_NO_RSP,
|
|
||||||
ESP_GATT_AUTH_REQ_NONE
|
|
||||||
);
|
|
||||||
|
|
||||||
if (status) {
|
|
||||||
ESP_LOGW("ble_client", "Error sending write value to BLE gattc server, status=%d", status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
decltype(v)::foo = 1; // debug type of v by mis-casting it and looking at compiler error
|
|
||||||
*/
|
|
||||||
|
|
||||||
on_disconnect:
|
|
||||||
then:
|
|
||||||
- lambda: |-
|
|
||||||
ESP_LOGD("ble_client", "Disconnected from PH-260BD");
|
|
||||||
|
|
||||||
sensor:
|
|
||||||
- platform: template
|
|
||||||
name: "Tent Reservoir EC (µS)"
|
|
||||||
id: ec_us
|
|
||||||
unit_of_measurement: "µS/cm"
|
|
||||||
accuracy_decimals: 0
|
|
||||||
state_class: measurement
|
|
||||||
icon: mdi:water-opacity
|
|
||||||
filters:
|
|
||||||
- filter_out: nan
|
|
||||||
- throttle: 30s
|
|
||||||
|
|
||||||
- platform: template
|
|
||||||
name: "Tent Reservoir Temperature"
|
|
||||||
id: temp
|
|
||||||
unit_of_measurement: "°C"
|
|
||||||
accuracy_decimals: 1
|
|
||||||
state_class: measurement
|
|
||||||
device_class: temperature
|
|
||||||
filters:
|
|
||||||
- filter_out: nan
|
|
||||||
- throttle: 30s
|
|
||||||
|
|
||||||
- platform: template
|
|
||||||
name: "Tent Reservoir pH"
|
|
||||||
id: ph
|
|
||||||
unit_of_measurement: "pH"
|
|
||||||
accuracy_decimals: 2
|
|
||||||
state_class: measurement
|
|
||||||
icon: mdi:ph
|
|
||||||
filters:
|
|
||||||
- filter_out: nan
|
|
||||||
- throttle: 30s
|
|
||||||
|
|
||||||
- platform: ble_client
|
|
||||||
ble_client_id: ph_260bd
|
|
||||||
id: ph_260bd_sensor
|
|
||||||
internal: true
|
|
||||||
service_uuid: FFE0
|
|
||||||
characteristic_uuid: FFE1
|
|
||||||
notify: true
|
|
||||||
|
|
||||||
# The PH-260BD puts bytes onto the characteristic value which needs to be treated as text:
|
|
||||||
#
|
|
||||||
# [1] pry(main)> ['372e35312070480d0a32312e372020e284830d0a'].pack('H*')
|
|
||||||
# => "7.51 pH\r\n21.7 \xE2\x84\x83\r\n"
|
|
||||||
# [2] pry(main)> puts ['372e35312070480d0a32312e372020e284830d0a'].pack('H*')
|
|
||||||
# 7.51 pH
|
|
||||||
# 21.7 ℃
|
|
||||||
#
|
|
||||||
# It alternates between putting the EC/TDS value alone (as a string, with units) and the pH and
|
|
||||||
# temperature together. Perhaps it can't fit all three in a single buffer.
|
|
||||||
#
|
|
||||||
# All values follow: number(s)/dot, space(s), unit, carriage return, new line
|
|
||||||
#
|
|
||||||
# This lambda parses the string and publishes each value+unit to the appropriate template sensor on each newline.
|
|
||||||
lambda: |-
|
|
||||||
ESP_LOGD("ble_client.receive", "value received with %d bytes: [%.*s]", x.size(), x.size(), &x[0]);
|
|
||||||
|
|
||||||
if (x.size() == 0) return NAN;
|
|
||||||
//decltype(parse_float)::foo= 1;
|
|
||||||
|
|
||||||
std::string val_str = "";
|
|
||||||
std::string val_unit = "";
|
|
||||||
|
|
||||||
// ESP_LOGD("ble_client.receive", "value received with %d bytes: [%.*s]", x.size(), x.size(), &x[0]);
|
|
||||||
|
|
||||||
// https://git.faked.org/jan/ph-260bd/-/blob/master/src/main.cpp#L7
|
|
||||||
static int factorMsToPpm = 700;
|
|
||||||
|
|
||||||
for (int i = 0; i < x.size(); i++) {
|
|
||||||
auto c = x[i];
|
|
||||||
switch(c) {
|
|
||||||
case '\x30': // "0"
|
|
||||||
case '\x31': // "1"
|
|
||||||
case '\x32': // "2"
|
|
||||||
case '\x33': // "3"
|
|
||||||
case '\x34': // "4"
|
|
||||||
case '\x35': // "5"
|
|
||||||
case '\x36': // "6"
|
|
||||||
case '\x37': // "7"
|
|
||||||
case '\x38': // "8"
|
|
||||||
case '\x39': // "9"
|
|
||||||
case '\x2E': // "."
|
|
||||||
val_str += c;
|
|
||||||
break;
|
|
||||||
case '\x20': // " "
|
|
||||||
break; // proceed until we hit units
|
|
||||||
case '\x0d': // '\r'
|
|
||||||
break; // ignore
|
|
||||||
case '\x0a': // '\n'
|
|
||||||
// FIXME: Don't publish temperature when ppt is set as it drops the first char
|
|
||||||
|
|
||||||
if (auto val = parse_number<float>(val_str)) {
|
|
||||||
if (val_unit == "pH") {
|
|
||||||
id(ph).publish_state(*val);
|
|
||||||
} else if (val_unit == "\xE2\x84\x83") { // ℃ char
|
|
||||||
id(temp).publish_state(*val);
|
|
||||||
} else if (val_unit == "uS") { // microsiemens
|
|
||||||
id(ec_us)->publish_state(*val);
|
|
||||||
} else if (val_unit == "mS") { // millisiemens
|
|
||||||
id(ec_us)->publish_state(*val * 1000);
|
|
||||||
} else if (val_unit == "ppm") { // TDS parts per million
|
|
||||||
id(ec_us)->publish_state(*val / factorMsToPpm * 1000);
|
|
||||||
} else if (val_unit == "ppt") { // TDS parts per thousand
|
|
||||||
id(ec_us)->publish_state(*val / factorMsToPpm * 1000 * 1000);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
ESP_LOGW("ble_client.receive", "value received with unknown unit: [%s]", val_unit.c_str());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ESP_LOGW("ble_client.receive", "value could not be parsed as float: [%s]", val_str.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
val_unit = "";
|
|
||||||
val_str = "";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
val_unit += c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0.0; // this sensor isn't actually used
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ esp32_ble_tracker:
|
||||||
scan_parameters:
|
scan_parameters:
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
|
bluetooth_proxy:
|
||||||
|
|
||||||
ble_gateway:
|
ble_gateway:
|
||||||
id: blegateway
|
id: blegateway
|
||||||
discovery: true
|
discovery: true
|
||||||
|
|
|
@ -0,0 +1,195 @@
|
||||||
|
# JDY-08
|
||||||
|
# https://amperkot.ru/static/3236/uploads/datasheets/JDY-08.pdf
|
||||||
|
# [13:44:48][I][ble_client:085]: Attempting BLE connection to 7c:01:0a:43:4e:9e
|
||||||
|
# [13:44:49][D][ble_client_lambda:035]: Connected to BLE device
|
||||||
|
# [13:44:49][I][ble_client:161]: Service UUID: 0xFFE0
|
||||||
|
# [13:44:49][I][ble_client:162]: start_handle: 0x1 end_handle: 0x9
|
||||||
|
# [13:44:49][I][ble_client:341]: characteristic 0xFFE1, handle 0x3, properties 0x1c
|
||||||
|
# [13:44:49][I][ble_client:341]: characteristic 0xFFE2, handle 0x7, properties 0x1c
|
||||||
|
# [13:44:49][I][ble_client:161]: Service UUID: 0x1800
|
||||||
|
# [13:44:49][I][ble_client:162]: start_handle: 0xa end_handle: 0x14
|
||||||
|
# [13:44:49][I][ble_client:341]: characteristic 0x2A00, handle 0xc, properties 0x2
|
||||||
|
# [13:44:49][I][ble_client:341]: characteristic 0x2A01, handle 0xe, properties 0x2
|
||||||
|
# [13:44:49][I][ble_client:341]: characteristic 0x2A02, handle 0x10, properties 0xa
|
||||||
|
# [13:44:49][I][ble_client:341]: characteristic 0x2A05, handle 0x17, properties 0x20
|
||||||
|
ble_client:
|
||||||
|
- mac_address: "7C:01:0A:43:4E:9E"
|
||||||
|
id: ph_260bd
|
||||||
|
on_connect:
|
||||||
|
then:
|
||||||
|
- wait_until: # wait until characteristic is discovered
|
||||||
|
lambda: |-
|
||||||
|
esphome::ble_client::BLEClient* client = id(ph_260bd);
|
||||||
|
|
||||||
|
auto service_uuid = 0xFFE0; // can't get it off `sensor` because it is protected
|
||||||
|
auto char_uuid = 0xFFE1; // can't get it off `sensor` because it is protected
|
||||||
|
|
||||||
|
esphome::ble_client::BLECharacteristic* chr = client->get_characteristic(service_uuid, char_uuid);
|
||||||
|
|
||||||
|
return chr != nullptr;
|
||||||
|
- lambda: |-
|
||||||
|
ESP_LOGD("ble_client_lambda", "Connected to PH-260BD");
|
||||||
|
|
||||||
|
//esphome::ble_client::BLESensor* sensor = id(ph_260bd_sensor);
|
||||||
|
esphome::ble_client::BLEClient* client = id(ph_260bd);
|
||||||
|
|
||||||
|
auto service_uuid = 0xFFE0; // can't get it off `sensor` because it is protected
|
||||||
|
auto char_uuid = 0xFFE1; // can't get it off `sensor` because it is protected
|
||||||
|
|
||||||
|
esphome::ble_client::BLECharacteristic* chr = client->get_characteristic(service_uuid, char_uuid);
|
||||||
|
|
||||||
|
if (chr == nullptr) {
|
||||||
|
ESP_LOGW("ble_client", "[0xFFE1] Characteristic not found. State update can not be written.");
|
||||||
|
} else {
|
||||||
|
unsigned char newVal[8] = {
|
||||||
|
0x00, 0x03, 0x00, 0x00,
|
||||||
|
0x00, 0x14, 0x44, 0x14
|
||||||
|
};
|
||||||
|
int status = esp_ble_gattc_write_char(
|
||||||
|
client->gattc_if,
|
||||||
|
client->conn_id,
|
||||||
|
chr->handle,
|
||||||
|
sizeof(newVal),
|
||||||
|
newVal,
|
||||||
|
ESP_GATT_WRITE_TYPE_NO_RSP,
|
||||||
|
ESP_GATT_AUTH_REQ_NONE
|
||||||
|
);
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
ESP_LOGW("ble_client", "Error sending write value to BLE gattc server, status=%d", status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
decltype(v)::foo = 1; // debug type of v by mis-casting it and looking at compiler error
|
||||||
|
*/
|
||||||
|
|
||||||
|
on_disconnect:
|
||||||
|
then:
|
||||||
|
- lambda: |-
|
||||||
|
ESP_LOGD("ble_client", "Disconnected from PH-260BD");
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: template
|
||||||
|
name: "Tent Reservoir EC (µS)"
|
||||||
|
id: ec_us
|
||||||
|
unit_of_measurement: "µS/cm"
|
||||||
|
accuracy_decimals: 0
|
||||||
|
state_class: measurement
|
||||||
|
icon: mdi:water-opacity
|
||||||
|
filters:
|
||||||
|
- filter_out: nan
|
||||||
|
- throttle: 30s
|
||||||
|
|
||||||
|
- platform: template
|
||||||
|
name: "Tent Reservoir Temperature"
|
||||||
|
id: temp
|
||||||
|
unit_of_measurement: "°C"
|
||||||
|
accuracy_decimals: 1
|
||||||
|
state_class: measurement
|
||||||
|
device_class: temperature
|
||||||
|
filters:
|
||||||
|
- filter_out: nan
|
||||||
|
- throttle: 30s
|
||||||
|
|
||||||
|
- platform: template
|
||||||
|
name: "Tent Reservoir pH"
|
||||||
|
id: ph
|
||||||
|
unit_of_measurement: "pH"
|
||||||
|
accuracy_decimals: 2
|
||||||
|
state_class: measurement
|
||||||
|
icon: mdi:ph
|
||||||
|
filters:
|
||||||
|
- filter_out: nan
|
||||||
|
- throttle: 30s
|
||||||
|
|
||||||
|
- platform: ble_client
|
||||||
|
type: characteristic
|
||||||
|
ble_client_id: ph_260bd
|
||||||
|
id: ph_260bd_sensor
|
||||||
|
internal: true
|
||||||
|
service_uuid: FFE0
|
||||||
|
characteristic_uuid: FFE1
|
||||||
|
notify: true
|
||||||
|
|
||||||
|
# The PH-260BD puts bytes onto the characteristic value which needs to be treated as text:
|
||||||
|
#
|
||||||
|
# [1] pry(main)> ['372e35312070480d0a32312e372020e284830d0a'].pack('H*')
|
||||||
|
# => "7.51 pH\r\n21.7 \xE2\x84\x83\r\n"
|
||||||
|
# [2] pry(main)> puts ['372e35312070480d0a32312e372020e284830d0a'].pack('H*')
|
||||||
|
# 7.51 pH
|
||||||
|
# 21.7 ℃
|
||||||
|
#
|
||||||
|
# It alternates between putting the EC/TDS value alone (as a string, with units) and the pH and
|
||||||
|
# temperature together. Perhaps it can't fit all three in a single buffer.
|
||||||
|
#
|
||||||
|
# All values follow: number(s)/dot, space(s), unit, carriage return, new line
|
||||||
|
#
|
||||||
|
# This lambda parses the string and publishes each value+unit to the appropriate template sensor on each newline.
|
||||||
|
lambda: |-
|
||||||
|
ESP_LOGD("ble_client.receive", "value received with %d bytes: [%.*s]", x.size(), x.size(), &x[0]);
|
||||||
|
|
||||||
|
if (x.size() == 0) return NAN;
|
||||||
|
//decltype(parse_float)::foo= 1;
|
||||||
|
|
||||||
|
std::string val_str = "";
|
||||||
|
std::string val_unit = "";
|
||||||
|
|
||||||
|
// ESP_LOGD("ble_client.receive", "value received with %d bytes: [%.*s]", x.size(), x.size(), &x[0]);
|
||||||
|
|
||||||
|
// https://git.faked.org/jan/ph-260bd/-/blob/master/src/main.cpp#L7
|
||||||
|
static int factorMsToPpm = 700;
|
||||||
|
|
||||||
|
for (int i = 0; i < x.size(); i++) {
|
||||||
|
auto c = x[i];
|
||||||
|
switch(c) {
|
||||||
|
case '\x30': // "0"
|
||||||
|
case '\x31': // "1"
|
||||||
|
case '\x32': // "2"
|
||||||
|
case '\x33': // "3"
|
||||||
|
case '\x34': // "4"
|
||||||
|
case '\x35': // "5"
|
||||||
|
case '\x36': // "6"
|
||||||
|
case '\x37': // "7"
|
||||||
|
case '\x38': // "8"
|
||||||
|
case '\x39': // "9"
|
||||||
|
case '\x2E': // "."
|
||||||
|
val_str += c;
|
||||||
|
break;
|
||||||
|
case '\x20': // " "
|
||||||
|
break; // proceed until we hit units
|
||||||
|
case '\x0d': // '\r'
|
||||||
|
break; // ignore
|
||||||
|
case '\x0a': // '\n'
|
||||||
|
// FIXME: Don't publish temperature when ppt is set as it drops the first char
|
||||||
|
|
||||||
|
if (auto val = parse_number<float>(val_str)) {
|
||||||
|
if (val_unit == "pH") {
|
||||||
|
id(ph).publish_state(*val);
|
||||||
|
} else if (val_unit == "\xE2\x84\x83") { // ℃ char
|
||||||
|
id(temp).publish_state(*val);
|
||||||
|
} else if (val_unit == "uS") { // microsiemens
|
||||||
|
id(ec_us)->publish_state(*val);
|
||||||
|
} else if (val_unit == "mS") { // millisiemens
|
||||||
|
id(ec_us)->publish_state(*val * 1000);
|
||||||
|
} else if (val_unit == "ppm") { // TDS parts per million
|
||||||
|
id(ec_us)->publish_state(*val / factorMsToPpm * 1000);
|
||||||
|
} else if (val_unit == "ppt") { // TDS parts per thousand
|
||||||
|
id(ec_us)->publish_state(*val / factorMsToPpm * 1000 * 1000);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ESP_LOGW("ble_client.receive", "value received with unknown unit: [%s]", val_unit.c_str());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ESP_LOGW("ble_client.receive", "value could not be parsed as float: [%s]", val_str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
val_unit = "";
|
||||||
|
val_str = "";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
val_unit += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0; // this sensor isn't actually used
|
|
@ -59,6 +59,11 @@ config:
|
||||||
- cards:
|
- cards:
|
||||||
- entities:
|
- entities:
|
||||||
- entity: automation.warm_up_bo_s_office
|
- entity: automation.warm_up_bo_s_office
|
||||||
|
icon: mdi:heating-coil
|
||||||
|
name: Keep warm
|
||||||
|
- entity: input_number.bo_s_office_target_temperature
|
||||||
|
icon: mdi:temperature-celsius
|
||||||
|
name: Target
|
||||||
type: entities
|
type: entities
|
||||||
- entities:
|
- entities:
|
||||||
- entity: sensor.ble_temperature_bos_office_a4c1380f0b98
|
- entity: sensor.ble_temperature_bos_office_a4c1380f0b98
|
||||||
|
|
|
@ -10,9 +10,11 @@ config:
|
||||||
- state: unavailable
|
- state: unavailable
|
||||||
- area: Garden Shed
|
- area: Garden Shed
|
||||||
- entity_id: /human_readable/
|
- entity_id: /human_readable/
|
||||||
|
- entity_id: /garden_shed/
|
||||||
include:
|
include:
|
||||||
- name: /[gG]arden/
|
- name: /[gG]arden/
|
||||||
- name: /[tT]ent/
|
options:
|
||||||
|
secondary_info: last-updated
|
||||||
type: custom:auto-entities
|
type: custom:auto-entities
|
||||||
- card:
|
- card:
|
||||||
type: history-graph
|
type: history-graph
|
||||||
|
@ -24,12 +26,20 @@ config:
|
||||||
- state: unavailable
|
- state: unavailable
|
||||||
- area: Garden Shed
|
- area: Garden Shed
|
||||||
- entity_id: /human_readable/
|
- entity_id: /human_readable/
|
||||||
|
- entity_id: /garden_shed/
|
||||||
include:
|
include:
|
||||||
- name: /[gG]arden/
|
- name: /[gG]arden/
|
||||||
- name: /[tT]ent/
|
- name: /[tT]ent/
|
||||||
- entity_id: sensor.home_weather_temperature
|
- entity_id: sensor.home_weather_temperature
|
||||||
- entity_id: sensor.home_weather_forecast_temperature
|
- entity_id: sensor.home_weather_forecast_temperature
|
||||||
type: custom:auto-entities
|
type: custom:auto-entities
|
||||||
|
- entities:
|
||||||
|
- entity: sensor.ble_humidity_greenhouse_a4c1381cb175
|
||||||
|
secondary_info: last-changed
|
||||||
|
- entity: sensor.ble_temperature_greenhouse_a4c1381cb175
|
||||||
|
secondary_info: last-changed
|
||||||
|
title: Greenhouse (A4C1381CB175)
|
||||||
|
type: entities
|
||||||
icon: mdi:flower
|
icon: mdi:flower
|
||||||
path: garden
|
path: garden
|
||||||
title: Garden
|
title: Garden
|
||||||
|
@ -53,12 +63,6 @@ config:
|
||||||
show_state: true
|
show_state: true
|
||||||
- entity: switch.tent_cam_night_vision
|
- entity: switch.tent_cam_night_vision
|
||||||
show_state: true
|
show_state: true
|
||||||
- entity: sensor.tent_cam_battery_level
|
|
||||||
show_state: true
|
|
||||||
- entity: sensor.tent_cam_battery_temperature
|
|
||||||
show_state: true
|
|
||||||
- entity: sensor.tent_cam_light_level
|
|
||||||
show_state: true
|
|
||||||
type: picture-glance
|
type: picture-glance
|
||||||
view_layout:
|
view_layout:
|
||||||
position: sidebar
|
position: sidebar
|
||||||
|
@ -107,7 +111,7 @@ config:
|
||||||
state_color: true
|
state_color: true
|
||||||
tap_action:
|
tap_action:
|
||||||
action: toggle
|
action: toggle
|
||||||
entity: switch.tent_power_plug
|
entity: sensor.tent_wattage
|
||||||
name: Power
|
name: Power
|
||||||
secondary_info:
|
secondary_info:
|
||||||
entity: sensor.tent_wattage
|
entity: sensor.tent_wattage
|
||||||
|
@ -127,29 +131,15 @@ config:
|
||||||
position: sidebar
|
position: sidebar
|
||||||
- entities:
|
- entities:
|
||||||
- entities:
|
- entities:
|
||||||
- entity: sensor.tent_humidity
|
- entity: sensor.ble_humidity_tent_a4c1385ec751
|
||||||
format: precision1
|
format: precision1
|
||||||
name: Humidity
|
name: Humidity
|
||||||
entity: sensor.tent_temperature
|
entity: sensor.ble_temperature_tent_a4c1385ec751
|
||||||
format: precision1
|
format: precision1
|
||||||
icon: mdi:tent
|
icon: mdi:tent
|
||||||
name: Tent
|
name: Tent
|
||||||
state_header: Temperature
|
state_header: Temperature
|
||||||
type: custom:multiple-entity-row
|
type: custom:multiple-entity-row
|
||||||
- entities:
|
|
||||||
- entity: sensor.tent_reservoir_ec_us
|
|
||||||
format: kilo
|
|
||||||
name: EC
|
|
||||||
unit: false
|
|
||||||
- entity: sensor.tent_reservoir_ph
|
|
||||||
name: pH
|
|
||||||
unit: false
|
|
||||||
entity: sensor.tent_reservoir_temperature
|
|
||||||
format: precision1
|
|
||||||
icon: mdi:cup-water
|
|
||||||
name: Reservoir
|
|
||||||
state_header: Temperature
|
|
||||||
type: custom:multiple-entity-row
|
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
state_color: false
|
state_color: false
|
||||||
type: entities
|
type: entities
|
||||||
|
@ -264,10 +254,10 @@ config:
|
||||||
show_state: false
|
show_state: false
|
||||||
type: custom:multiple-entity-row
|
type: custom:multiple-entity-row
|
||||||
- entities:
|
- entities:
|
||||||
- hide_if_template: '{% set v = states(''sensor.tent_humidity'') %} {% set
|
- hide_if_template: '{% set v = states(''sensor.ble_humidity_tent_a4c1385ec751'')
|
||||||
min = states(''input_number.minimum_tent_humidity'') %} {% set max =
|
%} {% set min = states(''input_number.minimum_tent_humidity'') %} {%
|
||||||
states(''input_number.maximum_tent_humidity'') %} {{ iif(v < max and
|
set max = states(''input_number.maximum_tent_humidity'') %} {{ iif(v
|
||||||
v > min, v, -1 * v) }}'
|
< max and v > min, v, -1 * v) }}'
|
||||||
icon: mdi:alert-decagram
|
icon: mdi:alert-decagram
|
||||||
styles:
|
styles:
|
||||||
--paper-item-icon-color: red
|
--paper-item-icon-color: red
|
||||||
|
@ -311,18 +301,18 @@ config:
|
||||||
service: input_number.increment
|
service: input_number.increment
|
||||||
service_data:
|
service_data:
|
||||||
entity_id: input_number.maximum_tent_humidity
|
entity_id: input_number.maximum_tent_humidity
|
||||||
entity: sensor.tent_humidity
|
entity: sensor.ble_humidity_tent_a4c1385ec751
|
||||||
name: Humidity
|
name: Humidity
|
||||||
secondary_info:
|
secondary_info:
|
||||||
entity: sensor.tent_humidity
|
entity: sensor.ble_humidity_tent_a4c1385ec751
|
||||||
name: false
|
name: false
|
||||||
show_state: false
|
show_state: false
|
||||||
type: custom:multiple-entity-row
|
type: custom:multiple-entity-row
|
||||||
- entities:
|
- entities:
|
||||||
- hide_if_template: '{% set v = states(''sensor.tent_temperature'') %} {%
|
- hide_if_template: '{% set v = states(''sensor.ble_temperature_tent_a4c1385ec751'')
|
||||||
set min = states(''input_number.minimum_tent_temperature'') %} {% set
|
%} {% set min = states(''input_number.minimum_tent_temperature'') %}
|
||||||
max = states(''input_number.maximum_tent_temperature'') %} {{ iif(v
|
{% set max = states(''input_number.maximum_tent_temperature'') %} {{
|
||||||
< max and v > min, v, -1 * v) }}'
|
iif(v < max and v > min, v, -1 * v) }}'
|
||||||
icon: mdi:alert-decagram
|
icon: mdi:alert-decagram
|
||||||
styles:
|
styles:
|
||||||
--paper-item-icon-color: red
|
--paper-item-icon-color: red
|
||||||
|
@ -366,11 +356,11 @@ config:
|
||||||
service: input_number.increment
|
service: input_number.increment
|
||||||
service_data:
|
service_data:
|
||||||
entity_id: input_number.maximum_tent_temperature
|
entity_id: input_number.maximum_tent_temperature
|
||||||
entity: sensor.tent_temperature
|
entity: sensor.ble_temperature_tent_a4c1385ec751
|
||||||
icon: mdi:temperature-celsius
|
icon: mdi:temperature-celsius
|
||||||
name: Temperature
|
name: Temperature
|
||||||
secondary_info:
|
secondary_info:
|
||||||
entity: sensor.tent_temperature
|
entity: sensor.ble_temperature_tent_a4c1385ec751
|
||||||
name: false
|
name: false
|
||||||
show_state: false
|
show_state: false
|
||||||
type: custom:multiple-entity-row
|
type: custom:multiple-entity-row
|
||||||
|
@ -388,8 +378,8 @@ config:
|
||||||
entities:
|
entities:
|
||||||
- sensor.tent_reservoir_ph
|
- sensor.tent_reservoir_ph
|
||||||
- sensor.tent_vpd
|
- sensor.tent_vpd
|
||||||
- sensor.tent_humidity
|
- sensor.ble_humidity_tent_a4c1385ec751
|
||||||
- sensor.tent_temperature
|
- sensor.ble_temperature_tent_a4c1385ec751
|
||||||
- input_number.minimum_ph
|
- input_number.minimum_ph
|
||||||
- input_number.maximum_ph
|
- input_number.maximum_ph
|
||||||
- input_number.minimum_tent_vpd
|
- input_number.minimum_tent_vpd
|
||||||
|
@ -402,24 +392,43 @@ config:
|
||||||
view_layout:
|
view_layout:
|
||||||
position: sidebar
|
position: sidebar
|
||||||
- cards:
|
- cards:
|
||||||
- days_to_show: 3
|
- cards:
|
||||||
entities:
|
- entities:
|
||||||
- entity: sensor.bendigo_temp
|
- entity: sensor.home_weather_temperature
|
||||||
- entity: sensor.home_weather_temperature
|
name: Weather
|
||||||
name: Weather
|
- entity: sensor.ble_temperature_tent_a4c1385ec751
|
||||||
- entity: sensor.tent_temperature
|
name: Tent
|
||||||
name: Tent
|
- attribute: current_temperature
|
||||||
|
entity: climate.garden_shed
|
||||||
|
icon: mdi:thermometer
|
||||||
|
name: Shed
|
||||||
|
suffix: "\xB0C"
|
||||||
|
type: attribute
|
||||||
|
type: entities
|
||||||
|
- days_to_show: 3
|
||||||
|
entities:
|
||||||
|
- entity: sensor.home_weather_temperature
|
||||||
|
name: Weather
|
||||||
|
- entity: sensor.ble_temperature_tent_a4c1385ec751
|
||||||
|
name: Tent
|
||||||
|
type: statistics-graph
|
||||||
title: Air Temperatures
|
title: Air Temperatures
|
||||||
type: statistics-graph
|
type: custom:stack-in-card
|
||||||
- days_to_show: 3
|
- days_to_show: 3
|
||||||
entities:
|
entities:
|
||||||
- entity: sensor.bendigo_humidity
|
|
||||||
- entity: sensor.home_weather_humidity
|
- entity: sensor.home_weather_humidity
|
||||||
name: Weather
|
name: Weather
|
||||||
- entity: sensor.tent_humidity
|
- entity: sensor.ble_humidity_tent_a4c1385ec751
|
||||||
name: Tent
|
name: Tent
|
||||||
title: Humidity
|
title: Humidity
|
||||||
type: statistics-graph
|
type: statistics-graph
|
||||||
|
- air_rh: sensor.ble_humidity_tent_a4c1385ec751
|
||||||
|
air_temp: sensor.ble_temperature_tent_a4c1385ec751
|
||||||
|
crop: Cannabis
|
||||||
|
leaf_temp: sensor.ble_temperature_tent_a4c1385ec751
|
||||||
|
leaf_temp_offset: -2
|
||||||
|
title: Veg tent
|
||||||
|
type: custom:vpdchart-card
|
||||||
- days_to_show: 3
|
- days_to_show: 3
|
||||||
entities:
|
entities:
|
||||||
- entity: sensor.tent_vpd
|
- entity: sensor.tent_vpd
|
||||||
|
@ -428,30 +437,9 @@ config:
|
||||||
type: statistics-graph
|
type: statistics-graph
|
||||||
- days_to_show: 3
|
- days_to_show: 3
|
||||||
entities:
|
entities:
|
||||||
- entity: sensor.tent_reservoir_temperature
|
- entity: sensor.ble_illuminance_tent_c47c8d6dd13f
|
||||||
name: "\xB0C"
|
|
||||||
refresh_interval: 120
|
|
||||||
title: Reservoir Temperature
|
|
||||||
type: statistics-graph
|
|
||||||
- days_to_show: 3
|
|
||||||
entities:
|
|
||||||
- entity: sensor.tent_reservoir_ec_us
|
|
||||||
name: EC
|
|
||||||
refresh_interval: 120
|
|
||||||
title: Reservoir EC
|
|
||||||
type: statistics-graph
|
|
||||||
- days_to_show: 3
|
|
||||||
entities:
|
|
||||||
- entity: sensor.tent_reservoir_ph
|
|
||||||
name: pH
|
|
||||||
refresh_interval: 120
|
|
||||||
title: Reservoir pH
|
|
||||||
type: statistics-graph
|
|
||||||
- days_to_show: 3
|
|
||||||
entities:
|
|
||||||
- entity: sensor.tent_hhcc_1_illuminance
|
|
||||||
name: A
|
name: A
|
||||||
- entity: sensor.tent_hhcc_2_illuminance
|
- entity: sensor.ble_illuminance_tent_c47c8d6dd155
|
||||||
name: B
|
name: B
|
||||||
stat_types:
|
stat_types:
|
||||||
- max
|
- max
|
||||||
|
@ -459,25 +447,25 @@ config:
|
||||||
type: statistics-graph
|
type: statistics-graph
|
||||||
- days_to_show: 3
|
- days_to_show: 3
|
||||||
entities:
|
entities:
|
||||||
- entity: sensor.tent_hhcc_1_moisture
|
- entity: sensor.ble_moisture_tent_c47c8d6dd13f
|
||||||
name: A
|
name: A
|
||||||
- entity: sensor.tent_hhcc_2_moisture
|
- entity: sensor.ble_moisture_tent_c47c8d6dd155
|
||||||
name: B
|
name: B
|
||||||
title: Soil Moisture
|
title: Soil Moisture
|
||||||
type: statistics-graph
|
type: statistics-graph
|
||||||
- days_to_show: 3
|
- days_to_show: 3
|
||||||
entities:
|
entities:
|
||||||
- entity: sensor.tent_hhcc_1_temperature
|
- entity: sensor.ble_temperature_tent_c47c8d6dd13f
|
||||||
name: A
|
name: A
|
||||||
- entity: sensor.tent_hhcc_2_temperature
|
- entity: sensor.ble_temperature_tent_c47c8d6dd155
|
||||||
name: B
|
name: B
|
||||||
title: Soil Temperatures
|
title: Soil Temperatures
|
||||||
type: statistics-graph
|
type: statistics-graph
|
||||||
- days_to_show: 3
|
- days_to_show: 3
|
||||||
entities:
|
entities:
|
||||||
- entity: sensor.tent_hhcc_1_soil_conductivity
|
- entity: sensor.ble_conductivity_tent_c47c8d6dd13f
|
||||||
name: A
|
name: A
|
||||||
- entity: sensor.tent_hhcc_2_soil_conductivity
|
- entity: sensor.ble_conductivity_tent_c47c8d6dd155
|
||||||
name: B
|
name: B
|
||||||
title: Soil EC
|
title: Soil EC
|
||||||
type: statistics-graph
|
type: statistics-graph
|
||||||
|
@ -490,9 +478,7 @@ config:
|
||||||
title: Automations
|
title: Automations
|
||||||
type: entities
|
type: entities
|
||||||
filter:
|
filter:
|
||||||
exclude:
|
exclude: null
|
||||||
- name: /Snapshot|Restore/
|
|
||||||
- entity_id: /night_mode/
|
|
||||||
include:
|
include:
|
||||||
- entity_id: script.refill_tent_humidifier
|
- entity_id: script.refill_tent_humidifier
|
||||||
options:
|
options:
|
||||||
|
@ -525,7 +511,8 @@ config:
|
||||||
- domain: script
|
- domain: script
|
||||||
or:
|
or:
|
||||||
- entity_id: /tent/
|
- entity_id: /tent/
|
||||||
- area: Garden Shed
|
- area_id: /tent/
|
||||||
|
- area: /Tent/
|
||||||
sort:
|
sort:
|
||||||
entities:
|
entities:
|
||||||
- hide_if: 'on'
|
- hide_if: 'on'
|
||||||
|
@ -543,7 +530,6 @@ config:
|
||||||
method: last_triggered
|
method: last_triggered
|
||||||
reverse: true
|
reverse: true
|
||||||
- domain: automation
|
- domain: automation
|
||||||
entity_id: /tent/
|
|
||||||
options:
|
options:
|
||||||
entities:
|
entities:
|
||||||
- icon: mdi:play
|
- icon: mdi:play
|
||||||
|
@ -556,6 +542,11 @@ config:
|
||||||
state_color: true
|
state_color: true
|
||||||
toggle: true
|
toggle: true
|
||||||
type: custom:multiple-entity-row
|
type: custom:multiple-entity-row
|
||||||
|
or:
|
||||||
|
- entity_id: /tent/
|
||||||
|
- entity_id: /grow_camera/
|
||||||
|
- area_id: /tent/
|
||||||
|
- area: /Tent/
|
||||||
sort:
|
sort:
|
||||||
method: last_triggered
|
method: last_triggered
|
||||||
reverse: true
|
reverse: true
|
||||||
|
@ -568,15 +559,11 @@ config:
|
||||||
view_layout:
|
view_layout:
|
||||||
position: sidebar
|
position: sidebar
|
||||||
- entities:
|
- entities:
|
||||||
- entity: button.garden_shed_ble_relay_restart
|
- entity: button.garden_shed_ble_gateway_restart
|
||||||
name: Restart
|
name: Restart
|
||||||
- entity: binary_sensor.garden_shed_ble_relay_status
|
|
||||||
name: Status
|
|
||||||
secondary_info: last-changed
|
secondary_info: last-changed
|
||||||
- entity: sensor.garden_shed_ble_relay_wifi_signal
|
- entity: sensor.garden_shed_ble_gateway_wifi_signal
|
||||||
name: Wi-fi Signal
|
name: Wi-fi Signal
|
||||||
- entity: sensor.garden_shed_ble_relay_uptime_human_readable
|
|
||||||
name: Uptime
|
|
||||||
title: Sensor Proxy
|
title: Sensor Proxy
|
||||||
type: entities
|
type: entities
|
||||||
view_layout:
|
view_layout:
|
||||||
|
|
|
@ -60,6 +60,28 @@ config:
|
||||||
- entities:
|
- entities:
|
||||||
- entity: switch.nas
|
- entity: switch.nas
|
||||||
- entity: switch.tumtum
|
- entity: switch.tumtum
|
||||||
|
- type: section
|
||||||
|
- entity: automation.power_nas_tumtum_according_to_sleep
|
||||||
|
name: Turn off while sleeping
|
||||||
|
type: entities
|
||||||
|
- entities:
|
||||||
|
- entity: sensor.ups_status
|
||||||
|
name: Status
|
||||||
|
- entity: sensor.ups_battery_charge
|
||||||
|
name: Charge
|
||||||
|
- entity: sensor.ups_load
|
||||||
|
name: Load
|
||||||
|
- entity: automation.notify_on_ups_state_change
|
||||||
|
name: Notify on state change
|
||||||
|
- entity: automation.power_nas_tumtum_according_to_ups
|
||||||
|
name: Shutdown servers on battery
|
||||||
|
footer:
|
||||||
|
detail: 2
|
||||||
|
entity: sensor.ups_battery_charge
|
||||||
|
hours_to_show: 6
|
||||||
|
type: graph
|
||||||
|
show_header_toggle: false
|
||||||
|
title: UPS
|
||||||
type: entities
|
type: entities
|
||||||
icon: mdi:wardrobe-outline
|
icon: mdi:wardrobe-outline
|
||||||
path: server-closet
|
path: server-closet
|
||||||
|
@ -295,6 +317,54 @@ config:
|
||||||
path: hass
|
path: hass
|
||||||
theme: Backend-selected
|
theme: Backend-selected
|
||||||
title: HASS
|
title: HASS
|
||||||
|
- badges: []
|
||||||
|
cards:
|
||||||
|
- entities:
|
||||||
|
- entity: device_tracker.ugw3
|
||||||
|
- entity: sensor.unifi_gateway_alerts
|
||||||
|
- entity: device_tracker.unifi_controller
|
||||||
|
- entity: sensor.unifi_gateway_firmware_upgradable
|
||||||
|
- entity: sensor.unifi_gateway_lan
|
||||||
|
- entity: sensor.unifi_gateway_vpn
|
||||||
|
- entity: sensor.unifi_gateway_www
|
||||||
|
- entity: sensor.unifi_gateway_wlan
|
||||||
|
type: entities
|
||||||
|
- card:
|
||||||
|
type: entities
|
||||||
|
filter:
|
||||||
|
exclude: []
|
||||||
|
include:
|
||||||
|
- integration: unifi
|
||||||
|
not:
|
||||||
|
domain: device_tracker
|
||||||
|
type: custom:auto-entities
|
||||||
|
- card:
|
||||||
|
state_color: true
|
||||||
|
title: Clients
|
||||||
|
type: entities
|
||||||
|
filter:
|
||||||
|
exclude: []
|
||||||
|
include:
|
||||||
|
- domain: device_tracker
|
||||||
|
integration: unifi
|
||||||
|
options:
|
||||||
|
attribute: ip
|
||||||
|
type: attribute
|
||||||
|
sort:
|
||||||
|
method: friendly_name
|
||||||
|
state: home
|
||||||
|
- type: section
|
||||||
|
- domain: device_tracker
|
||||||
|
integration: unifi
|
||||||
|
not:
|
||||||
|
state: home
|
||||||
|
sort:
|
||||||
|
method: friendly_name
|
||||||
|
type: custom:auto-entities
|
||||||
|
icon: mdi:lan-connect
|
||||||
|
path: lan
|
||||||
|
theme: Backend-selected
|
||||||
|
title: LAN
|
||||||
- badges: []
|
- badges: []
|
||||||
cards:
|
cards:
|
||||||
- all_series_config:
|
- all_series_config:
|
||||||
|
|
|
@ -87,7 +87,7 @@ config:
|
||||||
name: peak
|
name: peak
|
||||||
entity: sensor.monthly_energy_import_offpeak
|
entity: sensor.monthly_energy_import_offpeak
|
||||||
format: precision1
|
format: precision1
|
||||||
name: Cycle
|
name: Month
|
||||||
state_header: offpeak
|
state_header: offpeak
|
||||||
type: custom:multiple-entity-row
|
type: custom:multiple-entity-row
|
||||||
- entities:
|
- entities:
|
||||||
|
@ -475,6 +475,8 @@ config:
|
||||||
title: Settings
|
title: Settings
|
||||||
type: entities
|
type: entities
|
||||||
- entities:
|
- entities:
|
||||||
|
- entity: sensor.inverter_battery_mode
|
||||||
|
name: Current
|
||||||
- action_name: Set
|
- action_name: Set
|
||||||
entity: script.inverter_self_consumption
|
entity: script.inverter_self_consumption
|
||||||
icon: mdi:recycle-variant
|
icon: mdi:recycle-variant
|
||||||
|
@ -516,6 +518,10 @@ config:
|
||||||
secondary_info: last-triggered
|
secondary_info: last-triggered
|
||||||
toggle: true
|
toggle: true
|
||||||
type: custom:multiple-entity-row
|
type: custom:multiple-entity-row
|
||||||
|
- entity: automation.inverter_maximise_output_new
|
||||||
|
icon: mdi:arrow-up-bold-box-outline
|
||||||
|
name: Maximise output (WIP)
|
||||||
|
secondary_info: last-triggered
|
||||||
- entity: automation.update_pvoutput
|
- entity: automation.update_pvoutput
|
||||||
icon: mdi:solar-power-variant-outline
|
icon: mdi:solar-power-variant-outline
|
||||||
name: Send to PVOutput
|
name: Send to PVOutput
|
||||||
|
@ -534,6 +540,16 @@ config:
|
||||||
- domain: script
|
- domain: script
|
||||||
name: /[Ii]nverter/
|
name: /[Ii]nverter/
|
||||||
type: custom:auto-entities
|
type: custom:auto-entities
|
||||||
|
- card:
|
||||||
|
type: entities
|
||||||
|
filter:
|
||||||
|
include:
|
||||||
|
- entity_id: input_number.inverter_active_power_buffer
|
||||||
|
options:
|
||||||
|
name: Buffer
|
||||||
|
- attributes:
|
||||||
|
solar: 'true'
|
||||||
|
type: custom:auto-entities
|
||||||
- cards:
|
- cards:
|
||||||
- entities:
|
- entities:
|
||||||
battery: sensor.inverter_battery_power
|
battery: sensor.inverter_battery_power
|
||||||
|
@ -545,9 +561,17 @@ config:
|
||||||
w_decimals: 0
|
w_decimals: 0
|
||||||
watt_threshold: 900
|
watt_threshold: 900
|
||||||
- entities:
|
- entities:
|
||||||
- sensor.inverter_active_power
|
- entity: sensor.inverter_active_power
|
||||||
|
name: Active Power
|
||||||
|
- entity: sensor.inverter_battery_power
|
||||||
|
name: Battery Power
|
||||||
type: entities
|
type: entities
|
||||||
type: custom:stack-in-card
|
type: custom:stack-in-card
|
||||||
|
- entities:
|
||||||
|
- entity: sensor.inverter_target_battery_level
|
||||||
|
- entity: sensor.inverter_battery_level
|
||||||
|
hours_to_show: 6
|
||||||
|
type: history-graph
|
||||||
icon: mdi:wrench
|
icon: mdi:wrench
|
||||||
path: configure
|
path: configure
|
||||||
theme: Backend-selected
|
theme: Backend-selected
|
||||||
|
@ -682,6 +706,19 @@ config:
|
||||||
state_header: Current
|
state_header: Current
|
||||||
type: custom:multiple-entity-row
|
type: custom:multiple-entity-row
|
||||||
type: entities
|
type: entities
|
||||||
|
- entities:
|
||||||
|
- entity: sensor.inverter_pv_power
|
||||||
|
name: PV Power
|
||||||
|
- entity: sensor.inverter_mppt1_current
|
||||||
|
name: MPPT1 Current
|
||||||
|
- entity: sensor.inverter_mppt2_current
|
||||||
|
name: MPPT2 Current
|
||||||
|
- entity: sensor.inverter_mppt1_voltage
|
||||||
|
name: MPPT1 Voltage
|
||||||
|
- entity: sensor.inverter_mppt2_voltage
|
||||||
|
name: MPPT2 Voltage
|
||||||
|
hours_to_show: 2
|
||||||
|
type: history-graph
|
||||||
title: Panels
|
title: Panels
|
||||||
type: custom:stack-in-card
|
type: custom:stack-in-card
|
||||||
- entities:
|
- entities:
|
||||||
|
|
|
@ -3,26 +3,6 @@ config:
|
||||||
views:
|
views:
|
||||||
- badges: []
|
- badges: []
|
||||||
cards:
|
cards:
|
||||||
- card:
|
|
||||||
type: custom:mushroom-chips-card
|
|
||||||
card_param: chips
|
|
||||||
filter:
|
|
||||||
exclude:
|
|
||||||
- entity_id: /tent/
|
|
||||||
- entity_id: '*double_lamp_*'
|
|
||||||
- area: Garden Shed
|
|
||||||
- name: /Purifier/
|
|
||||||
include:
|
|
||||||
- domain: light
|
|
||||||
options:
|
|
||||||
content_info: name
|
|
||||||
type: light
|
|
||||||
use_light_color: true
|
|
||||||
sort:
|
|
||||||
method: name
|
|
||||||
sort:
|
|
||||||
method: friendly_name
|
|
||||||
type: custom:auto-entities
|
|
||||||
- cards:
|
- cards:
|
||||||
- card:
|
- card:
|
||||||
chips:
|
chips:
|
||||||
|
@ -147,6 +127,7 @@ config:
|
||||||
- state: standby
|
- state: standby
|
||||||
- entity_id: /spotify/
|
- entity_id: /spotify/
|
||||||
- entity_id: /denon/
|
- entity_id: /denon/
|
||||||
|
- entity_id: /global/
|
||||||
- attributes:
|
- attributes:
|
||||||
source: HEOS Music
|
source: HEOS Music
|
||||||
include:
|
include:
|
||||||
|
@ -199,6 +180,7 @@ config:
|
||||||
- state: unknown
|
- state: unknown
|
||||||
- entity_id: /vacuum.*attached/
|
- entity_id: /vacuum.*attached/
|
||||||
- entity_id: /inverter_.*_soc/
|
- entity_id: /inverter_.*_soc/
|
||||||
|
- entity_id: /athom/
|
||||||
include:
|
include:
|
||||||
- attributes:
|
- attributes:
|
||||||
device_class: moisture
|
device_class: moisture
|
||||||
|
@ -286,78 +268,191 @@ config:
|
||||||
type: custom:power-flow-card
|
type: custom:power-flow-card
|
||||||
w_decimals: 0
|
w_decimals: 0
|
||||||
watt_threshold: 900
|
watt_threshold: 900
|
||||||
- elements:
|
- cards:
|
||||||
- attribute: mean
|
- collapsible_controls: false
|
||||||
entity: sensor.ble_temperature_living_room_a4c1382a9b6e
|
entity: climate.living_room_a_c
|
||||||
style:
|
fill_container: true
|
||||||
background: rgba(10,10,10,0.2)
|
hvac_modes:
|
||||||
left: 23%
|
- auto
|
||||||
padding: 3px
|
- dry
|
||||||
top: 22%
|
- heat
|
||||||
suffix: "\xB0C"
|
- cool
|
||||||
tap_action: more-info
|
- 'off'
|
||||||
type: custom:state-attribute-element
|
- heat_cool
|
||||||
- attribute: mean
|
icon: mdi:air-conditioner
|
||||||
entity: sensor.ble_temperature_bos_office_a4c1380f0b98
|
layout: horizontal
|
||||||
style:
|
primary_info: state
|
||||||
background: rgba(10,10,10,0.2)
|
secondary_info: last-changed
|
||||||
left: 72%
|
show_temperature_control: true
|
||||||
padding: 3px
|
type: custom:mushroom-climate-card
|
||||||
top: 80%
|
- card:
|
||||||
suffix: "\xB0C"
|
entities:
|
||||||
tap_action: more-info
|
- switch.living_room_a_c_ionizer
|
||||||
type: custom:state-attribute-element
|
type: entities
|
||||||
- attribute: mean
|
conditions:
|
||||||
entity: sensor.ble_temperature_ris_office_a4c138e78afe
|
- entity: climate.living_room_a_c
|
||||||
style:
|
state_not: 'off'
|
||||||
background: rgba(10,10,10,0.2)
|
type: conditional
|
||||||
left: 88.8%
|
- card:
|
||||||
padding: 3px
|
entities:
|
||||||
top: 80%
|
- switch.living_room_a_c_jet_mode
|
||||||
suffix: "\xB0C"
|
type: entities
|
||||||
tap_action: more-info
|
conditions:
|
||||||
type: custom:state-attribute-element
|
- entity: switch.living_room_a_c_jet_mode
|
||||||
- attribute: mean
|
state_not: unavailable
|
||||||
entity: sensor.ble_temperature_analog_room_a4c138bcab08
|
type: conditional
|
||||||
style:
|
- entities:
|
||||||
background: rgba(10,10,10,0.2)
|
- entity: climate.living_room_a_c
|
||||||
left: 80%
|
name: A/C
|
||||||
padding: 3px
|
- entity: sensor.ble_temperature_living_room_a4c1382a9b6e
|
||||||
top: 47%
|
- entity: sensor.area_temperature_degc_living_room
|
||||||
suffix: "\xB0C"
|
name: Average temperature
|
||||||
type: custom:state-attribute-element
|
hours_to_show: 6
|
||||||
- attribute: mean
|
type: history-graph
|
||||||
entity: sensor.ble_temperature_kitchen_a4c1389485e3
|
type: custom:stack-in-card
|
||||||
style:
|
icon: hass:home
|
||||||
background: rgba(10,10,10,0.2)
|
panel: false
|
||||||
left: 53.3%
|
path: default_view
|
||||||
padding: 3px
|
title: Home
|
||||||
top: 20%
|
- badges: []
|
||||||
suffix: "\xB0C"
|
cards:
|
||||||
tap_action: more-info
|
- cards:
|
||||||
type: custom:state-attribute-element
|
- cards:
|
||||||
- attribute: mean
|
- entity: person.bo_jeanes
|
||||||
entity: sensor.ble_temperature_bedroom_a4c138feb60c
|
fill_container: false
|
||||||
style:
|
hide_name: false
|
||||||
background: rgba(10,10,10,0.2)
|
hide_state: false
|
||||||
left: 29%
|
type: custom:mushroom-person-card
|
||||||
padding: 3px
|
use_entity_picture: true
|
||||||
top: 77%
|
- double_tap_action:
|
||||||
suffix: "\xB0C"
|
action: none
|
||||||
tap_action: more-info
|
entity: sensor.template_room_bo_phone
|
||||||
type: custom:state-attribute-element
|
icon: "{% if is_state(entity, 'not_home') and is_state('person.bo_jeanes',\
|
||||||
- attribute: mean
|
\ 'home') %}\n mdi:cellphone-off\n{% else %}\n mdi:cellphone-marker\n\
|
||||||
entity: sensor.ble_temperature_spare_room_a4c138d8ef42
|
{% endif %}"
|
||||||
style:
|
secondary: "{% if is_state('person.bo_jeanes', 'not_home') %}\n ~{{ states('proximity.bo_home')\
|
||||||
background: rgba(10,10,10,0.2)
|
\ }}m from home\n{% elif is_state(entity, 'not_home') %}\n Unknown\n\
|
||||||
left: 53.3%
|
{% else %}\n {{ states(entity) | replace(\"_s_\",\"'s \") | replace(\"\
|
||||||
padding: 3px
|
_\",\" \") | title }}\n ~{{ state_attr(entity, 'distance') }}m\n{% endif\
|
||||||
top: 80%
|
\ %}"
|
||||||
suffix: "\xB0C"
|
tap_action:
|
||||||
tap_action: more-info
|
action: more-info
|
||||||
type: custom:state-attribute-element
|
type: custom:mushroom-template-card
|
||||||
image: /local/floorplan-top.jpg
|
type: vertical-stack
|
||||||
type: picture-elements
|
- cards:
|
||||||
|
- entity: person.ri_liu
|
||||||
|
fill_container: false
|
||||||
|
hide_name: false
|
||||||
|
hide_state: false
|
||||||
|
layout: horizontal
|
||||||
|
type: custom:mushroom-person-card
|
||||||
|
use_entity_picture: true
|
||||||
|
- double_tap_action:
|
||||||
|
action: none
|
||||||
|
entity: sensor.template_room_ri_phone
|
||||||
|
icon: "{% if is_state(entity, 'not_home') and is_state('person.ri_liu',\
|
||||||
|
\ 'home') %}\n mdi:cellphone-off\n{% else %}\n mdi:cellphone-marker\n\
|
||||||
|
{% endif %}"
|
||||||
|
secondary: "{% if is_state('person.ri_liu', 'not_home') %}\n ~{{ states('proximity.ri_home')\
|
||||||
|
\ }}m from home\n{% elif is_state(entity, 'not_home') %}\n Unknown\n\
|
||||||
|
{% else %}\n {{ states(entity) | replace(\"_s_\",\"'s \") | replace(\"\
|
||||||
|
_\",\" \") | title }}\n ~{{ state_attr(entity, 'distance') }}m\n{% endif\
|
||||||
|
\ %}"
|
||||||
|
tap_action:
|
||||||
|
action: more-info
|
||||||
|
type: custom:mushroom-template-card
|
||||||
|
type: vertical-stack
|
||||||
|
type: horizontal-stack
|
||||||
|
- aspect_ratio: '16:9'
|
||||||
|
auto_fit: true
|
||||||
|
entities:
|
||||||
|
- entity: person.bo_jeanes
|
||||||
|
- entity: person.ri_liu
|
||||||
|
hours_to_show: 12
|
||||||
|
type: map
|
||||||
|
icon: mdi:account-supervisor-circle
|
||||||
|
path: people
|
||||||
|
theme: Backend-selected
|
||||||
|
title: People
|
||||||
|
- badges: []
|
||||||
|
cards:
|
||||||
|
- entities:
|
||||||
|
- entity: binary_sensor.in_bed
|
||||||
|
name: Anyone In bed
|
||||||
|
secondary_info: last-updated
|
||||||
|
- entity: input_boolean.bo_in_bed
|
||||||
|
- entity: input_boolean.ri_in_bed
|
||||||
|
- entity: cover.bedroom_blinds
|
||||||
|
- entity: sensor.bedroom_blinds_motor_state
|
||||||
|
- entity: automation.in_bed_detection
|
||||||
|
- entity: automation.manage_bedroom_blinds
|
||||||
|
type: entities
|
||||||
|
- chips:
|
||||||
|
- entity: binary_sensor.in_bed
|
||||||
|
type: entity
|
||||||
|
type: custom:mushroom-chips-card
|
||||||
|
- double_tap_action:
|
||||||
|
action: toggle
|
||||||
|
entity: cover.bedroom_blinds
|
||||||
|
fill_container: false
|
||||||
|
primary_info: name
|
||||||
|
show_buttons_control: false
|
||||||
|
show_position_control: true
|
||||||
|
type: custom:mushroom-cover-card
|
||||||
|
icon: mdi:bed
|
||||||
|
path: bedroom
|
||||||
|
theme: Backend-selected
|
||||||
|
title: Bedroom
|
||||||
|
- badges: []
|
||||||
|
cards:
|
||||||
|
- entity: weather.home_weather
|
||||||
|
number_of_forecasts: '3'
|
||||||
|
type: custom:weather-card
|
||||||
|
- entities:
|
||||||
|
- entity: sun.sun
|
||||||
|
- entity: sensor.home_weather_condition
|
||||||
|
- entity: sensor.home_weather_temperature
|
||||||
|
name: "\xB0C Current"
|
||||||
|
- entity: sensor.home_weather_humidity
|
||||||
|
name: Humidity
|
||||||
|
- entity: sensor.home_weather_cloud_coverage
|
||||||
|
name: Cloud coverage
|
||||||
|
hours_to_show: 24
|
||||||
|
refresh_interval: 0
|
||||||
|
type: history-graph
|
||||||
|
- center_latitude: -36.7769283
|
||||||
|
center_longitude: 144.2634146
|
||||||
|
extra_labels: true
|
||||||
|
map_style: Voyager
|
||||||
|
marker_latitude: -36.7769283
|
||||||
|
marker_longitude: 144.2634146
|
||||||
|
show_marker: true
|
||||||
|
show_range: true
|
||||||
|
show_zoom: true
|
||||||
|
type: custom:bom-radar-card
|
||||||
|
zoom_level: 8
|
||||||
|
- entities:
|
||||||
|
- entity: sun.sun
|
||||||
|
- entity: weather.home_weather
|
||||||
|
- entity: sensor.home_weather_condition
|
||||||
|
- entity: sensor.home_weather_forecast_condition
|
||||||
|
- entity: weather.home
|
||||||
|
- entity: weather.home_hourly
|
||||||
|
- entity: sensor.home_weather_cloud_coverage
|
||||||
|
- entity: sensor.home_weather_forecast_cloud_coverage
|
||||||
|
type: history-graph
|
||||||
|
icon: hass:thermometer
|
||||||
|
path: climate
|
||||||
|
title: Climate
|
||||||
|
- badges: []
|
||||||
|
cards:
|
||||||
|
- calibration_source:
|
||||||
|
camera: true
|
||||||
|
entity: vacuum.robot_vacuum
|
||||||
|
map_source:
|
||||||
|
camera: camera.vacuum_map
|
||||||
|
type: custom:xiaomi-vacuum-map-card
|
||||||
|
vacuum_platform: default
|
||||||
- calibration_source:
|
- calibration_source:
|
||||||
camera: true
|
camera: true
|
||||||
entity: vacuum.dreame_p2028_4394_robot_cleaner
|
entity: vacuum.dreame_p2028_4394_robot_cleaner
|
||||||
|
@ -502,166 +597,6 @@ config:
|
||||||
two_finger_pan: true
|
two_finger_pan: true
|
||||||
type: custom:xiaomi-vacuum-map-card
|
type: custom:xiaomi-vacuum-map-card
|
||||||
vacuum_platform: default
|
vacuum_platform: default
|
||||||
icon: hass:home
|
|
||||||
panel: false
|
|
||||||
path: default_view
|
|
||||||
title: Home
|
|
||||||
- badges: []
|
|
||||||
cards:
|
|
||||||
- cards:
|
|
||||||
- cards:
|
|
||||||
- entity: person.bo_jeanes
|
|
||||||
fill_container: false
|
|
||||||
hide_name: false
|
|
||||||
hide_state: false
|
|
||||||
type: custom:mushroom-person-card
|
|
||||||
use_entity_picture: true
|
|
||||||
- double_tap_action:
|
|
||||||
action: none
|
|
||||||
entity: sensor.template_room_bo_phone
|
|
||||||
icon: "{% if is_state(entity, 'not_home') and is_state('person.bo_jeanes',\
|
|
||||||
\ 'home') %}\n mdi:cellphone-off\n{% else %}\n mdi:cellphone-marker\n\
|
|
||||||
{% endif %}"
|
|
||||||
secondary: "{% if is_state('person.bo_jeanes', 'not_home') %}\n ~{{ states('proximity.bo_home')\
|
|
||||||
\ }}m from home\n{% elif is_state(entity, 'not_home') %}\n Unknown\n\
|
|
||||||
{% else %}\n {{ states(entity) | replace(\"_s_\",\"'s \") | replace(\"\
|
|
||||||
_\",\" \") | title }}\n ~{{ state_attr(entity, 'distance') }}m\n{% endif\
|
|
||||||
\ %}"
|
|
||||||
tap_action:
|
|
||||||
action: more-info
|
|
||||||
type: custom:mushroom-template-card
|
|
||||||
type: vertical-stack
|
|
||||||
- cards:
|
|
||||||
- entity: person.ri_liu
|
|
||||||
fill_container: false
|
|
||||||
hide_name: false
|
|
||||||
hide_state: false
|
|
||||||
layout: horizontal
|
|
||||||
type: custom:mushroom-person-card
|
|
||||||
use_entity_picture: true
|
|
||||||
- double_tap_action:
|
|
||||||
action: none
|
|
||||||
entity: sensor.template_room_ri_phone
|
|
||||||
icon: "{% if is_state(entity, 'not_home') and is_state('person.ri_liu',\
|
|
||||||
\ 'home') %}\n mdi:cellphone-off\n{% else %}\n mdi:cellphone-marker\n\
|
|
||||||
{% endif %}"
|
|
||||||
secondary: "{% if is_state('person.ri_liu', 'not_home') %}\n ~{{ states('proximity.ri_home')\
|
|
||||||
\ }}m from home\n{% elif is_state(entity, 'not_home') %}\n Unknown\n\
|
|
||||||
{% else %}\n {{ states(entity) | replace(\"_s_\",\"'s \") | replace(\"\
|
|
||||||
_\",\" \") | title }}\n ~{{ state_attr(entity, 'distance') }}m\n{% endif\
|
|
||||||
\ %}"
|
|
||||||
tap_action:
|
|
||||||
action: more-info
|
|
||||||
type: custom:mushroom-template-card
|
|
||||||
type: vertical-stack
|
|
||||||
type: horizontal-stack
|
|
||||||
icon: mdi:account-supervisor-circle
|
|
||||||
path: people
|
|
||||||
theme: Backend-selected
|
|
||||||
title: People
|
|
||||||
- badges: []
|
|
||||||
cards:
|
|
||||||
- entities:
|
|
||||||
- entity: binary_sensor.in_bed
|
|
||||||
name: Anyone In bed
|
|
||||||
secondary_info: last-updated
|
|
||||||
- entity: input_boolean.bo_in_bed
|
|
||||||
- entity: input_boolean.ri_in_bed
|
|
||||||
type: entities
|
|
||||||
- aqi:
|
|
||||||
entity_id: sensor.bedroom_purifier_pm2_5
|
|
||||||
unit: "\xB5g/m\xB3"
|
|
||||||
compact_view: true
|
|
||||||
entity: fan.bedroom_purifier
|
|
||||||
shortcuts:
|
|
||||||
- icon: mdi:weather-night
|
|
||||||
name: Silent
|
|
||||||
preset_mode: Silent
|
|
||||||
- icon: mdi:circle-slice-2
|
|
||||||
name: 25%
|
|
||||||
percentage: 25
|
|
||||||
- icon: mdi:circle-slice-4
|
|
||||||
name: 50%
|
|
||||||
percentage: 50
|
|
||||||
- icon: mdi:circle-slice-6
|
|
||||||
name: 75%
|
|
||||||
percentage: 75
|
|
||||||
- icon: mdi:circle-slice-8
|
|
||||||
name: 100%
|
|
||||||
percentage: 100
|
|
||||||
- icon: mdi:brightness-auto
|
|
||||||
name: Auto
|
|
||||||
preset_mode: Auto
|
|
||||||
show_name: false
|
|
||||||
show_state: false
|
|
||||||
show_toolbar: true
|
|
||||||
stats:
|
|
||||||
- entity_id: sensor.bedroom_purifier_temperature
|
|
||||||
unit: "\xB0C"
|
|
||||||
- entity_id: sensor.bedroom_purifier_humidity
|
|
||||||
unit: '%'
|
|
||||||
- entity_id: sensor.bedroom_purifier_filter_life_remaining
|
|
||||||
subtitle: Filter Remaining
|
|
||||||
unit: '%'
|
|
||||||
type: custom:purifier-card
|
|
||||||
- chips:
|
|
||||||
- entity: binary_sensor.in_bed
|
|
||||||
type: entity
|
|
||||||
type: custom:mushroom-chips-card
|
|
||||||
icon: mdi:bed
|
|
||||||
path: bedroom
|
|
||||||
theme: Backend-selected
|
|
||||||
title: Bedroom
|
|
||||||
- badges: []
|
|
||||||
cards:
|
|
||||||
- entity: weather.home_weather
|
|
||||||
number_of_forecasts: '3'
|
|
||||||
type: custom:weather-card
|
|
||||||
- entities:
|
|
||||||
- entity: sun.sun
|
|
||||||
- entity: sensor.home_weather_condition
|
|
||||||
- entity: sensor.home_weather_temperature
|
|
||||||
name: "\xB0C Current"
|
|
||||||
- entity: sensor.home_weather_humidity
|
|
||||||
name: Humidity
|
|
||||||
- entity: sensor.home_weather_cloud_coverage
|
|
||||||
name: Cloud coverage
|
|
||||||
hours_to_show: 24
|
|
||||||
refresh_interval: 0
|
|
||||||
type: history-graph
|
|
||||||
- center_latitude: -36.7769283
|
|
||||||
center_longitude: 144.2634146
|
|
||||||
extra_labels: true
|
|
||||||
map_style: Voyager
|
|
||||||
marker_latitude: -36.7769283
|
|
||||||
marker_longitude: 144.2634146
|
|
||||||
show_marker: true
|
|
||||||
show_range: true
|
|
||||||
show_zoom: true
|
|
||||||
type: custom:bom-radar-card
|
|
||||||
zoom_level: 8
|
|
||||||
- entities:
|
|
||||||
- entity: sun.sun
|
|
||||||
- entity: weather.home_weather
|
|
||||||
- entity: sensor.home_weather_condition
|
|
||||||
- entity: sensor.home_weather_forecast_condition
|
|
||||||
- entity: weather.home
|
|
||||||
- entity: weather.home_hourly
|
|
||||||
- entity: sensor.home_weather_cloud_coverage
|
|
||||||
- entity: sensor.home_weather_forecast_cloud_coverage
|
|
||||||
type: history-graph
|
|
||||||
icon: hass:thermometer
|
|
||||||
path: climate
|
|
||||||
title: Climate
|
|
||||||
- badges: []
|
|
||||||
cards:
|
|
||||||
- calibration_source:
|
|
||||||
camera: true
|
|
||||||
entity: vacuum.robot_vacuum
|
|
||||||
map_source:
|
|
||||||
camera: camera.vacuum_map
|
|
||||||
type: custom:xiaomi-vacuum-map-card
|
|
||||||
vacuum_platform: default
|
|
||||||
icon: ''
|
icon: ''
|
||||||
panel: false
|
panel: false
|
||||||
path: misc
|
path: misc
|
||||||
|
|
|
@ -4,7 +4,7 @@ items:
|
||||||
url: /hacsfiles/mini-graph-card/mini-graph-card-bundle.js?hacstag=1512800620110
|
url: /hacsfiles/mini-graph-card/mini-graph-card-bundle.js?hacstag=1512800620110
|
||||||
- id: 286fca3cd80f4192b815b715ef5f999e
|
- id: 286fca3cd80f4192b815b715ef5f999e
|
||||||
type: module
|
type: module
|
||||||
url: /hacsfiles/vertical-stack-in-card/vertical-stack-in-card.js?hacstag=142051833042
|
url: /hacsfiles/vertical-stack-in-card/vertical-stack-in-card.js?hacstag=142051833044
|
||||||
- id: 032c18f548ea467b8bce3884fe451d82
|
- id: 032c18f548ea467b8bce3884fe451d82
|
||||||
type: module
|
type: module
|
||||||
url: /hacsfiles/vacuum-card/vacuum-card.js?hacstag=261291295263
|
url: /hacsfiles/vacuum-card/vacuum-card.js?hacstag=261291295263
|
||||||
|
@ -13,7 +13,7 @@ items:
|
||||||
url: /hacsfiles/weather-card/weather-card.js
|
url: /hacsfiles/weather-card/weather-card.js
|
||||||
- id: 69e31fab8ea64da890a5c68fc590320f
|
- id: 69e31fab8ea64da890a5c68fc590320f
|
||||||
type: module
|
type: module
|
||||||
url: /hacsfiles/lovelace-xiaomi-vacuum-map-card/xiaomi-vacuum-map-card.js?hacstag=1933720442011
|
url: /hacsfiles/lovelace-xiaomi-vacuum-map-card/xiaomi-vacuum-map-card.js?hacstag=193372044212
|
||||||
- id: f2b643a296014c8292cbb3ba1b9af69b
|
- id: f2b643a296014c8292cbb3ba1b9af69b
|
||||||
type: module
|
type: module
|
||||||
url: /hacsfiles/kb-better-graph-colors/kb-better-graph-colors.js
|
url: /hacsfiles/kb-better-graph-colors/kb-better-graph-colors.js
|
||||||
|
@ -22,10 +22,10 @@ items:
|
||||||
url: /hacsfiles/purifier-card/purifier-card.js?hacstag=274738925223
|
url: /hacsfiles/purifier-card/purifier-card.js?hacstag=274738925223
|
||||||
- id: c623d3fc8954431685d17cd75bf572bb
|
- id: c623d3fc8954431685d17cd75bf572bb
|
||||||
type: module
|
type: module
|
||||||
url: /hacsfiles/apexcharts-card/apexcharts-card.js?hacstag=331701152201
|
url: /hacsfiles/apexcharts-card/apexcharts-card.js?hacstag=331701152202
|
||||||
- id: 4cb20baf31e442e9830e4af74f089a0d
|
- id: 4cb20baf31e442e9830e4af74f089a0d
|
||||||
type: module
|
type: module
|
||||||
url: /hacsfiles/lovelace-auto-entities/auto-entities.js?hacstag=1677445841110
|
url: /hacsfiles/lovelace-auto-entities/auto-entities.js?hacstag=1677445841121
|
||||||
- id: 8468c5604c2d41d294fb0143cea43765
|
- id: 8468c5604c2d41d294fb0143cea43765
|
||||||
type: module
|
type: module
|
||||||
url: /hacsfiles/simple-thermostat/simple-thermostat.js?hacstag=158654878243
|
url: /hacsfiles/simple-thermostat/simple-thermostat.js?hacstag=158654878243
|
||||||
|
@ -49,7 +49,7 @@ items:
|
||||||
url: /hacsfiles/miflora-card/miflora-card.js?hacstag=197715418010
|
url: /hacsfiles/miflora-card/miflora-card.js?hacstag=197715418010
|
||||||
- id: ddb6d1b21fc44ae692519ea38c9cf9cb
|
- id: ddb6d1b21fc44ae692519ea38c9cf9cb
|
||||||
type: module
|
type: module
|
||||||
url: /hacsfiles/bom-radar-card/bom-radar-card.js?hacstag=294609880206
|
url: /hacsfiles/bom-radar-card/bom-radar-card.js?hacstag=294609880210
|
||||||
- id: edc63027be67460bab526d3dd3b4a8b2
|
- id: edc63027be67460bab526d3dd3b4a8b2
|
||||||
type: module
|
type: module
|
||||||
url: /hacsfiles/secondaryinfo-entity-row/secondaryinfo-entity-row.js?hacstag=15971160550
|
url: /hacsfiles/secondaryinfo-entity-row/secondaryinfo-entity-row.js?hacstag=15971160550
|
||||||
|
@ -91,7 +91,7 @@ items:
|
||||||
url: /hacsfiles/lovelace-paper-buttons-row/paper-buttons-row.js?hacstag=244872232101
|
url: /hacsfiles/lovelace-paper-buttons-row/paper-buttons-row.js?hacstag=244872232101
|
||||||
- id: 78939a4781bd40f6accb3cba860a100f
|
- id: 78939a4781bd40f6accb3cba860a100f
|
||||||
type: module
|
type: module
|
||||||
url: /hacsfiles/lovelace-mushroom/mushroom.js?hacstag=444350375200
|
url: /hacsfiles/lovelace-mushroom/mushroom.js?hacstag=444350375213
|
||||||
- id: 4795f91c6d3a4fd3a5b1900f9990217e
|
- id: 4795f91c6d3a4fd3a5b1900f9990217e
|
||||||
type: module
|
type: module
|
||||||
url: /hacsfiles/stack-in-card/stack-in-card.js?hacstag=248954055020
|
url: /hacsfiles/stack-in-card/stack-in-card.js?hacstag=248954055020
|
||||||
|
@ -109,7 +109,7 @@ items:
|
||||||
url: /hacsfiles/lovelace-battery-entity-row/battery-entity-row.js?hacstag=303857065131
|
url: /hacsfiles/lovelace-battery-entity-row/battery-entity-row.js?hacstag=303857065131
|
||||||
- id: 867c82efa08d47a3a9ccbe9f5afb238a
|
- id: 867c82efa08d47a3a9ccbe9f5afb238a
|
||||||
type: module
|
type: module
|
||||||
url: /hacsfiles/numberbox-card/numberbox-card.js?hacstag=304967918312
|
url: /hacsfiles/numberbox-card/numberbox-card.js?hacstag=30496791840
|
||||||
- id: 6a72c3dfa03446ffae4b9d8093bb5b7a
|
- id: 6a72c3dfa03446ffae4b9d8093bb5b7a
|
||||||
type: module
|
type: module
|
||||||
url: /hacsfiles/custom-ui/custom-ui.js?hacstag=267558148202204191
|
url: /hacsfiles/custom-ui/custom-ui.js?hacstag=267558148202204191
|
||||||
|
@ -119,15 +119,6 @@ items:
|
||||||
- id: 8217392f44e24fe98b652c7f36ab302e
|
- id: 8217392f44e24fe98b652c7f36ab302e
|
||||||
type: module
|
type: module
|
||||||
url: /hacsfiles/ha-sankey-chart/ha-sankey-chart.js?hacstag=4558460880110
|
url: /hacsfiles/ha-sankey-chart/ha-sankey-chart.js?hacstag=4558460880110
|
||||||
- id: 84ed6341c9b245aba7e66cbdc51e2ccb
|
|
||||||
type: module
|
|
||||||
url: /hacsfiles/state-attribute-element/state-attribute-element.js?hacstag=142038085040
|
|
||||||
- id: a70f15c06c9544b7bf7ad3bcf9dc6325
|
|
||||||
type: module
|
|
||||||
url: /hacsfiles/state-element/state-element.js?hacstag=142344403002
|
|
||||||
- id: ecebe38b38124fb1ba83b3ca1ee43e7d
|
|
||||||
type: module
|
|
||||||
url: /hacsfiles/text-element/text-element.js?hacstag=141897999002
|
|
||||||
- id: 0afffa6b08dd44be820b7e45428e0e4c
|
- id: 0afffa6b08dd44be820b7e45428e0e4c
|
||||||
type: module
|
type: module
|
||||||
url: /hacsfiles/radial-menu/radial-menu.js?hacstag=181124811160
|
url: /hacsfiles/radial-menu/radial-menu.js?hacstag=181124811160
|
||||||
|
@ -140,3 +131,6 @@ items:
|
||||||
- id: c6b759faf93a4e22ab9faa3ebcaa218b
|
- id: c6b759faf93a4e22ab9faa3ebcaa218b
|
||||||
type: module
|
type: module
|
||||||
url: /hacsfiles/button-card/button-card.js?hacstag=146194325342
|
url: /hacsfiles/button-card/button-card.js?hacstag=146194325342
|
||||||
|
- id: 9675930fcc78426396cc7c66b614f74c
|
||||||
|
type: module
|
||||||
|
url: /hacsfiles/vpdchart-card/vpdchart-card.js?hacstag=540873855100
|
||||||
|
|
Loading…
Reference in New Issue