PVOUTPUT uploader via nodered

@picnic Thanks, I got it sorted and PVoutput uploads are working fine for me now. Also using the the energy dashboard here but PVoutput has all my history from Day 1 of solar so want to keep that going.
Cheers

I just found this solution and it is really great. I have one issue. The last upload of each day goes to the next day with this flow. I measn that each day the first upload is the last day’s last status, so e.g. 9th September starts in PVOutput with 9th September 23:55 and contains the data of 8th September 23:55 Then continues to upload with the first data of 9th September. So right after midnight I can see the current day’s 23:55 data even if it is only 00:10
I tried to add a “condition” not to upload data between 23:53 and 00:03 but the olny change that the first uplod of the day changed to 23:50 :frowning:
What could I do? (I changed the Input and Output Timezone of Date formatter node to Europe /Budapest because I live here.

Sorry for the late kick, but did you find a solution? Experiencing the same problem here.

I’m experiencing the same issue… Any solution?

Hmm interesting problem. Are you all using the Date/Time Formatter node to make your date and time?
I’m guessing this issues lies with that and the timing of the join node.

Sorry for late reply. Yes, I’m using NodeRed date/time formatter nodes, both on the correct timezone.

Anyone found a solution yet?

Even if my last upload of the day is at 22:55, it still shows as the next day…

Well, I’ve made a change to the join. Instead of waiting for 5 message parts and the next, I’ve cleared the 5, and I let the join send the message after 2 seconds. That seems to work :slight_smile:

Ok, I’m going to try this.

1 Like

I simplified the code here a bit and made it much cleaner. Still gets you the same result.
Just put the following in function node and change the necessary HA states.
Add moment to the setup modules in your function.

var d = moment().format("YYYYMMDD");
var t = moment().format("HH:mm");
var v1 = global.get("homeassistant.homeAssistant.states['sensor.solar_daily_energy_peak'].state")*1000;
var v2 = global.get("homeassistant.homeAssistant.states['sensor.total_solar_power'].state");
var v3 = global.get("homeassistant.homeAssistant.states['sensor.consumed_daily_energy_peak'].state")*1000;
var v4 = global.get("homeassistant.homeAssistant.states['sensor.total_consumed_power'].state");
var v5 = global.get("homeassistant.homeAssistant.states['sensor.edmonton_temperature'].state");
var v6 = global.get("homeassistant.homeAssistant.states['sensor.utility_2_voltage'].state");
msg.payload = {
    d: d,
    t: t,
    v1: v1,
    v2: v2,
    v3: v3,
    v4: v4,
    v5: v5,
    v6: v6
}
msg.action = msg.payload
msg.headers = { 
    'X-Pvoutput-Apikey': 'b34t98sidf***************8888a4c',
    'X-Pvoutput-SystemId': '*****',
    'Content-Type': 'application/x-www-form-urlencoded'
};
msg.url = "http://pvoutput.org/service/r2/addstatus.jsp";
return msg;



Hi Picnic,

Where does this code go? Trying to figure this out but struggling.

appreciate any help.

This goes inside a function node. Here’s a complete flow:

[{"id":"2168eae5932e10ca","type":"debug","z":"c7434384.70251","name":"Header Check","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":710,"y":1880,"wires":[]},{"id":"94287b6905ebc2f4","type":"http request","z":"c7434384.70251","name":"Post","method":"POST","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":530,"y":1880,"wires":[["2168eae5932e10ca"]]},{"id":"44a1c730d435d36d","type":"function","z":"c7434384.70251","name":"PV Output","func":"var d = moment().format(\"YYYYMMDD\");\nvar t = moment().format(\"HH:mm\");\nvar v1 = global.get(\"homeassistant.homeAssistant.states['sensor.solar_daily_energy_peak'].state\")*1000;\nvar v2 = global.get(\"homeassistant.homeAssistant.states['sensor.total_solar_power'].state\");\nvar v3 = global.get(\"homeassistant.homeAssistant.states['sensor.consumed_daily_energy_peak'].state\")*1000;\nvar v4 = global.get(\"homeassistant.homeAssistant.states['sensor.total_consumed_power'].state\");\nvar v5 = global.get(\"homeassistant.homeAssistant.states['sensor.edmonton_temperature'].state\");\nvar v6 = global.get(\"homeassistant.homeAssistant.states['sensor.utility_2_voltage'].state\");\nmsg.payload = {\n    d: d,\n    t: t,\n    v1: v1,\n    v2: v2,\n    v3: v3,\n    v4: v4,\n    v5: v5,\n    v6: v6\n}\nmsg.action = msg.payload\nmsg.headers = { \n    'X-Pvoutput-Apikey': 'xxxxxxxxxxxxxxxxxxxxxxx',\n    'X-Pvoutput-SystemId': 'xxxxxxxxx',\n    'Content-Type': 'application/x-www-form-urlencoded'\n};\nmsg.url = \"http://pvoutput.org/service/r2/addstatus.jsp\";\nreturn msg;\n\n","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[{"var":"moment","module":"moment"}],"x":350,"y":1880,"wires":[["94287b6905ebc2f4"]]},{"id":"ee0c4287ff0f128f","type":"inject","z":"c7434384.70251","name":"Every 5 Minutes","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"300","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":1880,"wires":[["44a1c730d435d36d"]]}]

Simple and effective.
Thanks.

Reviving an old thread - I have a Shelly Pro 3EM and would like to get consumption data uploaded to PVOutput which has all my solar history from day 1.

I’m fairly new to HA, and even newer to Node Red!

I see Picnic DjR’s flow a few posts up, but I’m not sure what to do with it where, and how!

Maybe seeing the contents/config of each of the boxes would help.

Could someone assist, please?

Hi @Jay95.
Here is my latest flow. You will need the Moment node to make it work.
Also my sensor names are probably different than yours.



[{"id":"8e2e2f4c4fd42bd7","type":"function","z":"9abffacc.573c48","name":"PV Output","func":"var d = moment().format(\"YYYYMMDD\");\nvar t = moment().format(\"HH:mm\");\nvar v1 = global.get(\"homeassistant.homeAssistant.states['sensor.solar_daily_energy_peak'].state\")*1000;\nvar v2 = global.get(\"homeassistant.homeAssistant.states['sensor.total_solar_power'].state\");\nvar v3 = global.get(\"homeassistant.homeAssistant.states['sensor.consumed_daily_energy_peak'].state\")*1000;\nvar v4 = global.get(\"homeassistant.homeAssistant.states['sensor.total_consumed_power'].state\");\nvar v5 = global.get(\"homeassistant.homeAssistant.states['sensor.edmonton_temperature'].state\");\nvar v6 = global.get(\"homeassistant.homeAssistant.states['sensor.utility_2_voltage'].state\");\nmsg.payload = {\n    d: d,\n    t: t,\n    v1: v1,\n    v2: v2,\n    v3: v3,\n    v4: v4,\n    v5: v5,\n    v6: v6\n}\nmsg.action = msg.payload\nmsg.headers = { \n    'X-Pvoutput-Apikey': '*****************',\n    'X-Pvoutput-SystemId': '12345',\n    'Content-Type': 'application/x-www-form-urlencoded'\n};\nmsg.url = \"http://pvoutput.org/service/r2/addstatus.jsp\";\nreturn msg;\n\n","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[{"var":"moment","module":"moment"}],"x":450,"y":700,"wires":[["5012a069e06b2374"]]},{"id":"5012a069e06b2374","type":"http request","z":"9abffacc.573c48","name":"Post","method":"POST","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":630,"y":700,"wires":[["f704d04765d66902"]]},{"id":"09245f50958dd8ae","type":"inject","z":"9abffacc.573c48","name":"Every 5 Minutes","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"300","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":240,"y":700,"wires":[["8e2e2f4c4fd42bd7"]]},{"id":"f704d04765d66902","type":"debug","z":"9abffacc.573c48","name":"Header Check","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":810,"y":700,"wires":[]}]

Do you know how to import a flow?

Thanks Picnic,

I haven’t played with node red at all, but keen to get into it. I’ll do some googling on how to import a flow rather than keep bugging you!

Cheers

@Jay95 Let me know if you need any help setting up your shelly or getting this working

Thanks again Picnic, very generous of you!
Your flow is uploading well, I have voltage and temp appearing in PVOutput perfectly, but the Energy Used and Power Used aren’t quite right and I believe it’s due to what sensors are outputed from the Shelly Pro 3EM.

The only sensors I have available from the Shelly as Totals are Total Active Power (which is the instantaneous power used) and the Total Active Energy (which is a cumulative total that increases each day).

I’m wondering if I need to use the ‘c1’ flag to PVOutput to say that it is cumulative Total Active Energy? Otherwise, I wonder how to upload just the Delta value between 12.01am to the time of the upload, for each day?

https://pvoutput.org/help/push_services.html

Apologies if this is going too far off topic!

Here is my sensor.yaml for creating the sensors needed from my Shelly EM’s. In your case you may need to put the 3 phases of you 3EM together.

- platform: template
  sensors:
    consumed_power_1:
      value_template: >
        {{ (states('sensor.solar_power_1')|float(0) 
        + states('sensor.utility_power_1')|float(0)) |round(2) }}
      friendly_name: "Consumed Power 1"
      unit_of_measurement: "W"
    consumed_power_2:
      value_template: >
        {{ (states('sensor.solar_power_2')|float(0) 
        + states('sensor.utility_power_2')|float(0)) |round(2) }}
      friendly_name: "Consumed Power 2"
      unit_of_measurement: "W"
    total_consumed_power:
      value_template: >
        {{ (states('sensor.consumed_power_1')|float(0) 
        + states('sensor.consumed_power_2')|float(0))| round(2) }}
      friendly_name: "Total Consumed Power"
      unit_of_measurement: "W"
    total_solar_power:
      value_template: >
        {{ (states('sensor.solar_power_1')|float(0) 
        + states('sensor.solar_power_2')|float(0))| round(2) }}
      friendly_name: "Total Solar Power"
      unit_of_measurement: "W"
    total_utility_power:
      value_template: >
        {{ (states('sensor.utility_power_1')|float(0) 
        + states('sensor.utility_power_2')|float(0))| round(2) }}
      friendly_name: "Total Utility Power"
      unit_of_measurement: "W"
    total_returned_power:
      value_template: >
        {{ (states('sensor.total_utility_power')|float(0) 
        * (-1)|float(0))| round(2) }}
      friendly_name: "Total Returned Power"
      unit_of_measurement: "W"

- platform: integration
  source: sensor.total_utility_power
  name: total_utility_energy
  unit_prefix: k
  unit_time: h
  method: left

- platform: integration
  source: sensor.total_consumed_power
  name: total_consumed_energy
  unit_prefix: k
  unit_time: h
  method: left

- platform: integration
  source: sensor.total_returned_power
  name: total_returned_energy
  unit_prefix: k
  unit_time: h
  method: left

- platform: integration
  source: sensor.total_solar_power
  name: total_solar_energy
  unit_prefix: k
  unit_time: h
  method: left

- platform: integration
  name: Grid Import Energy
  source: sensor.grid_import_power
  unit_prefix: k
  unit_time: h
  method: left

- platform: integration
  name: Grid Export Energy
  source: sensor.grid_export_power
  unit_prefix: k
  unit_time: h
  method: left

and my meter.yaml:

  utility_yearly_energy:
    source: sensor.total_utility_energy
    cycle: yearly
    tariffs: 
      - peak
    net_consumption: false


  utility_monthly_energy:
    source: sensor.total_utility_energy
    cycle: monthly
    net_consumption: false
    offset:
      days: 21
    tariffs: 
      - peak
    
  utility_daily_energy:
    source: sensor.total_utility_energy
    cycle: daily  
    net_consumption: false
    tariffs: 
      - peak
    
  solar_daily_energy:
    source: sensor.total_solar_energy
    cycle: daily  
    net_consumption: false
    tariffs: 
      - peak
    
  solar_monthly_energy:
    source: sensor.total_solar_energy
    cycle: monthly  
    net_consumption: false
    offset:
      days: 21
    tariffs: 
      - peak    

  solar_yearly_energy:
    source: sensor.total_solar_energy
    cycle: yearly  
    net_consumption: false
    tariffs: 
      - peak
      
  consumed_daily_energy:
    source: sensor.total_consumed_energy
    cycle: daily  
    net_consumption: false
    tariffs: 
      - peak    
      
  consumed_monthly_energy:
    source: sensor.total_consumed_energy
    cycle: monthly  
    net_consumption: false
    offset:
      days: 21
    tariffs: 
      - peak    
      
  consumed_yearly_energy:
    source: sensor.total_consumed_energy
    cycle: yearly  
    net_consumption: false
    tariffs: 
      - peak    
 
  returned_daily_energy:
    source: sensor.total_returned_energy
    cycle: daily  
    net_consumption: false
    tariffs: 
      - peak    
      
  returned_monthly_energy:
    source: sensor.total_returned_energy
    cycle: monthly  
    net_consumption: false
    offset:
      days: 21
    tariffs: 
      - peak    
      
  retured_yearly_energy:
    source: sensor.total_returned_energy
    cycle: yearly  
    net_consumption: false
    tariffs: 
      - peak    
            

Up and working well now!
It was just a matter of setting the ‘c’ variable as ‘3’ which tells PVOutput that the Consumption data is cumulative (resets to 0 at midnight each day). See below snip.

At the moment the Total Active Power is just what the power usage was at the time of posting to PVOutput. Ideally it would be the average power figure over the 5min period. I’ll put my thinking cap on and see if I can work out how to do that calc in NodeRed then post the average figure to PVOutput.