substitutions:
devicename: sofarsolar-logger
friendly_name: SofarSolar
hostname: "esp8266-sofar"
comment: "SofarSolar modbus interface"
icon: "mdi:solar-power-variant-outline"
restore_mode: "restore_default_off"
wifi:
ssid: "MALINA"
password: "---------"
ap:
ssid: "Fallback-AP-${devicename}"
password: ""
ap_timeout: 300s
api:
password: "TbkEdpMbUuwCNxfU6CK3KHo392"
ota:
password: "TbkEdpMbUuwCNxfU6CK3KHo392"
safe_mode: False
captive_portal:
mdns:
disabled: false
esphome:
name: $devicename
platform: ESP8266
board: d1_mini_pro
board_flash_mode: dout
comment: SofarSolar Logger (Modbus/RS485)
logger:
level: INFO
baud_rate: 0
status_led:
pin:
number: GPIO2
inverted: true
external_components:
- source:
type: git
url: https://github.com/ssieb/custom_components
components: [ heapmon ]
- source: github://pr#4444
components: [async_tcp, web_server_base]
refresh: always
uart:
id: mod_bus
tx_pin: 1
rx_pin: 3
baud_rate: 9600
stop_bits: 1
#web_server:
# port: 80
# ota: false
modbus:
id: mod_bus_sofar
modbus_controller:
- id: sofarsolar
address: 0x01
modbus_id: mod_bus_sofar
update_interval: 5s
text_sensor:
- platform: template
name: "ESP-Sofar Uptime (human readable)"
id: uptime_human
icon: "mdi:clock-start"
update_interval: 5s
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} Status
id: inverter_status
register_type: holding
icon: "mdi:information-outline"
address: 0x0000
response_size: 2
lambda: |-
auto z = "Unknown";
char d = data[item->offset+1];
if (d == 0) z = "Wait";
else if (d == 1) z = "Check";
else if (d == 2) z = "Normal";
else if (d == 3) z = "Fault";
else if (d == 4) z = "Permanent";
return {z};
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} Fault Message
id: inverter_fault_message
register_type: holding
icon: "mdi:alert-outline"
address: 0x0001
response_size: 10
lambda: |-
std::string z = "";
int idx = item->offset;
//byte[0]
if ((data[idx] & 0x1) != 0) z += "GridOVP,";
if ((data[idx] & 0x2) != 0) z += "GridUVP,";
if ((data[idx] & 0x4) != 0) z += "GridOFP,";
if ((data[idx] & 0x8) != 0) z += "GridUFP,";
if ((data[idx] & 0x10) != 0) z += "PVUVP,";
if ((data[idx] & 0x20) != 0) z += "GridLVRT,";
if ((data[idx] & 0x40) != 0) z += "reserve-ID7,";
if ((data[idx] & 0x80) != 0) z += "reserve-ID8,";
//byte[1]
idx++;
if ((data[idx] & 0x1) != 0) z += "PVOVP,";
if ((data[idx] & 0x2) != 0) z += "IpvUnbalance,";
if ((data[idx] & 0x4) != 0) z += "PvConfigSetWrong,";
if ((data[idx] & 0x8) != 0) z += "GFCIFault,";
if ((data[idx] & 0x10) != 0) z += "PhaseSequenceFault,";
if ((data[idx] & 0x20) != 0) z += "HwBoostOCP,";
if ((data[idx] & 0x40) != 0) z += "HwAcOCP,";
if ((data[idx] & 0x80) != 0) z += "AcRmsOCP,";
//byte[2]
idx++;
if ((data[idx] & 0x1) != 0) z += "HwADFaultIGrid,";
if ((data[idx] & 0x2) != 0) z += "HwADFaultDCI,";
if ((data[idx] & 0x4) != 0) z += "HwADFaultVGrid,";
if ((data[idx] & 0x8) != 0) z += "GFCIDeviceFault,";
if ((data[idx] & 0x10) != 0) z += "MChip_Fault,";
if ((data[idx] & 0x20) != 0) z += "HwAuxPowerFault,";
if ((data[idx] & 0x40) != 0) z += "BusVoltZeroFault,";
if ((data[idx] & 0x80) != 0) z += "IacRmsUnbalance,";
//byte[3]
idx++;
if ((data[idx] & 0x1) != 0) z += "BusUVP,";
if ((data[idx] & 0x2) != 0) z += "BusOVP,";
if ((data[idx] & 0x4) != 0) z += "VbusUnbalance,";
if ((data[idx] & 0x8) != 0) z += "DciOCP,";
if ((data[idx] & 0x10) != 0) z += "SwOCPInstant,";
if ((data[idx] & 0x20) != 0) z += "SwBOCPInstant,";
if ((data[idx] & 0x40) != 0) z += "reserved-ID31,";
if ((data[idx] & 0x80) != 0) z += "reserved-ID32,";
//byte[4]
idx++;
if (data[idx] != 0) z += "reserved-ID33~40,";
//byte[5]
idx++;
if (data[idx] != 0) z += "reserved-ID41~48,";
//byte[6]
idx++;
if ((data[idx] & 0x1) != 0) z += "ConsistentFault_VGrid,";
if ((data[idx] & 0x2) != 0) z += "ConsistentFault_FGrid,";
if ((data[idx] & 0x4) != 0) z += "ConsistentFault_DCI,";
if ((data[idx] & 0x8) != 0) z += "ConsistentFault_GFCI,";
if ((data[idx] & 0x10) != 0) z += "SpiCommLose,";
if ((data[idx] & 0x20) != 0) z += "SciCommLose,";
if ((data[idx] & 0x40) != 0) z += "RelayTestFail,";
if ((data[idx] & 0x80) != 0) z += "PvIsoFault,";
//byte[7]
idx++;
if ((data[idx] & 0x1) != 0) z += "OverTempFault_Inv,";
if ((data[idx] & 0x2) != 0) z += "OverTempFault_Boost,";
if ((data[idx] & 0x4) != 0) z += "OverTempFault_Env,";
if ((data[idx] & 0x8) != 0) z += "PEConnectFault,";
if ((data[idx] & 0x10) != 0) z += "reserved-ID61,";
if ((data[idx] & 0x20) != 0) z += "reserved-ID62,";
if ((data[idx] & 0x40) != 0) z += "reserved-ID63,";
if ((data[idx] & 0x80) != 0) z += "reserved-ID64,";
//byte[8]
idx++;
if ((data[idx] & 0x1) != 0) z += "unrecoverHwAcOCP,";
if ((data[idx] & 0x2) != 0) z += "unrecoverBusOVP,";
if ((data[idx] & 0x4) != 0) z += "unrecoverIacRmsUnbalance,";
if ((data[idx] & 0x8) != 0) z += "unrecoverIpvUnbalance,";
if ((data[idx] & 0x10) != 0) z += "unrecoverVbusUnbalance,";
if ((data[idx] & 0x20) != 0) z += "unrecoverOCPInstant,";
if ((data[idx] & 0x40) != 0) z += "unrecoverPvConfigSetWrong,";
if ((data[idx] & 0x80) != 0) z += "reserved-ID72,";
//byte[9]
idx++;
if ((data[idx] & 0x1) != 0) z += "reserved-ID73,";
if ((data[idx] & 0x2) != 0) z += "unrecoverIPVInstant,";
if ((data[idx] & 0x4) != 0) z += "unrecoverWRITEEEPROM,";
if ((data[idx] & 0x8) != 0) z += "unrecoverREADEEPROM,";
if ((data[idx] & 0x10) != 0) z += "unrecoverRelayFail,";
if ((data[idx] & 0x20) != 0) z += "reserved-ID78,";
if ((data[idx] & 0x40) != 0) z += "reserved-ID79,";
if ((data[idx] & 0x80) != 0) z += "reserved-ID80,";
if(z.length() > 0){
z.pop_back();
}
return {z};
sensor:
- platform: wifi_signal
id: inverter_wifi_signal
name: "ESP-Sofar WiFi Signal"
update_interval: 60s
icon: "mdi:wifi"
- platform: uptime
id: inverter_uptime
name: "ESP-Sofar Uptime"
filters:
- lambda: return x / 60.0;
unit_of_measurement: minutes
icon: "mdi:clock-start"
- platform: heapmon
id: heapspace
name: "ESP-Sofar Heapsize"
icon: "mdi:memory"
update_interval: 5s
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} DC1 Voltage
id: inverter_dc_v1
register_type: holding
address: 0x0006
unit_of_measurement: "V"
state_class: "measurement"
device_class: "voltage"
icon: "mdi:alpha-v-circle-outline"
value_type: U_WORD
accuracy_decimals: 1
filters:
- multiply: 0.1
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} DC1 Current
id: inverter_dc_c1
register_type: holding
address: 0x0007
unit_of_measurement: "A"
state_class: "measurement"
device_class: "current"
icon: "mdi:alpha-a-circle-outline"
value_type: U_WORD
accuracy_decimals: 2
filters:
- multiply: 0.01
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} DC2 Voltage
id: inverter_dc_v2
register_type: holding
address: 0x0008
unit_of_measurement: "V"
state_class: "measurement"
device_class: "voltage"
icon: "mdi:alpha-v-circle-outline"
value_type: U_WORD
accuracy_decimals: 1
filters:
- multiply: 0.1
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} DC2 Current
id: inverter_dc_c2
register_type: holding
address: 0x0009
unit_of_measurement: "A"
state_class: "measurement"
device_class: "current"
icon: "mdi:alpha-a-circle-outline"
value_type: U_WORD
accuracy_decimals: 2
filters:
- multiply: 0.01
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} DC1 Power
id: inverter_dc_power1
register_type: holding
address: 0x000a
unit_of_measurement: "W"
state_class: "measurement"
device_class: "power"
icon: "mdi:solar-power"
value_type: U_WORD
filters:
- multiply: 10
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} DC2 Power
id: inverter_dc_power2
register_type: holding
address: 0x000b
unit_of_measurement: "W"
state_class: "measurement"
device_class: "power"
icon: "mdi:solar-power"
value_type: U_WORD
filters:
- multiply: 10
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} AC Power
id: inverter_ac_power
register_type: holding
address: 0x000c
unit_of_measurement: "W"
state_class: "measurement"
device_class: "power"
icon: "mdi:solar-power-variant-outline"
value_type: U_WORD
filters:
- multiply: 10
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} AC Reactive Power
id: inverter_ac_reactive_power
register_type: holding
address: 0x000d
unit_of_measurement: "kVar"
state_class: "measurement"
#device_class: "reactive_power"
icon: "mdi:math-cos"
value_type: S_WORD
filters:
- multiply: 10
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} AC Freq
id: inverter_ac_freq
register_type: holding
address: 0x000e
unit_of_measurement: "Hz"
state_class: "measurement"
#device_class: "frequency"
icon: "mdi:current-ac"
value_type: U_WORD
accuracy_decimals: 2
filters:
- multiply: 0.01
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} L1 Voltage
id: inverter_ac_v1
register_type: holding
address: 0x000f
unit_of_measurement: "V"
state_class: "measurement"
device_class: "voltage"
icon: "mdi:alpha-v-circle"
value_type: U_WORD
accuracy_decimals: 1
filters:
- multiply: 0.1
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} L1 Current
id: inverter_ac_c1
register_type: holding
address: 0x0010
unit_of_measurement: "A"
state_class: "measurement"
device_class: "current"
icon: "mdi:alpha-a-circle"
value_type: U_WORD
accuracy_decimals: 2
filters:
- multiply: 0.01
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} L2 Voltage
id: inverter_ac_v2
register_type: holding
address: 0x0011
unit_of_measurement: "V"
state_class: "measurement"
device_class: "voltage"
icon: "mdi:alpha-v-circle"
value_type: U_WORD
accuracy_decimals: 1
filters:
- multiply: 0.1
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} L2 Current
id: inverter_ac_c2
register_type: holding
address: 0x0012
unit_of_measurement: "A"
state_class: "measurement"
device_class: "current"
icon: "mdi:alpha-a-circle"
value_type: U_WORD
accuracy_decimals: 2
filters:
- multiply: 0.01
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} L3 Voltage
id: inverter_ac_v3
register_type: holding
address: 0x0013
unit_of_measurement: "V"
state_class: "measurement"
device_class: "voltage"
icon: "mdi:alpha-v-circle"
value_type: U_WORD
accuracy_decimals: 1
filters:
- multiply: 0.1
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} L3 Current
id: inverter_ac_c3
register_type: holding
address: 0x0014
unit_of_measurement: "A"
state_class: "measurement"
device_class: "current"
icon: "mdi:alpha-a-circle"
value_type: U_WORD
accuracy_decimals: 2
filters:
- multiply: 0.01
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} Energy total
id: inverter_energy_total
register_type: holding
address: 0x0015
unit_of_measurement: "kWh"
accuracy_decimals: 2
device_class: "energy"
state_class: "total_increasing"
icon: "mdi:solar-power-variant-outline"
value_type: U_DWORD
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} Energy generation time total
id: inverter_energy_generation_time_total
register_type: holding
address: 0x0017
unit_of_measurement: "h"
icon: "mdi:timeline-clock"
value_type: U_DWORD
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} Energy today
id: inverter_energy_today
register_type: holding
address: 0x0019
unit_of_measurement: "kWh"
state_class: "measurement"
device_class: "energy"
icon: "mdi:solar-power-variant-outline"
value_type: U_WORD
accuracy_decimals: 2
filters:
- multiply: 0.01
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} Energy generation time today
id: inverter_energy_generation_time_today
register_type: holding
address: 0x001A
unit_of_measurement: "min"
icon: "mdi:timeline-clock"
value_type: U_WORD
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} Temprature module
id: inverter_temp_module
register_type: holding
address: 0x001B
unit_of_measurement: "°C"
state_class: "measurement"
device_class: "temperature"
icon: "mdi:temperature-celsius"
value_type: U_WORD
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} Temprature inverter
id: inverter_temp_inverter
register_type: holding
address: 0x001C
unit_of_measurement: "°C"
state_class: "measurement"
device_class: "temperature"
icon: "mdi:temperature-celsius"
value_type: U_WORD
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} Bus voltage
id: inverter_bus_voltage
register_type: holding
address: 0x001D
unit_of_measurement: "V"
state_class: "measurement"
device_class: "voltage"
icon: "mdi:alpha-v-circle-outline"
value_type: U_WORD
accuracy_decimals: 1
filters:
- multiply: 0.1
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} PV1+ isolation resistance
id: inverter_dc_isolation_resistance1
register_type: holding
address: 0x0024
unit_of_measurement: "Ohm"
state_class: "measurement"
icon: "mdi:omega"
value_type: U_WORD
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} PV2+ isolation resistance
id: inverter_dc_isolation_resistance2
register_type: holding
address: 0x0025
unit_of_measurement: "Ohm"
state_class: "measurement"
icon: "mdi:omega"
value_type: U_WORD
- platform: modbus_controller
modbus_controller_id: sofarsolar
name: ${friendly_name} PV- isolation resistance
id: inverter_cathode_to_ground_impedance
register_type: holding
address: 0x0026
unit_of_measurement: "Ohm"
state_class: "measurement"
icon: "mdi:omega"
value_type: U_WORD
- platform: template
name: ${friendly_name} AC Current (total)
lambda: |-
return (id(inverter_ac_c1).state + id(inverter_ac_c2).state + id(inverter_ac_c3).state);
unit_of_measurement: A
accuracy_decimals: 2
icon: "mdi:alpha-a-circle"
device_class: "current"
state_class: "measurement"
update_interval: 5s
- platform: template
name: ${friendly_name} DC Current (total)
lambda: |-
return (id(inverter_dc_c1).state + id(inverter_dc_c2).state);
unit_of_measurement: A
accuracy_decimals: 1
state_class: "measurement"
device_class: "current"
icon: "mdi:alpha-a-circle-outline"
update_interval: 5s
- platform: template
name: ${friendly_name} DC Power (total)
lambda: |-
return (id(inverter_dc_power2).state + id(inverter_dc_power1).state);
unit_of_measurement: W
state_class: "measurement"
device_class: "power"
accuracy_decimals: 0
icon: "mdi:alpha-a-circle-outline"
update_interval: 5s
- platform: uptime
name: ${friendly_name} Uptime
id: uptime_sensor
update_interval: 5s
icon: "mdi:clock-start"
internal: true
on_raw_value:
then:
- text_sensor.template.publish:
id: uptime_human
state: !lambda |-
int seconds = round(id(uptime_sensor).raw_state);
seconds = seconds % (24 * 3600);
int hours = seconds / 3600;
seconds = seconds % 3600;
int minutes = seconds / 60;
seconds = seconds % 60;
return (
(hours ? to_string(hours) + "h " : "") +
(minutes ? to_string(minutes) + "m " : "") +
(to_string(seconds) + "s")
).c_str();
- platform: template
unit_of_measurement: "%"
name: "ESP-Sofar WiFi Signal (human readable)"
accuracy_decimals: 0
update_interval: 30s
device_class: "signal_strength"
icon: "mdi:wifi"
lambda: return (-0.0134 * (id(inverter_wifi_signal).state * id(inverter_wifi_signal).state ) ) + (-0.2228 * id(inverter_wifi_signal).state) + 100.2;
switch:
- platform: restart
name: "ESP-Sofar Restart"
binary_sensor:
- platform: status
name: "ESP-Sofar Status"