alexeyden / openess

Metrics export daemon for PowMr solar invertors (self hosted SmartESS mobile app replacement)
4 stars 1 forks source link
homeassistant solar

OpenESS

A service that exports power consumption and other metrics from Chinese solar inverters over MQTT. It can be used as a replacement for proprietary SmartESS mobile app.

In theory it can work with most inverters supported by SmartESS, but some inverters will probably require minor improvements/fixes in code -- see limitations.

Supported inverters

Tested and working:

Unsupported:

Please let me know via issues if your inverter happen to work too (and more so if it doesn't), so I can update the list here.

Features and limitations

The service periodically polls specified Modbus registers, interprets their values based on register space descriptors pulled from SmartESS and exports interpreted human-readable values over MQTT (e.g. to Home Assistant). In addition, it can configure the datalogger (SSID and password) and the inverter itself via CLI tool which is bundled into the service.

Register values are exported at openess/registers/{name} topics. Additionally, the datalogger connection status is exported at openess/status (online/offline).

Currently only WiFi dataloggers are supported (no BLE/serial). I've only tested it with a thing called Wi-Fi Plug Pro (Aliexpress link) that came with my inverter, but others will probably work too.

The service depends on original register space descriptor files pulled from SmartESS APK, see xxxx.json files in data/. The appropriate file is selected based on protocol string reported by datalogger during connection process.

Some other techinal limitations:

Installation and configuration

Installation:

  1. Build the service with make dist ARCH=arm64 (omit ARCH=arm64 to build for host arch)
  2. Copy openess.tar.xz to target machine and extract it there.
  3. Install the service with cd data/ && sudo ./install.sh. You can uninstall later it with sudo ./install.sh uninstall if needed.
  4. Run the service in CLI mode to check if it can properly connect to the datalogger: openess -d 192.168.1.37:58899. Note what descriptor file is used (look for client: loaded protocol descriptor: 0925.json log entry). You can also change datalogger SSID/password here (see CLI description below).
  5. Edit the config file at /etc/openess/config.json. You must specify datalogger address (DeviceAddr), MQTT broker address (Export.Broker) and a set of exported registers for your inverter (Collector.Registers). You can lookup register names in your xxxx.json file found out at previous step.
  6. Enable and start the service: sudo systemctl enable openess --now

Configuration file:

{
    "BindPort": 8899,                   // local TCP port used for datalogger connection
    "DeviceAddr": "192.168.1.37:58899", // datalogger address
    "ProtoPath": "data/",               // a path to descriptor files (xxxx.json)
    "Export": {  
        // MQTT export config
        "Broker": "tcp://127.0.0.1:1883", // broker address (required)
        "ClientId": "MyExporter",         // client id (optional)
        "User": "user",                   // auth creds (optional)
        "Password": "password"            // auth creds (optional)
    },
    "Collector": {
        "Interval": "500ms", // polling interval
        "Enabled": true,     // enable polling
        "Registers": {
            // A list of registers to poll.
            // Keys are MQTT register topic names: openess/registers/{name}
            // Values are register names from descriptor file
            "working_state": "Working State",
            "output_voltage": "Output voltage",
            "output_power": "Output apparent power ",
            "output_active_power": "Output active power",
            "output_power_percent": "AC output Load %"
        }
    }
}

Using the CLI mode

Ensure that service is stopped before running the CLI. Type help to get a list of supported commands. Type exit or ^D to exit.

Setting datalogger SSID/password:

$ openess -d 192.168.1.37:58899
INFO    2024/01/24 13:52:04 client: connecting to device 192.168.1.37:58899
INFO    2024/01/24 13:52:04 client: connected to datalogger: manufacturer 37 device type 8 (protocol v1.2 props 0925,5,5,#0#)
% set-param ssid HomeWifi
% set-param password MyPassword
% set-param restart 1
% exit

Reading registers:

% read-named  "Working State"
Line Mode
% read-named "Output apparent power "
4287VA

Writing registers:

% write-named "Remove all power history" 1
010c
% write-named "LCD backlight" 0
001d

When writing registers, enumeration variants are represented by numeric values, so you have to look up proper values in the xxxx.json descrptor file.

Integration with Home Assistant

Example configuration:

mqtt:
  sensor:
    - name: "powmr_output_power"
      state_topic: "openess/register/output_active_power"
      availability_topic: "openess/status"
      value_template: "{{value | float | round(2)}}"
      unit_of_measurement: "W"
      device_class: power
      state_class: measurement
    - name: "powmr_output_power_percent"
      availability_topic: "openess/status"
      state_topic: "openess/register/output_power_percent"
      value_template: "{{value | float | round(2)}}"
      unit_of_measurement: "%"
      device_class: power_factor
      state_class: measurement

# You have to integrate values of output power sensor over time,
# either via `inegration` or `utility_meter` to get consumption in KWh,
# otherwise it wouldnt show up in the Energy tab

sensor:
  - platform: integration
    source: sensor.powmr_output_power
    name: energy_spent
    unit_prefix: k
    round: 2