Featured image

I have a Growatt solar inverter, which has a ShineWiFi-X datalogger attached to send metrics to Growatt’s servers, which can be viewed in their app.

However, Growatt are not very friendly, they block the official Growatt Home Assistant plugin, which logins into the Growatt portal and grabs the solar datalogger metrics. By block, I mean they heavily rate limit logins and eventually lock accounts for 24 hours:

{'msg': '507', 'lockDuration': '24', 'success': False, 'error': 'Current account has been locked for 24 hours'}

Or, they block the user-agent the plugin uses. Either way, very unreliable.

Instead, the community have made a proxy named “Grott” that forwards the data being sent from the datalogger, to MQTT (and therefore Home Assistant), and then to Growatt, so the app still works. It also means you can continue to configure the datalogger via their portal.
alt text (Shamelessly stolen from the Grott repo)

I run Home Assistant in Docker, which means I need to manually set up an MQTT (Mosquito) instance (container). If you’re running Home Assistant as a system service (e.g. on a dedicated Raspberry Pi), or running HA OS, you can use the Mosquitto Add-on and remove the mosquitto service from the docker-compose.yml file below.

Configuration files Link to heading

docker-compose.yml Link to heading

---
version: "3.5"
services:
  home-assistant:
    image: homeassistant/home-assistant:latest
    container_name: home-assistant
    volumes:
      - /docker/home-assistant/config/:/config
      - /etc/localtime:/etc/localtime:ro
    ports:
      - 8123:8123
    restart: unless-stopped
    networks:
      - traefik

  mosquitto:
    image: eclipse-mosquitto:latest
    container_name: mosquitto
    volumes:
      - ./mosquitto/config/mosquitto.conf:/mosquitto/config/mosquitto.conf
    ports:
      - 1883:1883
    restart: unless-stopped
    networks:
      - traefik

  grott:
    image: ledidobe/grott:latest
    container_name: grott
    environment:
      - gmqttip=10.2.0.1
      - gmqttport=1883
      - TZ=Australia/Brisbane
      - gblockcmd=True
      - ggrowattip=server.growatt.com
    ports:
      - 5279:5279

mosquitto.conf Link to heading

persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
bind_address 0.0.0.0
port 1883
protocol mqtt
allow_anonymous true

All traffic is local, so I’m not worrying about authentication.

Grott seems to only support IP addresses for the MQTT host (gmqttip) unfortunately, so I’m just exposing the MQTT port and pointing Grott at my server’s IP address.

Home Assistant integration Link to heading

In Home Assistant, add the MQTT integration:
alt text

Select the first MQTT option:
alt text

The Broker is the hostname of the Mosquitto docker container (mosquitto) and the port is 1883
alt text

Updating the Datalogger to send data to Grott Link to heading

  1. Log into the Growatt portal and go to All Devices
    alt text

  2. Go to Datalogger settings
    alt text

  3. Select the “Set IP” option, and enter the (internal) IP of the server running Grott
    alt text The password is the current date in YYYYMMDD format (e.g. 20250106)
    Click “Yes” to save (lol)

Bonus: Increase the metric frequency from the default of 5 minutes Link to heading

In the same settings window, click Advanced Setting, then select the first Register and enter “4” (the register of the update frequency) and set the value to 1 - 10 (1 minute to 10 minutes).
alt text

Adding the sensors to Home Assistant Link to heading

In your Home Assistant configuration.yaml, add the following mqtt section:

mqtt:
  sensor:
    - name: Solar - State
      state_topic: energy/growatt
      value_template: >
        {% if (value_json['values']['pvstatus'] | int == 0) %}
          Waiting
        {% elif (value_json['values']['pvstatus'] | int == 1) %}
          Normal
        {% elif (value_json['values']['pvstatus'] | int == 2) %}
          Fault
        {% else %}
          Unknown
        {% endif %}        
      icon: mdi:power-settings
    - name: Solar - Energy Today
      state_topic: energy/growatt
      value_template: "{{ value_json['values']['pvenergytoday'] | float / 10 }}" 
      unit_of_measurement: "kWh"
      icon: mdi:solar-power
    - name: Solar - Energy Total
      state_topic: energy/growatt
      value_template: "{{ value_json['values']['pvenergytotal'] | float / 10 }}"
      unit_of_measurement: "kWh"
      icon: mdi:solar-power
    - name: Solar - Power In
      state_topic: energy/growatt
      value_template: "{{ value_json['values']['pvpowerin'] | float / 10000 }}"
      unit_of_measurement: "kW"
      icon: mdi:solar-power
    - name: Solar - Power Out
      state_topic: energy/growatt
      value_template: "{{ value_json['values']['pvpowerout'] | float / 10000 }}"
      unit_of_measurement: "kW"
      icon: mdi:solar-power
    - name: Solar - Temperature (Array)
      state_topic: energy/growatt
      value_template: "{{ value_json['values']['pvtemperature'] | float / 10 }}"
      unit_of_measurement: "°C"
      icon: mdi:thermometer
    - name: Solar - Temperature (IPM)
      state_topic: energy/growatt
      value_template: "{{ value_json['values']['pvipmtemperature'] | float / 10 }}"
      unit_of_measurement: "°C"
      icon: mdi:thermometer
    - name: Solar - Grid Voltage
      state_topic: energy/growatt
      value_template: "{{ value_json['values']['pvgridvoltage'] | float / 10 }}" 
      unit_of_measurement: "V"
      icon: mdi:flash
    - name: Solar - Frequency
      state_topic: energy/growatt
      value_template: "{{ value_json['values']['pvfrequentie'] | float / 100 }}" 
      unit_of_measurement: "Hz"
      icon: mdi:flash

The payload sent from the datalogger is as follows (in case you’re wanting to add more sensors):

{
    "device": "device-id",
    "time": "2025-01-06",
    "buffered": "no",
    "values": {
        "datalogserial": "dl-serial",
        "pvserial": "pv-serial",
        "pvstatus": 1,
        "pvpowerin": 22739,
        "pv1voltage": 3259,
        "pv1current": 38,
        "pv1watt": 12710,
        "pv2voltage": 2645,
        "pv2current": 36,
        "pv2watt": 10029,
        "pvpowerout": 22281,
        "pvfrequentie": 5002,
        "pvgridvoltage": 2402,
        "pvgridcurrent": 91,
        "pvgridpower": 22294,
        "pvgridvoltage2": 0,
        "pvgridcurrent2": 0,
        "pvgridpower2": 0,
        "pvgridvoltage3": 0,
        "pvgridcurrent3": 0,
        "pvgridpower3": 0,
        "totworktime": 113047997,
        "pvenergytoday": 36,
        "pvenergytotal": 313514,
        "epvtotal": 319001,
        "epv1today": 20,
        "epv1total": 176043,
        "epv2today": 16,
        "epv2total": 142958,
        "pvtemperature": 374,
        "pvipmtemperature": 408
    }
}