REST sensor and comma delimited data

Hi all

I have TIGO optimisers on my solar panels and would like to pull panel data in to Home Assistant. They provide an API, however it returns the data in a tab delimited format, which is less than ideal. Please see an example below:

DATETIME,04C05B902A65.panels.A1_Pin,04C05B902A65.panels.A2_Pin,04C05B902A65.panels.A3_Pin,04C05B902A65.panels.A4_Pin,04C05B902A65.panels.A5_Pin,04C05B902A65.panels.A6_Pin,04C05B902A65.panels.A7_Pin,04C05B902A65.panels.A8_Pin,04C05B902A65.panels.A9_Pin
2021/06/01 16:43:00.000,206,209,208,209,177,209,212,230,232
2021/06/01 16:44:00.000,205,208,207,208,177,208,211,230,232
2021/06/01 16:45:00.000,204,207,206,207,175,207,209,227,229
2021/06/01 16:46:00.000,204,206,205,206,175,206,209,221,228
2021/06/01 16:47:00.000,202,204,204,204,173,205,207,220,228
2021/06/01 16:48:00.000,198,202,202,202,171,203,206,224,227
2021/06/01 16:49:00.000,199,202,201,201,170,202,204,223,225
2021/06/01 16:50:00.000,198,201,201,201,169,201,204,222,224
2021/06/01 16:51:00.000,197,200,199,200,168,200,203,220,223
2021/06/01 16:52:00.000,195,198,198,199,167,199,201,215,222

Ideally, what i’d like to do is capture only the last line (most recent) in my REST sensor, then I could set up a template sensors to pull back each individual number as a sensor (Everything after the time is a wattage output from a solar panel. I have 9 in total).

Paul

Could you use a command-line sensor instead?

  - platform: command_line
    command: "curl YOUR_REST_URL | tail -n 1"
    name: "TIGO data"
    scan_interval: 120

That’s a really good idea. I hadn’t considered using the command line sensor

Marking as solution. This seems to work well enough for me.

1 Like

Could you please share more info, how did you implemented this sollution?

@mehstg please could you post the curl command? thank you

Sorry I totally forgot to reply to this, we had a bank holiday weekend in the UK and I switched off completely! Are you the same person who contacted me about this through Twitter too?

So, what I did was kind of janky, but it works OK for me. A proper HA addon would be better.

I wrote a simple script to curl the data from the API. You will have to add your System ID to this, and an authorisation bearer token (The Tigo API docs will help you with this).

powerPerPanelMin.sh

#!/bin/bash

curl --location --request GET "https://api2.tigoenergy.com/api/v3/data/aggregate?system_id=<redacted>&start=$(date +"%Y-%m-%dT00:00:01")&end=$(date +"%Y-%m-%dT%H:%M:%S")&level=min&header=key" --header "Authorization: Bearer <REDACTED>" --silent | tail -1 | cut -d',' -f2-

Then, set up a command line sensor to run this script periodically. In your configuration.yaml add something like this:

  # Pull in granular panel wattage from Tigo API
  - platform: command_line
    command: "bash /config/tigo/powerPerPanelMin.sh"
    name: "Solar Panels"
    scan_interval: 120

This will get the data in to HA as sensor.solar_panels. At this point you should be able to check this in Developer Tools in HA. Note: If you see "message":"Premium required.","code":0,"status":402} it’s because you are using the free account, API access requires a premium Tigo account.

Then it’s just a case of stripping out the necessary data in to separate sensors. I have 9 panels, so have done it like this:

  # Template solar panels out nicely
  - platform: template
    sensors:
      solar_panel_1:
        friendly_name: "Solar Panel 1 - South"
        unit_of_measurement: "W"
        value_template: "{{ states.sensor.solar_panels.state.split(',')[0] }}"
      solar_panel_2:
        friendly_name: "Solar Panel 2 - South"
        unit_of_measurement: "W"
        value_template: "{{ states.sensor.solar_panels.state.split(',')[1] }}"
      solar_panel_3:
        friendly_name: "Solar Panel 3 - South"
        unit_of_measurement: "W"
        value_template: "{{ states.sensor.solar_panels.state.split(',')[2] }}"
      solar_panel_4:
        friendly_name: "Solar Panel 4 - South"
        unit_of_measurement: "W"
        value_template: "{{ states.sensor.solar_panels.state.split(',')[3] }}"
      solar_panel_5:
        friendly_name: "Solar Panel 5 - South"
        unit_of_measurement: "W"
        value_template: "{{ states.sensor.solar_panels.state.split(',')[4] }}"
      solar_panel_6:
        friendly_name: "Solar Panel 6 - South"
        unit_of_measurement: "W"
        value_template: "{{ states.sensor.solar_panels.state.split(',')[5] }}"
      solar_panel_7:
        friendly_name: "Solar Panel 7 - South"
        unit_of_measurement: "W"
        value_template: "{{ states.sensor.solar_panels.state.split(',')[6] }}"
      solar_panel_8:
        friendly_name: "Solar Panel 8 - West"
        unit_of_measurement: "W"
        value_template: "{{ states.sensor.solar_panels.state.split(',')[7] }}"
      solar_panel_9:
        friendly_name: "Solar Panel 9 - West"
        unit_of_measurement: "W"
        value_template: "{{ states.sensor.solar_panels.state.split(',')[8] }}"

Hope that helps!

2 Likes

Thank you for your fast reply. I didn’t write to you on twitter.

I get my system id and auth token. When I run curl command the “premium required” appear.

So, it isn’t possible to get power from panels without paying for a premium account?

Exactly that unfortunately. API access is a “premium” feature. https://support.tigoenergy.com/hc/en-us/articles/202342726-Monitoring-Features-Pricing

1 Like

Hi,

I tried the api, and it returns a token that lasts for six months. Did you automate the token refresh in some way?

Thanks

Iirc, I am manually updating it. It wouldn’t be hard to automate though, Curl the authorization bearer out to a file, then edit the script to read the token in from a file rather than have it hard coded.

did they change this?
in the table it shows W is available for “free” in 15min steps (ridiculous enough, that you have to pull your own data from the cloud):

The comparison chart (below), lists the features that are available within the Free and Premium (subscription) packages

Features Free Premium
Module-level data Energy (Wh)
Power (W)
Reclaimed Power (W)
Energy (Wh)
Power (W)
Reclaimed Power (W)
Voltage (V)
Current (A)
Module-level granularity 15-minutes 1-minute

Has anyone managed to get this working since the original solution posted by mehstg’s post in June 2022? From what I understand the syntax has changed in home assistant and so now the scripts don’t seem to work.

I’m still very new with home assistant, so I don’t know what to fix, but I’m at the point where I can execute the script to get my Tigo data in the list and have got the sensors showing up in dev tools, but they’re all showing as unavailable. I’ve tried reading the documentation on templating, but I’m banging my head against a wall trying to get it finished.
For anyone else struggling, what I did so far was:

I first figured out that I needed to add sensor: !include sensors.yaml to my configuration.yaml and the script to pull data from the Tigo API in there as well, then added the code for the “template solar panels out nicely” to sensors.yaml (which I had to create). This got the sensors for my optimisers up.

I think looking at the documentation for template I need to use number instead of value-template, but again am so inexperienced with home assistant that I don’t know what I’m doing, so hopefully someone can help bridge the gap and get this done.

Apologies for replying to an old thread, but it seemed more appropriate than starting a new one with a similar topic.

For anyone else, I got it sorted. None of my extra steps were necessary; turns out the command_line syntax is different now, so the working configuration is:

# Pull in granular panel wattage from Tigo API
command_line:
 - sensor:
    command: "bash /config/tigo/powerPerPanelMin.sh"
    name: "Solar Panels"
    scan_interval: 60

the sensor then appeared and I went from there. I’ll be investigating if I can get any additional data from the API like RSSI/voltage/current or reclaimed power usable in the next few days.

OK I got three other sensors working for the signal strength, voltage and current. There’s an issue now where the data (for me at least, having 19 panels) is exceeding the maximum state length of 255 characters, so if anyone can help with figuring that out that’d be great.

“/homeassistant/tigo/TigoIin.sh”:

#!/bin/bash


curl --location --request GET "https://api2.tigoenergy.com/api/v3/data/aggregate?system_id=redacted&start=$(date +"%Y-%m-%dT00:00:01")&end=$(date +"%Y-%m-%dT%H:%M:%S")&level=min&param=Iin&header=key" --header "Authorization: Bearer redacted" --silent | tail -1 | cut -d',' -f2-

&param=xxx, where xxx is either Pin (power), Vin (voltage), RSSI (signal strength), or Iin (current)

The configuration.yaml:

# Pull in granular panel data from Tigo API
command_line:
 - sensor:
    command: "bash /config/tigo/TigoIin.sh"
    name: "Tigo Current"
    scan_interval: 120
 - sensor:
     command: "bash /config/tigo/TigoPin.sh"
     name: "Tigo Power"
     scan_interval: 120
 - sensor:
     command: "bash /config/tigo/TigoRSSI.sh"
     name: "Tigo RSSI"
     scan_interval: 120
 - sensor:
     command: "bash /config/tigo/TigoVin.sh"
     name: "Tigo Voltage"
     scan_interval: 120

Templates:

#Optimiser Templates for Current,Power,RSSI,Voltage
template:
  - sensor:
      - name: "Panel A1 Current - Back"
        unit_of_measurement: "A"
        state: >
          {% set value = states('sensor.tigo_current').split(',')[0] %}
          {{ value if value | length > 0 else '0' }}
  - sensor:      
      - name: "Panel A1 Power - Back"
        unit_of_measurement: "W"
        state: >
          {% set value = states('sensor.tigo_power').split(',')[0] %}
          {{ value if value | length > 0 else '0' }}
  - sensor:
      - name: "Panel A1 Signal Strength - Back"
        unit_of_measurement: "dBm"
        state: >
          {% set value = states('sensor.tigo_rssi').split(',')[0] %}
          {{ value if value | length > 0 else '0' }}
  - sensor:
      - name: "Panel A1 Voltage - Back"
        unit_of_measurement: "V"
        state: >
          {% set value = states('sensor.tigo_voltage').split(',')[0] %}
          {{ value if value | length > 0 else '0' }}

Hope that helps anyone.

Edit: As a final update to this, there were cases where the state length exceeded 255 characters. Fixed it with the new bash script:

#!/bin/bash

curl --location --request GET "https://api2.tigoenergy.com/api/v3/data/aggregate?system_id=redacted&start=$(date +"%Y-%m-%dT00:00:01")&end=$(date +"%Y-%m-%dT%H:%M:%S")&level=min&param=Iin&header=key" \
--header "Authorization: Bearer redacted" \
--silent | tail -1 | \
cut -d',' -f2- | \
awk -v OFS=',' '{for(i=1;i<=NF;i++) $i=sprintf("%.5f", $i)} 1' FS=','

which now returns 5 decimal places, so that it doesn’t exceed 255 limit. That should be it.

1 Like

Hi, @matknowles
I used your approach to tigo energy, but I have zero sensors. Don’t you know where the problem could be?

Edit:
I found the problem to be that new bash script.
When I removed it I got the values.

Thanks

immagine

hello!
I have this… some help?
thank you