PVOuput Uploader

Thanks - I appreciate the reply but that is way beyond me.

I got a little further and am able to call that script but get a:

Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/homeassistant/components/python_script.py", line 166, in execute
    exec(compiled.code, restricted_globals, local)
  File "pvoutput.py", line 5, in <module>
NameError: name 'object' is not defined

I think I will just go the CURL method and see where that gets me.

OK, for anybody interested, I have the solution!! It has taken a while since I’ve been busy, but it’s quite simple:

shell_command:
   pvoutputcurl: 'curl -d "d={{now().strftime("%Y%m%d")}}" -d "t={{now().strftime("%H:%M")}}" -d "v4={{states.sensor.studioforpvoutput_mean.state|round(0)}}" -H "X-Pvoutput-Apikey: apikeygoeshere" -H "X-Pvoutput-SystemId: idgoeshere" https://pvoutput.org/service/r2/addstatus.jsp'   

(the sensor mean has a max age of 5 minutes of realtime readings)

And then run an automation:

  - alias: UploadPvoutput
    hide_entity: False
    trigger:
      platform: time
      minutes: '/5'
      seconds: 00
    action:
      service: shell_command.pvoutputcurl

In the above example I am uploading “v4”. but you can do whatever you want as per the documentation:

https://pvoutput.org/help.html#api-addstatus

8 Likes

Hello

I have copied your shell command and automation, but when it runs i get the error below. Any suggestions?

2019-01-11 11:40:05 INFO (MainThread) [homeassistant.components.automation] Executing pvoupload
2019-01-11 11:40:05 INFO (MainThread) [homeassistant.helpers.script] Script pvoupload: Running script
2019-01-11 11:40:05 INFO (MainThread) [homeassistant.helpers.script] Script pvoupload: Executing step call service

2019-01-11 11:40:05 ERROR (MainThread) [homeassistant.components.shell_command] Error rendering command template: UndefinedError: ‘None’ has no attribute ‘state’
Traceback (most recent call last):
File “/usr/src/app/homeassistant/helpers/template.py”, line 138, in async_render
return self._compiled.render(kwargs).strip()
File “/usr/local/lib/python3.6/site-packages/jinja2/asyncsupport.py”, line 76, in render
return original_render(self, *args, **kwargs)
File “/usr/local/lib/python3.6/site-packages/jinja2/environment.py”, line 1008, in render
return self.environment.handle_exception(exc_info, True)
File “/usr/local/lib/python3.6/site-packages/jinja2/environment.py”, line 780, in handle_exception
reraise(exc_type, exc_value, tb)
File “/usr/local/lib/python3.6/site-packages/jinja2/_compat.py”, line 37, in reraise
raise value.with_traceback(tb)
File “<template>”, line 1, in top-level template code
File “/usr/src/app/homeassistant/helpers/template.py”, line 446, in forgiving_round
value = round(float(value), precision)
jinja2.exceptions.UndefinedError: ‘None’ has no attribute ‘state’

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/usr/src/app/homeassistant/components/shell_command.py”, line 54, in async_service_handler
rendered_args = args_compiled.async_render(service.data)
File “/usr/src/app/homeassistant/helpers/template.py”, line 140, in async_render
raise TemplateError(err)
homeassistant.exceptions.TemplateError: UndefinedError: ‘None’ has no attribute ‘state’

I’m no HA/python expert, but that sounds like you don’t have a value associated with what you’re trying to put in the curl command. Have you made sure the value works in the templating area in HA?

Hi Greenhouse

thankyou for the quick response. No, i have not setup a value nor tested anything in the templating area. This is my first foray into curl/automation. Back to the doco i go :slight_smile:

In the pvoutput curl statement I changed

states.sensor.studioforpvoutput_mean.state

to

states.sensor.currentcost_power.state

and now the error is gone and it is uploading power usage data :slight_smile:

As an update to this, I made a couple of modifications to my automation as to only upload when my internet is ‘online’ (heaps of internet drop outs in our 3rd world internet here in Australia).

In addition to that, sometimes I get an error “homeassistant.exceptions.TemplateError: UndefinedError: ‘None’ has no attribute ‘state’”, even when there is a state. My solution is to wait 10 seconds and then try again, with an almost 100% success rate (before the double-up I would get 1-3 missed uploads a day).

  - alias: UploadPvoutput
    initial_state: 'on'    
    hide_entity: False
    trigger:
      platform: time_pattern
      minutes: '/5'
      seconds: 00  
    action:
      - wait_template: "{{ is_state('binary_sensor.online', 'on') }}"
        timeout: '00:00:30'
        continue_on_timeout: 'false'
      - service: shell_command.pvshellgh        
      - delay: 0:00:10
      - service: shell_command.pvshellgh 
1 Like

Thank you Adam
the simple curl solution saved me so much time and frustration to try to upload to pvoutput.org

I was looking for this too and I am happy I found this solution. I don;t like my API key in the YAML files though as I use Github so I did this to template the API key:

sensor:
  - platform: template
    sensors:
      pvoutput_api_key:
        value_template: !secret pvoutput_api_key
        
      pvoutput_system_id:
        value_template: !secret pvoutput_system_id

and in the curl command:

shell_command:
   pvoutput_generation: 'curl -d "d={{now().strftime("%Y%m%d")}}" -d "t={{now().strftime("%H:%M")}}" -d "v2={{states.sensor.cs31011195_output_power.state|round(0)}}" -H "X-Pvoutput-Apikey: {{states.sensor.pvoutput_api_key.state}}" -H "X-Pvoutput-SystemId: {{states.sensor.pvoutput_system_id.state}}" https://pvoutput.org/service/r2/addstatus.jsp'

   pvoutput_consumption: 'curl -d "d={{now().strftime("%Y%m%d")}}" -d "t={{now().strftime("%H:%M")}}" -d "c1=1" -d "v3={{(states.sensor.energy_consumption_tariff_1.state|int)+(states.sensor.energy_consumption_tariff_2.state|int)}}" -H "X-Pvoutput-Apikey: {{states.sensor.pvoutput_api_key.state}}" -H "X-Pvoutput-SystemId: {{states.sensor.pvoutput_system_id.state}}" https://pvoutput.org/service/r2/addstatus.jsp'

I am using two commands as I have a cumulative energy usage value from my smart meter and a power generation value from the solar power invertor. (note: the c1=1 means cumulative)

3 Likes

Hi Didier,
I am testing Home assistant for the first time and i am struggling trying to use the description you posted.
I input the portion sensor and shell_command into configuration.yaml . The API and system id into the file secret.yalm
Checking the file configuration.yaml system says it is OK …no errors… but how to run every 5 minutes the command to upload data to PVOUTPUT?
Would be very appreaciated a support from you.

many thanks in advance
Cheers

Finally I did it !! :grinning:
automation file was wrongly formatted.

Hi @ciottomate glad you figured it out already :slight_smile: I was on holiday and could not respond any sooner.

For those who come looking for the answer, create an automation rule that runs every 5 mins and runs the two shell scripts:

  alias: PVOutput Uploader
  description: Uploads values to PVOutput.
  trigger:
  - platform: time_pattern
    minutes: /5
  condition: []
  action:
  - service: shell_command.pvoutput_consumption
    data: {}
  - service: shell_command.pvoutput_generation
    data: {}
  mode: single
1 Like

Hi,

So I got the API working fine thanks to your posts above, however I’m a bit confused how I create a 5min average sensor to send to PVoutput.
I have a template sensor that calculates my instantaneous house consumption (removing solar generation):

      # Template sensor for values of power consumption (active_power < 0)
      energy_consumption:
        friendly_name: "Power Consumption"
        unit_of_measurement: 'W'
        value_template: >-
          {% if (states('sensor.house_consumption')|float - 685 - states('sensor.pv_power')|float - states('sensor.pv_power_2')|float) < 0 %}
            {{ (states('sensor.house_consumption')|float - 685 - states('sensor.pv_power')|float - states('sensor.pv_power_2')|float) * -1 }}
          {% else %}
            {{ (states('sensor.house_consumption')|float - 685 + states('sensor.pv_power')|float + states('sensor.pv_power_2')|float) }}
          {% endif %}

How do I turn that into a 5 min average to send up to Pvoutput.
You mentioned you had something with a timestamp or similar?

There doesn’t seem to be a average, only min-max median, confused.

Thanks for any bone you can throw me.

For anyone looking in the future, I think I figured it out using statistics:

sensor:
  # Sensor for 5 min average consumption for Pvoutput
  - platform: statistics
    name: "Energy Consumption 5min"
    entity_id: sensor.energy_consumption
    state_characteristic: mean
    max_age:
      minutes: 5
    sampling_size: 300
1 Like

That is a very smart solution!

In my case I simply upload the cumulative power amount, whereas you have the actual power (the difference is Wh vs W)

The following solution works in my setup, and does away with the secret problem. It uploads power and energy generation.

In configuration.yaml:


rest_command:
  pvoutput_generation:
    method: POST
    url: https://pvoutput.org/service/r2/addstatus.jsp
    headers:
      X-Pvoutput-Apikey: !secret pvoutput_api_key
      X-Pvoutput-SystemId: !secret pvoutput_system_id
    payload: 'd={{now().strftime("%Y%m%d")}}&t={{now().strftime("%H:%M")}}&v1={{states.sensor.growatt_energytoday.state|round(1)*1000}}&v2={{states.sensor.growatt_acpower.state|round(0)}}'
    content_type: "application/x-www-form-urlencoded"

In automations:


alias: PVOutput Uploader (rest_command)
description: Uploads values to PVOutput
trigger:
  - platform: time_pattern
    minutes: /5
    seconds: '0'
condition:
  - condition: state
    entity_id: sensor.growatt_status
    state: Normal
action:
  - service: rest_command.pvoutput_generation
    data: {}
mode: single

I am using the sensors described here : ESPHome modbus Growatt ShineWiFi-S

4 Likes

With recent modernization of the PVOutputPro integration, this should be fairly easy to add to the core integration as a service.

Will put it on my list to do, could use it myself as well (not as high priority though)

14 Likes

Awesome, thanks for that example. Based on that I’ve got a functioning configuration for a Fronius inverter. The config below uploads all the standard fields, including consumption, voltage, temperature etc. So if anyone else adapts this for there fronius choose which fields you want to upload, v1 and v3 are the essential ones I believe.

Note to deal with the ‘unknown’ state from a sensor in some circumstances the powerflow is set to default to 0, if it’s unable to be rounded.

rest_command:
  pvoutput_generation:
    method: POST
    url: https://pvoutput.org/service/r2/addstatus.jsp
    headers:
      X-Pvoutput-Apikey: !secret pvoutput_api_key
      X-Pvoutput-SystemId: !secret pvoutput_system_id
    payload: 'd={{now().strftime("%Y%m%d")}}&t={{now().strftime("%H:%M")}}&v1={{states.sensor.energy_total_fronius_inverter_1_http_192_168_xx_xx.state|round(0)}}&v2={{states.sensor.power_photovoltaics_fronius_power_flow_0_http_192_168_xx_xx.state|round(0,default=0)}}&v3={{states.sensor.energy_real_consumed_fronius_meter_0_http_192_168_xx_xx.state|round(0)}}&v4={{states.sensor.power_load_fronius_power_flow_0_http_192_168_xx_xx.state|round(0)*-1}}&v5={{states.sensor.outdoor_temperature|float}}&v6={{states.sensor.fronius_smartmeter_voltage_ac_phase_1.state|round(0)}}&c1=1'
    content_type: "application/x-www-form-urlencoded"

I think there’s a ‘}’ too many there?

Your correct, and yet strangely enough it was working perfectly fine and HA was happy with the configuration file…

^corrected.