Git Product home page Git Product logo

Comments (7)

fboundy avatar fboundy commented on June 30, 2024 1

43110 - is defined bit-wise as follows:

    Bit 0 (1)  - Spontaneous Mode      input_boolean.solis_storage_mode_spontaneous
    Bit 1 (2)  - Timed Mode            input_boolean.solis_storage_mode_timed
    Bit 2 (4)  - Off-Grid Mode         input_boolean.solis_storage_mode_off_grid
    Bit 3 (8)  - Battery Wake-Up Mode  input_boolean.solis_storage_mode_wake_up
    Bit 4 (16) - Backup Mode           input_boolean.solis_storage_mode_backup
    Bit 5 (32) - Grid Charge Mode      input_boolean.solis_storage_mode_grid_charge

So for timed charging you need both Bit 5 (32) and Bit 1 (2). Bit 0 seems to tell it to spontaneously follow the mode outside of timed periods (ie Self-Use). Hence 35 gives you timed charging (Bit 1 set) and 33 gives you normal Self-Use but with grid charging enabled.

from solis2mqtt.

NickSutton avatar NickSutton commented on June 30, 2024

I was able to make some progress with this, and it's actually fairly straight forward as the developer has already included the code to write a change to the inverter on receipt of a MQTT message.

So, for anyone else wanting to achieve the same these are the steps I put in place:

Subscribing to MQTT Topics
Your remote Pi Zero W, or whatever you have attached to the inverter is busy sending information from the solis to Home Assistant via MQTT. Presently it is not listening for replies from HA. To do this we need to get the Pi Zero W (or whatever) to subscribe to a 'topic' so it can listen out for those communications.

This piece of code, already included in solis2mqtt.py does just that:

    def subscribe(self):
        for entry in self.register_cfg:
            if 'write_function_code' in entry['modbus']:
                if not self.mqtt.on_message:
                    self.mqtt.on_message = self.on_mqtt_message
                logging.info("Subscribing to: "+self.cfg['inverter']['name'] + "/" + entry['name'] + "/set")
                self.mqtt.persistent_subscribe(self.cfg['inverter']['name'] + "/" + entry['name'] + "/set")

If we break this down we can see that the code is checking each of the registry blocks (in solis_modbus.yaml) for a write_function_code entry. If such an entry exists then MQTT will subscribe to a topic named as:

"+self.cfg['inverter']['name'] + "/" + entry['name'] + "/set"

The above naming draws from the config.yaml to get the inverter name, typically solis2mqtt followed by the name of the register block that contains the write_function_code entry. So could be something like:

solis2mqtt/write_storage_control/set

Now, in solis_modbus.yaml add a block in the following format:

- name: write_storage_control
  active: true
  modbus:
    register: 43110
    number_of_decimals: 0
    write_function_code: 6
    input_type: holding
    signed: false

It would be handy if we could build a list of the writable register codes here, 43110 is used to change the storage control value (typically 33/35)

Restart the process on the remote Pi Zero W with sudo systemctl restart solis2mqtt to take in to account the new register block.

You should see in the log that the topic (in this case) solis2mqtt/write_storage_control/set has been subscribed to, which means the Pi Zero W is now listening.

From HA you can use dev tools > services to issue a MQTT communication in a designated topic:

Screenshot 2022-11-28 at 12 42 31

The above should set your storage control value to 35 (if it is 33 currently etc).

To change different settings on the inverter just add new register blocks (with the correct register value!!) then issue new values to that MQTT topic.

Disclaimer: I don't know what I'm talking about most of the time and figured all this out in the middle of the night but it seems to work, as does my inverter. That said, if you mess this up you might well brick your inverter and need a replacement etc. All of the above at your own risk, I accept no responsibility for anything, at all, ever.

from solis2mqtt.

NickSutton avatar NickSutton commented on June 30, 2024

43110 - Storage control, usually 33 / 35
43000 - Inverter date/time: Year
43001 - Inverter date/time: Month
43002 - Inverter date/time: Day
43003 - Inverter date/time: Hour
43004 - Inverter date/time: Minute

43141 is the fixed period charge current in deci-Amps (ie 500 -> 50A) for dynamically changing the charge current limit

43141 - Time Charge Current
43142 - Time Discharge Current
43143 - Time Charge Start Hour
43144 - Time Charge Start Minute
43145 - Time Charge End Hour
43146 - Time Charge End Minute

This link is very useful: https://www.boards.ie/discussion/2058224611/solar-pv-monitoring-automation-thread/p25?fbclid=IwAR2J6yGwUrC6bol7VZ3YeoKDHZnY2H0ybJRIUNlsszz5l51GBee8dowKDng

from solis2mqtt.

NickSutton avatar NickSutton commented on June 30, 2024

Registers needed in solis2mqtt_modbus.yaml to write a charging window and current limit.

(This means the solis will charge for the full duration of the charging window, at the lowest possible current which should be kinder to batteries)

# Writable registry entries
# Battery charge Limit
- name: write_battery_charge_limit
  active: true
  modbus:
    register: 43141
    number_of_decimals: 0
    write_function_code: 6
    input_type: holding
    signed: false

# Write charging window
- name: write_charging_window_start_hours
  active: true
  modbus:
    register: 43143
    number_of_decimals: 0
    write_function_code: 6
    input_type: holding
    signed: false

- name: write_charging_window_start_mins
  active: true
  modbus:
    register: 43144
    number_of_decimals: 0
    write_function_code: 6
    input_type: holding
    signed: false

- name: write_charging_window_close_hours
  active: true
  modbus:
    register: 43145
    number_of_decimals: 0
    write_function_code: 6
    input_type: holding
    signed: false

- name: write_charging_window_close_mins
  active: true
  modbus:
    register: 43146
    number_of_decimals: 0
    write_function_code: 6
    input_type: holding
    signed: false

from solis2mqtt.

NickSutton avatar NickSutton commented on June 30, 2024

HA Script to write the charging window to the solis.

You will need to create the input_datetime helpers to set the start and end times

Settings > Devices & Services > Helpers > Create Helper > Date and/or Time > Time only

Then create the script below by pasting:
Settings > Automations & Scenes > Scripts > Add New (View in YAML)

alias: Write Solis Charging Window
sequence:
  - service: mqtt.publish
    data:
      topic: solis2mqtt/write_charging_window_start_hours/set
      payload_template: "{{(states('input_datetime.charging_start_time')).split(':')[0] | int}}"
  - service: mqtt.publish
    data:
      topic: solis2mqtt/write_charging_window_start_mins/set
      payload_template: "{{(states('input_datetime.charging_start_time')).split(':')[1] | int}}"
  - service: mqtt.publish
    data:
      topic: solis2mqtt/write_charging_window_close_hours/set
      payload_template: "{{(states('input_datetime.charging_end_time')).split(':')[0] | int}}"
  - service: mqtt.publish
    data:
      topic: solis2mqtt/write_charging_window_close_mins/set
      payload_template: "{{(states('input_datetime.charging_end_time')).split(':')[1] | int}}"
mode: single
icon: mdi:clock-digital

Run that then check the charging window on the solis. Disclaimer from above post applies.

from solis2mqtt.

NickSutton avatar NickSutton commented on June 30, 2024

To set the charging window we need some new entities and a new helper to set the charge target

Settings > Devices & Services > Helpers > Create Helper > Number

Also make sure you are pulling the battery voltage from the solis:

- name: battery_voltage
  description: Battery Voltage
  unit: V
  active: true
  modbus:
    register: 33133
    read_type: register
    number_of_decimals: 1
    function_code: 4
    signed: false
  homeassistant:
    device: sensor
    state_class: measurement
    device_class: voltage

In config.yaml create the following entities:

template:
  - sensor:
    ####### SOLIS DYNAMIC CHARGING
    - name: 'Charging Time Remaining'
      icon: 'mdi:timelapse'
      state: >
            {% if today_at(states('input_datetime.charging_end_time')) < now() -%}
                {{(((today_at(states('input_datetime.charging_end_time')) -
                  today_at(states('input_datetime.charging_start_time'))))
                  .total_seconds() / 36) | int / 100 }}
            {%- else -%}
                {{ max((((today_at(states('input_datetime.charging_end_time')) - 
                    max(now(), today_at(states('input_datetime.charging_start_time'))))
                    .total_seconds() / 36) | int) / 100) }}
            {%- endif %}
            
    - name: 'Target Charge Limit'
      icon: 'mdi:sine-wave'
      unit_of_measurement: 'A'
      state: >
            {{ ((
                (states('input_number.charge_target')|int / 100) - 
                (states('sensor.battery_soc')|int / 100)
               ) * 
              10000 / 
              states('sensor.battery_voltage')|int /
              states('sensor.charging_time_remaining')|int
              ) | round(1)
            }}

Then create the following script

alias: Set Solis Charging Current
sequence:
  - service: mqtt.publish
    data:
      topic: solis2mqtt/write_battery_charge_limit/set
      payload_template: "{{ states('sensor.target_charge_limit')|int * 10 }}"
mode: single
icon: mdi:sine-wave

from solis2mqtt.

NickSutton avatar NickSutton commented on June 30, 2024

Lastly, here is the automation I've used to call the two scripts every 20 mins within the charging window.

alias: Solis Overnight Inverter Charge Rate
description: >-
  Set Solis Inverter overnight charge rate so that it lasts the duration of the
  off peak period
trigger:
  - platform: time_pattern
    minutes: "0"
  - platform: time_pattern
    minutes: "20"
  - platform: time_pattern
    minutes: "40"
  - platform: time
    at: input_datetime.charging_start_time
condition:
  - condition: time
    after: input_datetime.charging_start_time
    before: input_datetime.charging_end_time
action:
  - service: script.set_solis_charging_current
    data: {}
  - service: script.write_solis_charging_window
    data: {}
mode: single

Huge thanks to @fboundy, without whom I'd have never got started with this

from solis2mqtt.

Related Issues (14)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.