Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrations rework & MeteoFrance integration #18

Merged
merged 8 commits into from
May 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,34 @@ This card supports translations. Please, help to add more translations and impro

## Supported integrations

This card supports two most popular integrations.
This card supports many other integrations.

- [Core Meteoalarm](https://www.home-assistant.io/integrations/meteoalarm/) - Home Assistant core integration based on ATOM Feed.
- [Core Météo-France](https://www.home-assistant.io/integrations/meteo_france/) - Home Assistant core integration based on Météo France alert.
- [xlcnd/meteoalarmeu](https://github.com/xlcnd/meteoalarmeu) - RRS Feed alternative for countries that does not use ATOM anymore [_Read more_](https://github.com/xlcnd/meteoalarmeu/issues/1).
- [_New integration?_](https://github.com/MrBartusek/MeteoalarmCard/issues/new/choose)

Currently the card will try to auto detect the "sourceType" of your entity but in case this doesn't work or you want to manually override this value just add "sourceType" key into your card configuration and choose one of these type.
In case of problem check you use the right entity for each integration.

---

| Integration | SourceType | Entity |
| ------------------ | ------------ | -------------------------- |
| Core Meteoalarm | meteoalarm | binary_sensor.meteoalarm |
| Core Météo-France | meteofrance | sensor.XX_weather_alert |
| xlcnd/meteoalarmeu | meteoalarmeu | binary_sensor.meteoalarmeu |

---

Like this for example

```yaml
type: 'custom:meteoalarm-card'
entity: 'sensor.75_weather_alert'
sourceType: 'meteofrance'
```

## Contributing

Want to contribute to the project?
Expand Down
20 changes: 20 additions & 0 deletions src/integrations/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# MeteoalarmCard Integrations

## Reference

### Integration
Each integrations class must include **all** of following:

| Name | Description |
| ----------------------------- | ------------------------------------------------------------------------------- |
| `get name()` | Name of the integration that will be used in config file |
| `supports(entity)` | Does this integration support following entity, used for auto-detect |
| `isWarningActive(entity)` | Is there any active warnings for this entity |
| `getResult(entity)` | Return [result](#result) |

### Result
| Name | Required | Description |
| ------------------ | -------- | ------------------------------------------------------------------------------- |
| `awarenessLevel` | Yes | `Level` from `data.js` file |
| `awarenessType` | Yes | `Event` from `data.js` file |
| `headline` | No | Name of the alert, if provided by integration |
35 changes: 35 additions & 0 deletions src/integrations/meteoalarm-integration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { EVENTS, LEVELS } from '../data';

export class MeteoAlarmIntegration
{
static get name()
{
return 'meteoalarm'
}

static supports(entity)
{
return entity.attributes.attribution == 'Information provided by MeteoAlarm'
}

static isWarningActive(entity)
{
return (entity.attributes.status || entity.attributes.state || entity.state) != 'off';
}

static getResult(entity)
{
const {
event,
headline,
awareness_type: awarenessType,
awareness_level: awarenessLevel,
} = entity.attributes;

return {
headline: event || headline,
awarenessLevel: LEVELS[Number(awarenessLevel.split(';')[0]) - 2],
awarenessType: EVENTS[Number(awarenessType.split(';')[0]) - 1]
}
}
}
32 changes: 32 additions & 0 deletions src/integrations/meteoalarmeu-integration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { EVENTS, LEVELS } from '../data';

export class MeteoAlarmeuIntegration
{
static get name()
{
return 'meteoalarmeu'
}

static supports(entity)
{
return entity.attributes.attribution == 'Information provided by meteoalarm.eu'
}

static isWarningActive(entity)
{
return (entity.attributes.status || entity.attributes.state || entity.state) != 'off';
}

static getResult(entity)
{
const {
awareness_type: awarenessType,
awareness_level: awarenessLevel
} = entity.attributes;

return {
awarenessLevel: LEVELS.find(e => e.name == awarenessLevel),
awarenessType: EVENTS.find(e => e.name == awarenessType)
}
}
}
79 changes: 79 additions & 0 deletions src/integrations/meteofrance-integration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { EVENTS, LEVELS } from '../data';

const STATE_GREEN = 'Vert';
const STATE_YELLOW = 'Jaune';
const STATE_ORANGE = 'Orange';
const STATE_RED = 'Rouge';

const EVENT_WIND = 'Vent violent';
const EVENT_SNOW_ICE = 'Neige-verglas';
const EVENT_THUNDERSTORMS = 'Orages';
const EVENT_FLOOD = 'Inondation';
const EVENT_RAIN_FLOOD = 'Pluie-inondation';

export class MeteoFranceIntegration
{
static get name()
{
return 'meteofrance'
}

static getStatesLevels()
{
return {
[STATE_YELLOW]: LEVELS[0],
[STATE_ORANGE]: LEVELS[1],
[STATE_RED]: LEVELS[2],
}
}

static getEventsTypes()
{
return {
[EVENT_WIND]: EVENTS[0],
[EVENT_SNOW_ICE]: EVENTS[1],
[EVENT_THUNDERSTORMS]: EVENTS[2],
[EVENT_FLOOD]: EVENTS[10],
[EVENT_RAIN_FLOOD]: EVENTS[11],
}
}

static supports(entity)
{
return entity.attributes.attribution === 'Data provided by Météo-France';
}

static isWarningActive(entity)
{
return entity.state !== STATE_GREEN;
}

static getResult(entity)
{
const statesLevels = this.getStatesLevels();
const eventsTypes = this.getEventsTypes();

let eventsState = {
[EVENT_WIND]: entity.attributes[EVENT_WIND],
[EVENT_SNOW_ICE]: entity.attributes[EVENT_SNOW_ICE],
[EVENT_THUNDERSTORMS]: entity.attributes[EVENT_THUNDERSTORMS],
[EVENT_FLOOD]: entity.attributes[EVENT_FLOOD],
[EVENT_RAIN_FLOOD]: entity.attributes[EVENT_RAIN_FLOOD],
};

let currentEvent = '';

Object.keys(eventsState).forEach(key =>
{
if(eventsState[key] !== STATE_GREEN)
{
currentEvent = key;
}
})

return {
awarenessLevel: statesLevels[entity.state],
awarenessType: eventsTypes[currentEvent]
}
}
}
19 changes: 7 additions & 12 deletions src/localize.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ var languages = {

const DEFAULT_LANG = 'en';

export default function localize(string, search, replace)
export default function localize(string)
{
const [section, key] = string.toLowerCase().split('.');

Expand All @@ -40,26 +40,21 @@ export default function localize(string, search, replace)
.replace(/['"]+/g, '')
.replace('-', '_');

let tranlated;
let translated;

try
{
tranlated = languages[lang][section][key];
translated = languages[lang][section][key];
}
catch (e)
{
tranlated = languages[DEFAULT_LANG][section][key];
translated = languages[DEFAULT_LANG][section][key];
}

if (tranlated === undefined)
if (translated === undefined)
{
tranlated = languages[DEFAULT_LANG][section][key];
translated = languages[DEFAULT_LANG][section][key] || string.toLowerCase();
}

if (search !== '' && replace !== '')
{
tranlated = tranlated.replace(search, replace);
}

return tranlated;
return translated;
}
Loading