Howto: GoodWe via Home Assistant to PV output

I setup my GoodWe inverter yesterday and setup an upload stream to PV output via my local Home Assistant server.

Connect GoodWe to Home Assistant
Setup GoodWe inverter on home Wifi Network
Look for inverter IP in DHCP router
In Home Assistant, use the GoodWe integration and fill in the IP
36 new instances will be setup for the inverter/device, one of them is; sensor.pv_power.

Prepare PV output
Make a system setup
Enable API access
Copy the API key
Copy the system id

Setup upload script
In configuration.yaml include
shell_command:
pvoutputcurl: ‘curl -d “d={{now().strftime(”%Y%m%d")}}" -d “t={{now().strftime(”%H:%M")}}" -d “v2={{states.sensor.pv_power.state|round(0)}}” -d “v5={{states.sensor.inverter_temperature.state|round(0)}}” -d “v6={{states.sensor.pv_voltage.state|round(0)}}” -H “X-Pvoutput-Apikey: typeinyourapikeyhere” -H “X-Pvoutput-SystemId: typeinyoursystemidherehttps://pvoutput.org/service/r2/addstatus.jsp

Setup 5 minute upload
In your automations, setup a new automation, switch to the YAML format and copy:

alias: Upload PV output
description: ‘’
trigger:

  • platform: time_pattern
    minutes: /5
    condition: []
    action:
  • service: shell_command.pvoutputcurl
    data: {}
    mode: single

Your setup may be a bit different, but these were the steps that worked for me.

Yes I adapt for my own setup… I added also the V1 & V3 infos since I can integrate them from an external device.

Thanks for this! I converted this to use rest_command instead of shell_command so that I could more easily store the api key etc in secrets.yaml.

I am not 100% sure I have mapped the right entities to the right API parameters yet, but the general idea is worth sharing:

automation:
  - id: 4f863af550147e9b3170
    alias: update pvoutput
    trigger:
      platform: time_pattern
      minutes: /5
    action:
      service: rest_command.update_pvoutput
      data: {}
    mode: single

rest_command:
  update_pvoutput:
    url: https://pvoutput.org/service/r2/addstatus.jsp
    method: post
    content_type: "application/x-www-form-urlencoded"
    headers:
      X-Pvoutput-Apikey: !secret pvoutput_api_key
      X-Pvoutput-SystemId: !secret pvoutput_system_id
    payload: >-
      d={{now().strftime("%Y%m%d")}}                                    {#- date -#}
      &t={{now().strftime("%H:%M")}}                                    {#- time -#}
      &c1=2                                                             {#- cumulative mode -#}
      &v1={{(states('sensor.inverter_pv_generation_today')|float * 1000)|round(0) }}
                                                                        {#- energy generation (Wh) -#}
      &v2={{states('sensor.inverter_active_power')|float|round(0)}}     {#- power generation (W) -#}
      &v3=                                                              {#- energy consumption (Wh) -#}
      &v4={{states('sensor.household_power_demand')|float|round(0)}}    {#- power consumption (W) -#}
      &v5={{states('sensor.home_weather_temperature')|float|round(1)}}  {#- ambient temperature -#}
      &v6={{states('sensor.inverter_phase_a_voltage')|float|round(1)}}  {#- voltage -#}
1 Like

Hello,

for some reason Home Assitant Visual studio code doesn’t accept the code into conif.yaml

Can you eloborate on that. I keep getting the “can not read a block mapping entry; a multiline key may not be an implicit key” error at the last line.

Am i missing something?
@rvalk1902

@bjeanes Thanks for posting your HA yaml. To make it easier to manage logic and exceptions, I’ve used join to build the payload string. This avoids adding unwanted spaces and linebreaks in the POST payload.

rest_command:
  update_pvoutput:
    url: https://pvoutput.org/service/r2/addstatus.jsp
    method: post
    content_type: "application/x-www-form-urlencoded"
    headers:
      X-Pvoutput-Apikey: !secret pvoutput_api_key
      X-Pvoutput-SystemId: !secret pvoutput_system_id
    payload: >-
      {#
         d: date
         t: time
         c1: cumulative mode (1,2,3)
         n: net flag (0,1)
         v1: energy generation (Wh)
         v2: power generation (W)
         v3: energy consumption (Wh)
         v4: power consumption (W)
         v5: ambient temperature
         v6: voltage
         v9: IO debit tariff (p)
         v7-v12: extended values
         m1: test message (30 chars)
      #}
      {% set p = 
      [
        'd=', now().strftime("%Y%m%d"),
        '&t=', now().strftime("%H:%M"),
        '&c1=1',
        '&v3=', ((states('sensor.real_solar_energy_self_consumption')|float(0) +
            states('sensor.grid_energy_import')|float(0))*1000)|round,                             
        '&v5=', states('sensor.ble_temperature_porch')|float|round(1),
        '&v9=', (iif(is_state('binary_sensor.octopus_energy_intelligent_dispatching', 'on'),
            states('sensor.current_day_min_rate'),
            states('sensor.current_day_max_rate'))|float(0) * 100)|round(3)
      ]|join %}
    
      {# Only add v2 & v6 if we have valid inverter data #}   
      {% if is_number(states('sensor.output_power')) %}
          {% set p = 
          [p, 
            '&v2=', states('sensor.output_power')|float|round,
            '&v6=',((states('sensor.pv1_average_voltage_per_panel')|float(0) +
                     states('sensor.pv2_average_voltage_per_panel')|float(0))/2)|round(1)
          ]|join %}
      {% endif %}
      {{p}}

Hello, I have adapted the script to my wishes. However, after adding the script, other rest_commands are no longer recognized, including this one, when configuring an action. Perhaps there is an error in the script, but I don’t see it. Please help

rest_command:
  update_pvoutput:
    url: https://pvoutput.org/service/r2/addstatus.jsp
    method: post
    headers:
      X-Pvoutput-Apikey: !secret pvoutput_api_key
      X-Pvoutput-SystemId: !secret pvoutput_system_id
      Content-Type: "application/x-www-form-urlencoded"
    payload: >-
      {#
         d: date
         t: time
         c1: cumulative mode (1,2,3)
         n: net flag (0,1)
         v1: energy generation (Wh)
         v2: power generation (W)
         v3: energy consumption (Wh)
         v4: power consumption (W)
         v5: ambient temperature
         v6: voltage
         v9: IO debit tariff (p)
         v7-v12: extended values
         m1: test message (30 chars)
      #}
      {% set p = 
      [
        'd=', now().strftime("%Y%m%d"),
        '&t=', now().strftime("%H:%M"),
        '&c1=1',
        '&v1=', ((states('sensor.p1_meter_energy_export')|float(0),
        '&v3=', ((states('sensor.p1_meter_energy_import')|float(0),                           
        '&v4=', ((states('sensor.p1_meter_power')|float(0)
      ]|join %}
      {# Only add v2 if we have valid inverter data #}   
      {% if is_number(states('sensor.omink_solar_solar_current_power')) %}
          {% set p = 
          [p, 
            '&v2=', states('sensor.omink_solar_solar_current_power')|float|round
          ]|join %}
      {% endif %}
      {# Only add v6 if we have valid temperature data #}   
      {% if is_number(states('sensor.temperatuur')) %}
          {% set p = 
          [p, 
            '&v2=', states('sensor.temperatuur')|float|round
          ]|join %}
      {% endif %}
      {{p}}