Initial commit

This commit is contained in:
2026-04-06 15:34:01 +03:00
commit bd5dc07ed8
13 changed files with 2081 additions and 0 deletions
+231
View File
@@ -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