Skip to content

Software for ESP32 to talk to Hoymiles/TSUN/Solenso Inverters

License

Notifications You must be signed in to change notification settings

soylentOrange/OpenDTU

 
 

Repository files navigation

OpenDTU with Modbus

For my personal needs, I wanted to have a smart meter with Modbus interface for my Hoymiles inverter. Instead of just buying one, I spend way too much time modifiying OpenDTU of tbnobody to include this feature. Luckily, most of the work was already done, see the acknowledgements.

Additional Modbus Interface

OpenDTU is extended by a Modbus server as proposed in PR#1893 - see the original fork of b0661.

The Modbus server serves TCP at port 502.

  • At Modbus ID 1 the server mimicks the Hoymiles Modbus TCP Interface registers in the original DTUPro.
  • At Modbus ID 125 the server serves a SunSpec compatible "total inverter" that provides the OpenDTU aggregated data from all registered inverters.
  • At Modbus ID 127 the server serves a SunSpec power meter that provides AC power and AC yield as if measuring all registered inverters.

Hint! Configure your inverter(s) in OpenDTU's inverter setting with the "Zero runtime data" option set to "on" to have an output of 0 Watts when the inverter is offline.

The webapp is extended by Modbus configuration and info views.

The Modbus library used for Modbus communication is eModbus. Documentation for the library is here. Note: I've forked eModbus to change the dependency of AsyncTCP and ESPAsyncTCP from me-no-dev to mathieucarbou/AsyncTCP and esphome/ESPAsyncTCP-esphome for using the eModbus-library in openDTU.

Homeassistant

Having the HACS addon Hoymiles Plant DTU-Pro Sensor installed in Home Assistant, add to Home Assistant's configuration.yaml:

sensor:
# change ip-address and panels to match your setup, the port is hardcoded to 502
  - platform: hoymiles_dtu
    host: 192.168.178.xxx
    name: Hoymiles PV
    # dtu_type for HM-type Inverter is 1
    dtu_type: 1
    monitored_conditions:
      - "pv_power"
      - "today_production"
      - "total_production"
      - "alarm_flag"
    monitored_conditions_pv:
      - "pv_power"
      - "today_production"
      - "total_production"
      - "pv_voltage"
      - "pv_current"
      - "grid_voltage"
      - "temperature"
      - "operating_status"
      - "alarm_code"
      - "alarm_count"
      - "link_status"
    panels: 3

Hint! Keep the port 502 and Modbus ID 1 for compatibility with HACS addon Hoymiles Plant DTU-Pro Sensor.

Minimal SunSpec Meter

A minimal SunSpec compliant meter is available at Modbus ID 127. Only provides AC power and AC yield as if measuring the output of all registered inverters. To be used e.g. as a "Fronius Smart Meter TCP" as orginally by AloisKlingler.

Fixed: This SunSpec Meter is functional now! Tested with pySunSpec2.

See output of the test script against ID 127 (minmal meter):

SunSpec compatibility test
using pySunSpec2

INFO: Test SunSpec-compatibility of 127 @ 192.168.178.112:502
INFO: open and scan device...

Got models:
  common
  ac_meter

common:
  ID:  1
  L:  65
  Mn:  OpenDTU
  Md:  OpenDTU Meter
  Opt:  Wemos D1 Mini 32
  Vr:  v24.11.7
  SN:  199980155940
  DA:  127

ac_meter:
  ID:  213
  L:  124
  A:  None
  AphA:  None
  AphB:  None
  AphC:  None
  PhV:  None
  PhVphA:  None
  PhVphB:  None
  PhVphC:  None
  PPV:  None
  PPVphAB:  None
  PPVphBC:  None
  PPVphCA:  None
  Hz:  None
  W:  -32.900001525878906
  WphA:  None
  WphB:  None
  WphC:  None
  VA:  None
  VAphA:  None
  VAphB:  None
  VAphC:  None
  VAR:  None
  VARphA:  None
  VARphB:  None
  VARphC:  None
  PF:  None
  PFphA:  None
  PFphB:  None
  PFphC:  None
  TotWhExp:  1307012.0
  TotWhExpPhA:  None
  TotWhExpPhB:  None
  TotWhExpPhC:  None
  TotWhImp:  0.0
  TotWhImpPhA:  None
  TotWhImpPhB:  None
  TotWhImpPhC:  None
  TotVAhExp:  None
  TotVAhExpPhA:  None
  TotVAhExpPhB:  None
  TotVAhExpPhC:  None
  TotVAhImp:  None
  TotVAhImpPhA:  None
  TotVAhImpPhB:  None
  TotVAhImpPhC:  None
  TotVArhImpQ1:  None
  TotVArhImpQ1phA:  None
  TotVArhImpQ1phB:  None
  TotVArhImpQ1phC:  None
  TotVArhImpQ2:  None
  TotVArhImpQ2phA:  None
  TotVArhImpQ2phB:  None
  TotVArhImpQ2phC:  None
  TotVArhExpQ3:  None
  TotVArhExpQ3phA:  None
  TotVArhExpQ3phB:  None
  TotVArhExpQ3phC:  None
  TotVArhExpQ4:  None
  TotVArhExpQ4phA:  None
  TotVArhExpQ4phB:  None
  TotVArhExpQ4phC:  None
  Evt:  0

INFO: close device...
INFO: Done!

Full SunSpec Meter

A SunSpec compliant inverter is available at Modbus ID 125, which provides the OpenDTU aggregated data from all registered inverters. To be used e.g. in evcc. Fixed: This SunSpec Meter is functional now! Tested with pySunSpec2.

See output of the test script against ID 125 (inverter):

SunSpec compatibility test
using pySunSpec2

INFO: Test SunSpec-compatibility of 125 @ 192.168.178.112:502
INFO: open and scan device...

Got models:
  common
  model_12
  inverter

common:
  ID:  1
  L:  66
  Mn:  OpenDTU
  Md:  OpenDTU Total
  Opt:  Wemos D1 Mini 32
  Vr:  v24.11.7
  SN:  199980155940
  DA:  125
  Pad:  32768

model_12:
  ID:  12
  L:  98
  Nam:  wifi
  CfgSt:  1
  ChgSt:  0
  Cap:  16
  Cfg:  1
  Ctl:  0
  Addr:  192.168.178.112
  Msk:  255.255.255.0
  Gw:  192.168.178.1
  DNS1:  192.168.178.244
  DNS2:  0.0.0.0
  NTP1:  None
  NTP2:  None
  DomNam:  None
  HostNam:  OpenDTU
  Pad:  32768

inverter:
  ID:  111
  L:  60
  A:  None
  AphA:  None
  AphB:  None
  AphC:  None
  PPVphAB:  None
  PPVphBC:  None
  PPVphCA:  None
  PhVphA:  None
  PhVphB:  None
  PhVphC:  None
  W:  15.699999809265137
  Hz:  None
  VA:  None
  VAr:  None
  PF:  None
  WH:  1306962.875
  DCA:  None
  DCV:  None
  DCW:  16.5
  TmpCab:  None
  TmpSnk:  None
  TmpTrns:  None
  TmpOt:  None
  St:  0
  StVnd:  0
  Evt1:  0
  Evt2:  0
  EvtVnd1:  0
  EvtVnd2:  0
  EvtVnd3:  0
  EvtVnd4:  0

INFO: close device...
INFO: Done!

Modbus Interface Details

The Modbus TCP server is available by default at port 502 and supports modbus FC03: READ_HOLD_REGISTER.

Hoymiles Modbus TCP Interface registers

The Modbus ID of the Hoymiles Modbus TCP Interface is 1 by default. See: src/ModbusDtuPro.cpp for the actually implemented registers.

Minimal SunSpec Meter Interface registers

The Modbus ID of the minimal SunSpec meter is 127 by default. See: Model 213 - Wye-Connect Meter Model (float) in the SunSpec Model repository for all of the registers and src/ModbusDtuMeter.cpp for the actually implemented registers. For a secondary production meter, added via modbus to a Fronius inverter (doesn't apply to all of their models), only a subset of the SunSpec mandatory points seems required:

  • Total Real Power (in W): Point 'W' in model 213 at offset 26
  • Total Real Energy Exported (in Wh): Point 'TotWhExp' in model 213 at offset 58

Additional Info when using the Minimal SunSpec Meter with Your Inverter:

  • The current firmware for my inverter will accept only a limited range for the modbus ID (thus, I changed the default value to 127)
  • The SunSpec model of the meter needs to be Model 213 - Wye-Connect Meter Model (float). Otherwise my inverter refused service.
  • Adding OpenDTU to the inverter is done by adding a component to your system (Production meter, Category: Inverter, Modbus Address: 127)
  • Note: You need to have the technician password in order to add OpenDTU to your inverter

Solarweb screenshot

Full SunSpec Meter Interface registers

The Modbus ID of the total SunSpec meter is 125 by default. See: Model 111 - Inverter (Single Phase) FLOAT Model in the SunSpec Model repository for all of the registers and src/ModbusDtuTotal.cpp for the actually implemented registers. For an inverter in pv usage mode, EVCC (see sunspec-inverter template) needs only:

  • AC Power (in W): point 'W' in model 111 at offset 20
  • AC Energy (in Wh): point 'WH' in model 111 at offset 30

To include the meter in EVCC, add an entry to the configuration evcc.yaml:

  - name: OpenDTU
    type: template
    template: sunspec-inverter
    usage: pv
    modbus: tcpip
    id: 125
    host: 192.168.178.XXX # Hostname
    port: 502 # Port

Build the firmware image

Clone this repository, and compile following the guide of OpenDTU. Use the included OpenDTU_build.yaml with the VSCode Extension Conda Wingman to create an environment with the required dependencies for building the firmware.

You (probably) do not have to compile the webapp (see OpenDTU guide) in advance as an updated webapp is alread part of this repository. On my mac, I set up the build environment with:

# install nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash

# install node
nvm install --lts

# install yarn
nvm use --lts
npm install --global yarn

To build the webapp, I use:

cd webapp
nvm use --lts
yarn cache clean
yarn install
yarn format
yarn build

Background

This project was started from this discussion (Mikrocontroller.net). It was the goal to replace the original Hoymiles DTU (Telemetry Gateway) with their cloud access. With a lot of reverse engineering the Hoymiles protocol was decrypted and analyzed.

Documentation

The documentation can be found here. Please feel free to support and create a PR in this repository to make the documentation even better.

Currently supported Inverters

A list of all currently supported inverters can be found here

Acknowledgements

  • This fork is based on the great project OpenDTU of tbnobody.

  • eModbus is a great piece of software. To handle the dependencies, I've forked the repo and changed the AsyncTCP library from me-no-dev to use mathieucarbou's AsyncTCP library.

  • Finally, this fork is including a Modbus server as proposed in openDTU's PR#1893 - see the original fork of b0661. I merely ported the modbus functions to the current version of openDTU and got everything in working order (which was way more work then expected...).

About

Software for ESP32 to talk to Hoymiles/TSUN/Solenso Inverters

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C++ 63.4%
  • Vue 25.2%
  • C 6.8%
  • TypeScript 2.4%
  • Python 1.9%
  • SCSS 0.1%
  • Other 0.2%