MODBUS help needed - Ampinvt solar controller to Home Assistant via ESPhome

It is unlikely that this code would work as-is but the principle is the same. All I did for this project was take the work of others and adapt it for the Ampinvt units so you could do the same for Renogy.

Those Renogy units are popular though, I’d be surprised if someone hadn’t already done it in HACS or somewhere on Github.

@TripitakaBC Are you still around these parts? I have spent two days trying to get this wrapped up and im close. There are a few questions I have if you are.

What pin on the RJ45 is considered 1? I get conflicting answers.

Second, I only get Unknown as value for the sensors. I cant tell if it is because of wiring, or because of the H file. If yours is unplugged from your charger, does it drop to zero, or go to unk?

Many thanks.

I’m still around!

I’ll need to revisit to check out the RJ45 question and the whole project in general; it has been sat there chugging away and I’ll need to refresh myself.

You do, however, raise an enlightening issue. My own sensors went to ‘Unknown’ status a while back, right about the same time I had a malfunction with my powerful electric fencing. I figured that I had fried the modbus hardware so I swapped them out with no improvement so I figured that I had fried the interface in the controller. I thought it was a long shot that it had also taken out my DC shunt interface but…it could happen.

With your post, I’m now thinking that it may not be hardware at all, it may be code changes in ESPhome that is causing the issue.

Either way, I’ll have to revisit and get back to you. It may be a while but I’ll see what I can do.

Im glad you are still around. Im new to coding. I have done a lot of tinkering, working on this will be the biggest thing I’m learning. If i figure out anything, Ill update here as well. Thank you so much!

I got it! I’ve tried so many things, but i think in my case TX goes to TX and RX to RX… I watched some obscure Indian video on Youtube and found that this is the case with the RS485 to TTL i have.

image

This is my Yaml. I actually copied it from @kitt2011 comment. The one listed in the project wouldn’t compile for me.

The supplied .H file works fine though.

  esphome:
    name: "solarcharger"
    comment: "Solar Charge Controller"
    includes:
      - ampinvt.h
 

  esp32:
    board: esp32dev
    framework:
      version: recommended
      type: arduino

 

  logger:
    baud_rate: 0
    level: DEBUG

  wifi:
    ssid: Brown Haus 2G
    password: Forreston1
    reboot_timeout: 8hours
    ap:
      ssid: "${devicename}"
      password: fallback_password
    manual_ip:
      static_ip: 192.168.1.100
      gateway: 192.168.1.1
      subnet: 255.255.255.0
    use_address: 192.168.1.100
 

  captive_portal:

  api:
    encryption:
      key: uhKxfrQ8TOE+EpHHJZnas0YINhTkx3RQH2aSp6+gXTY=
  ota:
    - platform: esphome
      password: Netpass1.
      port: 8266
   

  uart:

    id: uart_bus

    tx_pin: 17 # Yellow Wire - MPPT UART Transmit

    rx_pin: 16 # Green Wire - MPPT UART Receive

    rx_buffer_size: 2048

    baud_rate: 9600

    parity: NONE

    stop_bits: 1

    debug:

 

  time:
    - platform: homeassistant
      id: esptime
      on_time:
        - seconds: 0,30
          then:
            - uart.write: [ 0x01, 0xB3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xB5 ] # Reads only real-time data
  #          - uart.write: [ 0x01, 0xB2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xB4 ] # Reads only parameter settings

 

  sensor:
  - platform: custom

    lambda: |-

      auto ampinvtsensors = new ampinvtsensor(id(uart_bus));

      App.register_component(ampinvtsensors);

      return {\

      ampinvtsensors->ampinvt_op_status, \

      ampinvtsensors->ampinvt_battery_status, \

      ampinvtsensors->ampinvt_fan_status, \

      ampinvtsensors->ampinvt_overheat_status, \

      ampinvtsensors->ampinvt_dcoutput_status, \

      ampinvtsensors->ampinvt_inttemp1_status, \

      ampinvtsensors->ampinvt_inttemp2_status, \

      ampinvtsensors->ampinvt_exttemp_status, \

      ampinvtsensors->ampinvt_chg_status, \

      ampinvtsensors->ampinvt_equalchg_status, \

      ampinvtsensors->ampinvt_track_status, \

      ampinvtsensors->ampinvt_floatchg_status, \

      ampinvtsensors->ampinvt_chgcurrentlimit_status, \

      ampinvtsensors->ampinvt_chgderating_status, \

      ampinvtsensors->ampinvt_remoteprohibchg_status, \

      ampinvtsensors->ampinvt_pvovervolt_status, \

      ampinvtsensors->ampinvt_chgoutputrelay_status, \

      ampinvtsensors->ampinvt_loadoutput_status, \

      ampinvtsensors->ampinvt_fanrelay_status, \

      ampinvtsensors->ampinvt_overchgprotect_status, \

      ampinvtsensors->ampinvt_overvoltprotect_status, \

      ampinvtsensors->ampinvt_pv_voltage, \

      ampinvtsensors->ampinvt_battery_voltage, \

      ampinvtsensors->ampinvt_charge_current, \

      ampinvtsensors->ampinvt_mppt_temperature, \

      ampinvtsensors->ampinvt_battery_temperature, \

      ampinvtsensors->ampinvt_today_yield, \

      ampinvtsensors->ampinvt_generation_total, \

      };

    sensors:

    - name: "Operating Status"

      id: ampinvt_op_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_op_status_text_sensor).publish_state("Normal");

              }

              else  {

                id(ampinvt_op_status_text_sensor).publish_state("Abnormal");

              }

    - name: "Battery Status"

      id: ampinvt_battery_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_battery_status_text_sensor).publish_state("Normal");

              }

              else  {

                id(ampinvt_battery_status_text_sensor).publish_state("OD Protection On");

              }

    - name: "Fan Status"

      id: ampinvt_fan_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_fan_status_text_sensor).publish_state("Normal");

              }

              else  {

                id(ampinvt_fan_status_text_sensor).publish_state("Fan Failure");

              }

    - name: "Overheat Status"

      id: ampinvt_overheat_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_overheat_status_text_sensor).publish_state("Normal");

              }

              else  {

                id(ampinvt_overheat_status_text_sensor).publish_state("OT Protection On");

              }

    - name: "DC Output Status"

      id: ampinvt_dcoutput_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_dcoutput_status_text_sensor).publish_state("Normal");

              }

              else  {

                id(ampinvt_dcoutput_status_text_sensor).publish_state("DC Output Short");

              }

    - name: "Internal Temperature 1 Status"

      id: ampinvt_inttemp1_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_inttemp1_status_text_sensor).publish_state("Normal");

              }

              else  {

                id(ampinvt_inttemp1_status_text_sensor).publish_state("Fault");

              }

    - name: "Internal Temperature 2 Status"

      id: ampinvt_inttemp2_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_inttemp2_status_text_sensor).publish_state("Normal");

              }

              else  {

                id(ampinvt_inttemp2_status_text_sensor).publish_state("Fault");

              }

    - name: "External Temperature Status"

      id: ampinvt_exttemp_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_exttemp_status_text_sensor).publish_state("Normal");

              }

              else  {

                id(ampinvt_exttemp_status_text_sensor).publish_state("Fault");

              }

    - name: "Charging Status"

      id: ampinvt_chg_status

      icon: mdi:battery-charging

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_chg_status_text_sensor).publish_state("Not Charging");

              }

              else  {

                id(ampinvt_chg_status_text_sensor).publish_state("Charging");

              }

    - name: "Equal Charging Status"

      id: ampinvt_equalchg_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_equalchg_status_text_sensor).publish_state("Not Equalising");

              }

              else  {

                id(ampinvt_equalchg_status_text_sensor).publish_state("Equalising");

              }

    - name: "MPPT Tracking Status"

      id: ampinvt_track_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_track_status_text_sensor).publish_state("Not Tracking");

              }

              else  {

                id(ampinvt_track_status_text_sensor).publish_state("Tracking");

              }

    - name: "Float Charging Status"

      id: ampinvt_floatchg_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_floatchg_status_text_sensor).publish_state("Not Float Charging");

              }

              else  {

                id(ampinvt_floatchg_status_text_sensor).publish_state("Float Charging");

              }

    - name: "Charge Current Limit Status"

      id: ampinvt_chgcurrentlimit_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_chgcurrentlimit_status_text_sensor).publish_state("Normal");

              }

              else  {

                id(ampinvt_chgcurrentlimit_status_text_sensor).publish_state("Charge Current Limit");

              }

    - name: "Charge Derating Status"

      id: ampinvt_chgderating_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_chgderating_status_text_sensor).publish_state("Normal");

              }

              else  {

                id(ampinvt_chgderating_status_text_sensor).publish_state("Charge Derated");

              }

    - name: "Remote Prohibit Charging Status"

      id: ampinvt_remoteprohibchg_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_remoteprohibchg_status_text_sensor).publish_state("Normal");

              }

              else  {

                id(ampinvt_remoteprohibchg_status_text_sensor).publish_state("Remote denial");

              }

    - name: "Panel Overvoltage Status"

      id: ampinvt_pvovervolt_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_pvovervolt_status_text_sensor).publish_state("Normal");

              }

              else  {

                id(ampinvt_pvovervolt_status_text_sensor).publish_state("PV Overvoltage");

              }

    - name: "Charging Output Relay Status"

      id: ampinvt_chgoutputrelay_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_chgoutputrelay_status_text_sensor).publish_state("Closed");

              }

              else  {

                id(ampinvt_chgoutputrelay_status_text_sensor).publish_state("Open");

              }

    - name: "Load Output Status"

      id: ampinvt_loadoutput_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_loadoutput_status_text_sensor).publish_state("Closed");

              }

              else  {

                id(ampinvt_loadoutput_status_text_sensor).publish_state("Open");

              }

    - name: "Fan Relay Status"

      id: ampinvt_fanrelay_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_fanrelay_status_text_sensor).publish_state("Closed");

              }

              else  {

                id(ampinvt_fanrelay_status_text_sensor).publish_state("Open");

              }

    - name: "Overcharge Protection Status"

      id: ampinvt_overchgprotect_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_overchgprotect_status_text_sensor).publish_state("Normal");

              }

              else  {

                id(ampinvt_overchgprotect_status_text_sensor).publish_state("Overcharge Protection On");

              }

    - name: "Overvoltage Protection Status"

      id: ampinvt_overvoltprotect_status

      on_value:

        then:

          - lambda: |-

              if(x==0) {

                id(ampinvt_overvoltprotect_status_text_sensor).publish_state("Normal");

              }

              else  {

                id(ampinvt_overvoltprotect_status_text_sensor).publish_state("Overvoltage Protection On");

              }

    - name: "Solar Panel Voltage"

      id: ampinvt_pv_voltage

      unit_of_measurement: V

      accuracy_decimals: 1

      icon: mdi:flash

      filters:

        - multiply: 0.1

    - name: "Solar Battery Voltage"

      id: ampinvt_battery_voltage

      unit_of_measurement: V

      accuracy_decimals: 2

      icon: mdi:flash

      filters:

        - multiply: 0.01

    - name: "Solar Charge Current"

      id: ampinvt_charge_current

      unit_of_measurement: A

      accuracy_decimals: 2

      icon: mdi:current-dc

      filters:

      - multiply: 0.01

    - name: "Solar Controller Internal Temperature"

      id: ampinvt_mppt_temperature

      unit_of_measurement: °C

      accuracy_decimals: 1

      filters:

      - multiply: 0.1

    - name: "Solar Battery Temperature"

      id: ampinvt_battery_temperature

      unit_of_measurement: °C

      accuracy_decimals: 1

      filters:

        - multiply: 0.1

    - name: "Solar Daily Yield"

      id: ampinvt_today_yield

      unit_of_measurement: W

      accuracy_decimals: 1

      icon: mdi:solar-power

    - name: "Solar Total Yield"

      id: ampinvt_generation_total

      unit_of_measurement: KW

      device_class: energy #for use in energy dashboard

      state_class: total_increasing #for use in energy dashboard

      accuracy_decimals: 1

      icon: mdi:solar-power

      filters:

        - multiply: 0.001

  text_sensor:

  - platform: template

    name: "Ampinvt Operating Status"

    id: ampinvt_op_status_text_sensor

  - platform: template

    name: "Ampinvt Battery Status"

    id: ampinvt_battery_status_text_sensor

  - platform: template

    name: "Ampinvt Fan Status"

    id: ampinvt_fan_status_text_sensor

  - platform: template

    name: "Ampinvt Overheat Status"

    id: ampinvt_overheat_status_text_sensor

  - platform: template

    name: "Ampinvt DC Output Status"

    id: ampinvt_dcoutput_status_text_sensor

  - platform: template

    name: "Ampinvt Internal Temp #1 Status"

    id: ampinvt_inttemp1_status_text_sensor

  - platform: template

    name: "Ampinvt Internal Temp #2 Status"

    id: ampinvt_inttemp2_status_text_sensor

  - platform: template

    name: "Ampinvt External Temperature Status"

    id: ampinvt_exttemp_status_text_sensor

  - platform: template

    name: "Ampinvt Charging Status"

    id: ampinvt_chg_status_text_sensor

  - platform: template

    name: "Ampinvt Equalising Status"

    id: ampinvt_equalchg_status_text_sensor

  - platform: template

    name: "Ampinvt MPPT Tracking Status"

    id: ampinvt_track_status_text_sensor

  - platform: template

    name: "Ampinvt Float Charging Status"

    id: ampinvt_floatchg_status_text_sensor

  - platform: template

    name: "Ampinvt Charge Current Limit Status"

    id: ampinvt_chgcurrentlimit_status_text_sensor

  - platform: template

    name: "Ampinvt Charge Derating Status"

    id: ampinvt_chgderating_status_text_sensor

  - platform: template

    name: "Ampinvt Remote Prohib Status"

    id: ampinvt_remoteprohibchg_status_text_sensor

  - platform: template

    name: "Ampinvt Panel Overvoltage Status"

    id: ampinvt_pvovervolt_status_text_sensor

  - platform: template

    name: "Ampinvt Charging Output Relay Status"

    id: ampinvt_chgoutputrelay_status_text_sensor

  - platform: template

    name: "Ampinvt Load Output Status"

    id: ampinvt_loadoutput_status_text_sensor

  - platform: template

    name: "Ampinvt Fan Relay Status"

    id: ampinvt_fanrelay_status_text_sensor

  - platform: template

    name: "Ampinvt Overcharge Protection Status"

    id: ampinvt_overchgprotect_status_text_sensor

  - platform: template

    name: "Ampinvt Overvoltage Protection Status"

    id: ampinvt_overvoltprotect_status_text_sensor

  switch:

    - platform: restart

      name: "Solar Controller Restart"

      id: solar_controller_restart