From 672bb59858f00ca47a535e308e12ba4d40e6dc72 Mon Sep 17 00:00:00 2001 From: tronikos Date: Wed, 19 Jun 2024 23:17:43 -0700 Subject: [PATCH] feat: Add ability to show a badge with the air quality index (#396) --- README.md | 2 ++ src/clock-weather-card.ts | 32 ++++++++++++++++++++++++++++-- src/localize/languages/bg.json | 1 + src/localize/languages/ca.json | 1 + src/localize/languages/cs.json | 1 + src/localize/languages/da.json | 1 + src/localize/languages/de.json | 1 + src/localize/languages/el.json | 1 + src/localize/languages/en.json | 1 + src/localize/languages/es.json | 1 + src/localize/languages/et.json | 1 + src/localize/languages/fi.json | 1 + src/localize/languages/fr.json | 1 + src/localize/languages/he.json | 1 + src/localize/languages/hu.json | 1 + src/localize/languages/id.json | 1 + src/localize/languages/is.json | 1 + src/localize/languages/it.json | 1 + src/localize/languages/ko.json | 1 + src/localize/languages/lt.json | 1 + src/localize/languages/nb.json | 1 + src/localize/languages/nl.json | 1 + src/localize/languages/pl.json | 1 + src/localize/languages/pt-br.json | 1 + src/localize/languages/pt.json | 1 + src/localize/languages/ro.json | 1 + src/localize/languages/ru.json | 1 + src/localize/languages/sk.json | 1 + src/localize/languages/sl.json | 1 + src/localize/languages/sr.json | 1 + src/localize/languages/srlatn.json | 1 + src/localize/languages/sv.json | 1 + src/localize/languages/th.json | 1 + src/localize/languages/tr.json | 1 + src/localize/languages/uk.json | 1 + src/localize/languages/ur.json | 1 + src/localize/languages/vi.json | 1 + src/localize/languages/zh-cn.json | 1 + src/localize/languages/zh-tw.json | 1 + src/styles.ts | 5 +++++ src/types.ts | 2 ++ 41 files changed, 76 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6ebccb98..bdc5d085 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,7 @@ use_browser_time: false time_zone: null show_decimal: false apparent_sensor: sensor.real_feel_temperature +aqi_sensor: sensor.air_quality_index ``` ### Options @@ -146,6 +147,7 @@ apparent_sensor: sensor.real_feel_temperature | time_zone | string | **Optional** | Uses the given [time zone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) to indicate the current date and time. If not provided, uses the time zone configured in HA | `null` | | show_decimal | boolean | **Optional** | Displays main temperature without rounding | `false` | | apparent_sensor | string | **Optional** | ID of the apparent temperature sensor entity. It is used to show the apparent temperature based on a sensor and will only show it if value is provided. | `''` | +| aqi_sensor | string | **Optional** | ID of the Air Quality Index sensor entity. It is used to show the AQI based on a sensor and will only show it if value is provided. | `''` | ## Footnotes diff --git a/src/clock-weather-card.ts b/src/clock-weather-card.ts index 1932d5c4..a34af9a9 100644 --- a/src/clock-weather-card.ts +++ b/src/clock-weather-card.ts @@ -27,7 +27,7 @@ import { import styles from './styles' import { actionHandler } from './action-handler-directive' import { localize } from './localize/localize' -import { type HassEntityBase } from 'home-assistant-js-websocket' +import { type HassEntity, type HassEntityBase } from 'home-assistant-js-websocket' import { extractMostOccuring, max, min, round, roundDown, roundIfNotNull, roundUp } from './utils' import { animatedIcons, staticIcons } from './images' import { version } from '../package.json' @@ -212,6 +212,8 @@ export class ClockWeatherCard extends LitElement { const temp = this.config.show_decimal ? this.getCurrentTemperature() : roundIfNotNull(this.getCurrentTemperature()) const tempUnit = weather.attributes.temperature_unit const apparentTemp = this.config.show_decimal ? this.getApparentTemperature() : roundIfNotNull(this.getApparentTemperature()) + const aqi = this.getAqi() + const aqiColor = this.getAqiColor(aqi) const humidity = roundIfNotNull(this.getCurrentHumidity()) const iconType = this.config.weather_icon_type const icon = this.toIcon(state, iconType, false, this.getIconAnimationKind()) @@ -220,6 +222,7 @@ export class ClockWeatherCard extends LitElement { const localizedHumidity = humidity !== null ? `${humidity}% ${this.localize('misc.humidity')}` : null const localizedApparent = apparentTemp !== null ? this.toConfiguredTempWithUnit(tempUnit, apparentTemp) : null const apparentString = this.localize('misc.feels-like') + const aqiString = this.localize('misc.aqi') return html` @@ -231,6 +234,7 @@ export class ClockWeatherCard extends LitElement { ${this.config.hide_clock ? weatherString : localizedTemp ? `${weatherString}, ${localizedTemp}` : weatherString} ${this.config.show_humidity && localizedHumidity ? html`
${localizedHumidity}` : ''} ${this.config.apparent_sensor && apparentTemp ? html`
${apparentString}: ${localizedApparent}` : ''} + ${this.config.aqi_sensor && aqi !== null ? html`
${aqi} ${aqiString}` : ''} ${this.config.hide_clock ? localizedTemp ?? 'n/a' : this.time()} @@ -431,7 +435,8 @@ export class ClockWeatherCard extends LitElement { use_browser_time: config.use_browser_time ?? false, time_zone: config.time_zone ?? undefined, show_decimal: config.show_decimal ?? false, - apparent_sensor: config.apparent_sensor ?? undefined + apparent_sensor: config.apparent_sensor ?? undefined, + aqi_sensor: config.aqi_sensor ?? undefined } } @@ -489,6 +494,29 @@ export class ClockWeatherCard extends LitElement { return null } + private getAqi (): number | null { + if (this.config.aqi_sensor) { + const aqiSensor = this.hass.states[this.config.aqi_sensor] as HassEntity | undefined + const aqi = aqiSensor?.state ? parseInt(aqiSensor.state) : undefined + if (aqi !== undefined && !isNaN(aqi)) { + return aqi + } + } + return null + } + + private getAqiColor (aqi: number | null): string | null { + if (aqi == null) { + return null + } + if (aqi <= 50) return 'green' + if (aqi <= 100) return 'yellowgreen' + if (aqi <= 150) return 'orange' + if (aqi <= 200) return 'red' + if (aqi <= 300) return 'purple' + return 'maroon' + } + private getSun (): HassEntityBase | undefined { return this.hass.states[this.config.sun_entity] } diff --git a/src/localize/languages/bg.json b/src/localize/languages/bg.json index a7093d11..d8c14bf8 100644 --- a/src/localize/languages/bg.json +++ b/src/localize/languages/bg.json @@ -26,6 +26,7 @@ "7": "Нд" }, "misc": { + "aqi": "AQI", "humidity": "Влажност", "feels-like": "Усеща се като" } diff --git a/src/localize/languages/ca.json b/src/localize/languages/ca.json index c4bbdc73..681a856f 100644 --- a/src/localize/languages/ca.json +++ b/src/localize/languages/ca.json @@ -26,6 +26,7 @@ "7": "Dg." }, "misc": { + "aqi": "AQI", "humidity": "humitat", "feels-like": "Feels like" } diff --git a/src/localize/languages/cs.json b/src/localize/languages/cs.json index b5565871..ff8d11cc 100644 --- a/src/localize/languages/cs.json +++ b/src/localize/languages/cs.json @@ -26,6 +26,7 @@ "7": "Ne" }, "misc": { + "aqi": "AQI", "humidity": "vlhkost", "feels-like": "pocitová teplota" } diff --git a/src/localize/languages/da.json b/src/localize/languages/da.json index ade8be57..6207fde0 100644 --- a/src/localize/languages/da.json +++ b/src/localize/languages/da.json @@ -26,6 +26,7 @@ "7": "Søn" }, "misc": { + "aqi": "AQI", "humidity": "fugtighed", "feels-like": "Feels like" } diff --git a/src/localize/languages/de.json b/src/localize/languages/de.json index 61e9543a..aeb42f91 100644 --- a/src/localize/languages/de.json +++ b/src/localize/languages/de.json @@ -26,6 +26,7 @@ "7": "So" }, "misc": { + "aqi": "AQI", "humidity": "Luftfeuchtigkeit", "feels-like": "Gefühlt" } diff --git a/src/localize/languages/el.json b/src/localize/languages/el.json index 07874e03..421c35ea 100644 --- a/src/localize/languages/el.json +++ b/src/localize/languages/el.json @@ -26,6 +26,7 @@ "7": "Κυρ" }, "misc": { + "aqi": "AQI", "humidity": "υγρασία", "feels-like": "Feels like" } diff --git a/src/localize/languages/en.json b/src/localize/languages/en.json index 10957e7d..5f0ab463 100644 --- a/src/localize/languages/en.json +++ b/src/localize/languages/en.json @@ -26,6 +26,7 @@ "7": "Sun" }, "misc": { + "aqi": "AQI", "humidity": "Humidity", "feels-like": "Feels like" } diff --git a/src/localize/languages/es.json b/src/localize/languages/es.json index 85780a79..0ecccb5c 100644 --- a/src/localize/languages/es.json +++ b/src/localize/languages/es.json @@ -26,6 +26,7 @@ "7": "Dom" }, "misc": { + "aqi": "AQI", "humidity": "humedad", "feels-like": "Feels like" } diff --git a/src/localize/languages/et.json b/src/localize/languages/et.json index 08b54287..fdb4e322 100644 --- a/src/localize/languages/et.json +++ b/src/localize/languages/et.json @@ -26,6 +26,7 @@ "7": "P" }, "misc": { + "aqi": "AQI", "humidity": "niiskus", "feels-like": "Feels like" } diff --git a/src/localize/languages/fi.json b/src/localize/languages/fi.json index 3595f81a..bb50ebbd 100644 --- a/src/localize/languages/fi.json +++ b/src/localize/languages/fi.json @@ -26,6 +26,7 @@ "7": "Su" }, "misc": { + "aqi": "AQI", "humidity": "kosteus", "feels-like": "Feels like" } diff --git a/src/localize/languages/fr.json b/src/localize/languages/fr.json index eddc3774..93e80882 100644 --- a/src/localize/languages/fr.json +++ b/src/localize/languages/fr.json @@ -26,6 +26,7 @@ "7": "Dim" }, "misc": { + "aqi": "AQI", "humidity": "humidité", "feels-like": "Feels like" } diff --git a/src/localize/languages/he.json b/src/localize/languages/he.json index 9814667f..c74deeba 100644 --- a/src/localize/languages/he.json +++ b/src/localize/languages/he.json @@ -26,6 +26,7 @@ "7": "ראשון" }, "misc": { + "aqi": "AQI", "humidity": "לחות", "feels-like": "Feels like" } diff --git a/src/localize/languages/hu.json b/src/localize/languages/hu.json index 21915d1f..22ec5756 100644 --- a/src/localize/languages/hu.json +++ b/src/localize/languages/hu.json @@ -26,6 +26,7 @@ "7": "V" }, "misc": { + "aqi": "AQI", "humidity": "páratartalom", "feels-like": "Feels like" } diff --git a/src/localize/languages/id.json b/src/localize/languages/id.json index a9efd0f5..ce894472 100644 --- a/src/localize/languages/id.json +++ b/src/localize/languages/id.json @@ -26,6 +26,7 @@ "7": "Min" }, "misc": { + "aqi": "AQI", "humidity": "Kelembapan", "feels-like": "Terasa seperti" } diff --git a/src/localize/languages/is.json b/src/localize/languages/is.json index 1b649c4e..3a412f8a 100644 --- a/src/localize/languages/is.json +++ b/src/localize/languages/is.json @@ -26,6 +26,7 @@ "7": "Sun" }, "misc": { + "aqi": "AQI", "humidity": "raki", "feels-like": "Feels like" } diff --git a/src/localize/languages/it.json b/src/localize/languages/it.json index eabbdadb..05cf54ff 100644 --- a/src/localize/languages/it.json +++ b/src/localize/languages/it.json @@ -26,6 +26,7 @@ "7": "Dom" }, "misc": { + "aqi": "AQI", "humidity": "umidità", "feels-like": "Feels like" } diff --git a/src/localize/languages/ko.json b/src/localize/languages/ko.json index 6d40212c..a10075fb 100644 --- a/src/localize/languages/ko.json +++ b/src/localize/languages/ko.json @@ -26,6 +26,7 @@ "7": "일" }, "misc": { + "aqi": "AQI", "humidity": "습도", "feels-like": "Feels like" } diff --git a/src/localize/languages/lt.json b/src/localize/languages/lt.json index e74c1475..f7e0685a 100644 --- a/src/localize/languages/lt.json +++ b/src/localize/languages/lt.json @@ -26,6 +26,7 @@ "7": "Sk" }, "misc": { + "aqi": "AQI", "humidity": "drėgmė", "feels-like": "Feels like" } diff --git a/src/localize/languages/nb.json b/src/localize/languages/nb.json index b291b9aa..3e2d5b87 100644 --- a/src/localize/languages/nb.json +++ b/src/localize/languages/nb.json @@ -26,6 +26,7 @@ "7": "Søn" }, "misc": { + "aqi": "AQI", "humidity": "fuktighet", "feels-like": "Feels like" } diff --git a/src/localize/languages/nl.json b/src/localize/languages/nl.json index 4a476308..f2046ac7 100644 --- a/src/localize/languages/nl.json +++ b/src/localize/languages/nl.json @@ -26,6 +26,7 @@ "7": "Zo" }, "misc": { + "aqi": "AQI", "humidity": "Vochtigheid", "feels-like": "Gevoelstemperatuur" } diff --git a/src/localize/languages/pl.json b/src/localize/languages/pl.json index 4ffc687c..f11e9155 100644 --- a/src/localize/languages/pl.json +++ b/src/localize/languages/pl.json @@ -26,6 +26,7 @@ "7": "niedz." }, "misc": { + "aqi": "AQI", "humidity": "wilgotność", "feels-like": "Odczuwalne" } diff --git a/src/localize/languages/pt-br.json b/src/localize/languages/pt-br.json index e415bc7b..ee625dbc 100644 --- a/src/localize/languages/pt-br.json +++ b/src/localize/languages/pt-br.json @@ -26,6 +26,7 @@ "7": "Dom" }, "misc": { + "aqi": "AQI", "humidity": "umidade", "feels-like": "Feels like" } diff --git a/src/localize/languages/pt.json b/src/localize/languages/pt.json index e9bb8b7f..00ff73c8 100644 --- a/src/localize/languages/pt.json +++ b/src/localize/languages/pt.json @@ -26,6 +26,7 @@ "7": "Dom" }, "misc": { + "aqi": "AQI", "humidity": "humidade", "feels-like": "Feels like" } diff --git a/src/localize/languages/ro.json b/src/localize/languages/ro.json index 540e9bab..5e2561fc 100644 --- a/src/localize/languages/ro.json +++ b/src/localize/languages/ro.json @@ -26,6 +26,7 @@ "7": "Dum" }, "misc": { + "aqi": "AQI", "humidity": "umiditate", "feels-like": "Feels like" } diff --git a/src/localize/languages/ru.json b/src/localize/languages/ru.json index 35099365..8ecd9879 100644 --- a/src/localize/languages/ru.json +++ b/src/localize/languages/ru.json @@ -26,6 +26,7 @@ "7": "Вс" }, "misc": { + "aqi": "AQI", "humidity": "влажность", "feels-like": "Feels like" } diff --git a/src/localize/languages/sk.json b/src/localize/languages/sk.json index bbfa86f1..6dcfea0a 100644 --- a/src/localize/languages/sk.json +++ b/src/localize/languages/sk.json @@ -26,6 +26,7 @@ "7": "Ned" }, "misc": { + "aqi": "AQI", "humidity": "vlhkosť", "feels-like": "pocitová teplota" } diff --git a/src/localize/languages/sl.json b/src/localize/languages/sl.json index 681e0254..0383b534 100644 --- a/src/localize/languages/sl.json +++ b/src/localize/languages/sl.json @@ -26,6 +26,7 @@ "7": "Ned" }, "misc": { + "aqi": "AQI", "humidity": "vlažnost", "feels-like": "Feels like" } diff --git a/src/localize/languages/sr.json b/src/localize/languages/sr.json index b4b1c7ef..f2b52555 100644 --- a/src/localize/languages/sr.json +++ b/src/localize/languages/sr.json @@ -26,6 +26,7 @@ "7": "Нед" }, "misc": { + "aqi": "AQI", "humidity": "Влажност", "feels-like": "Feels like" } diff --git a/src/localize/languages/srlatn.json b/src/localize/languages/srlatn.json index 3b9e2d4b..1f6b29af 100644 --- a/src/localize/languages/srlatn.json +++ b/src/localize/languages/srlatn.json @@ -26,6 +26,7 @@ "7": "Ned" }, "misc": { + "aqi": "AQI", "humidity": "Vlažnost", "feels-like": "Feels like" } diff --git a/src/localize/languages/sv.json b/src/localize/languages/sv.json index d089c2f4..7bc49daf 100644 --- a/src/localize/languages/sv.json +++ b/src/localize/languages/sv.json @@ -26,6 +26,7 @@ "7": "Sön" }, "misc": { + "aqi": "AQI", "humidity": "fuktighet", "feels-like": "Känns som" } diff --git a/src/localize/languages/th.json b/src/localize/languages/th.json index f26959ea..38cf5d5b 100644 --- a/src/localize/languages/th.json +++ b/src/localize/languages/th.json @@ -26,6 +26,7 @@ "7": "อา." }, "misc": { + "aqi": "AQI", "humidity": "ความชื้น", "feels-like": "Feels like" } diff --git a/src/localize/languages/tr.json b/src/localize/languages/tr.json index f8c4dc81..89a8a34a 100644 --- a/src/localize/languages/tr.json +++ b/src/localize/languages/tr.json @@ -26,6 +26,7 @@ "7": "Pzr" }, "misc": { + "aqi": "AQI", "humidity": "nem", "feels-like": "Feels like" } diff --git a/src/localize/languages/uk.json b/src/localize/languages/uk.json index 0ed45316..e09b1d10 100644 --- a/src/localize/languages/uk.json +++ b/src/localize/languages/uk.json @@ -26,6 +26,7 @@ "7": "Нд" }, "misc": { + "aqi": "AQI", "humidity": "вологість", "feels-like": "Feels like" } diff --git a/src/localize/languages/ur.json b/src/localize/languages/ur.json index 73f42bf1..238cd20b 100644 --- a/src/localize/languages/ur.json +++ b/src/localize/languages/ur.json @@ -26,6 +26,7 @@ "7": "اتوار" }, "misc": { + "aqi": "AQI", "humidity": "نمی", "feels-like": "Feels like" } diff --git a/src/localize/languages/vi.json b/src/localize/languages/vi.json index 88ca286d..57991549 100644 --- a/src/localize/languages/vi.json +++ b/src/localize/languages/vi.json @@ -26,6 +26,7 @@ "7": "CN" }, "misc": { + "aqi": "AQI", "humidity": "độ ẩm", "feels-like": "Feels like" } diff --git a/src/localize/languages/zh-cn.json b/src/localize/languages/zh-cn.json index 387a5106..4512292a 100644 --- a/src/localize/languages/zh-cn.json +++ b/src/localize/languages/zh-cn.json @@ -26,6 +26,7 @@ "7": "周日" }, "misc": { + "aqi": "AQI", "humidity": "湿度", "feels-like": "Feels like" } diff --git a/src/localize/languages/zh-tw.json b/src/localize/languages/zh-tw.json index 7152512f..6708f253 100644 --- a/src/localize/languages/zh-tw.json +++ b/src/localize/languages/zh-tw.json @@ -26,6 +26,7 @@ "7": "週日" }, "misc": { + "aqi": "AQI", "humidity": "濕度", "feels-like": "Feels like" } diff --git a/src/styles.ts b/src/styles.ts index 9e485208..74963572 100644 --- a/src/styles.ts +++ b/src/styles.ts @@ -125,4 +125,9 @@ export default css` height: 100%; position: absolute; } + + aqi { + padding: 2px; + border-radius: 5px; + } ` diff --git a/src/types.ts b/src/types.ts index 68ed3ca0..9c447184 100644 --- a/src/types.ts +++ b/src/types.ts @@ -32,6 +32,7 @@ export interface ClockWeatherCardConfig extends LovelaceCardConfig { time_zone?: string show_decimal?: boolean apparent_sensor?: string + aqi_sensor?: string } export interface MergedClockWeatherCardConfig extends LovelaceCardConfig { @@ -57,6 +58,7 @@ export interface MergedClockWeatherCardConfig extends LovelaceCardConfig { time_zone?: string show_decimal: boolean apparent_sensor?: string + aqi_sensor?: string } export const enum WeatherEntityFeature {