mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-08 09:56:36 +00:00
Weather card without chart (#1117)
* Weather card without chart * Lint * Add iron-icon * Add night icon and translation * More translations * Lint * Feedback * More Flexbox KungFu * Finishing * Use hass lang instead of browser lang * Add more info card * Lint * Improve support for other providers * Support non-daily forcasts * Here we go
This commit is contained in:
parent
f21db486eb
commit
a983a5dbc5
@ -15,7 +15,6 @@
|
|||||||
"fecha": "~2.3.0",
|
"fecha": "~2.3.0",
|
||||||
"font-roboto-local": "~1.0.1",
|
"font-roboto-local": "~1.0.1",
|
||||||
"font-roboto": "PolymerElements/font-roboto-local#~1.0.1",
|
"font-roboto": "PolymerElements/font-roboto-local#~1.0.1",
|
||||||
"google-apis": "GoogleWebComponents/google-apis#~2.0.0",
|
|
||||||
"iron-autogrow-textarea": "PolymerElements/iron-autogrow-textarea#^2.0.0",
|
"iron-autogrow-textarea": "PolymerElements/iron-autogrow-textarea#^2.0.0",
|
||||||
"iron-flex-layout": "PolymerElements/iron-flex-layout#^2.0.0",
|
"iron-flex-layout": "PolymerElements/iron-flex-layout#^2.0.0",
|
||||||
"iron-icon": "PolymerElements/iron-icon#^2.0.0",
|
"iron-icon": "PolymerElements/iron-icon#^2.0.0",
|
||||||
|
@ -3,7 +3,7 @@ import computeStateDomain from './compute_state_domain.js';
|
|||||||
const DOMAINS_WITH_MORE_INFO = [
|
const DOMAINS_WITH_MORE_INFO = [
|
||||||
'alarm_control_panel', 'automation', 'camera', 'climate', 'configurator',
|
'alarm_control_panel', 'automation', 'camera', 'climate', 'configurator',
|
||||||
'cover', 'fan', 'group', 'history_graph', 'light', 'lock', 'media_player', 'script',
|
'cover', 'fan', 'group', 'history_graph', 'light', 'lock', 'media_player', 'script',
|
||||||
'sun', 'updater', 'vacuum', 'input_datetime',
|
'sun', 'updater', 'vacuum', 'input_datetime', 'weather'
|
||||||
];
|
];
|
||||||
|
|
||||||
const HIDE_MORE_INFO = [
|
const HIDE_MORE_INFO = [
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||||
<link rel='import' href='../../bower_components/iron-flex-layout/iron-flex-layout-classes.html'>
|
<link rel='import' href='../../bower_components/iron-icon/iron-icon.html'>
|
||||||
<link rel='import' href='../../bower_components/google-apis/google-legacy-loader.html'>
|
|
||||||
<link rel='import' href='../components/ha-card.html'>
|
<link rel='import' href='../components/ha-card.html'>
|
||||||
|
|
||||||
<link rel='import' href='../util/hass-mixins.html'>
|
<link rel='import' href='../util/hass-mixins.html'>
|
||||||
@ -8,217 +7,214 @@
|
|||||||
<dom-module id='ha-weather-card'>
|
<dom-module id='ha-weather-card'>
|
||||||
<template>
|
<template>
|
||||||
<style>
|
<style>
|
||||||
.content {
|
:host {
|
||||||
padding: 0 16px 16px;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.attribution {
|
.content {
|
||||||
|
padding: 0 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
iron-icon {
|
||||||
|
color: var(--paper-item-icon-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.now {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.state {
|
||||||
|
--iron-icon-height: 72px;
|
||||||
|
--iron-icon-width: 72px;
|
||||||
|
font-size: 52px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.now-text {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.forecast {
|
||||||
|
margin-top: 24px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.forecast div {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.forecast .icon {
|
||||||
|
margin: 8px 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weekday {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attributes,
|
||||||
|
.templow {
|
||||||
color: var(--secondary-text-color);
|
color: var(--secondary-text-color);
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
.condicon {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 4em;
|
|
||||||
}
|
|
||||||
.condtemp {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 4em;
|
|
||||||
}
|
|
||||||
div.cond {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
div.conddetails {
|
|
||||||
float: right;
|
|
||||||
display: block table;
|
|
||||||
overflow: auto;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
span.line {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.condsmall {
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
.clear {
|
|
||||||
clear: both;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<google-legacy-loader on-api-load='googleApiLoaded'></google-legacy-loader>
|
<ha-card header='[[stateObj.attributes.friendly_name]]'>
|
||||||
<ha-card header='[[computeTitle(stateObj)]]'>
|
|
||||||
<div class='content'>
|
<div class='content'>
|
||||||
<div class='condpanel'>
|
<div class="now">
|
||||||
<div class='cond condicon'>[[nowCond]]</div>
|
<div class="state">
|
||||||
<div class='cond condtemp'>[[attr.temperature]]°</div>
|
<template is="dom-if" if="[[showWeatherIcon(stateObj.state)]]">
|
||||||
<div class='cond conddetails'>
|
<iron-icon icon="[[getWeatherIcon(stateObj.state)]]"></iron-icon>
|
||||||
<div class="condsmall" hidden$="[[!attr.wind_speed]]">
|
</template>
|
||||||
[[localize('attribute.weather.wind_speed')]]:
|
[[getTemperature(stateObj.attributes.temperature)]]
|
||||||
<span hidden$="[[!attr.wind_speed]]">
|
|
||||||
[[attr.wind_speed]]
|
|
||||||
</span>
|
|
||||||
<span hidden$="[[!windBearing]]">[[windBearing]]</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="condsmall" hidden$="[[!attr.humidity]]">
|
<div class="attributes">
|
||||||
[[localize('attribute.weather.humidity')]]: [[attr.humidity]]%
|
<div>
|
||||||
|
[[localize('ui.card.weather.attributes.humidity')]]:
|
||||||
|
[[stateObj.attributes.humidity]] %
|
||||||
</div>
|
</div>
|
||||||
<div class="condsmall" hidden$="[[!attr.visibility]]">
|
<template is="dom-if" if="[[stateObj.attributes.visibility]]">
|
||||||
[[localize('attribute.weather.visibility')]]: [[attr.visibility]]
|
<div>
|
||||||
|
[[localize('ui.card.weather.attributes.visibility')]]:
|
||||||
|
[[getVisibilty(stateObj.attributes.visibility)]]
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div>
|
||||||
|
[[localize('ui.card.weather.attributes.wind_speed')]]:
|
||||||
|
[[getWind(stateObj.attributes.wind_speed, stateObj.attributes.wind_bearing, localize)]]
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class='clear'></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div id='chart_id' hidden$="[[!attr.forecast]]"></div>
|
<div class="now-text">[[computeState(stateObj.state, localize)]]</div>
|
||||||
|
<template is="dom-if" if="[[forecast]]">
|
||||||
|
<div class="forecast">
|
||||||
|
<template is='dom-repeat' items='[[forecast]]'>
|
||||||
|
<div>
|
||||||
|
<div class="weekday">[[computeDateTime(item.datetime)]]</div>
|
||||||
|
<template is="dom-if" if="[[item.condition]]">
|
||||||
|
<div class="icon">
|
||||||
|
<iron-icon icon="[[getWeatherIcon(item.condition)]]"></iron-icon>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="temp">[[item.temperature]]°</div>
|
||||||
|
<template is="dom-if" if="[[item.templow]]">
|
||||||
|
<div class="templow">[[item.templow]]°</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
{
|
|
||||||
var _WEATHER_TO_ICON = {
|
|
||||||
cloudy: '\u2601\ufe0f',
|
|
||||||
fog: '\uD83C\uDF2B\ufe0f',
|
|
||||||
hail: 'Hail',
|
|
||||||
lightning: '\uD83C\uDF29\ufe0f',
|
|
||||||
'lightning-rainy': '\u26c8\ufe0f',
|
|
||||||
partlycloudy: '\u26c5\ufe0f',
|
|
||||||
pouring: '\uD83D\uDCA7\ufe0f',
|
|
||||||
rainy: '\uD83C\uDF27\ufe0f',
|
|
||||||
snowy: '\uD83C\uDF28\ufe0f',
|
|
||||||
'snowy-rainy': '\uD83C\uDF28\ufe0f',
|
|
||||||
sunny: '\u2600\ufe0f',
|
|
||||||
windy: '\uD83C\uDF2C\ufe0f',
|
|
||||||
'windy-variant': '\uD83C\uDF2C\ufe0f',
|
|
||||||
exceptional: '\u2b55\ufe0f',
|
|
||||||
};
|
|
||||||
|
|
||||||
var _DEGREE_TEXT = [
|
|
||||||
'N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE',
|
|
||||||
'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N'
|
|
||||||
];
|
|
||||||
/*
|
/*
|
||||||
* @appliesMixin window.hassMixins.LocalizeMixin
|
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||||
*/
|
*/
|
||||||
class HaWeatherCard extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
class HaWeatherCard extends
|
||||||
|
window.hassMixins.LocalizeMixin(window.hassMixins.EventsMixin(Polymer.Element)) {
|
||||||
static get is() { return 'ha-weather-card'; }
|
static get is() { return 'ha-weather-card'; }
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
hass: Object,
|
hass: Object,
|
||||||
stateObj: {
|
stateObj: Object,
|
||||||
type: Object,
|
forecast: {
|
||||||
observer: 'checkRequirements'
|
type: Array,
|
||||||
},
|
computed: 'computeForecast(stateObj.attributes.forecast)'
|
||||||
attr: Object,
|
}
|
||||||
windBearing: Object,
|
};
|
||||||
nowCond: Object,
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.cardinalDirections = [
|
||||||
|
'N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE',
|
||||||
|
'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N'
|
||||||
|
];
|
||||||
|
this.weatherIcons = {
|
||||||
|
'clear-night': 'mdi:weather-night',
|
||||||
|
cloudy: 'mdi:weather-cloudy',
|
||||||
|
fog: 'mdi:weather-fog',
|
||||||
|
hail: 'mdi:weather-hail',
|
||||||
|
lightning: 'mid:weather-lightning',
|
||||||
|
'lightning-rainy': 'mdi:weather-lightning-rainy',
|
||||||
|
partlycloudy: 'mdi:weather-partlycloudy',
|
||||||
|
pouring: 'mdi:weather-pouring',
|
||||||
|
rainy: 'mdi:weather-rainy',
|
||||||
|
snowy: 'mdi:weather-snowy',
|
||||||
|
'snowy-rainy': 'mdi:weather-snowy-rainy',
|
||||||
|
sunny: 'mdi:weather-sunny',
|
||||||
|
windy: 'mdi:weather-windy',
|
||||||
|
'windy-variant': 'mdi:weather-windy-variant'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
computeTitle(stateObj) {
|
ready() {
|
||||||
return stateObj.attributes.friendly_name;
|
this.addEventListener('click', this._onClick);
|
||||||
}
|
super.ready();
|
||||||
getDataArray() {
|
|
||||||
var dataArray = [];
|
|
||||||
var data = this.stateObj.attributes.forecast;
|
|
||||||
var i;
|
|
||||||
|
|
||||||
if (!this.stateObj.attributes.forecast) {
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < data.length; i++) {
|
_onClick() {
|
||||||
var d = data[i];
|
this.fire('hass-more-info', { entityId: this.stateObj.entity_id });
|
||||||
if (!d.condition) {
|
|
||||||
dataArray.push([new Date(d.datetime), null, d.temperature, d.templow]);
|
|
||||||
} else {
|
|
||||||
dataArray.push([new Date(d.datetime), _WEATHER_TO_ICON[data[i].condition],
|
|
||||||
d.temperature, d.templow]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dataArray;
|
computeForecast(forecast) {
|
||||||
|
return forecast && forecast.slice(0, 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkRequirements() {
|
getUnit(unit) {
|
||||||
if (!this.stateObj) {
|
return this.hass.config.core.unit_system[unit] || '';
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.stateObj.attributes) {
|
computeState(state, localize) {
|
||||||
return;
|
return localize(`state.weather.${state.replace('-', '_')}`) || state;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.attr = this.stateObj.attributes;
|
showWeatherIcon(condition) {
|
||||||
|
return condition in this.weatherIcons;
|
||||||
this.nowCond = _WEATHER_TO_ICON[this.stateObj.state];
|
|
||||||
this.windBearing = this.windBearingToText(this.attr.wind_bearing);
|
|
||||||
|
|
||||||
if (!window.google || !window.google.visualization) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.chartEngine) {
|
getWeatherIcon(condition) {
|
||||||
this.chartEngine = new window.google.visualization.LineChart(this.$.chart_id);
|
return this.weatherIcons[condition];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.attr.forecast) {
|
getTemperature(temp) {
|
||||||
return;
|
return `${temp}${this.getUnit('temperature')}`;
|
||||||
}
|
|
||||||
|
|
||||||
this.drawChart();
|
|
||||||
}
|
|
||||||
drawChart() {
|
|
||||||
var dataGrid = new window.google.visualization.DataTable();
|
|
||||||
var options = {
|
|
||||||
legend: {
|
|
||||||
position: 'top'
|
|
||||||
},
|
|
||||||
interpolateNulls: true,
|
|
||||||
titlePosition: 'none',
|
|
||||||
chartArea: {
|
|
||||||
left: 25,
|
|
||||||
top: 5,
|
|
||||||
height: '100%',
|
|
||||||
width: '90%',
|
|
||||||
bottom: 25,
|
|
||||||
},
|
|
||||||
curveType: 'function',
|
|
||||||
focusTarget: 'category',
|
|
||||||
colors: ['red', 'blue'],
|
|
||||||
annotations: {
|
|
||||||
textStyle: {
|
|
||||||
fontSize: '24',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
dataGrid.addColumn('datetime', 'Time');
|
|
||||||
dataGrid.addColumn({ type: 'string', role: 'annotation' });
|
|
||||||
dataGrid.addColumn('number', 'Temperature');
|
|
||||||
dataGrid.addColumn('number', 'Temperature Low');
|
|
||||||
|
|
||||||
var dataArray = this.getDataArray();
|
|
||||||
dataGrid.addRows(dataArray);
|
|
||||||
|
|
||||||
this.chartEngine.draw(dataGrid, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
googleApiLoaded() {
|
|
||||||
window.google.load('visualization', '1', {
|
|
||||||
packages: ['corechart'],
|
|
||||||
callback: function () {
|
|
||||||
this.checkRequirements();
|
|
||||||
}.bind(this),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
windBearingToText(degree) {
|
windBearingToText(degree) {
|
||||||
var degreenum = parseInt(degree);
|
const degreenum = parseInt(degree);
|
||||||
if (isFinite(degreenum)) {
|
if (isFinite(degreenum)) {
|
||||||
return _DEGREE_TEXT[(((degreenum + 11.25) / 22.5) | 0) % 16];
|
return this.cardinalDirections[(((degreenum + 11.25) / 22.5) | 0) % 16];
|
||||||
}
|
}
|
||||||
return '';
|
return degree;
|
||||||
|
}
|
||||||
|
|
||||||
|
getWind(speed, bearing, localize) {
|
||||||
|
if (bearing != null) {
|
||||||
|
const cardinalDirection = this.windBearingToText(bearing);
|
||||||
|
return `${speed} ${this.getUnit('length')}/h (${localize(cardinalDirection.toLowerCase()) || cardinalDirection})`;
|
||||||
|
}
|
||||||
|
return `${speed} ${this.getUnit('length')}/h`;
|
||||||
|
}
|
||||||
|
|
||||||
|
getVisibilty(visibilty) {
|
||||||
|
return `${visibilty} ${this.getUnit('length')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
computeDateTime(data) {
|
||||||
|
const date = new Date(data);
|
||||||
|
const provider = this.stateObj.attributes.attribution;
|
||||||
|
if (provider === 'Powered by Dark Sky' || provider === 'Data provided by OpenWeatherMap') {
|
||||||
|
return date.toLocaleTimeString(
|
||||||
|
this.hass.selectedLanguage || this.hass.language,
|
||||||
|
{ hour: 'numeric' }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return date.toLocaleDateString(this.hass.selectedLanguage || this.hass.language, { weekday: 'short' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define(HaWeatherCard.is, HaWeatherCard);
|
customElements.define(HaWeatherCard.is, HaWeatherCard);
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
<link rel='import' href='more-info-updater.html'>
|
<link rel='import' href='more-info-updater.html'>
|
||||||
<link rel='import' href='more-info-vacuum.html'>
|
<link rel='import' href='more-info-vacuum.html'>
|
||||||
<link rel='import' href='more-info-input_datetime.html'>
|
<link rel='import' href='more-info-input_datetime.html'>
|
||||||
|
<link rel='import' href='more-info-weather.html'>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
class MoreInfoContent extends Polymer.Element {
|
class MoreInfoContent extends Polymer.Element {
|
||||||
|
182
src/dialogs/more-info/controls/more-info-weather.html
Normal file
182
src/dialogs/more-info/controls/more-info-weather.html
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
<link rel='import' href='../../../../bower_components/polymer/polymer-element.html'>
|
||||||
|
<link rel='import' href='../../../../bower_components/iron-icon/iron-icon.html'>
|
||||||
|
|
||||||
|
<link rel='import' href='../../../util/hass-mixins.html'>
|
||||||
|
|
||||||
|
<dom-module id='more-info-weather'>
|
||||||
|
<template>
|
||||||
|
<style>
|
||||||
|
iron-icon {
|
||||||
|
color: var(--paper-item-icon-color);
|
||||||
|
}
|
||||||
|
.section {
|
||||||
|
margin: 16px 0 8px 0;
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
height: 32px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
flex: 1;
|
||||||
|
margin-left: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.temp,
|
||||||
|
.templow {
|
||||||
|
min-width: 48px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.templow {
|
||||||
|
margin: 0 16px;
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.attribution {
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="flex">
|
||||||
|
<iron-icon icon="mdi:thermometer"></iron-icon>
|
||||||
|
<div class="main">[[localize('ui.card.weather.attributes.temperature')]]</div>
|
||||||
|
<div>[[stateObj.attributes.temperature]] [[getUnit('temperature')]]</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex">
|
||||||
|
<iron-icon icon="mdi:water-percent"></iron-icon>
|
||||||
|
<div class="main">[[localize('ui.card.weather.attributes.humidity')]]</div>
|
||||||
|
<div>[[stateObj.attributes.humidity]] %</div>
|
||||||
|
</div>
|
||||||
|
<template is="dom-if" if="[[stateObj.attributes.visibility]]">
|
||||||
|
<div class="flex">
|
||||||
|
<iron-icon icon="mdi:eye"></iron-icon>
|
||||||
|
<div class="main">[[localize('ui.card.weather.attributes.visibility')]]</div>
|
||||||
|
<div>[[stateObj.attributes.visibility]] [[getUnit('length')]]</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="flex">
|
||||||
|
<iron-icon icon="mdi:weather-windy"></iron-icon>
|
||||||
|
<div class="main">[[localize('ui.card.weather.attributes.wind_speed')]]</div>
|
||||||
|
<div>[[getWind(stateObj.attributes.wind_speed, stateObj.attributes.wind_bearing, localize)]]</div>
|
||||||
|
</div>
|
||||||
|
<template is="dom-if" if="[[stateObj.attributes.pressure]]">
|
||||||
|
<div class="flex">
|
||||||
|
<iron-icon icon="mdi:gauge"></iron-icon>
|
||||||
|
<div class="main">[[localize('ui.card.weather.attributes.air_pressure')]]</div>
|
||||||
|
<div>[[stateObj.attributes.pressure]] hPa</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template is="dom-if" if="[[stateObj.attributes.forecast]]">
|
||||||
|
<div class="section">[[localize('ui.card.weather.forecast')]]:</div>
|
||||||
|
<template is='dom-repeat' items='[[stateObj.attributes.forecast]]'>
|
||||||
|
<div class="flex">
|
||||||
|
<template is="dom-if" if="[[item.condition]]">
|
||||||
|
<iron-icon icon="[[getWeatherIcon(item.condition)]]"></iron-icon>
|
||||||
|
</template>
|
||||||
|
<div class="main">[[computeDateTime(item.datetime)]]</div>
|
||||||
|
<template is="dom-if" if="[[item.templow]]">
|
||||||
|
<div class="templow">[[item.templow]] [[getUnit('temperature')]]</div>
|
||||||
|
</template>
|
||||||
|
<div class="temp">[[item.temperature]] [[getUnit('temperature')]]</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template is="dom-if" if="stateObj.attributes.attribution">
|
||||||
|
<div class="attribution">[[stateObj.attributes.attribution]]</div>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/*
|
||||||
|
* @appliesMixin window.hassMixins.LocalizeMixin
|
||||||
|
*/
|
||||||
|
class MoreInfoWeather extends window.hassMixins.LocalizeMixin(Polymer.Element) {
|
||||||
|
static get is() { return 'more-info-weather'; }
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
hass: Object,
|
||||||
|
stateObj: Object
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.cardinalDirections = [
|
||||||
|
'N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE',
|
||||||
|
'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N'
|
||||||
|
];
|
||||||
|
this.weatherIcons = {
|
||||||
|
'clear-night': 'mdi:weather-night',
|
||||||
|
cloudy: 'mdi:weather-cloudy',
|
||||||
|
fog: 'mdi:weather-fog',
|
||||||
|
hail: 'mdi:weather-hail',
|
||||||
|
lightning: 'mid:weather-lightning',
|
||||||
|
'lightning-rainy': 'mdi:weather-lightning-rainy',
|
||||||
|
partlycloudy: 'mdi:weather-partlycloudy',
|
||||||
|
pouring: 'mdi:weather-pouring',
|
||||||
|
rainy: 'mdi:weather-rainy',
|
||||||
|
snowy: 'mdi:weather-snowy',
|
||||||
|
'snowy-rainy': 'mdi:weather-snowy-rainy',
|
||||||
|
sunny: 'mdi:weather-sunny',
|
||||||
|
windy: 'mdi:weather-windy',
|
||||||
|
'windy-variant': 'mdi:weather-windy-variant'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
computeDateTime(data) {
|
||||||
|
const date = new Date(data);
|
||||||
|
const provider = this.stateObj.attributes.attribution;
|
||||||
|
if (provider === 'Powered by Dark Sky' || provider === 'Data provided by OpenWeatherMap') {
|
||||||
|
if (new Date().getDay() === date.getDay()) {
|
||||||
|
return date.toLocaleTimeString(
|
||||||
|
this.hass.selectedLanguage || this.hass.language,
|
||||||
|
{ hour: 'numeric' }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return date.toLocaleDateString(
|
||||||
|
this.hass.selectedLanguage || this.hass.language,
|
||||||
|
{ weekday: 'long', hour: 'numeric' }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return date.toLocaleDateString(
|
||||||
|
this.hass.selectedLanguage || this.hass.language,
|
||||||
|
{ weekday: 'long', month: 'short', day: 'numeric' }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUnit(unit) {
|
||||||
|
return this.hass.config.core.unit_system[unit] || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
windBearingToText(degree) {
|
||||||
|
const degreenum = parseInt(degree);
|
||||||
|
if (isFinite(degreenum)) {
|
||||||
|
return this.cardinalDirections[(((degreenum + 11.25) / 22.5) | 0) % 16];
|
||||||
|
}
|
||||||
|
return degree;
|
||||||
|
}
|
||||||
|
|
||||||
|
getWind(speed, bearing, localize) {
|
||||||
|
if (bearing != null) {
|
||||||
|
const cardinalDirection = this.windBearingToText(bearing);
|
||||||
|
return `${speed} ${this.getUnit('length')}/h (${localize(cardinalDirection.toLowerCase()) || cardinalDirection})`;
|
||||||
|
}
|
||||||
|
return `${speed} ${this.getUnit('length')}/h`;
|
||||||
|
}
|
||||||
|
|
||||||
|
getWeatherIcon(condition) {
|
||||||
|
return this.weatherIcons[condition];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define(MoreInfoWeather.is, MoreInfoWeather);
|
||||||
|
</script>
|
@ -1,11 +1,4 @@
|
|||||||
{
|
{
|
||||||
"attribute": {
|
|
||||||
"weather": {
|
|
||||||
"humidity": "Humidity",
|
|
||||||
"visibility": "Visibility",
|
|
||||||
"wind_speed": "Wind speed"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"domain": {
|
"domain": {
|
||||||
"alarm_control_panel": "Alarm control panel",
|
"alarm_control_panel": "Alarm control panel",
|
||||||
"automation": "Automation",
|
"automation": "Automation",
|
||||||
@ -269,6 +262,22 @@
|
|||||||
"off": "[%key:state::default::off%]",
|
"off": "[%key:state::default::off%]",
|
||||||
"on": "[%key:state::default::on%]"
|
"on": "[%key:state::default::on%]"
|
||||||
},
|
},
|
||||||
|
"weather": {
|
||||||
|
"clear_night": "Clear, night",
|
||||||
|
"cloudy": "Cloudy",
|
||||||
|
"fog": "Fog",
|
||||||
|
"hail": "Hail",
|
||||||
|
"lightning": "Lightning",
|
||||||
|
"lightning_rainy": "Lightning, rainy",
|
||||||
|
"partlycloudy": "Partly cloudy",
|
||||||
|
"pouring": "Pouring",
|
||||||
|
"rainy": "Rainy",
|
||||||
|
"snowy": "Snowy",
|
||||||
|
"snowy_rainy": "Snowy, rainy",
|
||||||
|
"sunny": "Sunny",
|
||||||
|
"windy": "Windy",
|
||||||
|
"windy_variant": "Windy"
|
||||||
|
},
|
||||||
"zwave": {
|
"zwave": {
|
||||||
"default": {
|
"default": {
|
||||||
"initializing": "Initializing",
|
"initializing": "Initializing",
|
||||||
@ -317,6 +326,34 @@
|
|||||||
},
|
},
|
||||||
"script": {
|
"script": {
|
||||||
"execute": "Execute"
|
"execute": "Execute"
|
||||||
|
},
|
||||||
|
"weather": {
|
||||||
|
"attributes": {
|
||||||
|
"air_pressure": "Air pressure",
|
||||||
|
"humidity": "Humidity",
|
||||||
|
"temperature": "Temperature",
|
||||||
|
"visibility": "Visibility",
|
||||||
|
"wind_speed": "Wind speed"
|
||||||
|
},
|
||||||
|
"cardinal_direction": {
|
||||||
|
"e": "E",
|
||||||
|
"ene": "ENE",
|
||||||
|
"ese": "ESE",
|
||||||
|
"n": "N",
|
||||||
|
"ne": "NE",
|
||||||
|
"nne": "NNE",
|
||||||
|
"nw": "NW",
|
||||||
|
"nnw": "NNW",
|
||||||
|
"s": "S",
|
||||||
|
"se": "SE",
|
||||||
|
"sse": "SSE",
|
||||||
|
"ssw": "SSW",
|
||||||
|
"sw": "SW",
|
||||||
|
"w": "W",
|
||||||
|
"wnw": "WNW",
|
||||||
|
"wsw": "WSW"
|
||||||
|
},
|
||||||
|
"forecast": "Forecast"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user