- alias: EE Read Envoy Battery id: ee_read_envoy_battery description: '' triggers: - trigger: homeassistant event: start - trigger: template value_template: '{{ states(this.entity_id) == "on" }}' for: hours: 0 minutes: 0 seconds: 1 conditions: [] actions: - repeat: sequence: - variables: request_time: '{{ now() }}' response: status: timeout - action: rest_command.read_envoy_batteries continue_on_error: true metadata: {} data: {} response_variable: response - variables: response_time: '{{ now() }}' latency: '{{ response_time | as_timestamp - request_time | as_timestamp }}' - action: notify.persistent_notification metadata: {} data: message: '{{ response }}' enabled: false - if: - condition: template value_template: "{{\n response is not defined or response.status == 'timeout'\ \ or\n response.status | int(0) = 200\n}}" then: - action: notify.persistent_notification metadata: {} data: message: '{{ now().strftime("%m/%d %H:%M:%S") }} -- Read Battery -- {{ response.status | default(response) }}' - stop: Rest command failure error: true enabled: false - delay: hours: 0 minutes: 1 seconds: 0 milliseconds: 0 else: - variables: newline: ' ' content: '{{ response.content | replace(newline, '' '') }}' devices: '{{ content[''devices:''] }}' pwr_soc: "{% set ns = namespace(pwr=0,soc=0,batts=[]) %}\n{% for d in\ \ devices %}\n {% set ns.pwr = ns.pwr + d.real_power_mw %}\n {% set\ \ ns.soc = ns.soc + d.soc %}\n {% set ns.batts = ns.batts + [d.soc]\ \ %}\n {% set ns.batts = ns.batts + [(-d.real_power_mw)] %}\n{% endfor\ \ %}\n{{\n { \n \"pwr\": ns.pwr,\n \"soc\": ns.soc,\n \"num\"\ : devices | count,\n \"batts\": ns.batts\n }\n}}" flow: '{{ -pwr_soc.pwr }}' soc: '{{ pwr_soc.soc }}' socpct: '{{ soc / pwr_soc.num }}' batts: '{{ pwr_soc.batts }}' - action: input_number.set_value metadata: {} data: value: '{{ socpct | round(2) }}' target: entity_id: input_number.ee_observed_charge - action: input_text.set_value metadata: {} data: value: '{{ batts }}' target: entity_id: input_text.ee_observed_batteries - action: input_datetime.set_datetime metadata: {} data: time: '{{ now().strftime(''%H:%M:%S'') }}' target: entity_id: input_datetime.ee_envoy_battery_reporting_time - action: input_number.set_value metadata: {} data: value: '{{ (latency * 1000) | int }}' target: entity_id: input_number.ee_observed_envoy_read_battery_latency - delay: hours: 0 minutes: 0 seconds: 2 milliseconds: 0 count: 60 - action: automation.turn_off metadata: {} data: stop_actions: false target: entity_id: '{{ this.entity_id }}' - action: automation.turn_on metadata: {} data: {} target: entity_id: '{{ this.entity_id }}' mode: single - alias: EE Read Envoy Livedata id: ee_read_envoy_livedata description: '' triggers: - trigger: homeassistant event: start - trigger: template value_template: '{{ states(this.entity_id) == "on" }}' for: hours: 0 minutes: 0 seconds: 1 conditions: [] actions: - repeat: sequence: - variables: request_time: '{{ now() }}' response: status: timeout - action: rest_command.read_envoy_livedata_status continue_on_error: true metadata: {} data: {} response_variable: response - variables: response_time: '{{ now() }}' just_now: '{{ (response_time | as_datetime).strftime("%H:%M:%S") }}' latency: '{{ response_time | as_timestamp - request_time | as_timestamp }}' - action: notify.persistent_notification metadata: {} data: message: '{{ response }}' enabled: false - if: - condition: template value_template: "{{\n response is not defined or response.status == 'timeout'\ \ or\n response.status | int(0) = 200\n}}" then: - action: notify.persistent_notification metadata: {} data: message: '{{ now().strftime("%m/%d %H:%M:%S") }} -- Read Livedata -- {{ response.status | default(response) }}' - stop: Rest command failed error: true enabled: false - delay: hours: 0 minutes: 1 seconds: 0 milliseconds: 0 else: - variables: content: '{{ response.content }}' connection: '{{ content.connection }}' sc_stream: '{{ connection.sc_stream }}' - if: - condition: template value_template: '{{ sc_stream = ''enabled'' }}' then: - action: rest_command.envoy_enable_livedata_stream metadata: {} data: {} response_variable: response - action: notify.persistent_notification metadata: {} data: message: '{{ now().strftime("%m/%d %H:%M:%S") }} Enabling Stream ' - delay: hours: 0 minutes: 1 seconds: 0 milliseconds: 0 else: - variables: meters: '{{ content.meters }}' last_update: '{{ meters.last_update }}' solar_production: '{{ meters.pv.agg_p_mw }}' net_consumption: '{{ meters.grid.agg_p_mw }}' battery_flow: '{{ - meters.storage.agg_p_mw }}' home_load: '{{ meters.load.agg_p_mw }}' total_consumption: '{{ home_load + battery_flow }}' - action: input_number.set_value metadata: {} data: value: '{{ battery_flow }}' target: entity_id: input_number.ee_observed_battery_flow enabled: true - action: input_number.set_value metadata: {} data: value: '{{ solar_production }}' target: entity_id: input_number.ee_observed_solar_production - action: input_number.set_value metadata: {} data: value: '{{ net_consumption }}' target: entity_id: input_number.ee_observed_net_consumption - action: input_number.set_value metadata: {} data: value: '{{ total_consumption }}' target: entity_id: input_number.ee_observed_total_consumption - action: input_number.set_value metadata: {} data: value: '{{ home_load }}' target: entity_id: input_number.ee_observed_home_load - action: input_datetime.set_datetime metadata: {} data: time: '{{ just_now }}' target: entity_id: input_datetime.ee_envoy_pc_reporting_time - action: input_number.set_value metadata: {} data: value: '{{ (latency * 1000) | int }}' target: entity_id: input_number.ee_observed_envoy_read_livedata_latency - action: notify.persistent_notification metadata: {} data: message: '{{ last_update | as_datetime }}' enabled: false - delay: hours: 0 minutes: 0 seconds: 1 milliseconds: 0 count: 60 - action: automation.turn_off metadata: {} data: stop_actions: false target: entity_id: '{{ this.entity_id }}' - action: automation.turn_on metadata: {} data: {} target: entity_id: '{{ this.entity_id }}' mode: single - alias: EE Read Envoy Relay id: ee_read_envoy_relay description: '' triggers: - trigger: time_pattern minutes: /1 conditions: [] actions: - action: rest_command.read_envoy_relay metadata: {} data: {} response_variable: envoy_ivp_ensemble_relay - variables: content: '{{ envoy_ivp_ensemble_relay.content }}' grid: '{{ content.mains_oper_state }}' - action: input_text.set_value metadata: {} data: value: '{{ grid }}' target: entity_id: input_text.ee_observed_grid_status mode: single - alias: EE Read Envoy Tariff id: ee_read_envoy_tariff description: '' triggers: - trigger: time_pattern minutes: /1 conditions: [] actions: - action: rest_command.read_envoy_tariff metadata: {} data: {} response_variable: response - action: script.ee_decode_tariff metadata: {} data: response: '{{ response }}' mode: single - alias: EE Read Envoy XML Info id: ee_read_envoy_xml_info description: '' triggers: - trigger: time_pattern hours: /12 conditions: [] actions: - action: rest_command.read_envoy_relay metadata: {} data: {} response_variable: envoy_ivp_ensemble_relay enabled: false - variables: content: '{{ envoy_ivp_ensemble_relay.content }}' grid: '{{ content.mains_oper_state == "closed" }}' enabled: false - action: rest_command.read_envoy_xml_info metadata: {} data: {} response_variable: envoy_info_xml - variables: xml_text: '{{ envoy_info_xml.content }}' time_tag: '{{ xml_text | regex_findall_index("") }}' time: '{{ time_tag[6:-7] }}' software_tag: '{{ xml_text | regex_findall_index(".*") }}' vers: '{{ software_tag[10:-11] }}' enabled: false - variables: xml_text: '{{ envoy_info_xml.content }}' software_tag: '{{ xml_text | regex_findall_index(".*") }}' vers: '{{ software_tag[10:-11] }}' - action: input_text.set_value metadata: {} data: value: '{{ vers }}' target: entity_id: input_text.ee_observed_vers mode: single - alias: EE Set Hour of Day description: '' triggers: - trigger: time_pattern hours: /1 - trigger: homeassistant event: start conditions: [] actions: - action: input_number.set_value metadata: {} data: value: '{{ now().hour }}' target: entity_id: input_number.ee_hour_of_day mode: single - alias: EE Set is TOU Workday id: ee_set_is_tou_workday description: Determine todays rates as to workday or holiday triggers: - trigger: time at: 00:15:00 - trigger: homeassistant event: start conditions: [] actions: - if: - condition: or conditions: - condition: time weekday: - sun - sat - condition: template value_template: '{{ states("calendar.utility_tou_holidays") == "on" }}' then: - action: input_boolean.turn_off metadata: {} data: {} target: entity_id: input_boolean.ee_solar_is_tou_workday else: - action: input_boolean.turn_on metadata: {} data: {} target: entity_id: input_boolean.ee_solar_is_tou_workday - variables: tidx: '{{ trigger.idx }}' - if: - condition: template value_template: '{{ tidx = 0 }}' then: - action: automation.turn_off metadata: {} data: stop_actions: true target: entity_id: - automation.ee_while_zn - automation.ee_while_dl - automation.ee_while_cp - action: automation.turn_on metadata: {} data: {} target: entity_id: automation.ee_while_cp - delay: hours: 0 minutes: 0 seconds: 5 milliseconds: 0 - action: automation.trigger metadata: {} data: skip_condition: true target: entity_id: - automation.ee_read_envoy_tariff - delay: hours: 0 minutes: 0 seconds: 5 milliseconds: 0 - action: automation.trigger metadata: {} data: skip_condition: true target: entity_id: - automation.ee_read_envoy_relay - delay: hours: 0 minutes: 0 seconds: 5 milliseconds: 0 - action: automation.trigger metadata: {} data: skip_condition: true target: entity_id: - automation.ee_read_envoy_xml_info mode: single - alias: EE While CP id: ee_while_cp description: '' triggers: - trigger: template value_template: "{{\n (states('input_text.ee_observed_tariff') == 'CP' or\n \ \ states('input_text.ee_observed_tariff') == 'ZN' or \n states('input_text.ee_observed_tariff')\ \ == 'DL') and \n states('input_number.ee_observed_solar_production') | float\ \ >= 100000 and\n states(this.entity_id) == 'on'\n}}" for: hours: 0 minutes: 0 seconds: 20 - trigger: time at: '16:45:00' conditions: [] actions: - variables: new_reserve: '{{ states(''sensor.ee_desired_battery_reserve'') | int }}' workday: '{{ states(''input_boolean.ee_solar_is_tou_workday'') == ''on'' }}' dl_time: '{% set yetz = now () %} {% set hr = yetz.hour * 100 + yetz.minute %} {{ hr >= 1644 }}' observed_tariff: '{{ states(''input_text.ee_observed_tariff'') }}' observed_production: '{{ states(''input_number.ee_observed_solar_production'') }}' - if: - condition: template value_template: '{{ workday and dl_time }}' then: - action: automation.turn_off metadata: {} data: stop_actions: false target: entity_id: '{{ this.entity_id }}' - action: automation.turn_on metadata: {} data: {} target: entity_id: automation.ee_while_dl else: - variables: response: status: timeout attempts: 0 - repeat: sequence: - if: - condition: template value_template: '{{ attempts > 0 }}' then: - if: - condition: template value_template: '{{ attempts < 10 }}' then: - delay: hours: 0 minutes: 0 seconds: 2 milliseconds: 0 else: - delay: hours: 0 minutes: 30 seconds: 0 milliseconds: 0 - action: notify.persistent_notification metadata: {} data: message: 'Tariff change fails (CP) {{ attempts }} {{ now().strftime(''%m/%d %H:%M:%S'') }}' - action: rest_command.send_envoy_param_tariff continue_on_error: true metadata: {} data: peak_rule: ZN peak_start: 420 peak_end: 1141 reserve: '{{ new_reserve }}' response_variable: response - variables: attempts: '{{ attempts + 1 }}' while: - condition: template value_template: '{{ attempts == 0 or response.status | int(0) = 200 and attempts < 100 }}' - action: script.ee_decode_tariff metadata: {} data: response: '{{ response }}' - delay: hours: 0 minutes: 1 seconds: 0 milliseconds: 0 - action: automation.turn_off metadata: {} data: stop_actions: false target: entity_id: '{{ this.entity_id }}' - action: automation.turn_on metadata: {} data: {} target: entity_id: automation.ee_while_zn mode: single - alias: EE While DL id: ee_while_dl description: '' triggers: - trigger: time at: '20:02:00' conditions: [] actions: - action: automation.turn_off metadata: {} data: stop_actions: false target: entity_id: '{{ this.entity_id }}' - action: automation.turn_on metadata: {} data: {} target: entity_id: automation.ee_while_cp mode: single - alias: EE While ZN id: ee_while_zn description: '' triggers: - alias: Climb Reserve in ZN trigger: template value_template: "{{\n states('input_text.ee_observed_tariff') == 'ZN' and \n\ \ states('input_number.ee_observed_tariff_battery_reserve') | float = states('sensor.ee_desired_battery_reserve')\ \ | float and\n states(this.entity_id) == 'on'\n}}" for: hours: 0 minutes: 0 seconds: 20 - alias: Drop out of ZN trigger: template value_template: "{{\n states('input_text.ee_observed_tariff') == 'ZN' and\n \ \ states('input_number.ee_observed_solar_production') | int < 50000 and\n states(this.entity_id)\ \ == 'on'\n}}" for: hours: 0 minutes: 0 seconds: 45 - alias: Ready for DL trigger: time at: '16:45:00' conditions: [] actions: - variables: tidx: '{{ trigger.idx }}' workday: '{{ states(''input_boolean.ee_solar_is_tou_workday'') == ''on'' }}' observed_tariff: '{{ states(''input_text.ee_observed_tariff'') }}' observed_production: '{{ states(''input_number.ee_observed_solar_production'') }}' - if: - alias: Climb Trigger? condition: template value_template: '{{ tidx == 0 }}' then: - variables: tariff: "{{\n { \n \"time\" : now().timestamp() | int,\n \"peak_rule\"\ : \"ZN\",\n \"peak_start\": 420,\n \"peak_end\": 1141,\n \"reserve\"\ : states('sensor.ee_desired_battery_reserve') | float \n }\n}}" else: - if: - condition: template value_template: '{{ tidx == 2 and not workday }}' then: - stop: It is 4:45pm but not workday - variables: tariff: "{{\n { \n \"time\" : now().timestamp() | int,\n \"peak_rule\"\ : \"DL\",\n \"peak_start\": 1021 if workday else 780,\n \"peak_end\"\ : 1201 if workday else 785,\n \"reserve\": min(50, states('input_number.ee_observed_charge')\ \ | int)\n }\n}}" - action: automation.turn_off metadata: {} data: stop_actions: false target: entity_id: '{{ this.entity_id }}' - if: - condition: and conditions: - condition: template value_template: '{{ workday }}' - condition: time after: '16:44:00' then: - action: automation.turn_on metadata: {} data: {} target: entity_id: automation.ee_while_dl else: - action: automation.turn_on metadata: {} data: {} target: entity_id: automation.ee_while_cp - variables: response: status: timeout attempts: 0 - repeat: sequence: - if: - condition: template value_template: '{{ attempts > 0 }}' then: - if: - condition: template value_template: '{{ attempts < 10 }}' then: - delay: hours: 0 minutes: 0 seconds: 2 milliseconds: 0 else: - delay: hours: 0 minutes: 30 seconds: 0 milliseconds: 0 - action: notify.persistent_notification metadata: {} data: message: 'Tariff change fails (ZN) {{ attempts }} {{ now().strftime(''%m/%d %H:%M:%S'') }}' - action: rest_command.send_envoy_param_tariff continue_on_error: true metadata: {} data: '{{ tariff }}' response_variable: response - variables: attempts: '{{ attempts + 1 }}' while: - condition: template value_template: "{{ \n attempts == 0 or \n response.status | int(0) = 200\ \ and attempts < 100\n}}" - action: script.ee_decode_tariff metadata: {} data: response: '{{ response }}' mode: single - alias: EE Read Envoy Battery id: ee_read_envoy_battery description: '' triggers: - trigger: homeassistant event: start - trigger: template value_template: '{{ states(this.entity_id) == "on" }}' for: hours: 0 minutes: 0 seconds: 1 conditions: [] actions: - repeat: sequence: - variables: request_time: '{{ now() }}' response: status: timeout - action: rest_command.read_envoy_batteries continue_on_error: true metadata: {} data: {} response_variable: response - variables: response_time: '{{ now() }}' latency: '{{ response_time | as_timestamp - request_time | as_timestamp }}' - action: notify.persistent_notification metadata: {} data: message: '{{ response }}' enabled: false - if: - condition: template value_template: "{{\n response is not defined or response.status == 'timeout'\ \ or\n response.status | int(0) = 200\n}}" then: - action: notify.persistent_notification metadata: {} data: message: '{{ now().strftime("%m/%d %H:%M:%S") }} -- Read Battery -- {{ response.status | default(response) }}' - stop: Rest command failure error: true enabled: false - delay: hours: 0 minutes: 1 seconds: 0 milliseconds: 0 else: - variables: newline: ' ' content: '{{ response.content | replace(newline, '' '') }}' devices: '{{ content[''devices:''] }}' pwr_soc: "{% set ns = namespace(pwr=0,soc=0,batts=[]) %}\n{% for d in\ \ devices %}\n {% set ns.pwr = ns.pwr + d.real_power_mw %}\n {% set\ \ ns.soc = ns.soc + d.soc %}\n {% set ns.batts = ns.batts + [d.soc]\ \ %}\n {% set ns.batts = ns.batts + [(-d.real_power_mw)] %}\n{% endfor\ \ %}\n{{\n { \n \"pwr\": ns.pwr,\n \"soc\": ns.soc,\n \"num\"\ : devices | count,\n \"batts\": ns.batts\n }\n}}" flow: '{{ -pwr_soc.pwr }}' soc: '{{ pwr_soc.soc }}' socpct: '{{ soc / pwr_soc.num }}' batts: '{{ pwr_soc.batts }}' - action: input_number.set_value metadata: {} data: value: '{{ socpct | round(2) }}' target: entity_id: input_number.ee_observed_charge - action: input_text.set_value metadata: {} data: value: '{{ batts }}' target: entity_id: input_text.ee_observed_batteries - action: input_datetime.set_datetime metadata: {} data: time: '{{ now().strftime(''%H:%M:%S'') }}' target: entity_id: input_datetime.ee_envoy_battery_reporting_time - action: input_number.set_value metadata: {} data: value: '{{ (latency * 1000) | int }}' target: entity_id: input_number.ee_observed_envoy_read_battery_latency - delay: hours: 0 minutes: 0 seconds: 2 milliseconds: 0 count: 60 - action: automation.turn_off metadata: {} data: stop_actions: false target: entity_id: '{{ this.entity_id }}' - action: automation.turn_on metadata: {} data: {} target: entity_id: '{{ this.entity_id }}' mode: single - alias: EE Read Envoy Livedata id: ee_read_envoy_livedata description: '' triggers: - trigger: homeassistant event: start - trigger: template value_template: '{{ states(this.entity_id) == "on" }}' for: hours: 0 minutes: 0 seconds: 1 conditions: [] actions: - repeat: sequence: - variables: request_time: '{{ now() }}' response: status: timeout - action: rest_command.read_envoy_livedata_status continue_on_error: true metadata: {} data: {} response_variable: response - variables: response_time: '{{ now() }}' just_now: '{{ (response_time | as_datetime).strftime("%H:%M:%S") }}' latency: '{{ response_time | as_timestamp - request_time | as_timestamp }}' - action: notify.persistent_notification metadata: {} data: message: '{{ response }}' enabled: false - if: - condition: template value_template: "{{\n response is not defined or response.status == 'timeout'\ \ or\n response.status | int(0) = 200\n}}" then: - action: notify.persistent_notification metadata: {} data: message: '{{ now().strftime("%m/%d %H:%M:%S") }} -- Read Livedata -- {{ response.status | default(response) }}' - stop: Rest command failed error: true enabled: false - delay: hours: 0 minutes: 1 seconds: 0 milliseconds: 0 else: - variables: content: '{{ response.content }}' connection: '{{ content.connection }}' sc_stream: '{{ connection.sc_stream }}' - if: - condition: template value_template: '{{ sc_stream = ''enabled'' }}' then: - action: rest_command.envoy_enable_livedata_stream metadata: {} data: {} response_variable: response - action: notify.persistent_notification metadata: {} data: message: '{{ now().strftime("%m/%d %H:%M:%S") }} Enabling Stream ' - delay: hours: 0 minutes: 1 seconds: 0 milliseconds: 0 else: - variables: meters: '{{ content.meters }}' last_update: '{{ meters.last_update }}' solar_production: '{{ meters.pv.agg_p_mw }}' net_consumption: '{{ meters.grid.agg_p_mw }}' battery_flow: '{{ - meters.storage.agg_p_mw }}' home_load: '{{ meters.load.agg_p_mw }}' total_consumption: '{{ home_load + battery_flow }}' - action: input_number.set_value metadata: {} data: value: '{{ battery_flow }}' target: entity_id: input_number.ee_observed_battery_flow enabled: true - action: input_number.set_value metadata: {} data: value: '{{ solar_production }}' target: entity_id: input_number.ee_observed_solar_production - action: input_number.set_value metadata: {} data: value: '{{ net_consumption }}' target: entity_id: input_number.ee_observed_net_consumption - action: input_number.set_value metadata: {} data: value: '{{ total_consumption }}' target: entity_id: input_number.ee_observed_total_consumption - action: input_number.set_value metadata: {} data: value: '{{ home_load }}' target: entity_id: input_number.ee_observed_home_load - action: input_datetime.set_datetime metadata: {} data: time: '{{ just_now }}' target: entity_id: input_datetime.ee_envoy_pc_reporting_time - action: input_number.set_value metadata: {} data: value: '{{ (latency * 1000) | int }}' target: entity_id: input_number.ee_observed_envoy_read_livedata_latency - action: notify.persistent_notification metadata: {} data: message: '{{ last_update | as_datetime }}' enabled: false - delay: hours: 0 minutes: 0 seconds: 1 milliseconds: 0 count: 60 - action: automation.turn_off metadata: {} data: stop_actions: false target: entity_id: '{{ this.entity_id }}' - action: automation.turn_on metadata: {} data: {} target: entity_id: '{{ this.entity_id }}' mode: single - alias: EE Read Envoy Relay id: ee_read_envoy_relay description: '' triggers: - trigger: time_pattern minutes: /1 conditions: [] actions: - action: rest_command.read_envoy_relay metadata: {} data: {} response_variable: envoy_ivp_ensemble_relay - variables: content: '{{ envoy_ivp_ensemble_relay.content }}' grid: '{{ content.mains_oper_state }}' - action: input_text.set_value metadata: {} data: value: '{{ grid }}' target: entity_id: input_text.ee_observed_grid_status mode: single - alias: EE Read Envoy Tariff id: ee_read_envoy_tariff description: '' triggers: - trigger: time_pattern minutes: /1 conditions: [] actions: - action: rest_command.read_envoy_tariff metadata: {} data: {} response_variable: response - action: script.ee_decode_tariff metadata: {} data: response: '{{ response }}' mode: single - alias: EE Read Envoy XML Info id: ee_read_envoy_xml_info description: '' triggers: - trigger: time_pattern hours: /12 conditions: [] actions: - action: rest_command.read_envoy_relay metadata: {} data: {} response_variable: envoy_ivp_ensemble_relay enabled: false - variables: content: '{{ envoy_ivp_ensemble_relay.content }}' grid: '{{ content.mains_oper_state == "closed" }}' enabled: false - action: rest_command.read_envoy_xml_info metadata: {} data: {} response_variable: envoy_info_xml - variables: xml_text: '{{ envoy_info_xml.content }}' time_tag: '{{ xml_text | regex_findall_index("") }}' time: '{{ time_tag[6:-7] }}' software_tag: '{{ xml_text | regex_findall_index(".*") }}' vers: '{{ software_tag[10:-11] }}' enabled: false - variables: xml_text: '{{ envoy_info_xml.content }}' software_tag: '{{ xml_text | regex_findall_index(".*") }}' vers: '{{ software_tag[10:-11] }}' - action: input_text.set_value metadata: {} data: value: '{{ vers }}' target: entity_id: input_text.ee_observed_vers mode: single - alias: EE Read Envoy Battery id: ee_read_envoy_battery description: '' triggers: - trigger: homeassistant event: start - trigger: template value_template: '{{ states(this.entity_id) == "on" }}' for: hours: 0 minutes: 0 seconds: 1 conditions: [] actions: - repeat: sequence: - variables: request_time: '{{ now() }}' response: status: timeout - action: rest_command.read_envoy_batteries continue_on_error: true metadata: {} data: {} response_variable: response - variables: response_time: '{{ now() }}' latency: '{{ response_time | as_timestamp - request_time | as_timestamp }}' - action: notify.persistent_notification metadata: {} data: message: '{{ response }}' enabled: false - if: - condition: template value_template: "{{\n response is not defined or response.status == 'timeout'\ \ or\n response.status | int(0) != 200\n}}" then: - action: notify.persistent_notification metadata: {} data: message: '{{ now().strftime("%m/%d %H:%M:%S") }} -- Read Battery -- {{ response.status | default(response) }}' - stop: Rest command failure error: true enabled: false - delay: hours: 0 minutes: 1 seconds: 0 milliseconds: 0 else: - variables: newline: ' ' content: '{{ response.content | replace(newline, '' '') }}' devices: '{{ content[''devices:''] }}' pwr_soc: "{% set ns = namespace(pwr=0,soc=0,batts=[]) %}\n{% for d in\ \ devices %}\n {% set ns.pwr = ns.pwr + d.real_power_mw %}\n {% set\ \ ns.soc = ns.soc + d.soc %}\n {% set ns.batts = ns.batts + [d.soc]\ \ %}\n {% set ns.batts = ns.batts + [(-d.real_power_mw)] %}\n{% endfor\ \ %}\n{{\n { \n \"pwr\": ns.pwr,\n \"soc\": ns.soc,\n \"num\"\ : devices | count,\n \"batts\": ns.batts\n }\n}}" flow: '{{ -pwr_soc.pwr }}' soc: '{{ pwr_soc.soc }}' socpct: '{{ soc / pwr_soc.num }}' batts: '{{ pwr_soc.batts }}' - action: input_number.set_value metadata: {} data: value: '{{ socpct | round(2) }}' target: entity_id: input_number.ee_observed_charge - action: input_text.set_value metadata: {} data: value: '{{ batts }}' target: entity_id: input_text.ee_observed_batteries - action: input_datetime.set_datetime metadata: {} data: time: '{{ now().strftime(''%H:%M:%S'') }}' target: entity_id: input_datetime.ee_envoy_battery_reporting_time - action: input_number.set_value metadata: {} data: value: '{{ (latency * 1000) | int }}' target: entity_id: input_number.ee_observed_envoy_read_battery_latency - delay: hours: 0 minutes: 0 seconds: 2 milliseconds: 0 count: 60 - action: automation.turn_off metadata: {} data: stop_actions: false target: entity_id: '{{ this.entity_id }}' - action: automation.turn_on metadata: {} data: {} target: entity_id: '{{ this.entity_id }}' mode: single - alias: EE Read Envoy Livedata id: ee_read_envoy_livedata description: '' triggers: - trigger: homeassistant event: start - trigger: template value_template: '{{ states(this.entity_id) == "on" }}' for: hours: 0 minutes: 0 seconds: 1 conditions: [] actions: - repeat: sequence: - variables: request_time: '{{ now() }}' response: status: timeout - action: rest_command.read_envoy_livedata_status continue_on_error: true metadata: {} data: {} response_variable: response - variables: response_time: '{{ now() }}' just_now: '{{ (response_time | as_datetime).strftime("%H:%M:%S") }}' latency: '{{ response_time | as_timestamp - request_time | as_timestamp }}' - action: notify.persistent_notification metadata: {} data: message: '{{ response }}' enabled: false - if: - condition: template value_template: "{{\n response is not defined or response.status == 'timeout'\ \ or\n response.status | int(0) != 200\n}}" then: - action: notify.persistent_notification metadata: {} data: message: '{{ now().strftime("%m/%d %H:%M:%S") }} -- Read Livedata -- {{ response.status | default(response) }}' - stop: Rest command failed error: true enabled: false - delay: hours: 0 minutes: 1 seconds: 0 milliseconds: 0 else: - variables: content: '{{ response.content }}' connection: '{{ content.connection }}' sc_stream: '{{ connection.sc_stream }}' - if: - condition: template value_template: '{{ sc_stream != ''enabled'' }}' then: - action: rest_command.envoy_enable_livedata_stream metadata: {} data: {} response_variable: response - action: notify.persistent_notification metadata: {} data: message: '{{ now().strftime("%m/%d %H:%M:%S") }} Enabling Stream ' - delay: hours: 0 minutes: 1 seconds: 0 milliseconds: 0 else: - variables: meters: '{{ content.meters }}' last_update: '{{ meters.last_update }}' solar_production: '{{ meters.pv.agg_p_mw }}' net_consumption: '{{ meters.grid.agg_p_mw }}' battery_flow: '{{ - meters.storage.agg_p_mw }}' home_load: '{{ meters.load.agg_p_mw }}' total_consumption: '{{ home_load + battery_flow }}' - action: input_number.set_value metadata: {} data: value: '{{ battery_flow }}' target: entity_id: input_number.ee_observed_battery_flow enabled: true - action: input_number.set_value metadata: {} data: value: '{{ solar_production }}' target: entity_id: input_number.ee_observed_solar_production - action: input_number.set_value metadata: {} data: value: '{{ net_consumption }}' target: entity_id: input_number.ee_observed_net_consumption - action: input_number.set_value metadata: {} data: value: '{{ total_consumption }}' target: entity_id: input_number.ee_observed_total_consumption - action: input_number.set_value metadata: {} data: value: '{{ home_load }}' target: entity_id: input_number.ee_observed_home_load - action: input_datetime.set_datetime metadata: {} data: time: '{{ just_now }}' target: entity_id: input_datetime.ee_envoy_pc_reporting_time - action: input_number.set_value metadata: {} data: value: '{{ (latency * 1000) | int }}' target: entity_id: input_number.ee_observed_envoy_read_livedata_latency - action: notify.persistent_notification metadata: {} data: message: '{{ last_update | as_datetime }}' enabled: false - delay: hours: 0 minutes: 0 seconds: 1 milliseconds: 0 count: 60 - action: automation.turn_off metadata: {} data: stop_actions: false target: entity_id: '{{ this.entity_id }}' - action: automation.turn_on metadata: {} data: {} target: entity_id: '{{ this.entity_id }}' mode: single - alias: EE Read Envoy Relay id: ee_read_envoy_relay description: '' triggers: - trigger: time_pattern minutes: /1 conditions: [] actions: - action: rest_command.read_envoy_relay metadata: {} data: {} response_variable: envoy_ivp_ensemble_relay - variables: content: '{{ envoy_ivp_ensemble_relay.content }}' grid: '{{ content.mains_oper_state }}' - action: input_text.set_value metadata: {} data: value: '{{ grid }}' target: entity_id: input_text.ee_observed_grid_status mode: single - alias: EE Read Envoy Tariff id: ee_read_envoy_tariff description: '' triggers: - trigger: time_pattern minutes: /1 conditions: [] actions: - action: rest_command.read_envoy_tariff metadata: {} data: {} response_variable: response - action: script.ee_decode_tariff metadata: {} data: response: '{{ response }}' mode: single - alias: EE Read Envoy XML Info id: ee_read_envoy_xml_info description: '' triggers: - trigger: time_pattern hours: /12 conditions: [] actions: - action: rest_command.read_envoy_relay metadata: {} data: {} response_variable: envoy_ivp_ensemble_relay enabled: false - variables: content: '{{ envoy_ivp_ensemble_relay.content }}' grid: '{{ content.mains_oper_state == "closed" }}' enabled: false - action: rest_command.read_envoy_xml_info metadata: {} data: {} response_variable: envoy_info_xml - variables: xml_text: '{{ envoy_info_xml.content }}' time_tag: '{{ xml_text | regex_findall_index("") }}' time: '{{ time_tag[6:-7] }}' software_tag: '{{ xml_text | regex_findall_index(".*") }}' vers: '{{ software_tag[10:-11] }}' enabled: false - variables: xml_text: '{{ envoy_info_xml.content }}' software_tag: '{{ xml_text | regex_findall_index(".*") }}' vers: '{{ software_tag[10:-11] }}' - action: input_text.set_value metadata: {} data: value: '{{ vers }}' target: entity_id: input_text.ee_observed_vers mode: single - alias: EE Set Hour of Day description: '' triggers: - trigger: time_pattern hours: /1 - trigger: homeassistant event: start conditions: [] actions: - action: input_number.set_value metadata: {} data: value: '{{ now().hour }}' target: entity_id: input_number.ee_hour_of_day mode: single - alias: EE Set is TOU Workday id: ee_set_is_tou_workday description: Determine todays rates as to workday or holiday triggers: - trigger: time at: 00:15:00 - trigger: homeassistant event: start conditions: [] actions: - if: - condition: or conditions: - condition: time weekday: - sun - sat - condition: template value_template: '{{ states("calendar.utility_tou_holidays") == "on" }}' then: - action: input_boolean.turn_off metadata: {} data: {} target: entity_id: input_boolean.ee_solar_is_tou_workday else: - action: input_boolean.turn_on metadata: {} data: {} target: entity_id: input_boolean.ee_solar_is_tou_workday - variables: tidx: '{{ trigger.idx }}' - if: - condition: template value_template: '{{ tidx != 0 }}' then: - action: automation.turn_off metadata: {} data: stop_actions: true target: entity_id: - automation.ee_while_zn - automation.ee_while_dl - automation.ee_while_cp - action: automation.turn_on metadata: {} data: {} target: entity_id: automation.ee_while_cp - delay: hours: 0 minutes: 0 seconds: 5 milliseconds: 0 - action: automation.trigger metadata: {} data: skip_condition: true target: entity_id: - automation.ee_read_envoy_tariff - delay: hours: 0 minutes: 0 seconds: 5 milliseconds: 0 - action: automation.trigger metadata: {} data: skip_condition: true target: entity_id: - automation.ee_read_envoy_relay - delay: hours: 0 minutes: 0 seconds: 5 milliseconds: 0 - action: automation.trigger metadata: {} data: skip_condition: true target: entity_id: - automation.ee_read_envoy_xml_info mode: single - alias: EE While CP id: ee_while_cp description: '' triggers: - trigger: template value_template: "{{\n (states('input_text.ee_observed_tariff') == 'CP' or\n \ \ states('input_text.ee_observed_tariff') == 'ZN' or \n states('input_text.ee_observed_tariff')\ \ == 'DL') and \n states('input_number.ee_observed_solar_production') | float\ \ >= 100000 and\n states(this.entity_id) == 'on'\n}}" for: hours: 0 minutes: 0 seconds: 20 - trigger: time at: '16:45:00' conditions: [] actions: - variables: new_reserve: '{{ states(''sensor.ee_desired_battery_reserve'') | int }}' workday: '{{ states(''input_boolean.ee_solar_is_tou_workday'') == ''on'' }}' dl_time: '{% set yetz = now () %} {% set hr = yetz.hour * 100 + yetz.minute %} {{ hr >= 1644 }}' observed_tariff: '{{ states(''input_text.ee_observed_tariff'') }}' observed_production: '{{ states(''input_number.ee_observed_solar_production'') }}' - if: - condition: template value_template: '{{ workday and dl_time }}' then: - action: automation.turn_off metadata: {} data: stop_actions: false target: entity_id: '{{ this.entity_id }}' - action: automation.turn_on metadata: {} data: {} target: entity_id: automation.ee_while_dl else: - variables: response: status: timeout attempts: 0 - repeat: sequence: - if: - condition: template value_template: '{{ attempts > 0 }}' then: - if: - condition: template value_template: '{{ attempts < 10 }}' then: - delay: hours: 0 minutes: 0 seconds: 2 milliseconds: 0 else: - delay: hours: 0 minutes: 30 seconds: 0 milliseconds: 0 - action: notify.persistent_notification metadata: {} data: message: 'Tariff change fails (CP) {{ attempts }} {{ now().strftime(''%m/%d %H:%M:%S'') }}' - action: rest_command.send_envoy_param_tariff continue_on_error: true metadata: {} data: peak_rule: ZN peak_start: 420 peak_end: 1141 reserve: '{{ new_reserve }}' response_variable: response - variables: attempts: '{{ attempts + 1 }}' while: - condition: template value_template: '{{ attempts == 0 or response.status | int(0) != 200 and attempts < 100 }}' - action: script.ee_decode_tariff metadata: {} data: response: '{{ response }}' - delay: hours: 0 minutes: 1 seconds: 0 milliseconds: 0 - action: automation.turn_off metadata: {} data: stop_actions: false target: entity_id: '{{ this.entity_id }}' - action: automation.turn_on metadata: {} data: {} target: entity_id: automation.ee_while_zn mode: single - alias: EE While DL id: ee_while_dl description: '' triggers: - trigger: time at: '20:02:00' conditions: [] actions: - action: automation.turn_off metadata: {} data: stop_actions: false target: entity_id: '{{ this.entity_id }}' - action: automation.turn_on metadata: {} data: {} target: entity_id: automation.ee_while_cp mode: single - alias: EE While ZN id: ee_while_zn description: '' triggers: - alias: Climb Reserve in ZN trigger: template value_template: "{{\n states('input_text.ee_observed_tariff') == 'ZN' and \n\ \ states('input_number.ee_observed_tariff_battery_reserve') | float != states('sensor.ee_desired_battery_reserve')\ \ | float and\n states(this.entity_id) == 'on'\n}}" for: hours: 0 minutes: 0 seconds: 20 - alias: Drop out of ZN trigger: template value_template: "{{\n states('input_text.ee_observed_tariff') == 'ZN' and\n \ \ states('input_number.ee_observed_solar_production') | int < 50000 and\n states(this.entity_id)\ \ == 'on'\n}}" for: hours: 0 minutes: 0 seconds: 45 - alias: Ready for DL trigger: time at: '16:45:00' conditions: [] actions: - variables: tidx: '{{ trigger.idx }}' workday: '{{ states(''input_boolean.ee_solar_is_tou_workday'') == ''on'' }}' observed_tariff: '{{ states(''input_text.ee_observed_tariff'') }}' observed_production: '{{ states(''input_number.ee_observed_solar_production'') }}' - if: - alias: Climb Trigger? condition: template value_template: '{{ tidx == 0 }}' then: - variables: tariff: "{{\n { \n \"time\" : now().timestamp() | int,\n \"peak_rule\"\ : \"ZN\",\n \"peak_start\": 420,\n \"peak_end\": 1141,\n \"reserve\"\ : states('sensor.ee_desired_battery_reserve') | float \n }\n}}" else: - if: - condition: template value_template: '{{ tidx == 2 and not workday }}' then: - stop: It is 4:45pm but not workday - variables: tariff: "{{\n { \n \"time\" : now().timestamp() | int,\n \"peak_rule\"\ : \"DL\",\n \"peak_start\": 1021 if workday else 780,\n \"peak_end\"\ : 1201 if workday else 785,\n \"reserve\": min(50, states('input_number.ee_observed_charge')\ \ | int)\n }\n}}" - action: automation.turn_off metadata: {} data: stop_actions: false target: entity_id: '{{ this.entity_id }}' - if: - condition: and conditions: - condition: template value_template: '{{ workday }}' - condition: time after: '16:44:00' then: - action: automation.turn_on metadata: {} data: {} target: entity_id: automation.ee_while_dl else: - action: automation.turn_on metadata: {} data: {} target: entity_id: automation.ee_while_cp - variables: response: status: timeout attempts: 0 - repeat: sequence: - if: - condition: template value_template: '{{ attempts > 0 }}' then: - if: - condition: template value_template: '{{ attempts < 10 }}' then: - delay: hours: 0 minutes: 0 seconds: 2 milliseconds: 0 else: - delay: hours: 0 minutes: 30 seconds: 0 milliseconds: 0 - action: notify.persistent_notification metadata: {} data: message: 'Tariff change fails (ZN) {{ attempts }} {{ now().strftime(''%m/%d %H:%M:%S'') }}' - action: rest_command.send_envoy_param_tariff continue_on_error: true metadata: {} data: '{{ tariff }}' response_variable: response - variables: attempts: '{{ attempts + 1 }}' while: - condition: template value_template: "{{ \n attempts == 0 or \n response.status | int(0) != 200\ \ and attempts < 100\n}}" - action: script.ee_decode_tariff metadata: {} data: response: '{{ response }}' mode: single