From 0f6156805bee6ebbcb6f564d69db1a43695b127b Mon Sep 17 00:00:00 2001 From: Nsbx Date: Thu, 20 May 2021 19:11:54 +0200 Subject: [PATCH 1/8] Update French Translation --- src/translations/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/translations/fr.json b/src/translations/fr.json index 85db09b..0fb4e96 100644 --- a/src/translations/fr.json +++ b/src/translations/fr.json @@ -21,7 +21,7 @@ "avalanches": "avalanches", "rain": "pluie", "flood": "inondation", - "rain_flood": "pluie d'inondation" + "rain_flood": "pluie/inondation" }, "messages": { "yellow": "Alerte jaune {0}", From e5dafd69ee465e2431c83ec9c84c35fcaebaa804 Mon Sep 17 00:00:00 2001 From: Nsbx Date: Thu, 20 May 2021 19:13:44 +0200 Subject: [PATCH 2/8] Fix typo --- src/localize.js | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/src/localize.js b/src/localize.js index 935a09f..129c605 100644 --- a/src/localize.js +++ b/src/localize.js @@ -21,18 +21,14 @@ var languages = { const DEFAULT_LANG = 'en'; -export default function localize(string, search, replace) -{ +export default function localize(string, search, replace) { const [section, key] = string.toLowerCase().split('.'); let langStored; - try - { + try { langStored = JSON.parse(localStorage.getItem('selectedLanguage')); - } - catch (e) - { + } catch (e) { langStored = localStorage.getItem('selectedLanguage'); } @@ -40,26 +36,21 @@ export default function localize(string, search, replace) .replace(/['"]+/g, '') .replace('-', '_'); - let tranlated; + let translated; - try - { - tranlated = languages[lang][section][key]; - } - catch (e) - { - tranlated = languages[DEFAULT_LANG][section][key]; + try { + translated = languages[lang][section][key]; + } catch (e) { + translated = languages[DEFAULT_LANG][section][key]; } - if (tranlated === undefined) - { - tranlated = languages[DEFAULT_LANG][section][key]; + if (translated === undefined) { + translated = languages[DEFAULT_LANG][section][key]; } - if (search !== '' && replace !== '') - { - tranlated = tranlated.replace(search, replace); + if (search !== '' && replace !== '') { + translated = translated.replace(search, replace); } - return tranlated; -} + return translated; +} \ No newline at end of file From acd355ea411cf80e0c6eac8c434abad808e28473 Mon Sep 17 00:00:00 2001 From: Nsbx Date: Thu, 20 May 2021 19:14:08 +0200 Subject: [PATCH 3/8] Code style --- src/data.js | 14 +++++--------- src/styles.js | 8 +++++--- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/data.js b/src/data.js index 88bfc86..55e3069 100644 --- a/src/data.js +++ b/src/data.js @@ -1,17 +1,13 @@ -class Event -{ - constructor(name, icon, translationKey) - { +class Event { + constructor(name, icon, translationKey) { this.name = name; this.icon = icon; this.translationKey = translationKey; } } -class Level -{ - constructor(name, color, translationKey) - { +class Level { + constructor(name, color, translationKey) { this.name = name; this.color = color; this.translationKey = translationKey; @@ -37,4 +33,4 @@ export const LEVELS = [ new Level('Yellow', '#ff9800', 'messages.yellow'), new Level('Orange', '#EE5A24', 'messages.orange'), new Level('Red', '#db4437', 'messages.red') -] +] \ No newline at end of file diff --git a/src/styles.js b/src/styles.js index 84c087d..9235bd1 100644 --- a/src/styles.js +++ b/src/styles.js @@ -1,6 +1,8 @@ -import { css } from 'lit-element'; +import { + css +} from 'lit-element'; -export default css` +export default css ` :host { display: flex; @@ -55,4 +57,4 @@ export default css` -webkit-line-clamp: 1; -webkit-box-orient: vertical; } -`; +`; \ No newline at end of file From 81393ca13fb139bd67b15c97f05b8665f47c19df Mon Sep 17 00:00:00 2001 From: Nsbx Date: Thu, 20 May 2021 19:14:43 +0200 Subject: [PATCH 4/8] Code style + Refacto Strategies pattern + MeteoFrance integration --- src/meteoalarm-card.js | 215 +++++++++--------- .../meteoalarmeu-strategy.js | 22 ++ .../integrations/meteoalarm-strategy.js | 23 ++ .../integrations/meteofrance-strategy.js | 70 ++++++ 4 files changed, 220 insertions(+), 110 deletions(-) create mode 100644 src/strategies/custom-integrations/meteoalarmeu-strategy.js create mode 100644 src/strategies/integrations/meteoalarm-strategy.js create mode 100644 src/strategies/integrations/meteofrance-strategy.js diff --git a/src/meteoalarm-card.js b/src/meteoalarm-card.js index 809186a..039dd78 100644 --- a/src/meteoalarm-card.js +++ b/src/meteoalarm-card.js @@ -4,10 +4,21 @@ import localize from './localize'; import styles from './styles'; import { EVENTS, LEVELS } from './data'; -class MeteoalarmCard extends LitElement -{ - static get properties() - { +import { MeteoAlarmStrategy } from './strategies/integrations/meteoalarm-strategy'; +import { MeteoFranceStrategy } from './strategies/integrations/meteofrance-strategy'; + +import { MeteoAlarmeuStrategy } from './strategies/custom-integrations/meteoalarmeu-strategy'; + +class MeteoalarmCard extends LitElement { + getStategies() { + return [ + MeteoAlarmStrategy, + MeteoFranceStrategy, + MeteoAlarmeuStrategy + ]; + } + + static get properties() { return { hass: Object, config: Object, @@ -15,170 +26,161 @@ class MeteoalarmCard extends LitElement }; } - static get styles() - { + static get styles() { return styles; } - static getStubConfig(hass, entities) - { + static getStubConfig(hass, entities) { const [entity] = entities.filter( (eid) => eid.includes('meteoalarm') ); return { entity: entity || '', + source_type: 'meteoalarm' }; } - get entity() - { + get entity() { return this.hass.states[this.config.entity]; } - setConfig(config) - { - if (!config.entity) - { + get sourceType() { + return this.config.source_type; + } + + setConfig(config) { + if (!config.entity) { throw new Error(localize('error.missing_entity')); } + + if (!config.source_type) { + config.source_type = 'meteoalarm'; + } + this.config = config; } - getCardSize() - { + getCardSize() { return 2; } - shouldUpdate(changedProps) - { + shouldUpdate(changedProps) { return hasConfigOrEntityChanged(this, changedProps); } - updated(changedProps) - { + updated(changedProps) { if ( changedProps.get('hass') && changedProps.get('hass').states[this.config.entity].state !== - this.hass.states[this.config.entity].state - ) - { + this.hass.states[this.config.entity].state + ) { this.requestInProgress = false; } } - handleMore() - { + handleMore() { fireEvent( this, - 'hass-more-info', - { + 'hass-more-info', { entityId: this.entity.entity_id, - }, - { + }, { bubbles: true, composed: true, } ); } - getAttributes(entity) - { - const { - status, - state, - event, - headline, - awareness_type: awarenessType, - awareness_level: awarenessLevel, - } = entity.attributes; - - const entityState = (status || state || entity.state) - + getAttributes(entity) { let result = { - isAvailable: entityState != 'unavailable', - isWarningActive: entityState == 'on' + isAvailable: false, + isWarningActive: false }; - console.log(result) - - if(result.isWarningActive) - { - if(awarenessLevel.includes(';')) - { - // meteoalarm core - result = {...result, ...{ - headline: event || headline, - awarenessLevel: LEVELS[Number(awarenessLevel.split(';')[0]) - 2], - awarenessType: EVENTS[Number(awarenessType.split(';')[0]) - 1] - }} + + this.getStategies().forEach(strategy => { + if (!strategy.supports(this.sourceType)) { + return; } - else - { - // custom_component xlcnd/meteoalarmeu - result = {...result, ...{ - awarenessLevel: LEVELS.find(e => e.name == awarenessLevel), - awarenessType: EVENTS.find(l => l.name == awarenessType) - }} + + if (!strategy.isAvailable(entity)) { + return; } - } - if(result.headline == undefined && result.isWarningActive) - { + result.isAvailable = true; + + if (!strategy.isWarningActive(entity)) { + return; + } + + result.isWarningActive = true; + + result = { + ...result, + ...strategy.getResult(entity) + } + }); + + if (result.headline == undefined && result.isWarningActive) { result.headline = this.generateHeadline(result.awarenessType, result.awarenessLevel) } return result } - generateHeadline(awarenessType, awarenessLevel) - { + generateHeadline(awarenessType, awarenessLevel) { // If headline is not issued, generate default one return localize(awarenessLevel.translationKey).replace('{0}', localize(awarenessType.translationKey)) } - getBackgroundColor() - { - const { isWarningActive: isWarningActive, awarenessLevel } = this.getAttributes(this.entity); + getBackgroundColor() { + const { + isWarningActive: isWarningActive, + awarenessLevel + } = this.getAttributes(this.entity); + return isWarningActive ? awarenessLevel.color : 'inherit' } - getFontColor() - { - const { isWarningActive: isWarningActive } = this.getAttributes(this.entity); + getFontColor() { + const { + isWarningActive: isWarningActive + } = this.getAttributes(this.entity); + return isWarningActive ? '#fff' : '--primary-text-color' } - renderIcon() - { + renderIcon() { let iconName = '' - if(!this.entity || !this.getAttributes(this.entity).isAvailable) - { + + if (!this.entity || !this.getAttributes(this.entity).isAvailable) { iconName = 'cloud-question' - } - else - { - const { isWarningActive: isWarningActive, awarenessType } = this.getAttributes(this.entity); + } else { + const { + isWarningActive: isWarningActive, + awarenessType + } = this.getAttributes(this.entity); + iconName = isWarningActive ? awarenessType.icon : 'shield-outline' } - return html` + return html ` ` } - renderStatus() - { - const { isWarningActive: isWarningActive, headline } = this.getAttributes(this.entity); - if(isWarningActive) - { - return html` + renderStatus() { + const { + isWarningActive: isWarningActive, + headline + } = this.getAttributes(this.entity); + + if (isWarningActive) { + return html `
${headline}
` - } - else - { - return html` + } else { + return html `
${localize('events.no_warnings')}
@@ -186,9 +188,8 @@ class MeteoalarmCard extends LitElement } } - renderNotAvailable() - { - return html` + renderNotAvailable() { + return html `
@@ -202,9 +203,8 @@ class MeteoalarmCard extends LitElement `; } - renderError() - { - return html` + renderError() { + return html `
@@ -216,16 +216,13 @@ class MeteoalarmCard extends LitElement `; } - render() - { - try - { - if(!this.entity || !this.getAttributes(this.entity).isAvailable) - { + render() { + try { + if (!this.entity || !this.getAttributes(this.entity).isAvailable) { return this.renderNotAvailable() } - return html` + return html `
`; - } - catch(e) - { + } catch (e) { console.error('=== METEOALARM CARD ERROR ===\nReport issue: https://bit.ly/3hK1hL4 \n\n', e) return this.renderError() } @@ -256,4 +251,4 @@ window.customCards.push({ type: 'meteoalarm-card', name: localize('common.name'), description: localize('common.description'), -}); +}); \ No newline at end of file diff --git a/src/strategies/custom-integrations/meteoalarmeu-strategy.js b/src/strategies/custom-integrations/meteoalarmeu-strategy.js new file mode 100644 index 0000000..4caa8ce --- /dev/null +++ b/src/strategies/custom-integrations/meteoalarmeu-strategy.js @@ -0,0 +1,22 @@ +import { EVENTS, LEVELS } from '../../data'; + +export class MeteoAlarmeuStrategy { + static supports(sourceType) { + return sourceType === 'xlcnd/meteoalarmeu'; + } + + static isWarningActive(entity) { + return (entity.attributes.status || entity.attributes.state || entity.state) != 'off'; + } + + static isAvailable(entity) { + return (entity.attributes.status || entity.attributes.state || entity.state) != 'unavailable' + } + + static getResult(entity) { + return { + awarenessLevel: LEVELS.find(e => e.name == entity.attributes.awarenessLevel), + awarenessType: EVENTS.find(l => l.name == entity.attributes.awarenessType) + } + } +} \ No newline at end of file diff --git a/src/strategies/integrations/meteoalarm-strategy.js b/src/strategies/integrations/meteoalarm-strategy.js new file mode 100644 index 0000000..d9f06f0 --- /dev/null +++ b/src/strategies/integrations/meteoalarm-strategy.js @@ -0,0 +1,23 @@ +import { EVENTS, LEVELS } from '../../data'; + +export class MeteoAlarmStrategy { + static supports(sourceType) { + return sourceType === 'meteoalarm'; + } + + static isAvailable(entity) { + return (entity.attributes.status || entity.attributes.state || entity.state) != 'unavailable' + } + + static isWarningActive(entity) { + return (entity.attributes.status || entity.attributes.state || entity.state) != 'off'; + } + + static getResult(entity) { + return { + headline: entity.attributes.event || entity.attributes.headline, + awarenessLevel: LEVELS[Number(entity.attributes.awarenessLevel.split(';')[0]) - 2], + awarenessType: EVENTS[Number(entity.attributes.awarenessType.split(';')[0]) - 2] + } + } +} \ No newline at end of file diff --git a/src/strategies/integrations/meteofrance-strategy.js b/src/strategies/integrations/meteofrance-strategy.js new file mode 100644 index 0000000..a1ce8ff --- /dev/null +++ b/src/strategies/integrations/meteofrance-strategy.js @@ -0,0 +1,70 @@ +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 MeteoFranceStrategy { + 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(sourceType) { + return sourceType === 'meteofrance'; + } + + static isAvailable(entity) { + return (entity.attributes.status || entity.attributes.state || entity.state) != 'unavailable' + } + + 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] + } + } +} \ No newline at end of file From 678dc7f104db1e4a5f5fe23a8c5b89ce768a0e57 Mon Sep 17 00:00:00 2001 From: Nsbx Date: Thu, 20 May 2021 20:21:30 +0200 Subject: [PATCH 5/8] Fix EsLint --- README.md | 25 ++- src/data.js | 14 +- src/localize.js | 25 ++- src/meteoalarm-card.js | 164 ++++++++++-------- .../meteoalarmeu-strategy.js | 39 +++-- .../integrations/meteoalarm-strategy.js | 41 +++-- .../integrations/meteofrance-strategy.js | 105 ++++++----- src/styles.js | 8 +- 8 files changed, 250 insertions(+), 171 deletions(-) diff --git a/README.md b/README.md index 4778200..1f4588c 100644 --- a/README.md +++ b/README.md @@ -59,12 +59,35 @@ 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) +To use one of these custom integration just add "sourceType" key into your card configuration and choose one of these type. +Also use the right entity for each entity. + +--- + +| 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 exemple + +```yaml +type: 'custom:meteoalarm-card' +entity: 'sensor.75_weather_alert' +sourceType: 'meteofrance' +``` + +By default the source type is `meteoalarm` ## Contributing Want to contribute to the project? diff --git a/src/data.js b/src/data.js index 55e3069..88bfc86 100644 --- a/src/data.js +++ b/src/data.js @@ -1,13 +1,17 @@ -class Event { - constructor(name, icon, translationKey) { +class Event +{ + constructor(name, icon, translationKey) + { this.name = name; this.icon = icon; this.translationKey = translationKey; } } -class Level { - constructor(name, color, translationKey) { +class Level +{ + constructor(name, color, translationKey) + { this.name = name; this.color = color; this.translationKey = translationKey; @@ -33,4 +37,4 @@ export const LEVELS = [ new Level('Yellow', '#ff9800', 'messages.yellow'), new Level('Orange', '#EE5A24', 'messages.orange'), new Level('Red', '#db4437', 'messages.red') -] \ No newline at end of file +] diff --git a/src/localize.js b/src/localize.js index 129c605..f254c2f 100644 --- a/src/localize.js +++ b/src/localize.js @@ -21,14 +21,18 @@ var languages = { const DEFAULT_LANG = 'en'; -export default function localize(string, search, replace) { +export default function localize(string, search, replace) +{ const [section, key] = string.toLowerCase().split('.'); let langStored; - try { + try + { langStored = JSON.parse(localStorage.getItem('selectedLanguage')); - } catch (e) { + } + catch (e) + { langStored = localStorage.getItem('selectedLanguage'); } @@ -38,19 +42,24 @@ export default function localize(string, search, replace) { let translated; - try { + try + { translated = languages[lang][section][key]; - } catch (e) { + } + catch (e) + { translated = languages[DEFAULT_LANG][section][key]; } - if (translated === undefined) { + if (translated === undefined) + { translated = languages[DEFAULT_LANG][section][key]; } - if (search !== '' && replace !== '') { + if (search !== '' && replace !== '') + { translated = translated.replace(search, replace); } return translated; -} \ No newline at end of file +} diff --git a/src/meteoalarm-card.js b/src/meteoalarm-card.js index 039dd78..8175203 100644 --- a/src/meteoalarm-card.js +++ b/src/meteoalarm-card.js @@ -2,15 +2,16 @@ import { LitElement, html } from 'lit-element'; import { hasConfigOrEntityChanged, fireEvent } from 'custom-card-helpers'; import localize from './localize'; import styles from './styles'; -import { EVENTS, LEVELS } from './data'; import { MeteoAlarmStrategy } from './strategies/integrations/meteoalarm-strategy'; import { MeteoFranceStrategy } from './strategies/integrations/meteofrance-strategy'; import { MeteoAlarmeuStrategy } from './strategies/custom-integrations/meteoalarmeu-strategy'; -class MeteoalarmCard extends LitElement { - getStategies() { +class MeteoalarmCard extends LitElement +{ + getStategies() + { return [ MeteoAlarmStrategy, MeteoFranceStrategy, @@ -18,7 +19,8 @@ class MeteoalarmCard extends LitElement { ]; } - static get properties() { + static get properties() + { return { hass: Object, config: Object, @@ -26,89 +28,108 @@ class MeteoalarmCard extends LitElement { }; } - static get styles() { + static get styles() + { return styles; } - static getStubConfig(hass, entities) { + static getStubConfig(hass, entities) + { const [entity] = entities.filter( (eid) => eid.includes('meteoalarm') ); return { entity: entity || '', - source_type: 'meteoalarm' + sourceType: 'meteoalarm' }; } - get entity() { + get entity() + { return this.hass.states[this.config.entity]; } - get sourceType() { - return this.config.source_type; + get sourceType() + { + return this.config.sourceType; } - setConfig(config) { - if (!config.entity) { + setConfig(config) + { + if(!config.entity) + { throw new Error(localize('error.missing_entity')); } - if (!config.source_type) { - config.source_type = 'meteoalarm'; + if(!config.sourceType) + { + config.sourceType = 'meteoalarm'; } this.config = config; } - getCardSize() { + getCardSize() + { return 2; } - shouldUpdate(changedProps) { + shouldUpdate(changedProps) + { return hasConfigOrEntityChanged(this, changedProps); } - updated(changedProps) { - if ( + updated(changedProps) + { + if( changedProps.get('hass') && changedProps.get('hass').states[this.config.entity].state !== this.hass.states[this.config.entity].state - ) { + ) + { this.requestInProgress = false; } } - handleMore() { + handleMore() + { fireEvent( this, - 'hass-more-info', { + 'hass-more-info', + { entityId: this.entity.entity_id, - }, { + }, + { bubbles: true, composed: true, } ); } - getAttributes(entity) { + getAttributes(entity) + { let result = { isAvailable: false, isWarningActive: false }; - this.getStategies().forEach(strategy => { - if (!strategy.supports(this.sourceType)) { + this.getStategies().forEach(strategy => + { + if(!strategy.supports(this.sourceType)) + { return; } - if (!strategy.isAvailable(entity)) { + if(!strategy.isAvailable(entity)) + { return; } result.isAvailable = true; - if (!strategy.isWarningActive(entity)) { + if(!strategy.isWarningActive(entity)) + { return; } @@ -117,70 +138,68 @@ class MeteoalarmCard extends LitElement { result = { ...result, ...strategy.getResult(entity) - } + } }); - if (result.headline == undefined && result.isWarningActive) { + if(result.headline == undefined && result.isWarningActive) + { result.headline = this.generateHeadline(result.awarenessType, result.awarenessLevel) } return result } - generateHeadline(awarenessType, awarenessLevel) { + generateHeadline(awarenessType, awarenessLevel) + { // If headline is not issued, generate default one return localize(awarenessLevel.translationKey).replace('{0}', localize(awarenessType.translationKey)) } - getBackgroundColor() { - const { - isWarningActive: isWarningActive, - awarenessLevel - } = this.getAttributes(this.entity); - + getBackgroundColor() + { + const { isWarningActive: isWarningActive, awarenessLevel } = this.getAttributes(this.entity); return isWarningActive ? awarenessLevel.color : 'inherit' } - getFontColor() { - const { - isWarningActive: isWarningActive - } = this.getAttributes(this.entity); - + getFontColor() + { + const { isWarningActive: isWarningActive } = this.getAttributes(this.entity); return isWarningActive ? '#fff' : '--primary-text-color' } - renderIcon() { + renderIcon() + { let iconName = '' - - if (!this.entity || !this.getAttributes(this.entity).isAvailable) { + if(!this.entity || !this.getAttributes(this.entity).isAvailable) + { iconName = 'cloud-question' - } else { - const { - isWarningActive: isWarningActive, - awarenessType - } = this.getAttributes(this.entity); + } + else + { + const { isWarningActive: isWarningActive, awarenessType } = this.getAttributes(this.entity); iconName = isWarningActive ? awarenessType.icon : 'shield-outline' } - return html ` + return html` ` } - renderStatus() { - const { - isWarningActive: isWarningActive, - headline - } = this.getAttributes(this.entity); + renderStatus() + { + const { isWarningActive: isWarningActive, headline } = this.getAttributes(this.entity); - if (isWarningActive) { - return html ` + if(isWarningActive) + { + return html`
${headline}
` - } else { - return html ` + } + else + { + return html`
${localize('events.no_warnings')}
@@ -188,8 +207,9 @@ class MeteoalarmCard extends LitElement { } } - renderNotAvailable() { - return html ` + renderNotAvailable() + { + return html`
@@ -203,8 +223,9 @@ class MeteoalarmCard extends LitElement { `; } - renderError() { - return html ` + renderError() + { + return html`
@@ -216,13 +237,16 @@ class MeteoalarmCard extends LitElement { `; } - render() { - try { - if (!this.entity || !this.getAttributes(this.entity).isAvailable) { + render() + { + try + { + if(!this.entity || !this.getAttributes(this.entity).isAvailable) + { return this.renderNotAvailable() } - return html ` + return html`
`; - } catch (e) { + } + catch(e) + { console.error('=== METEOALARM CARD ERROR ===\nReport issue: https://bit.ly/3hK1hL4 \n\n', e) return this.renderError() } @@ -251,4 +277,4 @@ window.customCards.push({ type: 'meteoalarm-card', name: localize('common.name'), description: localize('common.description'), -}); \ No newline at end of file +}); diff --git a/src/strategies/custom-integrations/meteoalarmeu-strategy.js b/src/strategies/custom-integrations/meteoalarmeu-strategy.js index 4caa8ce..bfa3e44 100644 --- a/src/strategies/custom-integrations/meteoalarmeu-strategy.js +++ b/src/strategies/custom-integrations/meteoalarmeu-strategy.js @@ -1,22 +1,27 @@ import { EVENTS, LEVELS } from '../../data'; -export class MeteoAlarmeuStrategy { - static supports(sourceType) { - return sourceType === 'xlcnd/meteoalarmeu'; - } +export class MeteoAlarmeuStrategy +{ + static supports(sourceType) + { + return sourceType === 'meteoalarmeu'; + } - static isWarningActive(entity) { - return (entity.attributes.status || entity.attributes.state || entity.state) != 'off'; - } + static isAvailable(entity) + { + return (entity.attributes.status || entity.attributes.state || entity.state) != 'unavailable' + } - static isAvailable(entity) { - return (entity.attributes.status || entity.attributes.state || entity.state) != 'unavailable' - } + static isWarningActive(entity) + { + return (entity.attributes.status || entity.attributes.state || entity.state) != 'off'; + } - static getResult(entity) { - return { - awarenessLevel: LEVELS.find(e => e.name == entity.attributes.awarenessLevel), - awarenessType: EVENTS.find(l => l.name == entity.attributes.awarenessType) - } - } -} \ No newline at end of file + static getResult(entity) + { + return { + awarenessLevel: LEVELS.find(e => e.name == entity.attributes.awarenessLevel), + awarenessType: EVENTS.find(l => l.name == entity.attributes.awarenessType) + } + } +} diff --git a/src/strategies/integrations/meteoalarm-strategy.js b/src/strategies/integrations/meteoalarm-strategy.js index d9f06f0..d24e1a0 100644 --- a/src/strategies/integrations/meteoalarm-strategy.js +++ b/src/strategies/integrations/meteoalarm-strategy.js @@ -1,23 +1,28 @@ import { EVENTS, LEVELS } from '../../data'; -export class MeteoAlarmStrategy { - static supports(sourceType) { - return sourceType === 'meteoalarm'; - } +export class MeteoAlarmStrategy +{ + static supports(sourceType) + { + return sourceType === 'meteoalarm'; + } - static isAvailable(entity) { - return (entity.attributes.status || entity.attributes.state || entity.state) != 'unavailable' - } + static isAvailable(entity) + { + return (entity.attributes.status || entity.attributes.state || entity.state) != 'unavailable' + } - static isWarningActive(entity) { - return (entity.attributes.status || entity.attributes.state || entity.state) != 'off'; - } + static isWarningActive(entity) + { + return (entity.attributes.status || entity.attributes.state || entity.state) != 'off'; + } - static getResult(entity) { - return { - headline: entity.attributes.event || entity.attributes.headline, - awarenessLevel: LEVELS[Number(entity.attributes.awarenessLevel.split(';')[0]) - 2], - awarenessType: EVENTS[Number(entity.attributes.awarenessType.split(';')[0]) - 2] - } - } -} \ No newline at end of file + static getResult(entity) + { + return { + headline: entity.attributes.event || entity.attributes.headline, + awarenessLevel: LEVELS[Number(entity.attributes.awarenessLevel.split(';')[0]) - 2], + awarenessType: EVENTS[Number(entity.attributes.awarenessType.split(';')[0]) - 2] + } + } +} diff --git a/src/strategies/integrations/meteofrance-strategy.js b/src/strategies/integrations/meteofrance-strategy.js index a1ce8ff..7b499bb 100644 --- a/src/strategies/integrations/meteofrance-strategy.js +++ b/src/strategies/integrations/meteofrance-strategy.js @@ -11,60 +11,69 @@ const EVENT_THUNDERSTORMS = 'Orages'; const EVENT_FLOOD = 'Inondation'; const EVENT_RAIN_FLOOD = 'Pluie-inondation'; -export class MeteoFranceStrategy { - static getStatesLevels() { - return { - [STATE_YELLOW]: LEVELS[0], - [STATE_ORANGE]: LEVELS[1], - [STATE_RED]: LEVELS[2], - } - } +export class MeteoFranceStrategy +{ + 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 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(sourceType) { - return sourceType === 'meteofrance'; - } + static supports(sourceType) + { + return sourceType === 'meteofrance'; + } - static isAvailable(entity) { - return (entity.attributes.status || entity.attributes.state || entity.state) != 'unavailable' - } + static isAvailable(entity) + { + return (entity.attributes.status || entity.attributes.state || entity.state) != 'unavailable' + } - static isWarningActive(entity) { - return entity.state !== STATE_GREEN; - } + static isWarningActive(entity) + { + return entity.state !== STATE_GREEN; + } - static getResult(entity) { - const statesLevels = this.getStatesLevels(); - const eventsTypes = this.getEventsTypes(); + 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 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 = ''; + let currentEvent = ''; - Object.keys(eventsState).forEach(key => { - if (eventsState[key] !== STATE_GREEN) { - currentEvent = key; - } - }) + Object.keys(eventsState).forEach(key => + { + if(eventsState[key] !== STATE_GREEN) + { + currentEvent = key; + } + }) - return { - awarenessLevel: statesLevels[entity.state], - awarenessType: eventsTypes[currentEvent] - } - } -} \ No newline at end of file + return { + awarenessLevel: statesLevels[entity.state], + awarenessType: eventsTypes[currentEvent] + } + } +} diff --git a/src/styles.js b/src/styles.js index 9235bd1..84c087d 100644 --- a/src/styles.js +++ b/src/styles.js @@ -1,8 +1,6 @@ -import { - css -} from 'lit-element'; +import { css } from 'lit-element'; -export default css ` +export default css` :host { display: flex; @@ -57,4 +55,4 @@ export default css ` -webkit-line-clamp: 1; -webkit-box-orient: vertical; } -`; \ No newline at end of file +`; From d8ab74f564868a793b4060f6838f2ecf8d51fc95 Mon Sep 17 00:00:00 2001 From: Nsbx Date: Fri, 21 May 2021 19:30:47 +0200 Subject: [PATCH 6/8] Rename "strategy" and add "auto detect source type" system --- README.md | 7 ++--- .../meteoalarm-integration.js} | 21 ++++++++----- .../meteoalarmeu-integration.js} | 21 ++++++++----- .../meteofrance-integration.js} | 21 ++++++++----- src/meteoalarm-card.js | 30 +++++++++---------- 5 files changed, 56 insertions(+), 44 deletions(-) rename src/{strategies/integrations/meteoalarm-strategy.js => integrations/meteoalarm-integration.js} (55%) rename src/{strategies/custom-integrations/meteoalarmeu-strategy.js => integrations/meteoalarmeu-integration.js} (50%) rename src/{strategies/integrations/meteofrance-strategy.js => integrations/meteofrance-integration.js} (78%) diff --git a/README.md b/README.md index 1f4588c..683d325 100644 --- a/README.md +++ b/README.md @@ -66,8 +66,8 @@ This card supports many other integrations. - [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) -To use one of these custom integration just add "sourceType" key into your card configuration and choose one of these type. -Also use the right entity for each entity. +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. --- @@ -79,7 +79,7 @@ Also use the right entity for each entity. --- -Like this for exemple +Like this for example ```yaml type: 'custom:meteoalarm-card' @@ -87,7 +87,6 @@ entity: 'sensor.75_weather_alert' sourceType: 'meteofrance' ``` -By default the source type is `meteoalarm` ## Contributing Want to contribute to the project? diff --git a/src/strategies/integrations/meteoalarm-strategy.js b/src/integrations/meteoalarm-integration.js similarity index 55% rename from src/strategies/integrations/meteoalarm-strategy.js rename to src/integrations/meteoalarm-integration.js index d24e1a0..84a550e 100644 --- a/src/strategies/integrations/meteoalarm-strategy.js +++ b/src/integrations/meteoalarm-integration.js @@ -1,15 +1,20 @@ -import { EVENTS, LEVELS } from '../../data'; +import { EVENTS, LEVELS } from '../data'; -export class MeteoAlarmStrategy +export class MeteoAlarmIntegration { - static supports(sourceType) + static supports(sourceType, entity) { - return sourceType === 'meteoalarm'; - } + if(sourceType) + { + return sourceType === 'meteoalarm'; + } - static isAvailable(entity) - { - return (entity.attributes.status || entity.attributes.state || entity.state) != 'unavailable' + if(!('awarenessLevel' in entity.attributes)) + { + return false; + } + + return entity.attributes.awarenessLevel.includes(';'); } static isWarningActive(entity) diff --git a/src/strategies/custom-integrations/meteoalarmeu-strategy.js b/src/integrations/meteoalarmeu-integration.js similarity index 50% rename from src/strategies/custom-integrations/meteoalarmeu-strategy.js rename to src/integrations/meteoalarmeu-integration.js index bfa3e44..e7ea574 100644 --- a/src/strategies/custom-integrations/meteoalarmeu-strategy.js +++ b/src/integrations/meteoalarmeu-integration.js @@ -1,15 +1,20 @@ -import { EVENTS, LEVELS } from '../../data'; +import { EVENTS, LEVELS } from '../data'; -export class MeteoAlarmeuStrategy +export class MeteoAlarmeuIntegration { - static supports(sourceType) + static supports(sourceType, entity) { - return sourceType === 'meteoalarmeu'; - } + if(sourceType) + { + return sourceType === 'meteoalarmeu'; + } - static isAvailable(entity) - { - return (entity.attributes.status || entity.attributes.state || entity.state) != 'unavailable' + if(!('awarenessLevel' in entity.attributes)) + { + return false; + } + + return !entity.attributes.awarenessLevel.includes(';'); } static isWarningActive(entity) diff --git a/src/strategies/integrations/meteofrance-strategy.js b/src/integrations/meteofrance-integration.js similarity index 78% rename from src/strategies/integrations/meteofrance-strategy.js rename to src/integrations/meteofrance-integration.js index 7b499bb..ee73c0a 100644 --- a/src/strategies/integrations/meteofrance-strategy.js +++ b/src/integrations/meteofrance-integration.js @@ -1,4 +1,4 @@ -import { EVENTS, LEVELS } from '../../data'; +import { EVENTS, LEVELS } from '../data'; const STATE_GREEN = 'Vert'; const STATE_YELLOW = 'Jaune'; @@ -11,7 +11,7 @@ const EVENT_THUNDERSTORMS = 'Orages'; const EVENT_FLOOD = 'Inondation'; const EVENT_RAIN_FLOOD = 'Pluie-inondation'; -export class MeteoFranceStrategy +export class MeteoFranceIntegration { static getStatesLevels() { @@ -33,14 +33,19 @@ export class MeteoFranceStrategy } } - static supports(sourceType) + static supports(sourceType, entity) { - return sourceType === 'meteofrance'; - } + if(sourceType) + { + return sourceType === 'meteofrance'; + } - static isAvailable(entity) - { - return (entity.attributes.status || entity.attributes.state || entity.state) != 'unavailable' + if(!('attribution' in entity.attributes)) + { + return false; + } + + return entity.attributes.attribution === 'Data provided by Météo-France'; } static isWarningActive(entity) diff --git a/src/meteoalarm-card.js b/src/meteoalarm-card.js index 8175203..ed0bcd3 100644 --- a/src/meteoalarm-card.js +++ b/src/meteoalarm-card.js @@ -3,19 +3,18 @@ import { hasConfigOrEntityChanged, fireEvent } from 'custom-card-helpers'; import localize from './localize'; import styles from './styles'; -import { MeteoAlarmStrategy } from './strategies/integrations/meteoalarm-strategy'; -import { MeteoFranceStrategy } from './strategies/integrations/meteofrance-strategy'; - -import { MeteoAlarmeuStrategy } from './strategies/custom-integrations/meteoalarmeu-strategy'; +import { MeteoAlarmIntegration } from './integrations/meteoalarm-integration'; +import { MeteoFranceIntegration } from './integrations/meteofrance-integration'; +import { MeteoAlarmeuIntegration } from './integrations/meteoalarmeu-integration'; class MeteoalarmCard extends LitElement { getStategies() { return [ - MeteoAlarmStrategy, - MeteoFranceStrategy, - MeteoAlarmeuStrategy + MeteoAlarmIntegration, + MeteoFranceIntegration, + MeteoAlarmeuIntegration ]; } @@ -40,8 +39,7 @@ class MeteoalarmCard extends LitElement ); return { - entity: entity || '', - sourceType: 'meteoalarm' + entity: entity || '' }; } @@ -62,11 +60,6 @@ class MeteoalarmCard extends LitElement throw new Error(localize('error.missing_entity')); } - if(!config.sourceType) - { - config.sourceType = 'meteoalarm'; - } - this.config = config; } @@ -107,6 +100,11 @@ class MeteoalarmCard extends LitElement ); } + entityIsAvailable(entity) + { + return (entity.attributes.status || entity.attributes.state || entity.state) != 'unavailable' + } + getAttributes(entity) { let result = { @@ -116,12 +114,12 @@ class MeteoalarmCard extends LitElement this.getStategies().forEach(strategy => { - if(!strategy.supports(this.sourceType)) + if(!strategy.supports(this.sourceType, entity)) { return; } - if(!strategy.isAvailable(entity)) + if(!this.entityIsAvailable(entity)) { return; } From b90beb5247f10d12e554250aa4ba87a344ea717e Mon Sep 17 00:00:00 2001 From: MrBartusek Date: Sat, 22 May 2021 16:01:46 +0200 Subject: [PATCH 7/8] Fix integrations, code cleanup, documentation --- src/integrations/README.md | 20 +++++ src/integrations/meteoalarm-integration.js | 30 ++++---- src/integrations/meteoalarmeu-integration.js | 26 +++---- src/integrations/meteofrance-integration.js | 17 ++-- src/localize.js | 7 +- src/meteoalarm-card.js | 81 ++++++++++---------- src/translations/en.json | 6 +- 7 files changed, 100 insertions(+), 87 deletions(-) create mode 100644 src/integrations/README.md diff --git a/src/integrations/README.md b/src/integrations/README.md new file mode 100644 index 0000000..0b53ce9 --- /dev/null +++ b/src/integrations/README.md @@ -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 | diff --git a/src/integrations/meteoalarm-integration.js b/src/integrations/meteoalarm-integration.js index 84a550e..c9af130 100644 --- a/src/integrations/meteoalarm-integration.js +++ b/src/integrations/meteoalarm-integration.js @@ -2,19 +2,14 @@ import { EVENTS, LEVELS } from '../data'; export class MeteoAlarmIntegration { - static supports(sourceType, entity) + static get name() { - if(sourceType) - { - return sourceType === 'meteoalarm'; - } - - if(!('awarenessLevel' in entity.attributes)) - { - return false; - } + return 'meteoalarm' + } - return entity.attributes.awarenessLevel.includes(';'); + static supports(entity) + { + return entity.attributes.attribution == 'Information provided by MeteoAlarm' } static isWarningActive(entity) @@ -24,10 +19,17 @@ export class MeteoAlarmIntegration static getResult(entity) { + const { + event, + headline, + awareness_type: awarenessType, + awareness_level: awarenessLevel, + } = entity.attributes; + return { - headline: entity.attributes.event || entity.attributes.headline, - awarenessLevel: LEVELS[Number(entity.attributes.awarenessLevel.split(';')[0]) - 2], - awarenessType: EVENTS[Number(entity.attributes.awarenessType.split(';')[0]) - 2] + headline: event || headline, + awarenessLevel: LEVELS[Number(awarenessLevel.split(';')[0]) - 2], + awarenessType: EVENTS[Number(awarenessType.split(';')[0]) - 1] } } } diff --git a/src/integrations/meteoalarmeu-integration.js b/src/integrations/meteoalarmeu-integration.js index e7ea574..566058c 100644 --- a/src/integrations/meteoalarmeu-integration.js +++ b/src/integrations/meteoalarmeu-integration.js @@ -2,19 +2,14 @@ import { EVENTS, LEVELS } from '../data'; export class MeteoAlarmeuIntegration { - static supports(sourceType, entity) + static get name() { - if(sourceType) - { - return sourceType === 'meteoalarmeu'; - } - - if(!('awarenessLevel' in entity.attributes)) - { - return false; - } + return 'meteoalarmeu' + } - return !entity.attributes.awarenessLevel.includes(';'); + static supports(entity) + { + return entity.attributes.attribution == 'Information provided by meteoalarm.eu' } static isWarningActive(entity) @@ -24,9 +19,14 @@ export class MeteoAlarmeuIntegration static getResult(entity) { + const { + awareness_type: awarenessType, + awareness_level: awarenessLevel + } = entity.attributes; + return { - awarenessLevel: LEVELS.find(e => e.name == entity.attributes.awarenessLevel), - awarenessType: EVENTS.find(l => l.name == entity.attributes.awarenessType) + awarenessLevel: LEVELS.find(e => e.name == awarenessLevel), + awarenessType: EVENTS.find(e => e.name == awarenessType) } } } diff --git a/src/integrations/meteofrance-integration.js b/src/integrations/meteofrance-integration.js index ee73c0a..b396171 100644 --- a/src/integrations/meteofrance-integration.js +++ b/src/integrations/meteofrance-integration.js @@ -13,6 +13,11 @@ const EVENT_RAIN_FLOOD = 'Pluie-inondation'; export class MeteoFranceIntegration { + static get name() + { + return 'meteofrance' + } + static getStatesLevels() { return { @@ -33,18 +38,8 @@ export class MeteoFranceIntegration } } - static supports(sourceType, entity) + static supports(entity) { - if(sourceType) - { - return sourceType === 'meteofrance'; - } - - if(!('attribution' in entity.attributes)) - { - return false; - } - return entity.attributes.attribution === 'Data provided by Météo-France'; } diff --git a/src/localize.js b/src/localize.js index f254c2f..9f80e37 100644 --- a/src/localize.js +++ b/src/localize.js @@ -53,12 +53,7 @@ export default function localize(string, search, replace) if (translated === undefined) { - translated = languages[DEFAULT_LANG][section][key]; - } - - if (search !== '' && replace !== '') - { - translated = translated.replace(search, replace); + translated = languages[DEFAULT_LANG][section][key] || string.toLowerCase(); } return translated; diff --git a/src/meteoalarm-card.js b/src/meteoalarm-card.js index ed0bcd3..592c32a 100644 --- a/src/meteoalarm-card.js +++ b/src/meteoalarm-card.js @@ -9,14 +9,6 @@ import { MeteoAlarmeuIntegration } from './integrations/meteoalarmeu-integration class MeteoalarmCard extends LitElement { - getStategies() - { - return [ - MeteoAlarmIntegration, - MeteoFranceIntegration, - MeteoAlarmeuIntegration - ]; - } static get properties() { @@ -39,18 +31,24 @@ class MeteoalarmCard extends LitElement ); return { - entity: entity || '' + entity: entity || '', + integration: 'automatic' }; } + get integrations() + { + return [MeteoAlarmIntegration, MeteoAlarmeuIntegration, MeteoFranceIntegration]; + } + get entity() { return this.hass.states[this.config.entity]; } - get sourceType() + get integration() { - return this.config.sourceType; + return this.keyToIntegration(this.config.integration) } setConfig(config) @@ -59,6 +57,14 @@ class MeteoalarmCard extends LitElement { throw new Error(localize('error.missing_entity')); } + if(!config.integration) + { + throw new Error(localize('error.missing_integration')); + } + if(config.integration != "automatic" && this.keyToIntegration(config.integration, config.entity) == undefined) + { + throw new Error(localize('error.invalid_integration')); + } this.config = config; } @@ -100,7 +106,19 @@ class MeteoalarmCard extends LitElement ); } - entityIsAvailable(entity) + keyToIntegration(key, entity = this.entity) + { + if(key == "automatic") + { + return this.integrations.find((i) => i.supports(entity)) + } + else + { + return this.integrations.find((i) => i.name == key) + } + } + + isEntityAvailable(entity) { return (entity.attributes.status || entity.attributes.state || entity.state) != 'unavailable' } @@ -108,42 +126,23 @@ class MeteoalarmCard extends LitElement getAttributes(entity) { let result = { - isAvailable: false, - isWarningActive: false + isAvailable: this.isEntityAvailable(entity), + isWarningActive: this.integration.isWarningActive(entity) }; - - this.getStategies().forEach(strategy => + + if(result.isWarningActive) { - if(!strategy.supports(this.sourceType, entity)) - { - return; - } - - if(!this.entityIsAvailable(entity)) - { - return; - } - - result.isAvailable = true; - - if(!strategy.isWarningActive(entity)) - { - return; - } - - result.isWarningActive = true; - result = { ...result, - ...strategy.getResult(entity) + ...this.integration.getResult(entity) } - }); - if(result.headline == undefined && result.isWarningActive) - { - result.headline = this.generateHeadline(result.awarenessType, result.awarenessLevel) + if(result.headline == undefined) + { + result.headline = this.generateHeadline(result.awarenessType, result.awarenessLevel) + } + } - return result } diff --git a/src/translations/en.json b/src/translations/en.json index b960bb5..f4ca220 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2,10 +2,12 @@ "common": { "name": "Meteoalarm Card", "description": "Meteoalarm card warns you about current weather events.", - "not_available": "Meteoalarm is not available" + "not_available": "Sensor is not available" }, "error": { - "missing_entity": "Specifying entity is required!" + "missing_entity": "Specifying entity is required!", + "missing_integration": "Specifying integration is required!", + "invalid_integration": "This integration is not valid!" }, "events": { "no_warnings": "No warnings", From 30b5d8b3c419b1c91bc503759ab3edb1fb2d4a9c Mon Sep 17 00:00:00 2001 From: MrBartusek Date: Sat, 22 May 2021 16:05:37 +0200 Subject: [PATCH 8/8] Fix eslint --- src/localize.js | 2 +- src/meteoalarm-card.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/localize.js b/src/localize.js index 9f80e37..33c644d 100644 --- a/src/localize.js +++ b/src/localize.js @@ -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('.'); diff --git a/src/meteoalarm-card.js b/src/meteoalarm-card.js index 592c32a..4e264c1 100644 --- a/src/meteoalarm-card.js +++ b/src/meteoalarm-card.js @@ -61,7 +61,7 @@ class MeteoalarmCard extends LitElement { throw new Error(localize('error.missing_integration')); } - if(config.integration != "automatic" && this.keyToIntegration(config.integration, config.entity) == undefined) + if(config.integration != 'automatic' && this.keyToIntegration(config.integration, config.entity) == undefined) { throw new Error(localize('error.invalid_integration')); } @@ -108,7 +108,7 @@ class MeteoalarmCard extends LitElement keyToIntegration(key, entity = this.entity) { - if(key == "automatic") + if(key == 'automatic') { return this.integrations.find((i) => i.supports(entity)) } @@ -129,7 +129,7 @@ class MeteoalarmCard extends LitElement isAvailable: this.isEntityAvailable(entity), isWarningActive: this.integration.isWarningActive(entity) }; - + if(result.isWarningActive) { result = { @@ -141,7 +141,7 @@ class MeteoalarmCard extends LitElement { result.headline = this.generateHeadline(result.awarenessType, result.awarenessLevel) } - + } return result }