Initial commit
This commit is contained in:
@@ -0,0 +1,231 @@
|
||||
This repository holds the custom integration for Home Assistant that is polling data from the electricity grid provider, to catch and notify home assistant whn there are power outages planned/unplanned.
|
||||
|
||||
The integration follows home assistant best practices.
|
||||
|
||||
It has the following configurations:
|
||||
|
||||
1. DEER Region: [TN, TS, MN] for Transilvania Nord, Transilvania Sud, Muntentia Nord
|
||||
For Cluj County it should default to TN.
|
||||
|
||||
2. City/Village: The city/village for which notifications should be raised
|
||||
3. Street: the street name, if left blank, notifications will be raised for all streets in the city/village.
|
||||
4. Polling interval standard: default to 15 minutes
|
||||
5. Polling interval for power outages: default to 1 minute
|
||||
|
||||
How It works:
|
||||
|
||||
Scenario 1: Normal operation
|
||||
The integration will poll the electricity grid provider every 15 minutes (or the custom set interval) and check if there are any power outages planned/unplanned. If there are, it will raise a notification.
|
||||
The endpoints polled are:
|
||||
https://outages.distributie-energie.ro/api/incidents/{Region}/0 for unplanned power outages
|
||||
https://outages.distributie-energie.ro/api/scheduled/{Region}/0/15 for planned power outages in the next 15 days.
|
||||
https://outages.distributie-energie.ro/api/scheduled/{Region}/0/azi for planned power outages today.
|
||||
|
||||
The data returned has the following format(s):
|
||||
|
||||
For scheduled power outages:
|
||||
[
|
||||
{
|
||||
"id": "82540",
|
||||
"nivel": "JT",
|
||||
"sucursala": "BAIA MARE",
|
||||
"judet": null,
|
||||
"centru": null,
|
||||
"linie": null,
|
||||
"denumireInst": null,
|
||||
"ansambluFunctional": "CALINESTI, Strada PRINCIPALA",
|
||||
"catInstalatii": null,
|
||||
"instalatie": null,
|
||||
"dataProgramareStart": "14/01/2026 08:00",
|
||||
"dataProgramareStop": "14/01/2026 15:00",
|
||||
"durataProgramare": "7h : 0'",
|
||||
"adreseLucrari": null,
|
||||
"intervaluriProgramari": null
|
||||
}
|
||||
]
|
||||
|
||||
In this case, the integration will search the fields: "ansambluFunctional" and "adreseLucrari" to see if the city/village and street name are present. the logic will follow the following process:
|
||||
we'll have a variable: cityPresent=city/village name is present, comparison done by first making both the expected and actual values as lower case.
|
||||
if it's true, we'l check in a simillar fashion the street name
|
||||
If we have a planned outage: we'll raise a home assistant event, with attributes for the planned start/stop and duration for the fields: dataProgramareStart, durataProgramareStop, durataProgramare, also ansamblulFunctional and adreseLucrari.
|
||||
|
||||
For unplanned power outages:
|
||||
[
|
||||
{
|
||||
"id": "69706",
|
||||
"judet": "SIBIU",
|
||||
"localitate": null,
|
||||
"sat": null,
|
||||
"tipArtera": null,
|
||||
"artera": null,
|
||||
"numar": null,
|
||||
"bloc": null,
|
||||
"adresa": "Loc: SURA MARE, Strada: VETERANILOR<br />Loc: SURA MARE",
|
||||
"dataStart": "10/01/2026 01:00",
|
||||
"dataStop": ""
|
||||
},
|
||||
|
||||
In this case the search will be done in field: adresa, and the logic will follow the same process as above.
|
||||
in case of unplanned power outages, we'll raise a home assistant event with the attributes: dataStart, dataStop, adresa.
|
||||
|
||||
When a planned or unplanned power outage is raised, the integration keep track of the notification data, and will only raise a new notification if the start dates/ duration or end date changes.
|
||||
|
||||
Scenario 2: Home assistant restart
|
||||
In case home assistant is restarted, the integration will keep track of the notification data, and will only raise a new notification if the start dates/ duration or end date changes.
|
||||
|
||||
Scenario 3: Power outage in progress
|
||||
The integration exposes a switch entity to control the polling interval.
|
||||
When home assistant detects that a power outage is in progress, the polling interval will be set to 1 minute (or the configured time), by enabling the outage polling mode switch.
|
||||
|
||||
## Entities Created
|
||||
|
||||
The integration creates the following entities:
|
||||
|
||||
### Sensors (11 total)
|
||||
|
||||
#### Planned Outages (15 days)
|
||||
- `sensor.deer_outages_planned_15_start` - Start datetime of planned outage (device_class: timestamp)
|
||||
- `sensor.deer_outages_planned_15_end` - End datetime of planned outage (device_class: timestamp)
|
||||
- `sensor.deer_outages_planned_15_duration` - Duration text (e.g., "7h : 0'")
|
||||
- `sensor.deer_outages_planned_15_address` - Location address text
|
||||
|
||||
#### Planned Outages (Today)
|
||||
- `sensor.deer_outages_planned_today_start` - Start datetime of today's planned outage (device_class: timestamp)
|
||||
- `sensor.deer_outages_planned_today_end` - End datetime of today's planned outage (device_class: timestamp)
|
||||
- `sensor.deer_outages_planned_today_duration` - Duration text
|
||||
- `sensor.deer_outages_planned_today_address` - Location address text
|
||||
|
||||
#### Unplanned Incidents
|
||||
- `sensor.deer_outages_unplanned_start` - Start datetime of unplanned incident (device_class: timestamp)
|
||||
- `sensor.deer_outages_unplanned_end` - End datetime of unplanned incident (device_class: timestamp)
|
||||
- `sensor.deer_outages_unplanned_address` - Location address text
|
||||
|
||||
All sensors use `RestoreEntity` to persist their state across Home Assistant restarts.
|
||||
|
||||
### Switch Entity
|
||||
|
||||
- `switch.deer_outages_outage_polling_mode` - Controls polling interval
|
||||
- **Off (default)**: Normal polling mode - polls every 15 minutes (or configured interval)
|
||||
- **On**: Outage polling mode - polls every 1 minute (or configured interval) for faster updates during active outages
|
||||
|
||||
The switch state is preserved across Home Assistant restarts.
|
||||
|
||||
## Events
|
||||
|
||||
In addition to sensors, the integration fires Home Assistant events for automation triggers:
|
||||
|
||||
### Event Types
|
||||
|
||||
1. **`deer_outages_planned`** - Fired when a planned outage is detected or changed
|
||||
|
||||
Event data:
|
||||
```python
|
||||
{
|
||||
"start": "14/01/2026 08:00",
|
||||
"end": "14/01/2026 15:00",
|
||||
"duration": "7h : 0'",
|
||||
"address": "CALINESTI, Strada PRINCIPALA",
|
||||
"city": "Cluj-Napoca",
|
||||
"street": "Principala",
|
||||
"type": "planned_15" # or "planned_today"
|
||||
}
|
||||
```
|
||||
|
||||
2. **`deer_outages_unplanned`** - Fired when an unplanned incident is detected or changed
|
||||
|
||||
Event data:
|
||||
```python
|
||||
{
|
||||
"start": "10/01/2026 01:00",
|
||||
"end": "",
|
||||
"address": "Loc: SURA MARE, Strada: VETERANILOR",
|
||||
"city": "Sura Mare",
|
||||
"street": ""
|
||||
}
|
||||
```
|
||||
|
||||
Events are only fired when:
|
||||
- A new outage is detected (wasn't present before)
|
||||
- An existing outage's start date, end date, or duration changes
|
||||
|
||||
## Automation Examples
|
||||
|
||||
### Example 1: Notification on Planned Outage
|
||||
```yaml
|
||||
automation:
|
||||
- alias: "Notify on Planned Outage"
|
||||
trigger:
|
||||
- platform: event
|
||||
event_type: deer_outages_planned
|
||||
action:
|
||||
- service: notify.mobile_app
|
||||
data:
|
||||
title: "Planned Power Outage"
|
||||
message: >
|
||||
Outage from {{ trigger.event.data.start }}
|
||||
to {{ trigger.event.data.end }}
|
||||
at {{ trigger.event.data.address }}
|
||||
```
|
||||
|
||||
### Example 2: Using Sensor States
|
||||
```yaml
|
||||
automation:
|
||||
- alias: "Alert on Today's Outage"
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: sensor.deer_outages_planned_today_start
|
||||
to: ~
|
||||
condition:
|
||||
- condition: template
|
||||
value_template: "{{ states('sensor.deer_outages_planned_today_start') not in ['unknown', 'unavailable', 'None'] }}"
|
||||
action:
|
||||
- service: notify.mobile_app
|
||||
data:
|
||||
title: "Power Outage Today!"
|
||||
message: >
|
||||
Power outage scheduled for today from
|
||||
{{ states('sensor.deer_outages_planned_today_start') }}
|
||||
to {{ states('sensor.deer_outages_planned_today_end') }}
|
||||
```
|
||||
|
||||
### Example 3: Auto-Enable Outage Mode
|
||||
```yaml
|
||||
automation:
|
||||
- alias: "Enable Fast Polling on Active Outage"
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: sensor.deer_outages_unplanned_start
|
||||
to: ~
|
||||
condition:
|
||||
- condition: template
|
||||
value_template: "{{ states('sensor.deer_outages_unplanned_start') not in ['unknown', 'unavailable', 'None'] }}"
|
||||
action:
|
||||
- service: switch.turn_on
|
||||
target:
|
||||
entity_id: switch.deer_outages_outage_polling_mode
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
### Manual Installation
|
||||
1. Copy the `custom_components/deer_outages` directory to your Home Assistant `custom_components` directory
|
||||
2. Restart Home Assistant
|
||||
3. Go to **Settings** > **Devices & Services** > **Add Integration**
|
||||
4. Search for "DEER Power Outages"
|
||||
5. Complete the configuration:
|
||||
- Select your region (TN, TS, or MN)
|
||||
- Enter your city/village name
|
||||
- Optionally enter your street name
|
||||
- Configure polling intervals (defaults: 15 min normal, 1 min outage)
|
||||
|
||||
### Testing the API
|
||||
Before installing in Home Assistant, you can test the API connection using the standalone script:
|
||||
|
||||
```bash
|
||||
python test_api.py TN Cluj-Napoca "Strada Avram Iancu"
|
||||
```
|
||||
|
||||
This will:
|
||||
- Test all three API endpoints
|
||||
- Show filtered results for your location
|
||||
- Validate the filtering logic
|
||||
Reference in New Issue
Block a user