Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

New options 'entity', 'pressure2mmhg', 'wind_unit', 'chart_only', 'temp_apparent' #16

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea/
19 changes: 12 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,16 @@ Then you can add the card to the view:

#### Configuration variables:

| Name | Optional | Description |
| ------- | -------- | -------------------------------------------------------------------------------------------------- |
| type | **No** | Should be `'custom:weather-card-chart'` |
| title | **No** | Card title |
| weather | **No** | An entity_id with the `weather` domain |
| Name | Optional | Description |
| -------- | -------- | -------------------------------------------------------------------------------------------------- |
| type | **No** | Should be `'custom:weather-card-chart'` |
| title | Yes | Default value: ``. Card title |
| weather | **No*** | An entity_id with the `weather` domain. Use only one: 'weather' or 'entity' option. |
| entity | **No*** | (For backward compatibility with Weather Forecast Card) An entity_id with the `weather` domain. Use only one: 'weather' or 'entity' option. |
| temp | Yes | Entity_id of the temperature sensor. Show temperature value from sensor instead |
| temp_apparent | Yes | Entity_id of the apparent temperature sensor |
| mode | Yes | Default value: `daily`. Set mode to `hourly` to display hours instead weekdays on the chart |
| wind | Yes | Entity_id of the wind sensor. Show wind value from sensor instead |
| temp | Yes | Entity_id of the temperature sensor. Show temperature value from sensor instead |
| mode | Yes | Default value: `daily`. Set mode to `hourly` to display hours instead weekdays on the chart |
| wind_unit | Yes | Default value: `ms`. Set wind_unit to `kmh` to display wind speed in km/h |
| pressure2mmhg | Yes | Default value: False. Set pressure2mmhg to True to display pressure in mmHg |
| chart_only | Yes | Default value: False. Set chart_only to True to display only temperature chart |
194 changes: 141 additions & 53 deletions weather-card-chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ const locale = {
tempLo: "Temperatur nat",
precip: "Nedbør",
uPress: "hPa",
uSpeed: "m/s",
uSpeed: {
"ms": "m/s",
"kmh": "km/h"
},
uPrecip: "mm",
cardinalDirections: [
'N', 'N-NØ', 'NØ', 'Ø-NØ', 'Ø', 'Ø-SØ', 'SØ', 'S-SØ',
Expand All @@ -16,7 +19,10 @@ const locale = {
tempLo: "Tiefsttemperatur",
precip: "Niederschlag",
uPress: "hPa",
uSpeed: "m/s",
uSpeed: {
"ms": "m/s",
"kmh": "km/h"
},
uPrecip: "mm",
cardinalDirections: [
'N', 'N-NO', 'NO', 'O-NO', 'O', 'O-SO', 'SO', 'S-SO',
Expand All @@ -26,9 +32,14 @@ const locale = {
en: {
tempHi: "Temperature",
tempLo: "Temperature night",
tempApp: "Feels like",
precip: "Precipitations",
uPress: "hPa",
uSpeed: "m/s",
uPressMmHg: "mmHg",
uSpeed: {
"ms": "m/s",
"kmh": "km/h"
},
uPrecip: "mm",
cardinalDirections: [
'N', 'N-NE', 'NE', 'E-NE', 'E', 'E-SE', 'SE', 'S-SE',
Expand All @@ -40,7 +51,10 @@ const locale = {
tempLo: "Temperatura mínima",
precip: "Precipitations",
uPress: "hPa",
uSpeed: "m/s",
uSpeed: {
"ms": "m/s",
"kmh": "km/h"
},
uPrecip: "mm",
cardinalDirections: [
'N', 'N-NE', 'NE', 'E-NE', 'E', 'E-SE', 'SE', 'S-SE',
Expand All @@ -52,7 +66,10 @@ const locale = {
tempLo: "Température nuit",
precip: "Précipitations",
uPress: "hPa",
uSpeed: "m/s",
uSpeed: {
"ms": "m/s",
"kmh": "km/h"
},
uPrecip: "mm",
cardinalDirections: [
'N', 'N-NE', 'NE', 'E-NE', 'E', 'E-SE', 'SE', 'S-SE',
Expand All @@ -64,7 +81,10 @@ const locale = {
tempLo: "Minimum temperatuur",
precip: "Neerslag",
uPress: "hPa",
uSpeed: "m/s",
uSpeed: {
"ms": "m/s",
"kmh": "km/h"
},
uPrecip: "mm",
cardinalDirections: [
'N', 'N-NO', 'NO', 'O-NO', 'O', 'O-ZO', 'ZO', 'Z-ZO',
Expand All @@ -74,9 +94,14 @@ const locale = {
ru: {
tempHi: "Температура",
tempLo: "Температура ночью",
tempApp: "Ощущается как",
precip: "Осадки",
uPress: "гПа",
uSpeed: "м/с",
uPressMmHg: "мм",
uSpeed: {
"ms": "м/с",
"kmh": "км/ч"
},
uPrecip: "мм",
cardinalDirections: [
'С', 'С-СВ', 'СВ', 'В-СВ', 'В', 'В-ЮВ', 'ЮВ', 'Ю-ЮВ',
Expand All @@ -88,7 +113,10 @@ const locale = {
tempLo: "Temperatur natt",
precip: "Nederbörd",
uPress: "hPa",
uSpeed: "m/s",
uSpeed: {
"ms": "m/s",
"kmh": "km/h"
},
uPrecip: "mm",
cardinalDirections: [
'N', 'N-NO', 'NO', 'O-NO', 'O', 'O-SO', 'SO', 'S-SO',
Expand All @@ -106,78 +134,107 @@ class WeatherCardChart extends Polymer.Element {
color: var(--paper-item-icon-color);
}
.card {
padding: 0 18px 18px 18px;
padding: 0 10px 10px 10px;
}
.content {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.main {
display: flex;
align-items: center;
font-size: 60px;
font-weight: 350;
margin-top: -10px;
}
.main ha-icon {
--iron-icon-height: 74px;
--iron-icon-width: 74px;
--mdc-icon-size: 74px;
margin-right: 20px;
margin-right: 10px;
}
.main sup {
font-size: 50%;
}
.main div {
.main ha-icon, .main .temp {
font-size: 400%;
font-weight: 300;
}
.main .temp {
cursor: pointer;
margin-top: -11px;
}
.main sup {
font-size: 32px;
.main .apparent {
cursor: pointer;
margin-top: 0.75em;
}
.attributes {
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
margin: 10px 0px 10px 0px;
margin: 0px 0px 10px 0px;
}
.attributes div {
text-align: center;
text-align: left;
}
.sun {
display: flex;
justify-content: space-evenly;
margin: 10px 0;
}
.sun div {
flex: 0 0 auto;
}
.conditions {
display: flex;
justify-content: space-between;
align-items: center;
margin: 0px 3px 0px 16px;
}
[hidden] {
display: none !important;
}
</style>
<ha-card header="[[title]]">
<div class="card">
<div class="main">
<ha-icon icon="[[getWeatherIcon(weatherObj.state)]]"></ha-icon>
<template is="dom-if" if="[[tempObj]]">
<div on-click="_tempAttr">[[roundNumber(tempObj.state)]]<sup>[[getUnit('temperature')]]</sup></div>
</template>
<template is="dom-if" if="[[!tempObj]]">
<div on-click="_weatherAttr">[[roundNumber(weatherObj.attributes.temperature)]]<sup>[[getUnit('temperature')]]</sup></div>
</template>
</div>
<div class="attributes" on-click="_weatherAttr">
<div>
<ha-icon icon="hass:water-percent"></ha-icon> [[roundNumber(weatherObj.attributes.humidity)]] %<br>
<ha-icon icon="hass:gauge"></ha-icon> [[roundNumber(weatherObj.attributes.pressure)]] [[ll('uPress')]]
</div>
<div>
<template is="dom-if" if="[[sunObj]]">
<ha-icon icon="mdi:weather-sunset-up"></ha-icon> [[computeTime(sunObj.attributes.next_rising)]]<br>
<ha-icon icon="mdi:weather-sunset-down"></ha-icon> [[computeTime(sunObj.attributes.next_setting)]]
</template>
</div>
<div>
<ha-icon icon="[[getWindDirIcon(windBearing)]]"></ha-icon> [[getWindDir(windBearing)]]<br>
<ha-icon icon="hass:weather-windy"></ha-icon>
<template is="dom-if" if="[[windObj]]">
[[roundNumber(windObj.state)]] [[ll('uSpeed')]]
<div class="content">
<div class="main" hidden="[[chartOnly]]">
<ha-icon icon="[[getWeatherIcon(weatherObj.state)]]"></ha-icon>
<div class="temp-content">
<template is="dom-if" if="[[tempObj]]">
<div class="temp" on-click="_tempAttr">[[roundNumber(tempObj.state)]]<sup>[[getUnit('temperature')]]</sup></div>
<template is="dom-if" if="[[apparentObj]]"><div class="apparent" on-click="_apparentAttr">[[ll('tempApp')]] [[roundNumber(apparentObj.state)]]<sup>[[getUnit('temperature')]]</sup></div></template>
</template>
<template is="dom-if" if="[[!windObj]]">
[[computeWind(weatherObj.attributes.wind_speed)]] [[ll('uSpeed')]]
<template is="dom-if" if="[[!tempObj]]">
<div class="temp" on-click="_weatherAttr">[[roundNumber(weatherObj.attributes.temperature)]]<sup>[[getUnit('temperature')]]</sup></div>
<template is="dom-if" if="[[apparentObj]]"><div class="apparent" on-click="_apparentAttr">[[ll('tempApp')]] [[roundNumber(apparentObj.state)]]<sup>[[getUnit('temperature')]]</sup></div></template>
</template>
</div>
</div>
<div class="attributes" on-click="_weatherAttr" hidden="[[chartOnly]]">
<div>
<ha-icon icon="hass:water-percent"></ha-icon> [[roundNumber(weatherObj.attributes.humidity)]] %<br>
<ha-icon icon="hass:gauge"></ha-icon> [[computePressure(weatherObj.attributes.pressure)]] [[ll('uPress')]]<br>
<ha-icon icon="[[getWindDirIcon(windBearing)]]"></ha-icon>
<template is="dom-if" if="[[windObj]]">
[[roundNumber(windObj.state)]]
</template>
<template is="dom-if" if="[[!windObj]]">
[[computeWind(weatherObj.attributes.wind_speed)]]
</template>
[[getWindUnit()]]
</div>
</div>
</div>
<template is="dom-if" if="[[sunObj]]">
<div class="sun" hidden="[[chartOnly]]">
<div>
<ha-icon icon="mdi:weather-sunset-up"></ha-icon> [[computeTime(sunObj.attributes.next_rising)]]
</div>
<div>
<ha-icon icon="mdi:weather-sunset-down"></ha-icon> [[computeTime(sunObj.attributes.next_setting)]]
</div>
</div>
</template>
<ha-chart-base hass="[[_hass]]" data="[[ChartData]]"></ha-chart-base>
<div class="conditions">
<template is="dom-repeat" items="[[forecast]]">
Expand All @@ -198,6 +255,8 @@ class WeatherCardChart extends Polymer.Element {
tempObj: Object,
windObj: Object,
mode: String,
wind_unit: String,
chartOnly: Boolean,
weatherObj: {
type: Object,
observer: 'dataChanged',
Expand All @@ -208,6 +267,7 @@ class WeatherCardChart extends Polymer.Element {
constructor() {
super();
this.mode = 'daily';
this.windUnit = 'ms';
this.weatherIcons = {
'clear-night': 'hass:weather-night',
'cloudy': 'hass:weather-cloudy',
Expand All @@ -233,22 +293,28 @@ class WeatherCardChart extends Polymer.Element {

setConfig(config) {
this.config = config;
this.title = config.title;
this.weatherObj = config.weather;
this.title = config.title || "";
this.weatherObj = config.weather || config.entity;
this.tempObj = config.temp;
this.apparentObj = config.temp_apparent;
this.windObj = config.wind;
this.mode = config.mode;
if (!config.weather) {
this.windUnit = config.wind_unit || 'ms';
this.pressure2mmhg = config.pressure2mmhg || false;
this.chartOnly = config.chart_only;
if (!this.weatherObj) {
throw new Error('Please define "weather" entity in the card config');
}
}

set hass(hass) {
this._hass = hass;
this.lang = this._hass.selectedLanguage || this._hass.language;
this.weatherObj = this.config.weather in hass.states ? hass.states[this.config.weather] : null;
this.weatherObj = this.config.weather in hass.states ? hass.states[this.config.weather] :
this.config.entity in hass.states ? hass.states[this.config.entity] : null;
this.sunObj = 'sun.sun' in hass.states ? hass.states['sun.sun'] : null;
this.tempObj = this.config.temp in hass.states ? hass.states[this.config.temp] : null;
this.apparentObj = this.config.temp_apparent in hass.states ? hass.states[this.config.temp_apparent] : null;
this.windObj = this.config.wind in hass.states ? hass.states[this.config.wind] : null;
this.forecast = this.weatherObj.attributes.forecast.slice(0,9);
this.windBearing = this.weatherObj.attributes.wind_bearing;
Expand All @@ -264,7 +330,10 @@ class WeatherCardChart extends Polymer.Element {
}

ll(str) {
if (locale[this.lang] === undefined)
if (str === "uPress" && this.pressure2mmhg) {
str = "uPressMmHg";
}
if (locale[this.lang] === undefined || locale[this.lang][str] === undefined)
return locale.en[str];
return locale[this.lang][str];
}
Expand All @@ -276,9 +345,17 @@ class WeatherCardChart extends Polymer.Element {
);
}

computePressure(pressure) {
var calcPressure = this.pressure2mmhg ? Math.round(pressure * 1000 / 1333)
: Math.round(pressure);
return calcPressure;
}

computeWind(speed) {
var calcSpeed = Math.round(speed * 1000 / 3600);
return calcSpeed;
if (this.windUnit === 'ms')
return Math.round(speed * 1000 / 3600);
else
return speed;
}

getCardSize() {
Expand All @@ -289,11 +366,18 @@ class WeatherCardChart extends Polymer.Element {
return this._hass.config.unit_system[unit] || '';
}

getWindUnit()
{
return this.ll('uSpeed')[this.windUnit];
}

getWeatherIcon(condition) {
return this.weatherIcons[condition];
}

getWindDirIcon(degree) {
if (degree == 'unknown')
return 'mdi:circle-small';
return this.cardinalDirectionsIcon[parseInt((degree + 22.5) / 45.0)];
}

Expand Down Expand Up @@ -508,8 +592,12 @@ class WeatherCardChart extends Polymer.Element {
this._fire('hass-more-info', { entityId: this.config.temp });
}

_apparentAttr() {
this._fire('hass-more-info', { entityId: this.config.temp_apparent });
}

_weatherAttr() {
this._fire('hass-more-info', { entityId: this.config.weather });
this._fire('hass-more-info', { entityId: this.config.weather || this.config.entity });
}
}

Expand Down