Skip to content

Instantly share code, notes, and snippets.

@lwsrbrts
Last active September 5, 2024 09:16
Ecoflow Smart Home Panel MQTT and YAML
# Configuration
$ACCESS_KEY = "your access key from Ecoflow Dev portal"
$SECRET_KEY = "your secret key from Ecoflow Dev portal"
$endpoint = "https://api-e.ecoflow.com" # May be different! Check the Ecoflow Dev Portal for yours.
function Get-Timestamp {
return [int64](([datetime]::UtcNow - [datetime]'1970-01-01').TotalMilliseconds)
}
function Get-Nonce {
return (Get-Random -Minimum 100000 -Maximum 999999).ToString()
}
function Get-Signature {
param (
[string]$access_key,
[string]$secret_key,
[string]$nonce,
[string]$timestamp
)
# Sort parameters by ASCII value and concatenate them
$strToSign = "accessKey=$access_key&nonce=$nonce&timestamp=$timestamp"
# Create HMAC-SHA256 signature
$hmac = New-Object System.Security.Cryptography.HMACSHA256
$hmac.Key = [System.Text.Encoding]::UTF8.GetBytes($secret_key)
$signBytes = $hmac.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($strToSign))
$signature = -join ($signBytes | ForEach-Object { "{0:x2}" -f $_ })
return $signature
}
function Get-MqttConnectionData {
$nonce = Get-Nonce
$timestamp = Get-Timestamp
# Generate the signature
$sign = Get-Signature -access_key $ACCESS_KEY -secret_key $SECRET_KEY -nonce $nonce -timestamp $timestamp
$headers = @{
"accessKey" = $ACCESS_KEY
"nonce" = $nonce
"timestamp" = $timestamp
"sign" = $sign
}
# URL for querying device data
$url = "$endpoint/iot-open/sign/certification"
# Send request
return Invoke-RestMethod -Uri $url -Method Get -Headers $headers
}
$connectionData = Get-MqttConnectionData
$connectionData
connection ecoflow-bridge
address mqtt-e.ecoflow.com:8883 # Use address from $connectionData output of Get-MqttConnectionCredentials.ps1
remote_username {OBTAINED-FROM-Get-MqttConnectionCredentials.ps1 - certificateAccount}
remote_password {OBTAINED-FROM-Get-MqttConnectionCredentials.ps1 - certificatePassword}
cleansession true
remote_clientid {USE-SOMETHING-UNIQUE}
try_private true
start_type automatic
restart_timeout 30 180
persistence true
bridge_insecure false
bridge_protocol_version mqttv311
bridge_tls_version tlsv1.2
bridge_cafile /etc/ssl/certs/ca-certificates.crt
# Smart Home Panel - {CERTIFICATEACCOUNT} comes from Get-MqttConnectionCredentials.ps1
topic "" in 0 ecoflow/SHP/data /open/{CERTIFICATEACCOUNT}/{SMARTHOMEPANELSERIAL}/quota
topic "" both 0 ecoflow/SHP/set /open/{CERTIFICATEACCOUNT}/{SMARTHOMEPANELSERIAL}/set
###
# Energy Dashboard
###
sensor:
- platform: integration
source: sensor.shp_circuit_1_power
name: SHP Circuit 1 Consumed Energy
unit_prefix: k
round: 3
- platform: integration
source: sensor.shp_circuit_2_power
name: SHP Circuit 2 Consumed Energy
unit_prefix: k
round: 3
- platform: integration
source: sensor.shp_circuit_3_power
name: SHP Circuit 3 Consumed Energy
unit_prefix: k
round: 3
- platform: integration
source: sensor.shp_circuit_4_power
name: SHP Circuit 4 Consumed Energy
unit_prefix: k
round: 3
- platform: integration
source: sensor.shp_circuit_5_power
name: SHP Circuit 5 Consumed Energy
unit_prefix: k
round: 3
- platform: integration
source: sensor.shp_circuit_6_power
name: SHP Circuit 6 Consumed Energy
unit_prefix: k
round: 3
- platform: integration
source: sensor.shp_circuit_7_power
name: SHP Circuit 7 Consumed Energy
unit_prefix: k
round: 3
method: left # regular spikes
- platform: integration
source: sensor.shp_circuit_8_power
name: SHP Circuit 8 Consumed Energy
unit_prefix: k
round: 3
- platform: integration
source: sensor.shp_circuit_9_power
name: SHP Circuit 9 Consumed Energy
unit_prefix: k
round: 3
- platform: integration
source: sensor.shp_circuit_10_power
name: SHP Circuit 10 Consumed Energy
unit_prefix: k
round: 3
method: left # regular spikes
###
# MQTT Sensors
###
mqtt:
binary_sensor:
- name: SHP Grid Available
object_id: shp_grid_available
unique_id: shp_grid_available
state_topic: ecoflow/SHP/data
qos: 0
device_class: connectivity
payload_on: "1"
payload_off: "0"
value_template: "{{ value_json.params.heartbeat.gridSta if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Delta Pro 1 Connected
object_id: shp_delta_pro_1_connected
unique_id: shp_delta_pro_1_connected
state_topic: ecoflow/SHP/data
qos: 0
device_class: connectivity
payload_on: "1"
payload_off: "0"
value_template: "{{ value_json.params.heartbeat.energyInfos[0].stateBean.isConnect if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Delta Pro 1 Enabled
object_id: shp_delta_pro_1_enabled
unique_id: shp_delta_pro_1_enabled
state_topic: ecoflow/SHP/data
qos: 0
device_class: connectivity
payload_on: "1"
payload_off: "0"
value_template: "{{ value_json.params.heartbeat.energyInfos[0].stateBean.isEnable if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Delta Pro 2 Connected
object_id: shp_delta_pro_2_connected
unique_id: shp_delta_pro_2_connected
state_topic: ecoflow/SHP/data
qos: 0
device_class: connectivity
payload_on: "1"
payload_off: "0"
value_template: "{{ value_json.params.heartbeat.energyInfos[1].stateBean.isConnect if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Delta Pro 2 Enabled
object_id: shp_delta_pro_2_enabled
unique_id: shp_delta_pro_2_enabled
state_topic: ecoflow/SHP/data
qos: 0
device_class: connectivity
payload_on: "1"
payload_off: "0"
value_template: "{{ value_json.params.heartbeat.energyInfos[1].stateBean.isEnable if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP AC1 Grid Charging
object_id: shp_ac1_grid_charging
unique_id: shp_ac1_grid_charging
state_topic: ecoflow/SHP/data
payload_on: "1"
payload_off: "0"
qos: 0
value_template: "{{ value_json.params.heartbeat.energyInfos[0].stateBean.isGridCharge if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP AC2 Grid Charging
object_id: shp_ac2_grid_charging
unique_id: shp_ac2_grid_charging
state_topic: ecoflow/SHP/data
payload_on: "1"
payload_off: "0"
qos: 0
value_template: "{{ value_json.params.heartbeat.energyInfos[1].stateBean.isGridCharge if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP EPS Enabled
object_id: shp_eps_enabled
unique_id: shp_eps_enabled
state_topic: ecoflow/SHP/eps
qos: 0
value_template: >-
{% set id = value_json.params.id %}
{% set eps = value_json.params.eps %}
{% if (id==24) and (eps is defined) %}{{(eps==true)|iif('ON','OFF')}}{%else%}{{this.state}}{%endif%}
- name: SHP Circuit 1 Auto
object_id: shp_circuit_1_auto
unique_id: shp_circuit_1_auto
state_topic: ecoflow/SHP/data
payload_on: "0"
payload_off: "1"
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[0].ctrlMode if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 2 Auto
object_id: shp_circuit_2_auto
unique_id: shp_circuit_2_auto
state_topic: ecoflow/SHP/data
payload_on: "0"
payload_off: "1"
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[1].ctrlMode if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 3 Auto
object_id: shp_circuit_3_auto
unique_id: shp_circuit_3_auto
state_topic: ecoflow/SHP/data
payload_on: "0"
payload_off: "1"
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[2].ctrlMode if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 4 Auto
object_id: shp_circuit_4_auto
unique_id: shp_circuit_4_auto
state_topic: ecoflow/SHP/data
payload_on: "0"
payload_off: "1"
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[3].ctrlMode if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 5 Auto
object_id: shp_circuit_5_auto
unique_id: shp_circuit_5_auto
state_topic: ecoflow/SHP/data
payload_on: "0"
payload_off: "1"
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[4].ctrlMode if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 6 Auto
object_id: shp_circuit_6_auto
unique_id: shp_circuit_6_auto
state_topic: ecoflow/SHP/data
payload_on: "0"
payload_off: "1"
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[5].ctrlMode if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 7 Auto
object_id: shp_circuit_7_auto
unique_id: shp_circuit_7_auto
state_topic: ecoflow/SHP/data
payload_on: "0"
payload_off: "1"
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[6].ctrlMode if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 8 Auto
object_id: shp_circuit_8_auto
unique_id: shp_circuit_8_auto
state_topic: ecoflow/SHP/data
payload_on: "0"
payload_off: "1"
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[7].ctrlMode if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 9 Auto
object_id: shp_circuit_9_auto
unique_id: shp_circuit_9_auto
state_topic: ecoflow/SHP/data
payload_on: "0"
payload_off: "1"
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[8].ctrlMode if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 10 Auto
object_id: shp_circuit_10_auto
unique_id: shp_circuit_10_auto
state_topic: ecoflow/SHP/data
payload_on: "0"
payload_off: "1"
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[9].ctrlMode if value_json['params']['heartbeat'] is defined else this.state }}"
sensor:
- name: SHP Circuit 1 State
object_id: shp_circuit_1_state
unique_id: shp_circuit_1_state
state_topic: ecoflow/SHP/data
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[0].ctrlSta if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 2 State
object_id: shp_circuit_2_state
unique_id: shp_circuit_2_state
state_topic: ecoflow/SHP/data
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[1].ctrlSta if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 3 State
object_id: shp_circuit_3_state
unique_id: shp_circuit_3_state
state_topic: ecoflow/SHP/data
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[2].ctrlSta if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 4 State
object_id: shp_circuit_4_state
unique_id: shp_circuit_4_state
state_topic: ecoflow/SHP/data
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[3].ctrlSta if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 5 State
object_id: shp_circuit_5_state
unique_id: shp_circuit_5_state
state_topic: ecoflow/SHP/data
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[4].ctrlSta if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 6 State
object_id: shp_circuit_6_state
unique_id: shp_circuit_6_state
state_topic: ecoflow/SHP/data
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[5].ctrlSta if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 7 State
object_id: shp_circuit_7_state
unique_id: shp_circuit_7_state
state_topic: ecoflow/SHP/data
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[6].ctrlSta if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 8 State
object_id: shp_circuit_8_state
unique_id: shp_circuit_8_state
state_topic: ecoflow/SHP/data
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[7].ctrlSta if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 9 State
object_id: shp_circuit_9_state
unique_id: shp_circuit_9_state
state_topic: ecoflow/SHP/data
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[8].ctrlSta if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 10 State
object_id: shp_circuit_10_state
unique_id: shp_circuit_10_state
state_topic: ecoflow/SHP/data
qos: 0
value_template: "{{ value_json.params.heartbeat.loadCmdChCtrlInfos[9].ctrlSta if value_json['params']['heartbeat'] is defined else this.state }}"
- name: SHP Circuit 1 Power
state_topic: ecoflow/SHP/data
object_id: shp_circuit_1_power
unique_id: shp_circuit_1_power
qos: 0
device_class: power
unit_of_measurement: "W"
state_class: measurement
value_template: "{{ value_json.params.infoList[0].chWatt | round(0) if value_json['params']['infoList'] is defined else this.state }}"
- name: SHP Circuit 2 Power
state_topic: ecoflow/SHP/data
object_id: shp_circuit_2_power
unique_id: shp_circuit_2_power
qos: 0
device_class: power
unit_of_measurement: "W"
state_class: measurement
value_template: "{{ value_json.params.infoList[1].chWatt | round(0) if value_json['params']['infoList'] is defined else this.state }}"
- name: SHP Circuit 3 Power
state_topic: ecoflow/SHP/data
object_id: shp_circuit_3_power
unique_id: shp_circuit_3_power
qos: 0
device_class: power
unit_of_measurement: "W"
state_class: measurement
value_template: "{{ value_json.params.infoList[2].chWatt | round(0) if value_json['params']['infoList'] is defined else this.state }}"
- name: SHP Circuit 4 Power
state_topic: ecoflow/SHP/data
object_id: shp_circuit_4_power
unique_id: shp_circuit_4_power
qos: 0
device_class: power
unit_of_measurement: "W"
state_class: measurement
value_template: "{{ value_json.params.infoList[3].chWatt | round(0) if value_json['params']['infoList'] is defined else this.state }}"
- name: SHP Circuit 5 Power
state_topic: ecoflow/SHP/data
object_id: shp_circuit_5_power
unique_id: shp_circuit_5_power
qos: 0
device_class: power
unit_of_measurement: "W"
state_class: measurement
value_template: "{{ value_json.params.infoList[4].chWatt | round(0) if value_json['params']['infoList'] is defined else this.state }}"
- name: SHP Circuit 6 Power
state_topic: ecoflow/SHP/data
object_id: shp_circuit_6_power
unique_id: shp_circuit_6_power
qos: 0
device_class: power
unit_of_measurement: "W"
state_class: measurement
value_template: "{{ value_json.params.infoList[5].chWatt | round(0) if value_json['params']['infoList'] is defined else this.state }}"
- name: SHP Circuit 7 Power
state_topic: ecoflow/SHP/data
object_id: shp_circuit_7_power
unique_id: shp_circuit_7_power
qos: 0
device_class: power
unit_of_measurement: "W"
state_class: measurement
value_template: "{{ value_json.params.infoList[6].chWatt | round(0) if value_json['params']['infoList'] is defined else this.state }}"
- name: SHP Circuit 8 Power
state_topic: ecoflow/SHP/data
object_id: shp_circuit_8_power
unique_id: shp_circuit_8_power
qos: 0
device_class: power
unit_of_measurement: "W"
state_class: measurement
value_template: "{{ value_json.params.infoList[7].chWatt | round(0) if value_json['params']['infoList'] is defined else this.state }}"
- name: SHP Circuit 9 Power
state_topic: ecoflow/SHP/data
object_id: shp_circuit_9_power
unique_id: shp_circuit_9_power
qos: 0
device_class: power
unit_of_measurement: "W"
state_class: measurement
value_template: "{{ value_json.params.infoList[8].chWatt | round(0) if value_json['params']['infoList'] is defined else this.state }}"
- name: SHP Circuit 10 Power
state_topic: ecoflow/SHP/data
object_id: shp_circuit_10_power
unique_id: shp_circuit_10_power
qos: 0
device_class: power
unit_of_measurement: "W"
state_class: measurement
value_template: "{{ value_json.params.infoList[9].chWatt | round(0) if value_json['params']['infoList'] is defined else this.state }}"
- name: SHP Delta Pro 1 Power
state_topic: ecoflow/SHP/data
object_id: shp_delta_pro_1_power
unique_id: shp_delta_pro_1_power
qos: 0
device_class: power
unit_of_measurement: "W"
state_class: measurement
value_template: "{{ value_json.params.infoList[10].chWatt | round(0) if value_json['params']['infoList'] is defined else this.state }}"
json_attributes_topic: ecoflow/SHP/data
json_attributes_template: "{{ value_json.params.infoList[10] | tojson if value_json['params']['infoList'] is defined else (states.sensor.shp_delta_pro_1_power.attributes | tojson) }}"
- name: SHP Delta Pro 2 Power
state_topic: ecoflow/SHP/data
object_id: shp_delta_pro_2_power
unique_id: shp_delta_pro_2_power
qos: 0
device_class: power
unit_of_measurement: "W"
state_class: measurement
value_template: "{{ value_json.params.infoList[11].chWatt | round(0) if value_json['params']['infoList'] is defined else this.state }}"
json_attributes_topic: ecoflow/SHP/data
json_attributes_template: "{{ value_json.params.infoList[11] | tojson if value_json['params']['infoList'] is defined else (states.sensor.shp_delta_pro_2_power.attributes | tojson) }}"
- name: SHP AC1 Battery Percentage
state_topic: ecoflow/SHP/data
unique_id: shp_ac1_battery_percentage
qos: 0
device_class: battery
unit_of_measurement: "%"
state_class: measurement
value_template: "{{ value_json.params.heartbeat.energyInfos[0].batteryPercentage | round(0) if value_json['params']['heartbeat'] is defined else this.state }}"
availability:
- topic: ecoflow/SHP/data
payload_available: "1"
payload_not_available: "0"
value_template: "{{ value_json.params.heartbeat.energyInfos[0].stateBean.isEnable if value_json['params']['heartbeat'] is defined else states('sensor.shp_delta_pro_1_enabled') }}"
- name: SHP AC2 Battery Percentage
state_topic: ecoflow/SHP/data
unique_id: shp_ac2_battery_percentage
qos: 0
device_class: battery
unit_of_measurement: "%"
state_class: measurement
value_template: "{{ value_json.params.heartbeat.energyInfos[1].batteryPercentage | round(0) if value_json['params']['heartbeat'] is defined else this.state }}"
availability:
- topic: ecoflow/SHP/data
payload_available: "1"
payload_not_available: "0"
value_template: "{{ value_json.params.heartbeat.energyInfos[1].stateBean.isEnable if value_json['params']['heartbeat'] is defined else states('sensor.shp_delta_pro_2_enabled') }}"
- name: SHP Battery Charge Level
object_id: shp_battery_charge_level
unique_id: shp_battery_charge_level
unit_of_measurement: "%"
device_class: battery
state_class: measurement
state_topic: ecoflow/SHP/limits
qos: 0
value_template: "{{ value_json.params.forceChargeHigh if value_json['params']['id'] == 29 else this.state }}"
- name: SHP Battery Discharge Level
object_id: shp_battery_discharge_level
unique_id: shp_battery_discharge_level
unit_of_measurement: "%"
device_class: battery
state_class: measurement
state_topic: ecoflow/SHP/limits
qos: 0
value_template: "{{ value_json.params.discLower if value_json['params']['id'] == 29 else this.state }}"
###
# Templates
###
template:
- sensor:
- name: ECOFLOW Smart Home Panel Combined Circuit Power
unit_of_measurement: "kW"
device_class: power
state_class: measurement
state: >-
{{ ((states.sensor
| selectattr('entity_id', 'search', 'sensor.shp_')
| rejectattr('entity_id', 'search', 'delta_pro')
| selectattr('entity_id', 'search', '_power$')
| map(attribute='state') | map('float') | sum) / 1000) | round(4)
}}
- name: SHP Circuits Battery Demand
unique_id: shp_circuits_battery_demand
icon: mdi:power-plug-battery-outline
unit_of_measurement: "W"
device_class: power
state_class: measurement
state: >-
{% set battery_enabled_circuits =
states.sensor
| selectattr('entity_id', 'search', 'shp_circuit_\d+_state')
| selectattr('state', 'eq', '1')
| map(attribute='entity_id')
| list
| regex_replace(find='state', replace='power')
%}
{{ states.sensor
| selectattr('entity_id', 'in', battery_enabled_circuits)
| map(attribute='state') | map('int') | sum
}}
- name: SHP Circuits Grid Demand
unique_id: shp_circuits_grid_demand
icon: mdi:transmission-tower-export
unit_of_measurement: "W"
device_class: power
state_class: measurement
state: >-
{% set grid_enabled_circuits =
states.sensor
| selectattr('entity_id', 'search', 'shp_circuit_\d+_state')
| selectattr('state', 'eq', '0')
| map(attribute='entity_id')
| list
| regex_replace(find='state', replace='power')
%}
{{ states.sensor
| selectattr('entity_id', 'in', grid_enabled_circuits)
| map(attribute='state') | map('int') | sum
}}
- trigger:
- platform: state
entity_id: sensor.grid_power_demand_watts
not_to:
- unavailable
- unknown
sensor:
- name: Supply Grid and SHP Demand Difference
unique_id: supply_grid_and_shp_demand_difference
icon: mdi:transmission-tower-import
unit_of_measurement: "W"
device_class: power
state_class: measurement
state: >-
{% set direct = (states('sensor.grid_power_demand_watts')|int)%}
{% set grid = (states('sensor.shp_circuits_grid_demand')|int) %}
{% set batt = (states('sensor.shp_circuits_battery_demand')|int) %}
{% set combi = grid + batt %}
{{ direct - min(combi,grid) }}
availability: >-
{% set direct = (states('sensor.grid_power_demand_watts')|int)%}
{% set grid = (states('sensor.shp_circuits_grid_demand')|int) %}
{% set batt = (states('sensor.shp_circuits_battery_demand')|int) %}
{% set combi = grid + batt %}
{{ direct - grid > 0 }}
- select:
- name: SHP Circuit 1 Mode
unique_id: shp_circuit_1_mode
state: >-
{% if is_state('binary_sensor.shp_circuit_1_auto','on') %}Auto
{% else %}
{% set i = int(states('sensor.shp_circuit_1_state')) %}
{% set o = {0:'Grid',1:'Battery',2:'Off'} %}
{{ o[i] if i in o.keys() }}
{% endif %}
options: "{{ ['Auto','Grid','Battery','Off'] }}"
icon: >-
{% set i = int(states('sensor.shp_circuit_1_state')) %}
{% set o = {0:'mdi:home-lightning-bolt-outline',1:'mdi:home-battery-outline',2:'mdi:home-off-outline'} %}
{{ o[i] if i in o.keys() }}
select_option:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: >-
{% set i = option %}
{% set p = '{"from":"HA","id":"' %}
{% set s = '","moduleType":0,"operateType":"TCP","params":' %}
{% set id = 999900000+(range(10000,99999)|random) %}
{% set o = {
'Auto':'{"sta":0,"ctrlMode":0,"ch":0,"cmdSet":11,"id":16},"version":"1.0"}',
'Grid':'{"sta":0,"ctrlMode":1,"ch":0,"cmdSet":11,"id":16},"version":"1.0"}',
'Battery':'{"sta":1,"ctrlMode":1,"ch":0,"cmdSet":11,"id":16},"version":"1.0"}',
'Off':'{"sta":2,"ctrlMode":1,"ch":0,"cmdSet":11,"id":16},"version":"1.0"}'
}
%}
{% if i in o.keys() %}{{p}}{{id}}{{s}}{{o[i]}}{% endif %}
- name: "SHP Circuit 2 Mode"
unique_id: shp_circuit_2_mode
state: >-
{% if is_state('binary_sensor.shp_circuit_2_auto','on') %}Auto
{% else %}
{% set i = int(states('sensor.shp_circuit_2_state')) %}
{% set o = {0:'Grid',1:'Battery',2:'Off'} %}
{{ o[i] if i in o.keys() }}
{% endif %}
options: "{{ ['Auto','Grid','Battery','Off'] }}"
icon: >-
{% set i = int(states('sensor.shp_circuit_2_state')) %}
{% set o = {0:'mdi:home-lightning-bolt-outline',1:'mdi:home-battery-outline',2:'mdi:home-off-outline'} %}
{{ o[i] if i in o.keys() }}
select_option:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: >-
{% set i = option %}
{% set p = '{"from":"HA","id":"' %}
{% set s = '","moduleType":0,"operateType":"TCP","params":' %}
{% set id = 999900000+(range(10000,99999)|random) %}
{% set o = {
'Auto':'{"sta":0,"ctrlMode":0,"ch":1,"cmdSet":11,"id":16},"version":"1.0"}',
'Grid':'{"sta":0,"ctrlMode":1,"ch":1,"cmdSet":11,"id":16},"version":"1.0"}',
'Battery':'{"sta":1,"ctrlMode":1,"ch":1,"cmdSet":11,"id":16},"version":"1.0"}',
'Off':'{"sta":2,"ctrlMode":1,"ch":1,"cmdSet":11,"id":16},"version":"1.0"}'
}
%}
{% if i in o.keys() %}{{p}}{{id}}{{s}}{{o[i]}}{% endif %}
- name: "SHP Circuit 3 Mode"
unique_id: shp_circuit_3_mode
state: >-
{% if is_state('binary_sensor.shp_circuit_3_auto','on') %}Auto
{% else %}
{% set i = int(states('sensor.shp_circuit_3_state')) %}
{% set o = {0:'Grid',1:'Battery',2:'Off'} %}
{{ o[i] if i in o.keys() }}
{% endif %}
options: "{{ ['Auto','Grid','Battery','Off'] }}"
icon: >-
{% set i = int(states('sensor.shp_circuit_3_state')) %}
{% set o = {0:'mdi:home-lightning-bolt-outline',1:'mdi:home-battery-outline',2:'mdi:home-off-outline'} %}
{{ o[i] if i in o.keys() }}
select_option:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: >-
{% set i = option %}
{% set p = '{"from":"HA","id":"' %}
{% set s = '","moduleType":0,"operateType":"TCP","params":' %}
{% set id = 999900000+(range(10000,99999)|random) %}
{% set o = {
'Auto':'{"sta":0,"ctrlMode":0,"ch":2,"cmdSet":11,"id":16},"version":"1.0"}',
'Grid':'{"sta":0,"ctrlMode":1,"ch":2,"cmdSet":11,"id":16},"version":"1.0"}',
'Battery':'{"sta":1,"ctrlMode":1,"ch":2,"cmdSet":11,"id":16},"version":"1.0"}',
'Off':'{"sta":2,"ctrlMode":1,"ch":2,"cmdSet":11,"id":16},"version":"1.0"}'
}
%}
{% if i in o.keys() %}{{p}}{{id}}{{s}}{{o[i]}}{% endif %}
- name: "SHP Circuit 4 Mode"
unique_id: shp_circuit_4_mode
state: >-
{% if is_state('binary_sensor.shp_circuit_4_auto','on') %}Auto
{% else %}
{% set i = int(states('sensor.shp_circuit_4_state')) %}
{% set o = {0:'Grid',1:'Battery',2:'Off'} %}
{{ o[i] if i in o.keys() }}
{% endif %}
options: "{{ ['Auto','Grid','Battery','Off'] }}"
icon: >-
{% set i = int(states('sensor.shp_circuit_4_state')) %}
{% set o = {0:'mdi:home-lightning-bolt-outline',1:'mdi:home-battery-outline',2:'mdi:home-off-outline'} %}
{{ o[i] if i in o.keys() }}
select_option:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: >-
{% set i = option %}
{% set p = '{"from":"HA","id":"' %}
{% set s = '","moduleType":0,"operateType":"TCP","params":' %}
{% set id = 999900000+(range(10000,99999)|random) %}
{% set o = {
'Auto':'{"sta":0,"ctrlMode":0,"ch":3,"cmdSet":11,"id":16},"version":"1.0"}',
'Grid':'{"sta":0,"ctrlMode":1,"ch":3,"cmdSet":11,"id":16},"version":"1.0"}',
'Battery':'{"sta":1,"ctrlMode":1,"ch":3,"cmdSet":11,"id":16},"version":"1.0"}',
'Off':'{"sta":2,"ctrlMode":1,"ch":3,"cmdSet":11,"id":16},"version":"1.0"}'
}
%}
{% if i in o.keys() %}{{p}}{{id}}{{s}}{{o[i]}}{% endif %}
- name: "SHP Circuit 5 Mode"
unique_id: shp_circuit_5_mode
state: >-
{% if is_state('binary_sensor.shp_circuit_5_auto','on') %}Auto
{% else %}
{% set i = int(states('sensor.shp_circuit_5_state')) %}
{% set o = {0:'Grid',1:'Battery',2:'Off'} %}
{{ o[i] if i in o.keys() }}
{% endif %}
options: "{{ ['Auto','Grid','Battery','Off'] }}"
icon: >-
{% set i = int(states('sensor.shp_circuit_5_state')) %}
{% set o = {0:'mdi:home-lightning-bolt-outline',1:'mdi:home-battery-outline',2:'mdi:home-off-outline'} %}
{{ o[i] if i in o.keys() }}
select_option:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: >-
{% set i = option %}
{% set p = '{"from":"HA","id":"' %}
{% set s = '","moduleType":0,"operateType":"TCP","params":' %}
{% set id = 999900000+(range(10000,99999)|random) %}
{% set o = {
'Auto':'{"sta":0,"ctrlMode":0,"ch":4,"cmdSet":11,"id":16},"version":"1.0"}',
'Grid':'{"sta":0,"ctrlMode":1,"ch":4,"cmdSet":11,"id":16},"version":"1.0"}',
'Battery':'{"sta":1,"ctrlMode":1,"ch":4,"cmdSet":11,"id":16},"version":"1.0"}',
'Off':'{"sta":2,"ctrlMode":1,"ch":4,"cmdSet":11,"id":16},"version":"1.0"}'
}
%}
{% if i in o.keys() %}{{p}}{{id}}{{s}}{{o[i]}}{% endif %}
- name: "SHP Circuit 6 Mode"
unique_id: shp_circuit_6_mode
state: >-
{% if is_state('binary_sensor.shp_circuit_6_auto','on') %}Auto
{% else %}
{% set i = int(states('sensor.shp_circuit_6_state')) %}
{% set o = {0:'Grid',1:'Battery',2:'Off'} %}
{{ o[i] if i in o.keys() }}
{% endif %}
options: "{{ ['Auto','Grid','Battery','Off'] }}"
icon: >-
{% set i = int(states('sensor.shp_circuit_6_state')) %}
{% set o = {0:'mdi:home-lightning-bolt-outline',1:'mdi:home-battery-outline',2:'mdi:home-off-outline'} %}
{{ o[i] if i in o.keys() }}
select_option:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: >-
{% set i = option %}
{% set p = '{"from":"HA","id":"' %}
{% set s = '","moduleType":0,"operateType":"TCP","params":' %}
{% set id = 999900000+(range(10000,99999)|random) %}
{% set o = {
'Auto':'{"sta":0,"ctrlMode":0,"ch":5,"cmdSet":11,"id":16},"version":"1.0"}',
'Grid':'{"sta":0,"ctrlMode":1,"ch":5,"cmdSet":11,"id":16},"version":"1.0"}',
'Battery':'{"sta":1,"ctrlMode":1,"ch":5,"cmdSet":11,"id":16},"version":"1.0"}',
'Off':'{"sta":2,"ctrlMode":1,"ch":5,"cmdSet":11,"id":16},"version":"1.0"}'
}
%}
{% if i in o.keys() %}{{p}}{{id}}{{s}}{{o[i]}}{% endif %}
- name: "SHP Circuit 7 Mode"
unique_id: shp_circuit_7_mode
state: >-
{% if is_state('binary_sensor.shp_circuit_7_auto','on') %}Auto
{% else %}
{% set i = int(states('sensor.shp_circuit_7_state')) %}
{% set o = {0:'Grid',1:'Battery',2:'Off'} %}
{{ o[i] if i in o.keys() }}
{% endif %}
options: "{{ ['Auto','Grid','Battery','Off'] }}"
icon: >-
{% set i = int(states('sensor.shp_circuit_7_state')) %}
{% set o = {0:'mdi:home-lightning-bolt-outline',1:'mdi:home-battery-outline',2:'mdi:home-off-outline'} %}
{{ o[i] if i in o.keys() }}
select_option:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: >-
{% set i = option %}
{% set p = '{"from":"HA","id":"' %}
{% set s = '","moduleType":0,"operateType":"TCP","params":' %}
{% set id = 999900000+(range(10000,99999)|random) %}
{% set o = {
'Auto':'{"sta":0,"ctrlMode":0,"ch":6,"cmdSet":11,"id":16},"version":"1.0"}',
'Grid':'{"sta":0,"ctrlMode":1,"ch":6,"cmdSet":11,"id":16},"version":"1.0"}',
'Battery':'{"sta":1,"ctrlMode":1,"ch":6,"cmdSet":11,"id":16},"version":"1.0"}',
'Off':'{"sta":2,"ctrlMode":1,"ch":6,"cmdSet":11,"id":16},"version":"1.0"}'
}
%}
{% if i in o.keys() %}{{p}}{{id}}{{s}}{{o[i]}}{% endif %}
- name: "SHP Circuit 8 Mode"
unique_id: shp_circuit_8_mode
state: >-
{% if is_state('binary_sensor.shp_circuit_8_auto','on') %}Auto
{% else %}
{% set i = int(states('sensor.shp_circuit_8_state')) %}
{% set o = {0:'Grid',1:'Battery',2:'Off'} %}
{{ o[i] if i in o.keys() }}
{% endif %}
options: "{{ ['Auto','Grid','Battery','Off'] }}"
icon: >-
{% set i = int(states('sensor.shp_circuit_8_state')) %}
{% set o = {0:'mdi:home-lightning-bolt-outline',1:'mdi:home-battery-outline',2:'mdi:home-off-outline'} %}
{{ o[i] if i in o.keys() }}
select_option:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: >-
{% set i = option %}
{% set p = '{"from":"HA","id":"' %}
{% set s = '","moduleType":0,"operateType":"TCP","params":' %}
{% set id = 999900000+(range(10000,99999)|random) %}
{% set o = {
'Auto':'{"sta":0,"ctrlMode":0,"ch":7,"cmdSet":11,"id":16},"version":"1.0"}',
'Grid':'{"sta":0,"ctrlMode":1,"ch":7,"cmdSet":11,"id":16},"version":"1.0"}',
'Battery':'{"sta":1,"ctrlMode":1,"ch":7,"cmdSet":11,"id":16},"version":"1.0"}',
'Off':'{"sta":2,"ctrlMode":1,"ch":7,"cmdSet":11,"id":16},"version":"1.0"}'
}
%}
{% if i in o.keys() %}{{p}}{{id}}{{s}}{{o[i]}}{% endif %}
- name: "SHP Circuit 9 Mode"
unique_id: shp_circuit_9_mode
state: >-
{% if is_state('binary_sensor.shp_circuit_9_auto','on') %}Auto
{% else %}
{% set i = int(states('sensor.shp_circuit_9_state')) %}
{% set o = {0:'Grid',1:'Battery',2:'Off'} %}
{{ o[i] if i in o.keys() }}
{% endif %}
options: "{{ ['Auto','Grid','Battery','Off'] }}"
icon: >-
{% set i = int(states('sensor.shp_circuit_9_state')) %}
{% set o = {0:'mdi:home-lightning-bolt-outline',1:'mdi:home-battery-outline',2:'mdi:home-off-outline'} %}
{{ o[i] if i in o.keys() }}
select_option:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: >-
{% set i = option %}
{% set p = '{"from":"HA","id":"' %}
{% set s = '","moduleType":0,"operateType":"TCP","params":' %}
{% set id = 999900000+(range(10000,99999)|random) %}
{% set o = {
'Auto':'{"sta":0,"ctrlMode":0,"ch":8,"cmdSet":11,"id":16},"version":"1.0"}',
'Grid':'{"sta":0,"ctrlMode":1,"ch":8,"cmdSet":11,"id":16},"version":"1.0"}',
'Battery':'{"sta":1,"ctrlMode":1,"ch":8,"cmdSet":11,"id":16},"version":"1.0"}',
'Off':'{"sta":2,"ctrlMode":1,"ch":8,"cmdSet":11,"id":16},"version":"1.0"}'
}
%}
{% if i in o.keys() %}{{p}}{{id}}{{s}}{{o[i]}}{% endif %}
- name: "SHP Circuit 10 Mode"
unique_id: shp_circuit_10_mode
state: >-
{% if is_state('binary_sensor.shp_circuit_10_auto','on') %}Auto
{% else %}
{% set i = int(states('sensor.shp_circuit_10_state')) %}
{% set o = {0:'Grid',1:'Battery',2:'Off'} %}
{{ o[i] if i in o.keys() }}
{% endif %}
options: "{{ ['Auto','Grid','Battery','Off'] }}"
icon: >-
{% set i = int(states('sensor.shp_circuit_10_state')) %}
{% set o = {0:'mdi:home-lightning-bolt-outline',1:'mdi:home-battery-outline',2:'mdi:home-off-outline'} %}
{{ o[i] if i in o.keys() }}
select_option:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: >-
{% set i = option %}
{% set p = '{"from":"HA","id":"' %}
{% set s = '","moduleType":0,"operateType":"TCP","params":' %}
{% set id = 999900000+(range(10000,99999)|random) %}
{% set o = {
'Auto':'{"sta":0,"ctrlMode":0,"ch":9,"cmdSet":11,"id":16},"version":"1.0"}',
'Grid':'{"sta":0,"ctrlMode":1,"ch":9,"cmdSet":11,"id":16},"version":"1.0"}',
'Battery':'{"sta":1,"ctrlMode":1,"ch":9,"cmdSet":11,"id":16},"version":"1.0"}',
'Off':'{"sta":2,"ctrlMode":1,"ch":9,"cmdSet":11,"id":16},"version":"1.0"}'
}
%}
{% if i in o.keys() %}{{p}}{{id}}{{s}}{{o[i]}}{% endif %}
- number:
- name: "SHP - Charge Limit"
unique_id: shp_charge_limit
state: "{{ states('sensor.shp_battery_charge_level') }}"
icon: mdi:battery-arrow-up
min: "50"
max: "100"
step: "1"
set_value:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: '{"from":"HA","id":"{{999900000+(range(10000,99999)|random)}}","moduleType":0,"operateType":"TCP","params":{"discLower":{{states("number.shp_discharge_limit")}},"forceChargeHigh":{{value}},"cmdSet":11,"id":29},"version":"1.0"}'
qos: 0
- name: "SHP - Discharge Limit"
unique_id: shp_discharge_limit
state: "{{ states('sensor.shp_battery_discharge_level') }}"
icon: mdi:battery-arrow-down-outline
min: "0"
max: "30"
step: "1"
set_value:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: '{"from":"HA","id":"{{999900000+(range(10000,99999)|random)}}","moduleType":0,"operateType":"TCP","params":{"discLower":{{value}},"forceChargeHigh":{{states("number.shp_charge_limit")}},"cmdSet":11,"id":29},"version":"1.0"}'
qos: 0
- button:
- name: "SHP - Update Real-Time Clock"
unique_id: shp_update_rtc
icon: mdi:clock-alert
press:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: >-
{%- set rtc = now() -%}
{"from":"HA","id":"{{999900000+(range(10000,99999)|random)}}","moduleType":0,"operateType":"TCP","params":{"cmdSet":11,"id":3,"week":{{rtc.strftime('%U')}},"sec":{{rtc.second}},"min":{{rtc.minute}},"hour":{{rtc.hour}},"day":{{rtc.day}},"month":{{rtc.month}},"year":{{rtc.year}}},"version":"1.0"}
qos: 1
###
# Switches
###
switch:
- platform: template
switches:
shp_eps:
friendly_name: "SHP EPS"
value_template: "{{ states('binary_sensor.shp_eps_enabled') }}"
turn_on:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: '{"from":"HA","id":"{{999900000+(range(10000,99999)|random)}}","moduleType":0,"operateType":"TCP","params":{"cmdSet":11,"id":24,"eps":1},"version":"1.0"}'
turn_off:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: '{"from":"HA","id":"{{999900000+(range(10000,99999)|random)}}","moduleType":0,"operateType":"TCP","params":{"cmdSet":11,"id":24,"eps":0},"version":"1.0"}'
icon_template: >-
{% if is_state('binary_sensor.shp_eps_enabled','on') %}
mdi:speedometer
{% else %}
mdi:speedometer-slow
{% endif %}
shp_pro1_recharge:
friendly_name: "SHP AC1 Recharge"
value_template: "{{ states('binary_sensor.shp_ac1_grid_charging') }}"
turn_on:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: '{"from":"HA","id":"{{999900000+(range(10000,99999)|random)}}","moduleType":0,"operateType":"TCP","params":{"sta":2,"ctrlMode":1,"ch":10,"cmdSet":11,"id":17},"version":"1.0"}'
turn_off:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: '{"from":"HA","id":"{{999900000+(range(10000,99999)|random)}}","moduleType":0,"operateType":"TCP","params":{"sta":0,"ctrlMode":0,"ch":10,"cmdSet":11,"id":17},"version":"1.0"}'
icon_template: >-
{% if is_state('binary_sensor.shp_ac1_grid_charging','on') %}
mdi:battery-charging
{% else %}
mdi:battery
{% endif %}
shp_pro2_recharge:
friendly_name: "SHP AC2 Recharge"
value_template: "{{ states('binary_sensor.shp_ac2_grid_charging') }}"
turn_on:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: '{"from":"HA","id":"{{999900000+(range(10000,99999)|random)}}","moduleType":0,"operateType":"TCP","params":{"sta":2,"ctrlMode":1,"ch":11,"cmdSet":11,"id":17},"version":"1.0"}'
turn_off:
- service: mqtt.publish
data:
topic: ecoflow/SHP/set
payload: '{"from":"HA","id":"{{999900000+(range(10000,99999)|random)}}","moduleType":0,"operateType":"TCP","params":{"sta":0,"ctrlMode":0,"ch":11,"cmdSet":11,"id":17},"version":"1.0"}'
icon_template: >-
{% if is_state('binary_sensor.shp_ac2_grid_charging','on') %}
mdi:battery-charging
{% else %}
mdi:battery
{% endif %}
###
# Automations
###
automation:
###
# Limits is a little frustrating since the data isn't in the public API anywhere so we
# use the data being set to define these values and retain it in our own MQTT server.
# The issue here is that the data doesn't exist and can't be set either due to the
# circular requirement, so it is necessary to run the following, manually, once,
# to create the retained message in the topic we're monitoring to short circuit the
# circular reference. Sorry! If you've got a better way, let me know.
#
# action: mqtt.publish
# data:
# topic: ecoflow/SHP/limits
# payload: |
# {"from":"HA","id":"999947717","moduleType":0,"operateType":"TCP","params":{"discLower":8.0,"forceChargeHigh":100.0,"cmdSet":11,"id":29},"version":"1.0"}
# retain: true
###
- id: "EF_SHP_Limits"
alias: SHP - Limits
description: "Re-Publish SHP Charge/Discharge Limits to new Topic"
mode: single
trigger:
- platform: mqtt
topic: ecoflow/SHP/set
payload: 29
value_template: "{{ value_json.params['id'] }}"
condition: []
action:
- service: mqtt.publish
data:
topic: ecoflow/SHP/limits
payload: "{{trigger.payload}}"
retain: true
- id: "EF_SHP_EPS"
alias: SHP - EPS Status
description: "Re-Publish SHP EPS Status to new Topic"
mode: single
trigger:
- platform: mqtt
topic: ecoflow/SHP/set
payload: 24
value_template: "{{ value_json.params['id'] }}"
condition: []
action:
- service: mqtt.publish
data:
topic: ecoflow/SHP/eps
payload: "{{trigger.payload}}"
retain: true
- id: "EF_SHP_RTC"
alias: SHP - RTC Update
description: "Update the real-time clock for the Smart Home Panel"
trigger:
- platform: time_pattern
hours: "6"
condition: []
action:
- action: button.press
metadata: {}
data: {}
target:
entity_id: button.shp_update_real_time_clock
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment