EskomSePush: API available

Hi all,

Many of you might have seen it on MyBroadband, but EskomSePush launched their API for personal (and business) use:

EskomSePush Business API 2.0 (getpostman.com)

Features (From their site)

  • Real time status for National Loadshedding
  • Real time status per Area, Upcoming Events & Schedule
  • Areas Search by Text
  • Areas Nearby by GPS coordinates
  • User Generated Topics by approx GPS location

Check the link above for more details, quota limits, how to get a token and more requests etc.

Example request:

curl --location --request GET 'https://developer.sepush.co.za/business/2.0/area?id=eskde-10-fourwaysext10cityofjohannesburggauteng'

Response:

{
    "events": [
        {
            "end": "2022-08-08T22:30:00+02:00",
            "note": "Stage 2",
            "start": "2022-08-08T20:00:00+02:00"
        }
    ],
    "info": {
        "name": "Sandton-WEST (4)",
        "region": "Eskom Direct, City of Johannesburg, Gauteng"
    },
    "schedule": {
        "days": [
            {
                "date": "2022-08-08",
                "name": "Monday",
                "stages": [
                    [],
                    [
                        "20:00-22:30"
                    ],
                    [
                        "12:00-14:30",
                        "20:00-22:30"
                    ],
                    [
                        "04:00-06:30",
                        "12:00-14:30",
                        "20:00-22:30"
                    ],
                    [
                        "04:00-06:30",
                        "12:00-14:30",
                        "20:00-22:30"
                    ],
                    [
                        "04:00-06:30",
                        "12:00-14:30",
                        "20:00-00:30"
                    ],
                    [
                        "04:00-06:30",
                        "12:00-16:30",
                        "20:00-00:30"
                    ],
                    [
                        "04:00-08:30",
                        "12:00-16:30",
                        "20:00-00:30"
                    ]
                ]
            },
            {
                "date": "2022-08-09",
                "name": "Tuesday",
                "stages": [
                    [
                        "02:00-04:30"
                    ],
                    [
                        "02:00-04:30"
                    ],
                    [
                        "02:00-04:30",
                        "18:00-20:30"
                    ],
                    [
                        "02:00-04:30",
                        "10:00-12:30",
                        "18:00-20:30"
                    ],
                    [
                        "02:00-06:30",
                        "10:00-12:30",
                        "18:00-20:30"
                    ],
                    [
                        "02:00-06:30",
                        "10:00-12:30",
                        "18:00-20:30"
                    ],
                    [
                        "02:00-06:30",
                        "10:00-12:30",
                        "18:00-22:30"
                    ],
                    [
                        "02:00-06:30",
                        "10:00-14:30",
                        "18:00-22:30"
                    ]
                ]
            },
            {
                "date": "2022-08-10",
                "name": "Wednesday",
                "stages": [
                    [
                        "10:00-12:30"
                    ],
                    [
                        "02:00-04:30",
                        "10:00-12:30"
                    ],
                    [
                        "02:00-04:30",
                        "10:00-12:30"
                    ],
                    [
                        "02:00-04:30",
                        "10:00-12:30",
                        "18:00-20:30"
                    ],
                    [
                        "02:00-04:30",
                        "10:00-14:30",
                        "18:00-20:30"
                    ],
                    [
                        "02:00-06:30",
                        "10:00-14:30",
                        "18:00-20:30"
                    ],
                    [
                        "02:00-06:30",
                        "10:00-14:30",
                        "18:00-20:30"
                    ],
                    [
                        "02:00-06:30",
                        "10:00-14:30",
                        "18:00-22:30"
                    ]
                ]
            },
            {
                "date": "2022-08-11",
                "name": "Thursday",
                "stages": [
                    [
                        "18:00-20:30"
                    ],
                    [
                        "10:00-12:30",
                        "18:00-20:30"
                    ],
                    [
                        "02:00-04:30",
                        "10:00-12:30",
                        "18:00-20:30"
                    ],
                    [
                        "02:00-04:30",
                        "10:00-12:30",
                        "18:00-20:30"
                    ],
                    [
                        "02:00-04:30",
                        "10:00-12:30",
                        "18:00-22:30"
                    ],
                    [
                        "02:00-04:30",
                        "10:00-14:30",
                        "18:00-22:30"
                    ],
                    [
                        "02:00-06:30",
                        "10:00-14:30",
                        "18:00-22:30"
                    ],
                    [
                        "02:00-06:30",
                        "10:00-14:30",
                        "18:00-22:30"
                    ]
                ]
            },
            {
                "date": "2022-08-12",
                "name": "Friday",
                "stages": [
                    [],
                    [
                        "18:00-20:30"
                    ],
                    [
                        "10:00-12:30",
                        "18:00-20:30"
                    ],
                    [
                        "02:00-04:30",
                        "10:00-12:30",
                        "18:00-20:30"
                    ],
                    [
                        "02:00-04:30",
                        "10:00-12:30",
                        "18:00-20:30"
                    ],
                    [
                        "02:00-04:30",
                        "10:00-12:30",
                        "18:00-22:30"
                    ],
                    [
                        "02:00-04:30",
                        "10:00-14:30",
                        "18:00-22:30"
                    ],
                    [
                        "02:00-06:30",
                        "10:00-14:30",
                        "18:00-22:30"
                    ]
                ]
            }
        ],
        "source": "https://loadshedding.eskom.co.za/"
    }
}
1 Like

OK, now the Node-RED fundi’s can make an elegant interface and we’re all set.

I managed to do the GET request using NodeRed. Nice to have a “no code” solution.
Haven’t done anything with the response yet though.

2 Likes

I suppose one has to decide what to do with the information.
What do forum members do if load-shedding is imminent?
What would they automate?

So one important thing to note, there is a limit on the free personal api of 50 requests per day. So just spamming for updates wont do any good.

However what is great about this api is the following:

  1. Show both Eskom and Cape Town stages
  2. In addition to the current stage, it also shows FUTURE stages
  3. Any area supported by ESP, you can get the schedule of loadshedding slots

So for me, I guess the most useful automation would be to know that if I get a 4am or 6am loadshedding slot, if battery is low, do a) stop high usage those times b) maybe just up DoD so that batteries with whatever is left, is ready for that slot.

Most of the things at my home is already automated through home assistant, so this will just be one more datapoint for making decisions on when and if to run high loads.

To make this work, ideally I would need to build a custom integration to get it work the utmost best and also share with others to make it easier to use.

If I had the info, I’d set Min SoC to be equal to 20% + 6 x #hours of loadshedding if loadshedding is <= 1 hour from starting. If not <= 1 hour of starting, Min SoC reverts back to default.

I need 5% SoC per hour of shedding, 6% is therefore a margin for safety.

Under what conditions would you allow charging from grid? Presumably, you’d want to see what SOC you achieved during the day?

I’d allow charging from the grid if loadshedding is <= 1 hour away and I don’t have the required SoC to weather it.

You can implement the “battery life” option parallel to this if you want.

At least, that is how I would do it. Currently I don’t run battery life, because I’m happy to not fully charge my batteries every day.

1 Like

Sounds like a good plan.

Technically it is a little suboptimal, because I don’t actually think I need to implement this during day time. Even on the worst days, I still generate enough PV to meet my genuine back-up loads. So perhaps a refinement would include only running the automation conditional to being say < 1+#loadshedding hours away from sunset or < 1h after sunrise.

Anyways, over optimisation is rarely worth the effort and the risk, so don’t think it would really be worth it.

I agree, KISS.

Turning off non-essentials after dark?

I’ve had fairly simple rules so far - which is usually

  • keep my normal discharge-to-rate, which is 25%
  • an hour before loadshedding, ensure that I have at least 50% SOC. If not, charge from the grid up to there.

Usually not too much of a concern in the day, but very useful in the night.

My personal thought around the API is to

  • check very hour (thus 24 requests a day)
  • still keep the eskom sensor going and if that changes, get the latest updates from EskomSePush.

I didn’t think about this, but:
It would seem that could cost you up to an hour’s notice in the worst-case scenario. As 50 requests a day are allowed, I’d say that every half hour is the way to go.

2 Likes

My rules:
Is there LS?
Yes, what is the weather like tomorrow?
Enough sun Yes, carry on then.
If Not, bugger … Keep charged there we go.

Ps. And I check 3 sources for weather … they don’t all agree at the same time, sometimes day/week.
It is “seat of my pants” call.

I use HA. It only shows what Stage of sh1t Escam is in. It reports SoC and shows Grid, PV Charger and PV Inverter watts.

My SoC I set manually, normally varies between 20 and 30% except during LS in Winter, then it goes to 40-45%. Because the weather data is not all that reliable, and I have 24kWh available at 20% SoC I normally do not mess with my SoC to much. During long rainy spells, and LS its on 35-40%. Manually as I mentioned. If I had more reliable data on Weather, I may consider to use NodeRed or HA automations.

I can turn down my Geyser element should the need arise, anywhere from 1-100%. Well now 100% is not turned down but ya get the idea…

Groetnis

Jeeeeepers, that’s a lot of storage :joy:
I have 14kWh total, so have to play with minSoC a bit more to keep peace of mind during loadshedding.

I once forgot to up it on a cloudy day, only for loadshedding to hit at 4pm.
That was a stressful 2 hours…

And not quite enough during winter time. Need to ad 8-16kWh more soon. At 5% SoC ( currently only emergency and LS) about 30kWh.

Groetnis

Yes, but that brings you to 48 which is very close to the limit.

Hence once an hour (24 requests) and then whenever the loadshedding status changes, fetch the latest one.

OK, my first stab at using the API in Home Assistant:

sensors:
# Eskom load shedding sensor
  - platform: command_line
    name: eskom_loadshedding_status
    command: "curl https://loadshedding.eskom.co.za/LoadShedding/GetStatus"
    value_template: >- 
          {% if value | round(0) >= 0 %}
            {{ value | round(0) | abs - 1 }}
          {% else %}
            {{ states.sensor.eskom_loadshedding_status.state }}
          {% endif %}
    unit_of_measurement: "Stage"
    scan_interval: 180

#Eskom se push sensor
  - platform: rest
    name: EskomSePush
    resource: "https://developer.sepush.co.za/business/2.0/area"
    headers:
        Token: !secret EskomSePush 
    params:
        id: "<your area id here>"
#        test: "current"
    json_attributes:
      - events
      - info
      - schedule
    value_template: "OK"
    scan_interval: 3600
    
  - platform: rest
    name: EskomSePushAllowance
    resource: "https://developer.sepush.co.za/business/2.0/api_allowance"
    headers:
        Token: !secret EskomSePush 
    json_attributes_path: "$.allowance"
    json_attributes:
      - count
      - limit
      - type
    value_template: "OK"
    scan_interval: 3600

  - platform: template
    sensors:
      next_loadshedding_time:
        friendly_name: Next loadshedding time
        device_class: timestamp
        unique_id: Next_Loadshedding_Time
        value_template: "{{ state_attr('sensor.eskomsepush','events')[0].start }}"
      next_loadshedding_event:
        friendly_name: Next loadshedding event
        unique_id: Next_Loadshedding_Event
        value_template: "{{ state_attr('sensor.eskomsepush','events')[0].note }}"
      next_loadshedding_time_end:
        friendly_name: Next loadshedding end time
        unique_id: Next_Loadshedding_End_Time
        value_template: "{{ state_attr('sensor.eskomsepush','events')[0].end }}"
      time_till_loadshedding:
        friendly_name: Time until next loadshedding
        unique_id: Time_Until_Next_Loadshedding
        unit_of_measurement: mins
        value_template: '{{ [( as_timestamp(states.sensor.next_loadshedding_time.state) | int - as_timestamp(now()) | int ) / 60,-1] | max }}' 
      time_till_loadshedding_ends:
        friendly_name: Time until next loadshedding ends
        unique_id: Time_Until_Next_Loadshedding_ends
        unit_of_measurement: mins
        value_template: '{{ [( as_timestamp(states.sensor.next_loadshedding_time_end.state) | int - as_timestamp(now()) | int ) / 60,-1] | max }}' 

      eskomsepush_calls_remaining:
        friendly_name: EskomSePush API Calls remaining
        unique_id: EskomSePush_calls_remaining
        value_template: '{{ int(state_attr("sensor.eskomsepushallowance","limit")) - int(state_attr("sensor.eskomsepushallowance","count")) }}'

binary_sensors:
  - platform: template
    sensors:
      loadshedding_active:
        friendly_name: "Loadshedding active"
        device_class: problem
        value_template: >
            {% if (int(states('sensor.time_till_loadshedding')) <= 0 ) %}
             True
            {% else %}
             False
            {% endif %}     

This gives me:

image

Not the prettiest but good enough first attempt at midnight on a week’s night :slight_smile: The minutes until loadshedding is nice because it makes for easy automations, e.g. if less than 60 mins and battery < 50%, then charge from the grid up to 50%.

The only thing I noticed is that the API seems to return only UPCOMING events, and not one that you’re currently in. So I wrote this while I was an in Stage 4 loadshedding event and that wasn’t returned. Not sure yet how to check if you’re currently being loadshed.

5 Likes