November 7, 20232 yr UPDATE 2023/12/02: The following is easier to implement, and much less overhead and setup: https://github.com/Pho3niX90/solis_modbus This comes mainly from the following repo: https://github.com/fboundy/ha_solis_modbus There are a couple helpers there, which also writes to the inverter to change workmode, you could also easily change SOC with some automations etc. CONS: The datalogger will no longer report to the cloud, but support will still be able to assist with firmware upgrades, and remotely change settings PROS: Faster comms and data retrieval (configurable). There will be no more need to use the solis app, except for local config via bluetooth if needed. STEP 1: inside /config/secrets.yaml, add the following line, and change the IP to your inverters IP: solis_ip: 10.0.0.75 STEP 2: Create the following file /config/solis.yaml Inside, add the following. NOTE: you can change scan_interval for each sensor to match your liking. - name: "solis" type: tcp host: !secret solis_ip port: 502 # for S2-WL-ST sticks # port: 8899 # for DLS-L sticks sensors: - name: Solis Year RO slave: 1 address: 33022 scale: 1 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 30 state_class: measurement - name: Solis Month RO slave: 1 address: 33023 scale: 1 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 60 state_class: measurement - name: Solis Day RO slave: 1 address: 33024 scale: 1 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 60 state_class: measurement - name: Solis Hour RO slave: 1 address: 33025 scale: 1 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 60 state_class: measurement - name: Solis Minute RO slave: 1 address: 33026 scale: 1 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 60 state_class: measurement - name: Solis Year RW slave: 1 address: 43000 scale: 1 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 state_class: measurement - name: Solis Month RW slave: 1 address: 43001 scale: 1 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 state_class: measurement - name: Solis Day RW slave: 1 address: 43002 scale: 1 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 state_class: measurement - name: Solis Hour RW slave: 1 address: 43003 scale: 1 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 state_class: measurement - name: Solis Minute RW slave: 1 address: 43004 scale: 1 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 state_class: measurement - name: Solis Second RW slave: 1 address: 43005 scale: 1 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 state_class: measurement # Temperature - name: Solis Temperature unique_id: solis_temperature slave: 1 address: 33093 scale: 0.1 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 60 device_class: temperature state_class: measurement unit_of_measurement: °C # Grid - name: Solis Grid Frequency slave: 1 address: 33282 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 10 scale: 0.01 precision: 1 device_class: frequency state_class: measurement unit_of_measurement: Hz - name: Solis Grid Voltage slave: 1 address: 33251 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 5 scale: 0.1 precision: 1 device_class: voltage state_class: measurement unit_of_measurement: V - name: Solis Grid Current slave: 1 address: 33252 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 5 scale: 0.01 precision: 1 device_class: current state_class: measurement unit_of_measurement: A - name: Solis Grid Active Power unique_id: solis_grid_active_power slave: 1 address: 33257 # count: 2 input_type: input data_type: int32 lazy_error_count: 5 scan_interval: 5 scale: 1 precision: 1 device_class: power state_class: measurement unit_of_measurement: W # Energy Imported/Exported - name: Solis Daily Energy Imported unique_id: solis_daily_energy_imported slave: 1 address: 33171 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 300 scale: 0.1 precision: 1 device_class: energy state_class: total_increasing unit_of_measurement: kWh - name: Solis Daily Energy Exported slave: 1 address: 33175 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 300 scale: 0.1 precision: 1 device_class: energy state_class: total_increasing unit_of_measurement: kWh - name: Solis Total Energy Imported slave: 1 address: 33169 # count: 2 input_type: input data_type: uint32 lazy_error_count: 5 scan_interval: 3600 scale: 1 precision: 1 device_class: energy state_class: total unit_of_measurement: kWh - name: Solis Total Energy Exported slave: 1 address: 33173 # count: 2 input_type: input data_type: uint32 lazy_error_count: 5 scan_interval: 3600 scale: 1 precision: 1 device_class: energy state_class: total unit_of_measurement: kWh # Load - name: Solis House Load Power slave: 1 address: 33147 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 5 scale: 1 precision: 1 device_class: power state_class: measurement unit_of_measurement: W - name: Solis Backup Load Power unique_id: solis_backup_load_power slave: 1 address: 33148 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 5 scale: 1 precision: 1 device_class: power state_class: measurement unit_of_measurement: W # Consumption - name: Solis Daily Consumption slave: 1 address: 33179 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 300 scale: 0.1 precision: 1 device_class: energy state_class: total unit_of_measurement: kWh - name: Solis Total Consumption slave: 1 address: 33177 # count: 2 input_type: input data_type: uint32 lazy_error_count: 5 scan_interval: 3600 scale: 1 precision: 1 device_class: energy state_class: total unit_of_measurement: kWh # Battery - name: Solis Battery Power unique_id: solis_battery_power slave: 1 address: 33149 # count: 2 input_type: input data_type: int32 lazy_error_count: 5 scan_interval: 5 scale: 1 precision: 1 device_class: power state_class: measurement unit_of_measurement: W - name: Solis Battery SOC slave: 1 address: 33139 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 30 scale: 1 precision: 1 device_class: battery state_class: measurement unit_of_measurement: "%" - name: Solis Battery SOH slave: 1 address: 33140 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 1 device_class: battery state_class: measurement unit_of_measurement: "%" - name: Solis Battery Voltage unique_id: solis_battery_voltage slave: 1 address: 33133 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 5 scale: 0.1 precision: 1 device_class: voltage state_class: measurement unit_of_measurement: V - name: Solis Battery Voltage (BMS) slave: 1 address: 33141 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 0.01 precision: 1 device_class: voltage state_class: measurement unit_of_measurement: V - name: Solis Battery Current unique_id: solis_battery_current slave: 1 address: 33134 input_type: input data_type: int16 lazy_error_count: 5 scan_interval: 5 scale: 0.1 precision: 1 device_class: current state_class: measurement unit_of_measurement: A - name: Solis Battery Current (BMS) slave: 1 address: 33142 input_type: input data_type: int16 lazy_error_count: 5 scan_interval: 60 scale: 0.01 precision: 1 device_class: current state_class: measurement unit_of_measurement: A - name: Solis Battery Charge Current Limit (BMS) slave: 1 address: 33143 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 0.1 precision: 1 device_class: current state_class: measurement unit_of_measurement: A - name: Solis Battery Discharge Current Limit (BMS) slave: 1 address: 33144 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 0.1 precision: 1 device_class: current state_class: measurement unit_of_measurement: A - name: Solis Battery Charge Current Limit slave: 1 address: 33206 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 30 scale: 0.1 precision: 1 device_class: current state_class: measurement unit_of_measurement: A - name: Solis Battery Discharge Current Limit slave: 1 address: 33207 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 30 scale: 0.1 precision: 1 device_class: current state_class: measurement unit_of_measurement: A # Battery Totals - name: Solis Daily Battery Charge slave: 1 address: 33163 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 300 scale: 0.1 precision: 1 device_class: energy state_class: total_increasing unit_of_measurement: kWh - name: Solis Daily Battery Discharge slave: 1 address: 33167 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 300 scale: 0.1 precision: 1 device_class: energy state_class: total_increasing unit_of_measurement: kWh - name: Solis Total Battery Charge slave: 1 address: 33161 # count: 2 input_type: input data_type: uint32 lazy_error_count: 5 scan_interval: 3600 scale: 1 precision: 1 device_class: energy state_class: total unit_of_measurement: kWh - name: Solis Total Battery Discharge slave: 1 address: 33165 # count: 2 input_type: input data_type: uint32 lazy_error_count: 5 scan_interval: 3600 scale: 1 precision: 1 device_class: energy state_class: total unit_of_measurement: kWh # Inverter DC Input - name: Solis PV1 Voltage slave: 1 address: 33049 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 0.1 precision: 1 device_class: voltage state_class: measurement unit_of_measurement: V - name: Solis PV2 Voltage slave: 1 address: 33051 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 0.1 precision: 1 device_class: voltage state_class: measurement unit_of_measurement: V - name: Solis PV1 Current slave: 1 address: 33050 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 0.1 precision: 1 device_class: current state_class: measurement unit_of_measurement: A - name: Solis PV2 Current slave: 1 address: 33052 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 0.1 precision: 1 device_class: current state_class: measurement unit_of_measurement: A - name: Solis Inverter DC Power slave: 1 address: 33057 # count: 2 input_type: input data_type: uint32 lazy_error_count: 5 scan_interval: 30 scale: 1 precision: 1 device_class: power state_class: measurement unit_of_measurement: W # Inverter AC Output - name: Solis Inverter AC Power slave: 1 address: 33079 # count: 2 input_type: input data_type: int32 lazy_error_count: 5 scan_interval: 30 scale: 1 precision: 1 device_class: power state_class: measurement unit_of_measurement: W - name: Solis Inverter Voltage slave: 1 address: 33073 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 30 scale: 0.1 precision: 1 device_class: voltage state_class: measurement unit_of_measurement: V - name: Solis Inverter Current slave: 1 address: 33076 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 30 scale: 0.1 precision: 1 device_class: current state_class: measurement unit_of_measurement: A - name: Solis Inverter Apparent Power slave: 1 address: 33083 # count: 2 input_type: input data_type: int32 lazy_error_count: 5 scan_interval: 30 scale: 1 precision: 1 device_class: apparent_power state_class: measurement unit_of_measurement: VA - name: Solis Inverter Frequency slave: 1 address: 33094 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 30 scale: .01 precision: 1 device_class: frequency state_class: measurement unit_of_measurement: Hz # Generation - name: Solis Daily Generation slave: 1 address: 33035 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 300 scale: .1 precision: 1 device_class: energy state_class: total_increasing unit_of_measurement: kWh - name: Solis Monthly Generation slave: 1 address: 33031 # count: 2 input_type: input data_type: uint32 lazy_error_count: 5 scan_interval: 3600 scale: 1 precision: 1 device_class: energy state_class: total unit_of_measurement: kWh - name: Solis Yearly Generation slave: 1 address: 33037 # count: 2 input_type: input data_type: uint32 lazy_error_count: 5 scan_interval: 3600 scale: 1 precision: 1 device_class: energy state_class: total unit_of_measurement: kWh - name: Solis Total Generation slave: 1 address: 33029 # count: 2 input_type: input data_type: uint32 lazy_error_count: 5 scan_interval: 3600 scale: 1 precision: 1 device_class: energy state_class: total unit_of_measurement: kWh # Flags and Status - name: Solis Energy Storage Control Switch slave: 1 address: 33132 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 30 scale: 1 precision: 1 state_class: measurement - name: Solis Battery Current Direction slave: 1 address: 33135 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 30 scale: 1 precision: 1 state_class: measurement - name: Solis Inverter Status slave: 1 address: 33095 input_type: input data_type: uint16 lazy_error_count: 5 scan_interval: 30 scale: 1 precision: 1 state_class: measurement # Holding registers # Timed Charge and Discharge Currenmt Limits (R/W) - name: Solis Charge Current Limit slave: 1 address: 43117 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 0.1 precision: 1 state_class: measurement device_class: current unit_of_measurement: A - name: Solis Discharge Current Limit slave: 1 address: 43118 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 0.1 precision: 1 state_class: measurement device_class: current unit_of_measurement: A # Timed Charge and Discharge Settings (R/W) - name: Solis Timed Charge Current Limit slave: 1 address: 43141 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 0.1 precision: 1 state_class: measurement device_class: current unit_of_measurement: A - name: Solis Timed Discharge Current Limit slave: 1 address: 43142 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 0.1 precision: 1 state_class: measurement device_class: current unit_of_measurement: A - name: Solis Timed Charge Start Hour slave: 1 address: 43143 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Charge Start Minute slave: 1 address: 43144 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Charge End Hour slave: 1 address: 43145 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Charge End Minute slave: 1 address: 43146 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Discharge Start Hour slave: 1 address: 43147 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Discharge Start Minute slave: 1 address: 43148 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Discharge End Hour slave: 1 address: 43149 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Discharge End Minute slave: 1 address: 43150 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement # 2nd Timed slots - name: Solis Timed Charge 2 Start Hour slave: 1 address: 43153 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Charge 2 Start Minute slave: 1 address: 43154 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Charge 2 End Hour slave: 1 address: 43155 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Charge 2 End Minute slave: 1 address: 43156 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Discharge 2 Start Hour slave: 1 address: 43157 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Discharge 2 Start Minute slave: 1 address: 43158 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Discharge 2 End Hour slave: 1 address: 43159 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Discharge 2 End Minute slave: 1 address: 43160 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement # 3rd Timed slots - name: Solis Timed Charge 3 Start Hour slave: 1 address: 43163 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Charge 3 Start Minute slave: 1 address: 43164 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Charge 3 End Hour slave: 1 address: 43165 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Charge 3 End Minute slave: 1 address: 43166 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Discharge 3 Start Hour slave: 1 address: 43167 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Discharge 3 Start Minute slave: 1 address: 43168 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Discharge 3 End Hour slave: 1 address: 43169 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Timed Discharge 3 End Minute slave: 1 address: 43170 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement - name: Solis Backup Mode SOC slave: 1 address: 43024 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement device_class: battery unit_of_measurement: "%" - name: Solis Overdischarge SOC slave: 1 address: 43011 input_type: holding data_type: uint16 lazy_error_count: 5 scan_interval: 60 scale: 1 precision: 0 state_class: measurement device_class: battery unit_of_measurement: "%" STEP 3: Inside /config/configuration.yaml, add the following line modbus: !include solis.yaml STEP 4: Inside /config/configuration.yaml, add the following line template: !include solis-template.yaml Create /config/solis-template.yaml and add the following inside - sensor: - name: "Solis Battery SOC - Lead" unique_id: solis_battery_soc_leadacid unit_of_measurement: "%" state_class: measurement state: >- {% set num_batteries = 4 %} {% set total_voltage = states('sensor.solis_battery_voltage') | float %} {% set breakpoints = [ (52.0, 100), (51.8, 98), (51.6, 96), (51.4, 95), (51.3, 95), (51.2, 92.5), (51.1, 90), (51.05, 88), (51.0, 85), (50.9, 82), (50.8, 80), (50.7, 78), (50.6, 75), (50.5, 73), (50.4, 70), (50.3, 68), (50.2, 65), (50.1, 63), (50.0, 60), (49.8, 58), (49.6, 56), (49.4, 54), (49.2, 52), (49.0, 50), (48.8, 48), (48.6, 46), (48.4, 44), (48.2, 42), (48.0, 40), (47.9, 39), (47.8, 38), (47.7, 37), (47.6, 36), (47.5, 35), (47.4, 34), (47.3, 33), (47.25, 32), (46.9, 31), (46.2, 10), (46.04, 10), (46.0, 10), (45.8, 5), (45.6, 3), (45.4, 2), (45.2, 1) ] %} {% set state_of_charge = 0 %} {% for voltage, percentage in breakpoints %} {% if total_voltage >= voltage %} {% set state_of_charge = percentage %} {% break %} {% endif %} {% endfor %} {% if state_of_charge == 0 and total_voltage > breakpoints[-1][0] %} {% set state_of_charge = 100 %} {% endif %} {{ state_of_charge | round(2) }} - name: "Solis Grid Active Power (Negative)" unique_id: "Solis Grid Active Power (Negative)" unit_of_measurement: W device_class: power state_class: measurement state: >- {{ -1 * states('sensor.solis_grid_active_power') | float }} - name: "Solis Grid Export Power" unique_id: "Solis Grid Export Power" unit_of_measurement: W device_class: power state_class: measurement state: > {% set state = states.sensor.solis_grid_active_power.state | float %} {{ state if state > 0 else 0 }} - name: "Solis Grid Import Power" unique_id: "Solis Grid Import Power" unit_of_measurement: W device_class: power state_class: measurement state: > {% set state = states.sensor.solis_grid_active_power.state | float %} {{ -1 * state if state < 0 else 0 }} - name: "Solis Grid Mode" unique_id: "Solis Grid Mode" state: > {% set state = states.sensor.solis_grid_active_power.state | float %} {% if state > 50 -%} Export {%- elif state <-50 -%} Import {%- else -%} Zero {%- endif %} - name: "Solis Battery Mode" unique_id: "Solis Battery Mode" state: > {% set state = states.sensor.solis_battery_current_direction.state | int %} {{ 'Discharge' if state > 0 else 'Charge' }} - name: "Solis Battery Charge Power" unique_id: "Solis Battery Charge Power" device_class: power state_class: measurement unit_of_measurement: W state: > {% set state = states.sensor.solis_battery_current_direction.state | int %} {{ 0 if state > 0 else states('sensor.solis_battery_power') | float(2) }} - name: "Solis Battery Discharge Power" unique_id: "Solis Battery Discharge Power" device_class: power state_class: measurement unit_of_measurement: W state: > {% set state = states.sensor.solis_battery_current_direction.state | int %} {{ states('sensor.solis_battery_power') | float(2) if state > 0 else 0 }} - name: "Solis Manual Storage Mode" unique_id: "Solis Manual Storage Mode" state: > {{(states('input_boolean.solis_storage_mode_spontaneous') == 'on') | int + 2 * (states('input_boolean.solis_storage_mode_timed') == 'on') | int + 4 * (states('input_boolean.solis_storage_mode_off_grid') == 'on') | int + 8 * (states('input_boolean.solis_storage_mode_wake_up') == 'on') | int + 16 * (states('input_boolean.solis_storage_mode_backup') == 'on') | int + 32 * (states('input_boolean.solis_storage_mode_grid_charge') == 'on') | int + 64 * (states('input_boolean.solis_solis_storage_mode_feed_in_priority') == 'on') | int }} - name: "Solis Eco7 Time Remaining" unique_id: "Solis Eco7 Time Remaining" state_class: measurement state: > {% if today_at(states('input_datetime.economy_7_end')) < now() -%} {{(((today_at(states('input_datetime.economy_7_end')) - today_at(states('input_datetime.economy_7_start')))).total_seconds() / 36) | int / 100}} {%- else -%} {{max((((today_at(states('input_datetime.economy_7_end')) - max(now(), today_at(states('input_datetime.economy_7_start')))).total_seconds() / 36) | int) / 100,0)}} {%- endif %} - name: "Solis Eco7 Charge Current" unique_id: "Solis Eco7 Charge Current" device_class: current state_class: measurement unit_of_measurement: A state: > {{( ((states('input_number.solis_battery_capacity') | int * 1000) * ((states('input_number.eco7_target_soc') | int) - (states('sensor.solis_battery_soc') | int)) ) / 10 / (states('sensor.solis_eco7_time_remaining') | float) / (states('sensor.solis_battery_voltage_bms') | float) ) | int / 10 }} STEP 5 (OPTIONAL): This is so you are able to write to the inverter from HA, see https://github.com/fboundy/ha_solis_modbus#writing-to-the-inverter for more options. Add the following to your /config/scripts.yaml file, or create one if it doesn't exist. If it doesn't exist, just add script: !include scripts.yaml into /config/configuration.yaml set_solis_storage_toggles: alias: Set Solis Storage Toggles sequence: - if: - condition: template value_template: "{{states('sensor.solis_energy_storage_control_switch') | int | bitwise_and(64) == 64}}" then: - service: input_boolean.turn_on data: {} target: entity_id: - input_boolean.solis_storage_mode_feed_in_priority else: - service: input_boolean.turn_off data: {} target: entity_id: input_boolean.solis_storage_mode_feed_in_priority - if: - condition: template value_template: "{{states('sensor.solis_energy_storage_control_switch') | int | bitwise_and(32) == 32}}" then: - service: input_boolean.turn_on data: {} target: entity_id: - input_boolean.solis_storage_mode_grid_charge else: - service: input_boolean.turn_off data: {} target: entity_id: input_boolean.solis_storage_mode_grid_charge - if: - condition: template value_template: "{{states('sensor.solis_energy_storage_control_switch') | int | bitwise_and(16) == 16}}" then: - service: input_boolean.turn_on data: {} target: entity_id: input_boolean.solis_storage_mode_backup else: - service: input_boolean.turn_off data: {} target: entity_id: input_boolean.solis_storage_mode_backup - if: - condition: template value_template: "{{states('sensor.solis_energy_storage_control_switch') | int | bitwise_and(8) == 8}}" then: - service: input_boolean.turn_on data: {} target: entity_id: input_boolean.solis_storage_mode_wake_up else: - service: input_boolean.turn_off data: {} target: entity_id: - input_boolean.solis_storage_mode_wake_up - if: - condition: template value_template: "{{states('sensor.solis_energy_storage_control_switch') | int | bitwise_and(4) == 4}}" then: - service: input_boolean.turn_on data: {} target: entity_id: input_boolean.solis_storage_mode_off_grid else: - service: input_boolean.turn_off data: {} target: entity_id: input_boolean.solis_storage_mode_off_grid - if: - condition: template value_template: "{{states('sensor.solis_energy_storage_control_switch') | int | bitwise_and(2) == 2}}" then: - service: input_boolean.turn_on data: {} target: entity_id: - input_boolean.solis_storage_mode_timed else: - service: input_boolean.turn_off data: {} target: entity_id: input_boolean.solis_storage_mode_timed - if: - condition: template value_template: "{{states('sensor.solis_energy_storage_control_switch') | int | bitwise_and(1) == 1}}" then: - service: input_boolean.turn_on data: {} target: entity_id: input_boolean.solis_storage_mode_spontaneous else: - service: input_boolean.turn_off data: {} target: entity_id: - input_boolean.solis_storage_mode_spontaneous mode: single icon: mdi:toggle-switch-off-outline solis_set_time: alias: Solis Set Time sequence: - service: script.solis_write_holding_register data: register_addr: 43003 register_value: '{{now().hour}}' - service: script.solis_write_holding_register data: register_addr: 43004 register_value: '{{now().minute}}' - service: script.solis_write_holding_register data: register_addr: 43005 register_value: '{{now().second}}' mode: single solis_set_energy_storage_mode: alias: Solis Set Energy Storage Mode fields: storage_mode: description: Storage Mode to Set (uint16) example: 35 sequence: - service: script.solis_write_holding_register data: register_addr: 43110 register_value: "{{(states('input_boolean.solis_storage_mode_spontaneous') == 'on') | int + 2 * (states('input_boolean.solis_storage_mode_timed') == 'on') | int + 4 * (states('input_boolean.solis_storage_mode_off_grid') == 'on') | int + 8 * (states('input_boolean.solis_storage_mode_wake_up') == 'on') | int + 16 * (states('input_boolean.solis_storage_mode_backup') == 'on') | int + 32 * (states('input_boolean.solis_storage_mode_grid_charge') == 'on') | int }}" mode: single solis_set_charge_current: alias: Solis Set Charge Current fields: solis_set_charge_current: description: Fixed time charge current (A) example: 50 sequence: - service: script.solis_write_holding_register data: register_addr: 43141 register_value: "{{ charge_current * 10 }}" mode: single solis_write_holding_register: alias: Solis Write Holding Register fields: register_addr: description: Holding address to write to example: 43141 register_value: description: Value to write to holding address example: 500 sequence: - service: modbus.write_register data: address: "{{ register_addr }}" slave: 1 value: "{{ register_value }}" hub: solis - service: logbook.log data: message: Send {{register_value}} to {{register_addr}} name: Solis Write solis_set_eco7_times: alias: Solis Set Eco7 Times sequence: - service: script.solis_write_holding_register data: register_addr: 43143 register_value: "{{(states('input_datetime.economy_7_start')).split(':')[0] | int}}" - service: script.solis_write_holding_register data: register_addr: 43144 register_value: "{{(states('input_datetime.economy_7_start')).split(':')[1] | int}}" - service: script.solis_write_holding_register data: register_addr: 43145 register_value: "{{(states('input_datetime.economy_7_end')).split(':')[0] | int}}" - service: script.solis_write_holding_register data: register_addr: 43146 register_value: "{{(states('input_datetime.economy_7_end')).split(':')[1] | int}}" mode: single icon: mdi:battery-clock-outline LAST: Now restart home assistant, and you should see the new metrics/sensors pull in Edited December 2, 20232 yr by Pho3niX90 added integration link
November 7, 20232 yr Author For a nice live power view like this Just install power-flow-card-plus from hacs, I also recommend apexcharts-card for charting. The integrated "energy" view from HA doesn't support live information, so it's better to build your own energy dashboard For a "Gettting Started Dashboard" Install the following from hacs first layout-card stack-in-card history-explorer-card power-flow-card-plus views: - theme: Backend-selected title: Solis path: solis icon: mdi:flash cards: - type: custom:layout-card layout_type: custom:vertical-layout layout: width: 1000 max_cols: 1 cards: - type: custom:stack-in-card title: null mode: horizontal cards: - type: gauge entity: sensor.solis_inverter_dc_power name: Solar Power max: 6000 min: 0 needle: false - type: gauge entity: sensor.solis_backup_load_power name: Load max: 6000 min: 0 needle: false - type: gauge entity: sensor.solis_battery_soc name: Battery SOC needle: false severity: green: 50 yellow: 20 red: 12 - type: gauge entity: sensor.solis_inverter_ac_power name: Inverter Power max: 6000 min: -6000 needle: true severity: green: -6000 yellow: -10 red: 10 - type: gauge entity: sensor.solis_battery_power name: Battery Power max: 6000 min: -6000 needle: true severity: green: -6000 yellow: -10 red: 10 - type: gauge entity: sensor.solis_grid_active_power_negative name: Grid Power max: 6000 min: -6000 needle: true severity: green: -6000 yellow: -10 red: 10 - type: custom:layout-card layout_type: custom:masonry-layout layout: column_widths: 1fr 2fr; width: 400 cards: - type: custom:stack-in-card title: null mode: vertical cards: - type: energy-solar-consumed-gauge - type: custom:power-flow-card-plus entities: battery: entity: consumption: sensor.solis_battery_discharge_power production: sensor.solis_battery_charge_power state_of_charge: sensor.solis_battery_soc invert_state: true state_of_charge_unit: '%' display_state: two_way use_metadata: false color_value: true state_of_charge_unit_white_space: false grid: entity: sensor.solis_grid_active_power invert_state: true use_metadata: true name: Grid power_outage: entity: switch.grid_status_11 state_alert: 'off' solar: entity: sensor.solis_inverter_dc_power display_zero_state: true home: entity: sensor.solis_backup_load_power clickable_entities: true display_zero_lines: mode: show transparency: 50 grey_color: - 189 - 189 - 189 use_new_flow_rate_model: true w_decimals: 0 kw_decimals: 1 min_flow_rate: 0.75 max_flow_rate: 12 max_expected_power: 6000 min_expected_power: 300 watt_threshold: 1000 transparency_zero_lines: 0 title: Live power view_layout: position: sidebar - type: custom:history-explorer-card header: Power Chart cardName: historycard-93716784 combineSameUnits: true graphs: - type: line title: Load / Grid / Solar options: interval: daily ymax: 4000 entities: - entity: sensor.solis_grid_active_power_negative name: Grid - entity: sensor.solis_backup_load_power name: Load - entity: sensor.solis_inverter_dc_power name: Solar Power - entity: sensor.power_production_now color: white fill: rgba(0,0,0,0) name: Forecast Solar - type: line title: Battery options: interval: daily ymin: 0 ymax: 100 entities: - entity: sensor.solis_battery_soc Edited November 7, 20232 yr by Pho3niX90
November 7, 20232 yr Awesome, I was wondering if Solis had something which could integrate into Home Assistant. I was considering the Solis inverters as an upgrade from the Luxpower (for in the future possibly), although Home Assistant integration is a deal breaker for me. Good to know this is available and one can write changes to the inverter settings for easy automation based on weather, loadshedding etc. I assume one would also be able to use the Sunsynk card by @slipx ? Just the entity names which would differ?
November 7, 20232 yr 9 minutes ago, PsyCLown said: Awesome, I was wondering if Solis had something which could integrate into Home Assistant. I was considering the Solis inverters as an upgrade from the Luxpower (for in the future possibly), although Home Assistant integration is a deal breaker for me. Good to know this is available and one can write changes to the inverter settings for easy automation based on weather, loadshedding etc. I assume one would also be able to use the Sunsynk card by @slipx ? Just the entity names which would differ? Yeah the way this has been setup you would just change the entities on Slipx card and bobs your uncle
November 7, 20232 yr Author 37 minutes ago, PsyCLown said: Awesome, I was wondering if Solis had something which could integrate into Home Assistant. I was considering the Solis inverters as an upgrade from the Luxpower (for in the future possibly), although Home Assistant integration is a deal breaker for me. Good to know this is available and one can write changes to the inverter settings for easy automation based on weather, loadshedding etc. I assume one would also be able to use the Sunsynk card by @slipx ? Just the entity names which would differ? It definitely works, for most sensors, it's just a matter of replacing the prefix "sunsynk" with "solis", the only thing that might need a PR is the inverter status, as I am not sure if they share the same numerical representation for the statuses. I will see if I can do a PR
November 7, 20232 yr 3 hours ago, PsyCLown said: Awesome, I was wondering if Solis had something which could integrate into Home Assistant. I was considering the Solis inverters as an upgrade from the Luxpower (for in the future possibly), although Home Assistant integration is a deal breaker for me. Good to know this is available and one can write changes to the inverter settings for easy automation based on weather, loadshedding etc. I assume one would also be able to use the Sunsynk card by @slipx ? Just the entity names which would differ? I know some people are using the card with Solis. There is an example here as well the integration method used https://slipx06.github.io/sunsynk-power-flow-card/examples/solis.html
November 8, 20232 yr Author 11 hours ago, slipx said: I know some people are using the card with Solis. There is an example here as well the integration method used https://slipx06.github.io/sunsynk-power-flow-card/examples/solis.html I created a PR last night, to support the solis statuses, battery discharge direction, grid down via voltage etc. I will help maintain from the solis side of things
December 2, 20232 yr Author This post was recognized by Energy-Jason! Pho3niX90 was awarded the badge 'Great Content' and 20 points. I have gone ahead an created an integration for the solis. Whilst the modbus did work, it sometimes created timeouts. The integration combines multiple registers into single calls, eliminating overhead, and also combining the entities into a single device. Repo: https://github.com/Pho3niX90/solis_modbus
December 4, 20232 yr On 2023/12/02 at 3:37 PM, Pho3niX90 said: I have gone ahead an created an integration for the solis. Whilst the modbus did work, it sometimes created timeouts. The integration combines multiple registers into single calls, eliminating overhead, and also combining the entities into a single device. Repo: https://github.com/Pho3niX90/solis_modbus This is a game changer. 100 times easier to setup and the data polling is perfect every time. Thank you for your effort and the patience you have had in helping me. I am a total noob at HA and you have helped every time!!
June 2, 20242 yr Im trying to connect to my solis inverter but it wont work. when I enter the ip and port it gives an error. I have the s2-wl-st stick.
June 22, 20242 yr On 2023/12/04 at 9:45 PM, cp69 said: This is a game changer. 100 times easier to setup and the data polling is perfect every time. Thank you for your effort and the patience you have had in helping me. I am a total noob at HA and you have helped every time!! "The datalogger will no longer report to the cloud, but support will still be able to assist with firmware upgrades, and remotely change settings" Is this also true for the Phoenix Modbus? Since enabling it my SolisCloud has gone dead
June 25, 20242 yr @Pho3niX90 what I am seeing with the latest modbus in my setup is intermittent data loss - This creates other problems where I have HA automation rules for example that looks when grid frequency goes to 0 only to find that it was a false positive. My datalogger is connected with CAT6 and tests 300mbps. In the Solis.yaml you have set the scan interval to every 60 seconds. In the Modbus method the sensor.py has a 5 second scan interval. Could it be that such a short interval across mutliple metrics could cause an issue? I like the added data metrics coming in but it degrades in the usability if the data ingestion is this sporadic... Edited June 25, 20242 yr by L_D
July 9, 20241 yr On 2024/06/25 at 5:02 PM, L_D said: @Pho3niX90 what I am seeing with the latest modbus in my setup is intermittent data loss - This creates other problems where I have HA automation rules for example that looks when grid frequency goes to 0 only to find that it was a false positive. My datalogger is connected with CAT6 and tests 300mbps. In the Solis.yaml you have set the scan interval to every 60 seconds. In the Modbus method the sensor.py has a 5 second scan interval. Could it be that such a short interval across mutliple metrics could cause an issue? I like the added data metrics coming in but it degrades in the usability if the data ingestion is this sporadic... I would recommend reaching out to Solis support as they said to us they had a firmware version to fix the grid frequency issue that some users have been experiencing. Note that they would need to have the inverter online in the portal as they push the firmware via the portal on their side. Hope This Helps You can email them at [email protected]
August 5, 20241 yr Has anyone else's modbus integration stopped working? Mine has gone dead. IP address is correct(static IP) and I can't see anything out of the ordinary
September 4, 20241 yr I'm desperately trying to get my S2-WL-ST to work on the Solis. I managed to connect to port 502 once with Modbuss Poll (as described by Solis), then never again. Do I have to set anything else so that port 502 is served?
February 13, 20251 yr Author Sorry was away for a while from the forum. The issues listed here have all been fixed since. I do not want to unnecessarily ping all, if you still have issues feel free to open an issue on the github page, or just ping me again. Will check in daily.
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.