PVOUTPUT uploader via nodered

Here is a flow i put together to upload my sensor data from HA to PVOutput.org.
This started off as a shell command posted by “Greenhouse” and flow posted by " Paul_F_Prinsloo".

[
    {
        "id": "24befeed.0cb5f2",
        "type": "tab",
        "label": "pvoutput",
        "disabled": false,
        "info": ""
    },
    {
        "id": "ab922e29.c77f7",
        "type": "api-current-state",
        "z": "24befeed.0cb5f2",
        "name": "Daily Solar (Watt hours)",
        "server": "cbbf6ce3.4f5eb",
        "version": 1,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "override_topic": false,
        "entity_id": "sensor.daily_solar_energy_wh",
        "state_type": "str",
        "state_location": "payload",
        "override_payload": "msg",
        "entity_location": "",
        "override_data": "none",
        "blockInputOverrides": false,
        "x": 230,
        "y": 220,
        "wires": [
            [
                "eca1effa.95a05"
            ]
        ]
    },
    {
        "id": "5948f34d.abb71c",
        "type": "inject",
        "z": "24befeed.0cb5f2",
        "name": "Every 5 Minutes",
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "repeat": "300",
        "crontab": "",
        "once": false,
        "onceDelay": "",
        "x": 210,
        "y": 140,
        "wires": [
            [
                "ab922e29.c77f7",
                "17526967.a07137",
                "a50a6ebe.4e214",
                "f6d9d089.0c42d",
                "7fd1ce58.84e1a",
                "e5e9e6d9.dd8f38",
                "cebb4284.5ca53",
                "82eeed4d.79b77"
            ]
        ]
    },
    {
        "id": "48a83575.9c7a9c",
        "type": "join",
        "z": "24befeed.0cb5f2",
        "name": "",
        "mode": "custom",
        "build": "object",
        "property": "payload",
        "propertyType": "msg",
        "key": "topic",
        "joiner": "\\n",
        "joinerType": "str",
        "accumulate": true,
        "timeout": "",
        "count": "8",
        "reduceRight": false,
        "reduceExp": "",
        "reduceInit": "",
        "reduceInitType": "",
        "reduceFixup": "",
        "x": 630,
        "y": 140,
        "wires": [
            [
                "99438705.c661e8"
            ]
        ]
    },
    {
        "id": "eca1effa.95a05",
        "type": "change",
        "z": "24befeed.0cb5f2",
        "name": "V1",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "v1",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 450,
        "y": 220,
        "wires": [
            [
                "48a83575.9c7a9c"
            ]
        ]
    },
    {
        "id": "17526967.a07137",
        "type": "api-current-state",
        "z": "24befeed.0cb5f2",
        "name": "Total Solar Power (Watts)",
        "server": "cbbf6ce3.4f5eb",
        "version": 1,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "override_topic": false,
        "entity_id": "sensor.total_solar_power",
        "state_type": "str",
        "state_location": "payload",
        "override_payload": "msg",
        "entity_location": "",
        "override_data": "none",
        "blockInputOverrides": false,
        "x": 230,
        "y": 260,
        "wires": [
            [
                "21c59578.da1c0a"
            ]
        ]
    },
    {
        "id": "a50a6ebe.4e214",
        "type": "api-current-state",
        "z": "24befeed.0cb5f2",
        "name": "Daily Consumed (Watt hours)",
        "server": "cbbf6ce3.4f5eb",
        "version": 1,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "override_topic": false,
        "entity_id": "sensor.daily_consumed_energy_wh",
        "state_type": "str",
        "state_location": "payload",
        "override_payload": "msg",
        "entity_location": "",
        "override_data": "none",
        "blockInputOverrides": false,
        "x": 240,
        "y": 300,
        "wires": [
            [
                "6363034f.3ac2ec"
            ]
        ]
    },
    {
        "id": "f6d9d089.0c42d",
        "type": "api-current-state",
        "z": "24befeed.0cb5f2",
        "name": "Consumed Power (Watts)",
        "server": "cbbf6ce3.4f5eb",
        "version": 1,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "override_topic": false,
        "entity_id": "sensor.total_consumed_power",
        "state_type": "str",
        "state_location": "payload",
        "override_payload": "msg",
        "entity_location": "",
        "override_data": "none",
        "blockInputOverrides": false,
        "x": 230,
        "y": 340,
        "wires": [
            [
                "853e698f.ac7f88"
            ]
        ]
    },
    {
        "id": "7fd1ce58.84e1a",
        "type": "api-current-state",
        "z": "24befeed.0cb5f2",
        "name": "Temperature",
        "server": "cbbf6ce3.4f5eb",
        "version": 1,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "override_topic": false,
        "entity_id": "sensor.dark_sky_temperature_0h",
        "state_type": "str",
        "state_location": "payload",
        "override_payload": "msg",
        "entity_location": "",
        "override_data": "none",
        "blockInputOverrides": false,
        "x": 190,
        "y": 380,
        "wires": [
            [
                "5580eb68.666464"
            ]
        ]
    },
    {
        "id": "e5e9e6d9.dd8f38",
        "type": "api-current-state",
        "z": "24befeed.0cb5f2",
        "name": "Volts",
        "server": "cbbf6ce3.4f5eb",
        "version": 1,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "override_topic": false,
        "entity_id": "sensor.utility_voltage",
        "state_type": "str",
        "state_location": "payload",
        "override_payload": "msg",
        "entity_location": "",
        "override_data": "none",
        "blockInputOverrides": false,
        "x": 170,
        "y": 420,
        "wires": [
            [
                "4e6cb33e.56467c"
            ]
        ]
    },
    {
        "id": "21c59578.da1c0a",
        "type": "change",
        "z": "24befeed.0cb5f2",
        "name": "V2",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "v2",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 450,
        "y": 260,
        "wires": [
            [
                "48a83575.9c7a9c"
            ]
        ]
    },
    {
        "id": "6363034f.3ac2ec",
        "type": "change",
        "z": "24befeed.0cb5f2",
        "name": "V3",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "v3",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 450,
        "y": 300,
        "wires": [
            [
                "48a83575.9c7a9c"
            ]
        ]
    },
    {
        "id": "853e698f.ac7f88",
        "type": "change",
        "z": "24befeed.0cb5f2",
        "name": "V4",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "v4",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 450,
        "y": 340,
        "wires": [
            [
                "48a83575.9c7a9c"
            ]
        ]
    },
    {
        "id": "5580eb68.666464",
        "type": "change",
        "z": "24befeed.0cb5f2",
        "name": "V5",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "v5",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 450,
        "y": 380,
        "wires": [
            [
                "48a83575.9c7a9c"
            ]
        ]
    },
    {
        "id": "4e6cb33e.56467c",
        "type": "change",
        "z": "24befeed.0cb5f2",
        "name": "V6",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "v6",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 450,
        "y": 420,
        "wires": [
            [
                "48a83575.9c7a9c"
            ]
        ]
    },
    {
        "id": "99438705.c661e8",
        "type": "function",
        "z": "24befeed.0cb5f2",
        "name": "Set API key here 1",
        "func": "msg.action = msg.payload;\nmsg.headers = { \n 'X-Pvoutput-Apikey': 'xxxxxxxxxxxxxxxxxxx',\n 'X-Pvoutput-SystemId': 'xxxxxx',\n 'Content-Type': 'application/x-www-form-urlencoded'\n};\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 710,
        "y": 200,
        "wires": [
            [
                "d19b860d.981778"
            ]
        ]
    },
    {
        "id": "d19b860d.981778",
        "type": "function",
        "z": "24befeed.0cb5f2",
        "name": "Set up data",
        "func": "msg.action = msg.payload;\n\nmsg.url = \"http://pvoutput.org/service/r2/addstatus.jsp\";\n\n\n\nreturn msg;\n\n",
        "outputs": 1,
        "noerr": 0,
        "x": 710,
        "y": 260,
        "wires": [
            [
                "172a0ac0.cd35c5"
            ]
        ]
    },
    {
        "id": "172a0ac0.cd35c5",
        "type": "http request",
        "z": "24befeed.0cb5f2",
        "name": "Post",
        "method": "POST",
        "ret": "txt",
        "paytoqs": false,
        "url": "",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "x": 710,
        "y": 320,
        "wires": [
            [
                "ea2bee87.e3fec"
            ]
        ]
    },
    {
        "id": "ea2bee87.e3fec",
        "type": "debug",
        "z": "24befeed.0cb5f2",
        "name": "headercheck",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "x": 710,
        "y": 380,
        "wires": []
    },
    {
        "id": "cebb4284.5ca53",
        "type": "moment",
        "z": "24befeed.0cb5f2",
        "name": "Date",
        "topic": "d",
        "input": "",
        "inputType": "date",
        "inTz": "America/Edmonton",
        "adjAmount": 0,
        "adjType": "days",
        "adjDir": "add",
        "format": "YYYYMMDD",
        "locale": "C",
        "output": "payload",
        "outputType": "msg",
        "outTz": "America/Edmonton",
        "x": 450,
        "y": 140,
        "wires": [
            [
                "48a83575.9c7a9c"
            ]
        ]
    },
    {
        "id": "82eeed4d.79b77",
        "type": "moment",
        "z": "24befeed.0cb5f2",
        "name": "Time",
        "topic": "t",
        "input": "",
        "inputType": "date",
        "inTz": "America/Edmonton",
        "adjAmount": 0,
        "adjType": "days",
        "adjDir": "add",
        "format": "HH:mm",
        "locale": "C",
        "output": "payload",
        "outputType": "msg",
        "outTz": "America/Edmonton",
        "x": 450,
        "y": 180,
        "wires": [
            [
                "48a83575.9c7a9c"
            ]
        ]
    },
    {
        "id": "cbbf6ce3.4f5eb",
        "type": "server",
        "z": "",
        "name": "Home Assistant",
        "legacy": false,
        "hassio": true,
        "rejectUnauthorizedCerts": true,
        "ha_boolean": "y|yes|true|on|home|open",
        "connectionDelay": false
    }
]
2 Likes

Thanks a lot for this. I adapted it to my use case but it’s been really useful having 99% ot the work already done.

Thanks for the feedback!
I also have the config files for all my shelly power sensors if that interests anyone.

Sorry for the late response, I got no notification for your reply, strange.

Lots of shellies here, and always looking for best practices, would be glad to see if I can reuse it. Thanks. :slight_smile:

sensors.yaml

- platform: mqtt
  name: "Utility Power 1"
  state_topic: "shellies/Utility/emeter/0/power"
  qos: 1
  unit_of_measurement: "W"
  icon: mdi:gauge
- platform: mqtt
  name: "Utility Power 2"
  state_topic: "shellies/Utility/emeter/1/power"
  qos: 1
  unit_of_measurement: "W"
  icon: mdi:gauge        
- platform: mqtt
  name: "Utility Voltage"
  state_topic: "shellies/Utility/emeter/1/voltage"
  qos: 1
  unit_of_measurement: "V"
  icon: mdi:gauge   
- platform: mqtt
  name: "Utility Energy 1"
  state_topic: "shellies/Utility/emeter/0/energy"
  qos: 1
  unit_of_measurement: "Wm"
- platform: mqtt
  name: "Utility Energy 2"
  state_topic: "shellies/Utility/emeter/1/energy"
  qos: 1
  unit_of_measurement: "Wm"

- platform: mqtt
  name: "Solar Power 1 Raw"
  state_topic: "shellies/Solar/emeter/0/power"
  qos: 1
  unit_of_measurement: "W"
  icon: mdi:gauge
- platform: mqtt
  name: "Solar Power 2 Raw"
  state_topic: "shellies/Solar/emeter/1/power"
  qos: 1
  unit_of_measurement: "W"
  icon: mdi:gauge        
- platform: mqtt
  name: "Solar Voltage"
  state_topic: "shellies/Solar/emeter/1/voltage"
  qos: 1
  unit_of_measurement: "V"
  icon: mdi:gauge   
- platform: mqtt
  name: "Solar Energy 1"
  state_topic: "shellies/Solar/emeter/0/energy"
  qos: 1
  unit_of_measurement: "Wm"
- platform: mqtt
  name: "Solar Energy 2"
  state_topic: "shellies/Solar/emeter/1/energy"
  qos: 1
  unit_of_measurement: "Wm"


- platform: integration
  source: sensor.total_solar_power
  name: total_solar_energy
  unit_prefix: k
  round: 2   
- platform: integration
  source: sensor.total_utility_power
  name: total_utility_energy
  unit_prefix: k
  round: 2  
- platform: integration
  source: sensor.total_consumed_power
  name: total_consumed_energy
  unit_prefix: k
  round: 2
  
- platform: template
  sensors:
    solar_power_1:
      value_template: >
        {{ (states('sensor.solar_power_1_raw')|float - 3) |round(2) }}
      friendly_name: 'Solar Power 1'
      unit_of_measurement: 'W'   
    solar_power_2:
      value_template: >
        {{ (states('sensor.solar_power_2_raw')|float - 3) |round(2) }}
      friendly_name: 'Solar Power 2'
      unit_of_measurement: 'W'       
    consumed_power_1:
      value_template: >
        {{ (states('sensor.solar_power_1')|float 
        + states('sensor.utility_power_1')|float) |round(2) }}
      friendly_name: 'Consumed Power 1'
      unit_of_measurement: 'W'       
    consumed_power_2:
      value_template: >
        {{ (states('sensor.solar_power_2')|float 
        + states('sensor.utility_power_2')|float) |round(2) }}
      friendly_name: 'Consumed Power 2'
      unit_of_measurement: 'W'          
    total_consumed_power:
      value_template: >
        {{ (states('sensor.consumed_power_1')|float 
        + states('sensor.consumed_power_2')|float)| round(2) }}
      friendly_name: 'Total Consumed Power'
      unit_of_measurement: 'W'   
    total_solar_power:
      value_template: >
        {{ (states('sensor.solar_power_1')|float 
        + states('sensor.solar_power_2')|float)| round(2) }}
      friendly_name: 'Total Solar Power'
      unit_of_measurement: 'W'       
    total_utility_power:
      value_template: >
        {{ (states('sensor.utility_power_1')|float 
        + states('sensor.utility_power_2')|float)| round(2) }}
      friendly_name: 'Total Utility Power'
      unit_of_measurement: 'W'
    total_solar_power_kw:
      value_template: >
        {{ (states('sensor.total_solar_power')|float /1000) | round(2) }}
      friendly_name: 'Total Solar Power kW'
      unit_of_measurement: 'kW'       
    total_utility_power_kw:
      value_template: >
        {{ (states('sensor.total_utility_power')|float /1000) | round(2) }}
      friendly_name: 'Total Utility Power kW'
      unit_of_measurement: 'kW'
    daily_solar_energy_wh:
      value_template: >
        {{ (states('sensor.solar_daily_energy_peak')|float *1000) | round(2) }}
      friendly_name: 'Daily Solar Energy Wh'
      unit_of_measurement: 'Wh'         
    daily_consumed_energy_wh:
      value_template: >
        {{ (states('sensor.consumed_daily_energy_peak')|float *1000) | round(2) }}
      friendly_name: 'Daily Solar Energy Wh'
      unit_of_measurement: 'Wh'

utility_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
    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: true
    tariffs: 
      - peak
    
  solar_monthly_energy:
    source: sensor.total_solar_energy
    cycle: monthly  
    net_consumption: true
    tariffs: 
      - peak    

  solar_yearly_energy:
    source: sensor.total_solar_energy
    cycle: yearly  
    net_consumption: true
    tariffs: 
      - peak
      
  consumed_daily_energy:
    source: sensor.total_consumed_energy
    cycle: daily  
    net_consumption: true
    tariffs: 
      - peak    
      
  consumed_monthly_energy:
    source: sensor.total_consumed_energy
    cycle: monthly  
    net_consumption: true
    tariffs: 
      - peak    
      
  consumed_yearly_energy:
    source: sensor.total_consumed_energy
    cycle: yearly  
    net_consumption: true
    tariffs: 
      - peak