Merge pull request #62 from home-assistant/remove-instance-singleton

Clean up - step 1: Remove instance singleton
This commit is contained in:
Paulus Schoutsen 2016-05-28 11:30:41 -07:00
commit 1840a90fcb
74 changed files with 500 additions and 538 deletions

View File

@ -21,7 +21,6 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"home-assistant-js": "git+https://github.com/home-assistant/home-assistant-js.git#ff2bd7efd23bb731d1bcc88996154c5d573395ed", "home-assistant-js": "git+https://github.com/home-assistant/home-assistant-js.git#ff2bd7efd23bb731d1bcc88996154c5d573395ed",
"lodash": "^4.11.2",
"moment": "^2.13.0" "moment": "^2.13.0"
}, },
"devDependencies": { "devDependencies": {

View File

@ -7,7 +7,7 @@
</style> </style>
<template> <template>
<template is='dom-repeat' items='[[states]]'> <template is='dom-repeat' items='[[states]]'>
<ha-state-label-badge state='[[item]]'></ha-state-label-badge> <ha-state-label-badge hass='[[hass]]' state='[[item]]'></ha-state-label-badge>
</template> </template>
</template> </template>
</dom-module> </dom-module>

View File

@ -6,6 +6,10 @@ export default new Polymer({
is: 'ha-badges-card', is: 'ha-badges-card',
properties: { properties: {
hass: {
type: Object,
},
states: { states: {
type: Array, type: Array,
}, },

View File

@ -1,7 +1,4 @@
import Polymer from '../polymer'; import Polymer from '../polymer';
import hass from '../util/home-assistant-js-instance';
const { moreInfoActions } = hass;
const UPDATE_INTERVAL = 10000; // ms const UPDATE_INTERVAL = 10000; // ms
@ -9,6 +6,10 @@ export default new Polymer({
is: 'ha-camera-card', is: 'ha-camera-card',
properties: { properties: {
hass: {
type: Object,
},
stateObj: { stateObj: {
type: Object, type: Object,
observer: 'updateCameraFeedSrc', observer: 'updateCameraFeedSrc',
@ -47,7 +48,7 @@ export default new Polymer({
}, },
cardTapped() { cardTapped() {
this.async(() => moreInfoActions.selectEntity(this.stateObj.entityId), 1); this.async(() => this.hass.moreInfoActions.selectEntity(this.stateObj.entityId), 1);
}, },
updateCameraFeedSrc(stateObj) { updateCameraFeedSrc(stateObj) {

View File

@ -38,13 +38,18 @@
<div class$='[[computeTitleClass(groupEntity)]]' on-tap='entityTapped'> <div class$='[[computeTitleClass(groupEntity)]]' on-tap='entityTapped'>
<div class='flex name'>[[computeTitle(states, groupEntity)]]</div> <div class='flex name'>[[computeTitle(states, groupEntity)]]</div>
<template is='dom-if' if='[[showGroupToggle(groupEntity, states)]]'> <template is='dom-if' if='[[showGroupToggle(groupEntity, states)]]'>
<ha-entity-toggle state-obj='[[groupEntity]]'></ha-entity-toggle> <ha-entity-toggle
hass='[[hass]]'
state-obj='[[groupEntity]]'></ha-entity-toggle>
</template> </template>
</div> </div>
<div class='states'> <div class='states'>
<template is='dom-repeat' items="[[states]]"> <template is='dom-repeat' items="[[states]]">
<div class='state' on-tap='entityTapped'> <div class='state' on-tap='entityTapped'>
<state-card-content class="state-card" state-obj="[[item]]"></state-card-content> <state-card-content
hass='[[hass]]'
class="state-card"
state-obj="[[item]]"></state-card-content>
</div> </div>
</template> </template>
</div> </div>

View File

@ -1,17 +1,18 @@
import Polymer from '../polymer'; import Polymer from '../polymer';
import hass from '../util/home-assistant-js-instance';
import canToggle from '../util/can-toggle'; import canToggle from '../util/can-toggle';
require('../components/ha-card'); require('../components/ha-card');
require('../components/entity/ha-entity-toggle'); require('../components/entity/ha-entity-toggle');
require('../state-summary/state-card-content'); require('../state-summary/state-card-content');
const { moreInfoActions } = hass;
export default new Polymer({ export default new Polymer({
is: 'ha-entities-card', is: 'ha-entities-card',
properties: { properties: {
hass: {
type: Object,
},
states: { states: {
type: Array, type: Array,
}, },
@ -45,7 +46,7 @@ export default new Polymer({
} else { } else {
entityId = this.groupEntity.entityId; entityId = this.groupEntity.entityId;
} }
this.async(() => moreInfoActions.selectEntity(entityId), 1); this.async(() => this.hass.moreInfoActions.selectEntity(entityId), 1);
}, },
showGroupToggle(groupEntity, states) { showGroupToggle(groupEntity, states) {
@ -54,6 +55,6 @@ export default new Polymer({
} }
// only show if we can toggle 2+ entities in group // only show if we can toggle 2+ entities in group
return states.reduce((sum, state) => sum + canToggle(state.entityId), 0) > 1; return states.reduce((sum, state) => sum + canToggle(this.hass, state.entityId), 0) > 1;
}, },
}); });

View File

@ -1,14 +1,15 @@
import classnames from 'classnames'; import classnames from 'classnames';
import Polymer from '../polymer'; import Polymer from '../polymer';
import hass from '../util/home-assistant-js-instance';
const { moreInfoActions } = hass;
export default new Polymer({ export default new Polymer({
is: 'ha-media_player-card', is: 'ha-media_player-card',
properties: { properties: {
hass: {
type: Object,
},
stateObj: { stateObj: {
type: Object, type: Object,
}, },
@ -54,7 +55,7 @@ export default new Polymer({
}, },
computePlayerObj(stateObj) { computePlayerObj(stateObj) {
return stateObj.domainModel(hass); return stateObj.domainModel(this.hass);
}, },
computePlaybackControlIcon(playerObj) { computePlaybackControlIcon(playerObj) {
@ -77,7 +78,7 @@ export default new Polymer({
handleOpenMoreInfo(ev) { handleOpenMoreInfo(ev) {
ev.stopPropagation(); ev.stopPropagation();
this.async(() => moreInfoActions.selectEntity(this.stateObj.entityId), 1); this.async(() => this.hass.moreInfoActions.selectEntity(this.stateObj.entityId), 1);
}, },
handlePlaybackControl(ev) { handlePlaybackControl(ev) {

View File

@ -1,20 +1,19 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import nuclearObserver from '../util/bound-nuclear-behavior';
const { entityGetters } = hass;
export default new Polymer({ export default new Polymer({
is: 'entity-list', is: 'entity-list',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
hass: {
type: Object,
},
entities: { entities: {
type: Array, type: Array,
bindNuclear: [ bindNuclear: hass => [
entityGetters.entityMap, hass.entityGetters.entityMap,
(map) => map.valueSeq().sortBy((entity) => entity.entityId).toArray(), (map) => map.valueSeq().sortBy((entity) => entity.entityId).toArray(),
], ],
}, },

View File

@ -31,7 +31,7 @@
</template> </template>
<template is='dom-if' if='[[value]]'>[[value]]</template> <template is='dom-if' if='[[value]]'>[[value]]</template>
<template is='dom-if' if='[[image]]'> <template is='dom-if' if='[[image]]'>
<iron-image sizing='cover' class='fit'src='[[image]]'></iron-image> <iron-image sizing='cover' class='fit' src='[[image]]'></iron-image>
</template> </template>
</div> </div>
</template> </template>

View File

@ -1,21 +1,26 @@
import Polymer from '../../polymer'; import Polymer from '../../polymer';
import hass from '../../util/home-assistant-js-instance';
require('../../components/ha-label-badge'); require('../../components/ha-label-badge');
const { /*
reactor, Leaflet clones this element before adding it to the map. This messes up
entityGetters, our Poylmer object and we lose the reference to the `hass` object.
moreInfoActions,
} = hass; That's why we refer here to window.hass instead of the hass property.
*/
export default new Polymer({ export default new Polymer({
is: 'ha-entity-marker', is: 'ha-entity-marker',
properties: { properties: {
hass: {
type: Object,
},
entityId: { entityId: {
type: String, type: String,
value: '', value: '',
reflectToAttribute: true,
}, },
state: { state: {
@ -46,12 +51,12 @@ export default new Polymer({
badgeTap(ev) { badgeTap(ev) {
ev.stopPropagation(); ev.stopPropagation();
if (this.entityId) { if (this.entityId) {
this.async(() => moreInfoActions.selectEntity(this.entityId), 1); this.async(() => window.hass.moreInfoActions.selectEntity(this.entityId), 1);
} }
}, },
computeState(entityId) { computeState(entityId) {
return entityId && reactor.evaluate(entityGetters.byId(entityId)); return entityId && window.hass.reactor.evaluate(window.hass.entityGetters.byId(entityId));
}, },
computeIcon(state) { computeIcon(state) {

View File

@ -1,14 +1,15 @@
import Polymer from '../../polymer'; import Polymer from '../../polymer';
import hass from '../../util/home-assistant-js-instance';
import OFF_STATES from '../../util/off-states'; import OFF_STATES from '../../util/off-states';
const { serviceActions } = hass;
export default new Polymer({ export default new Polymer({
is: 'ha-entity-toggle', is: 'ha-entity-toggle',
properties: { properties: {
hass: {
type: Object,
},
stateObj: { stateObj: {
type: Object, type: Object,
}, },
@ -89,7 +90,7 @@ export default new Polymer({
service = turnOn ? 'turn_on' : 'turn_off'; service = turnOn ? 'turn_on' : 'turn_off';
} }
const call = serviceActions.callService( const call = this.hass.serviceActions.callService(
domain, service, { entity_id: this.stateObj.entityId }); domain, service, { entity_id: this.stateObj.entityId });
if (!this.stateObj.attributes.assumed_state) { if (!this.stateObj.attributes.assumed_state) {

View File

@ -1,18 +1,17 @@
import Polymer from '../../polymer'; import Polymer from '../../polymer';
import hass from '../../util/home-assistant-js-instance';
import domainIcon from '../../util/domain-icon'; import domainIcon from '../../util/domain-icon';
import stateIcon from '../../util/state-icon'; import stateIcon from '../../util/state-icon';
require('../../components/ha-label-badge'); require('../../components/ha-label-badge');
const {
moreInfoActions,
} = hass;
export default new Polymer({ export default new Polymer({
is: 'ha-state-label-badge', is: 'ha-state-label-badge',
properties: { properties: {
hass: {
type: Object,
},
state: { state: {
type: Object, type: Object,
observer: 'stateChanged', observer: 'stateChanged',
@ -25,7 +24,7 @@ export default new Polymer({
badgeTap(ev) { badgeTap(ev) {
ev.stopPropagation(); ev.stopPropagation();
this.async(() => moreInfoActions.selectEntity(this.state.entityId), 1); this.async(() => this.hass.moreInfoActions.selectEntity(this.state.entityId), 1);
}, },
computeClasses(state) { computeClasses(state) {

View File

@ -1,20 +1,19 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import nuclearObserver from '../util/bound-nuclear-behavior';
const { eventGetters } = hass;
export default new Polymer({ export default new Polymer({
is: 'events-list', is: 'events-list',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
hass: {
type: Object,
},
events: { events: {
type: Array, type: Array,
bindNuclear: [ bindNuclear: hass => [
eventGetters.entityMap, hass.eventGetters.entityMap,
(map) => map.valueSeq().sortBy((event) => event.event).toArray(), (map) => map.valueSeq().sortBy((event) => event.event).toArray(),
], ],
}, },

View File

@ -58,7 +58,7 @@
<ha-demo-badge></ha-demo-badge> <ha-demo-badge></ha-demo-badge>
</template> </template>
<ha-badges-card states='[[cards.badges]]'></ha-badges-card> <ha-badges-card states='[[cards.badges]]' hass='[[hass]]'></ha-badges-card>
</div> </div>
</template> </template>
<template is='dom-if' if='[[!cards.badges]]'> <template is='dom-if' if='[[!cards.badges]]'>
@ -70,7 +70,7 @@
<div class='column flex-1'> <div class='column flex-1'>
<template is='dom-repeat' items='[[column]]' as='card'> <template is='dom-repeat' items='[[column]]' as='card'>
<div class='zone-card'> <div class='zone-card'>
<ha-card-chooser card-data='[[card]]' <ha-card-chooser card-data='[[card]]' hass='[[hass]]'
></ha-card-chooser> ></ha-card-chooser>
</div> </div>
</template> </template>

View File

@ -1,12 +1,9 @@
import Polymer from '../polymer'; import Polymer from '../polymer';
import hass from '../util/home-assistant-js-instance';
require('.//ha-demo-badge'); require('.//ha-demo-badge');
require('../cards/ha-badges-card'); require('../cards/ha-badges-card');
require('../cards/ha-card-chooser'); require('../cards/ha-card-chooser');
const { util } = hass;
// mapping domain to size of the card. // mapping domain to size of the card.
const DOMAINS_WITH_CARD = { const DOMAINS_WITH_CARD = {
camera: 4, camera: 4,
@ -38,6 +35,10 @@ export default new Polymer({
is: 'ha-cards', is: 'ha-cards',
properties: { properties: {
hass: {
type: Object,
},
showIntroduction: { showIntroduction: {
type: Boolean, type: Boolean,
value: false, value: false,
@ -70,6 +71,7 @@ export default new Polymer({
}, },
computeCards(columns, states, showIntroduction) { computeCards(columns, states, showIntroduction) {
const hass = this.hass;
const byDomain = states.groupBy(entity => entity.domain); const byDomain = states.groupBy(entity => entity.domain);
const hasGroup = {}; const hasGroup = {};
@ -137,6 +139,7 @@ export default new Polymer({
if (other.length > 0) { if (other.length > 0) {
cards.columns[curIndex].push({ cards.columns[curIndex].push({
hass,
cardType: 'entities', cardType: 'entities',
states: other, states: other,
groupEntity, groupEntity,
@ -145,12 +148,15 @@ export default new Polymer({
owncard.forEach(entity => { owncard.forEach(entity => {
cards.columns[curIndex].push({ cards.columns[curIndex].push({
hass,
cardType: entity.domain, cardType: entity.domain,
stateObj: entity, stateObj: entity,
}); });
}); });
} }
const expandGroup = this.hass.util.expandGroup;
byDomain.keySeq().sortBy(domain => getPriority(domain)) byDomain.keySeq().sortBy(domain => getPriority(domain))
.forEach(domain => { .forEach(domain => {
if (domain === 'a') { if (domain === 'a') {
@ -167,7 +173,7 @@ export default new Polymer({
} else if (domain === 'group') { } else if (domain === 'group') {
byDomain.get(domain).sortBy(entitySortBy) byDomain.get(domain).sortBy(entitySortBy)
.forEach(groupState => { .forEach(groupState => {
const entities = util.expandGroup(groupState, states); const entities = expandGroup(groupState, states);
entities.forEach(entity => { hasGroup[entity.entityId] = true; }); entities.forEach(entity => { hasGroup[entity.entityId] = true; });
addEntitiesCard(groupState.entityId, entities.toArray(), groupState); addEntitiesCard(groupState.entityId, entities.toArray(), groupState);
} }

View File

@ -140,7 +140,7 @@
<paper-item class='horizontal layout justified'> <paper-item class='horizontal layout justified'>
<div class='streaming'>Streaming updates</div> <div class='streaming'>Streaming updates</div>
<stream-status></stream-status> <stream-status hass='[[hass]]'></stream-status>
</paper-item> </paper-item>
<div class='divider'></div> <div class='divider'></div>

View File

@ -1,23 +1,17 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import nuclearObserver from '../util/bound-nuclear-behavior';
require('./stream-status'); require('./stream-status');
const {
configGetters,
navigationGetters,
authActions,
navigationActions,
} = hass;
export default new Polymer({ export default new Polymer({
is: 'ha-sidebar', is: 'ha-sidebar',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
hass: {
type: Object,
},
menuShown: { menuShown: {
type: Boolean, type: Boolean,
}, },
@ -32,17 +26,17 @@ export default new Polymer({
selected: { selected: {
type: String, type: String,
bindNuclear: navigationGetters.activePane, bindNuclear: hass => hass.navigationGetters.activePane,
}, },
hasHistoryComponent: { hasHistoryComponent: {
type: Boolean, type: Boolean,
bindNuclear: configGetters.isComponentLoaded('history'), bindNuclear: hass => hass.configGetters.isComponentLoaded('history'),
}, },
hasLogbookComponent: { hasLogbookComponent: {
type: Boolean, type: Boolean,
bindNuclear: configGetters.isComponentLoaded('logbook'), bindNuclear: hass => hass.configGetters.isComponentLoaded('logbook'),
}, },
}, },
@ -76,11 +70,11 @@ export default new Polymer({
this.handleLogOut(); this.handleLogOut();
return; return;
} }
navigationActions.navigate.apply(null, newChoice.split('/')); this.hass.navigationActions.navigate.apply(null, newChoice.split('/'));
this.debounce('updateStyles', () => this.updateStyles(), 1); this.debounce('updateStyles', () => this.updateStyles(), 1);
}, },
handleLogOut() { handleLogOut() {
authActions.logOut(); this.hass.authActions.logOut();
}, },
}); });

View File

@ -1,37 +1,32 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import nuclearObserver from '../util/bound-nuclear-behavior';
const {
configGetters,
viewActions,
viewGetters,
} = hass;
export default new Polymer({ export default new Polymer({
is: 'ha-view-tabs', is: 'ha-view-tabs',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
hass: {
type: Object,
},
locationName: { locationName: {
type: String, type: String,
bindNuclear: configGetters.locationName, bindNuclear: hass => hass.configGetters.locationName,
}, },
currentView: { currentView: {
type: String, type: String,
bindNuclear: [ bindNuclear: hass => [
viewGetters.currentView, hass.viewGetters.currentView,
view => view || '', view => view || '',
], ],
}, },
views: { views: {
type: Array, type: Array,
bindNuclear: [ bindNuclear: hass => [
viewGetters.views, hass.viewGetters.views,
views => views.valueSeq() views => views.valueSeq()
.sortBy(view => view.attributes.order) .sortBy(view => view.attributes.order)
.toArray(), .toArray(),
@ -48,7 +43,7 @@ export default new Polymer({
const current = this.currentView || null; const current = this.currentView || null;
this.expectChange = true; this.expectChange = true;
if (view !== current) { if (view !== current) {
this.async(() => viewActions.selectView(view), 0); this.async(() => this.hass.viewActions.selectView(view), 0);
} }
}, },
}); });

View File

@ -1,18 +1,20 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
require('./domain-icon'); require('./domain-icon');
require('./display-time'); require('./display-time');
require('./relative-ha-datetime'); require('./relative-ha-datetime');
const { moreInfoActions } = hass;
export default new Polymer({ export default new Polymer({
is: 'logbook-entry', is: 'logbook-entry',
properties: {
hass: {
type: Object,
},
},
entityClicked(ev) { entityClicked(ev) {
ev.preventDefault(); ev.preventDefault();
moreInfoActions.selectEntity(this.entryObj.entityId); this.hass.moreInfoActions.selectEntity(this.entryObj.entityId);
}, },
}); });

View File

@ -1,11 +1,7 @@
import moment from 'moment';
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
const UPDATE_INTERVAL = 60000; // 60 seconds const UPDATE_INTERVAL = 60000; // 60 seconds
const { util: { parseDateTime } } = hass;
export default new Polymer({ export default new Polymer({
is: 'relative-ha-datetime', is: 'relative-ha-datetime',
@ -43,7 +39,7 @@ export default new Polymer({
}, },
datetimeChanged(newVal) { datetimeChanged(newVal) {
this.parsedDateTime = newVal ? parseDateTime(newVal) : null; this.parsedDateTime = newVal ? new Date(newVal) : null;
this.updateRelative(); this.updateRelative();
}, },
@ -56,6 +52,6 @@ export default new Polymer({
updateRelative() { updateRelative() {
this.relativeTime = this.parsedDateTime ? this.relativeTime = this.parsedDateTime ?
moment(this.parsedDateTime).fromNow() : ''; window.moment(this.parsedDateTime).fromNow() : '';
}, },
}); });

View File

@ -1,21 +1,20 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import nuclearObserver from '../util/bound-nuclear-behavior';
require('./domain-icon'); require('./domain-icon');
const { serviceGetters } = hass;
export default new Polymer({ export default new Polymer({
is: 'services-list', is: 'services-list',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
hass: {
type: Object,
},
serviceDomains: { serviceDomains: {
type: Array, type: Array,
bindNuclear: serviceGetters.entityMap, bindNuclear: hass => hass.serviceGetters.entityMap,
}, },
}, },

View File

@ -1,7 +1,15 @@
import range from 'lodash/range';
import Polymer from '../polymer'; import Polymer from '../polymer';
function range(start, end) {
const result = [];
for (let i = start; i < end; i++) {
result.push(i);
}
return result;
}
function saveParseFloat(value) { function saveParseFloat(value) {
const parsed = parseFloat(value); const parsed = parseFloat(value);
return !isNaN(parsed) && isFinite(parsed) ? parsed : null; return !isNaN(parsed) && isFinite(parsed) ? parsed : null;

View File

@ -1,32 +1,31 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import nuclearObserver from '../util/bound-nuclear-behavior';
const { streamGetters, streamActions } = hass;
export default new Polymer({ export default new Polymer({
is: 'stream-status', is: 'stream-status',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
hass: {
type: Object,
},
isStreaming: { isStreaming: {
type: Boolean, type: Boolean,
bindNuclear: streamGetters.isStreamingEvents, bindNuclear: hass => hass.streamGetters.isStreamingEvents,
}, },
hasError: { hasError: {
type: Boolean, type: Boolean,
bindNuclear: streamGetters.hasStreamingEventsError, bindNuclear: hass => hass.streamGetters.hasStreamingEventsError,
}, },
}, },
toggleChanged() { toggleChanged() {
if (this.isStreaming) { if (this.isStreaming) {
streamActions.stop(); this.hass.streamActions.stop();
} else { } else {
streamActions.start(); this.hass.streamActions.start();
} }
}, },
}); });

View File

@ -1,19 +1,15 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import nuclearObserver from '../util/bound-nuclear-behavior';
const {
voiceActions,
voiceGetters,
} = hass;
export default new Polymer({ export default new Polymer({
is: 'ha-voice-command-dialog', is: 'ha-voice-command-dialog',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
hass: {
type: Object,
},
dialogOpen: { dialogOpen: {
type: Boolean, type: Boolean,
value: false, value: false,
@ -22,22 +18,22 @@ export default new Polymer({
finalTranscript: { finalTranscript: {
type: String, type: String,
bindNuclear: voiceGetters.finalTranscript, bindNuclear: hass => hass.voiceGetters.finalTranscript,
}, },
interimTranscript: { interimTranscript: {
type: String, type: String,
bindNuclear: voiceGetters.extraInterimTranscript, bindNuclear: hass => hass.voiceGetters.extraInterimTranscript,
}, },
isTransmitting: { isTransmitting: {
type: Boolean, type: Boolean,
bindNuclear: voiceGetters.isTransmitting, bindNuclear: hass => hass.voiceGetters.isTransmitting,
}, },
isListening: { isListening: {
type: Boolean, type: Boolean,
bindNuclear: voiceGetters.isListening, bindNuclear: hass => hass.voiceGetters.isListening,
}, },
showListenInterface: { showListenInterface: {
@ -53,7 +49,7 @@ export default new Polymer({
dialogOpenChanged(newVal) { dialogOpenChanged(newVal) {
if (!newVal && this.isListening) { if (!newVal && this.isListening) {
voiceActions.stop(); this.hass.voiceActions.stop();
} }
}, },

View File

@ -37,13 +37,18 @@
<template> <template>
<!-- entry-animation='slide-up-animation' exit-animation='slide-down-animation' --> <!-- entry-animation='slide-up-animation' exit-animation='slide-down-animation' -->
<paper-dialog id="dialog" with-backdrop opened='{{dialogOpen}}'> <paper-dialog id="dialog" with-backdrop opened='{{dialogOpen}}'>
<h2><state-card-content state-obj="[[stateObj]]" in-dialog></state-card-content></h2> <h2>
<state-card-content
state-obj="[[stateObj]]"
hass='[[hass]]' in-dialog></state-card-content>
</h2>
<paper-dialog-scrollable> <paper-dialog-scrollable>
<template is='dom-if' if="[[showHistoryComponent]]"> <template is='dom-if' if="[[showHistoryComponent]]">
<state-history-charts state-history="[[stateHistory]]" <state-history-charts state-history="[[stateHistory]]"
is-loading-data="[[isLoadingHistoryData]]"></state-history-charts> is-loading-data="[[isLoadingHistoryData]]"></state-history-charts>
</template> </template>
<more-info-content state-obj="[[stateObj]]"></more-info-content> <more-info-content
state-obj="[[stateObj]]" hass='[[hass]]'></more-info-content>
</paper-dialog-scrollable> </paper-dialog-scrollable>
</paper-dialog> </paper-dialog>
</template> </template>

View File

@ -1,38 +1,27 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import nuclearObserver from '../util/bound-nuclear-behavior';
require('../state-summary/state-card-content'); require('../state-summary/state-card-content');
require('../components/state-history-charts'); require('../components/state-history-charts');
require('../more-infos/more-info-content'); require('../more-infos/more-info-content');
const {
configGetters,
entityHistoryGetters,
entityHistoryActions,
moreInfoGetters,
moreInfoActions,
} = hass;
const DOMAINS_WITH_NO_HISTORY = ['camera', 'configurator', 'scene']; const DOMAINS_WITH_NO_HISTORY = ['camera', 'configurator', 'scene'];
export default new Polymer({ export default new Polymer({
is: 'more-info-dialog', is: 'more-info-dialog',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
stateObj: { stateObj: {
type: Object, type: Object,
bindNuclear: moreInfoGetters.currentEntity, bindNuclear: hass => hass.moreInfoGetters.currentEntity,
observer: 'stateObjChanged', observer: 'stateObjChanged',
}, },
stateHistory: { stateHistory: {
type: Object, type: Object,
bindNuclear: [ bindNuclear: hass => [
moreInfoGetters.currentEntityHistory, hass.moreInfoGetters.currentEntityHistory,
(history) => (history ? [history] : false), (history) => (history ? [history] : false),
], ],
}, },
@ -44,18 +33,18 @@ export default new Polymer({
isLoadingEntityHistoryData: { isLoadingEntityHistoryData: {
type: Boolean, type: Boolean,
bindNuclear: entityHistoryGetters.isLoadingEntityHistory, bindNuclear: hass => hass.entityHistoryGetters.isLoadingEntityHistory,
}, },
hasHistoryComponent: { hasHistoryComponent: {
type: Boolean, type: Boolean,
bindNuclear: configGetters.isComponentLoaded('history'), bindNuclear: hass => hass.configGetters.isComponentLoaded('history'),
observer: 'fetchHistoryData', observer: 'fetchHistoryData',
}, },
shouldFetchHistory: { shouldFetchHistory: {
type: Boolean, type: Boolean,
bindNuclear: moreInfoGetters.isCurrentEntityHistoryStale, bindNuclear: hass => hass.moreInfoGetters.isCurrentEntityHistoryStale,
observer: 'fetchHistoryData', observer: 'fetchHistoryData',
}, },
@ -95,7 +84,7 @@ export default new Polymer({
fetchHistoryData() { fetchHistoryData() {
if (this.stateObj && this.hasHistoryComponent && if (this.stateObj && this.hasHistoryComponent &&
this.shouldFetchHistory) { this.shouldFetchHistory) {
entityHistoryActions.fetchRecent(this.stateObj.entityId); this.hass.entityHistoryActions.fetchRecent(this.stateObj.entityId);
} }
}, },
@ -118,7 +107,7 @@ export default new Polymer({
if (newVal) { if (newVal) {
this.async(() => { this.delayedDialogOpen = true; }, 10); this.async(() => { this.delayedDialogOpen = true; }, 10);
} else if (!newVal && this.stateObj) { } else if (!newVal && this.stateObj) {
this.async(() => moreInfoActions.deselectEntity(), 10); this.async(() => this.hass.moreInfoActions.deselectEntity(), 10);
this.delayedDialogOpen = false; this.delayedDialogOpen = false;
} }
}, },

View File

@ -22,12 +22,14 @@
<template> <template>
<template is='dom-if' if='[[!loaded]]'> <template is='dom-if' if='[[!loaded]]'>
<login-form force-show-loading='[[computeForceShowLoading(dataLoaded, iconsLoaded)]]'> <login-form
hass='[[hass]]'
force-show-loading='[[computeForceShowLoading(dataLoaded, iconsLoaded)]]'>
</login-form> </login-form>
</template> </template>
<template is='dom-if' if='[[loaded]]'> <template is='dom-if' if='[[loaded]]'>
<home-assistant-main></home-assistant-main> <home-assistant-main hass='[[hass]]'></home-assistant-main>
</template> </template>
</template> </template>
</dom-module> </dom-module>

View File

@ -1,20 +1,18 @@
import moment from 'moment';
import Polymer from './polymer'; import Polymer from './polymer';
import hass from './util/home-assistant-js-instance'; import HomeAssistant from 'home-assistant-js';
import nuclearObserver from './util/bound-nuclear-behavior';
import validateAuth from './util/validate-auth'; import validateAuth from './util/validate-auth';
import hassBehavior from './util/hass-behavior';
window.hassBehavior = hassBehavior;
window.moment = moment;
require('./layouts/login-form'); require('./layouts/login-form');
require('./layouts/home-assistant-main'); require('./layouts/home-assistant-main');
const { // While we figure out how ha-entity-marker can keep it's references
localStoragePreferences, window.hass = new HomeAssistant();
navigationActions,
reactor,
startLocalStoragePreferencesSync,
syncGetters,
} = hass;
export default new Polymer({ export default new Polymer({
is: 'home-assistant', is: 'home-assistant',
@ -24,9 +22,13 @@ export default new Polymer({
icons: null, icons: null,
}, },
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
hass: {
type: Object,
value: window.hass,
},
auth: { auth: {
type: String, type: String,
}, },
@ -35,7 +37,7 @@ export default new Polymer({
}, },
dataLoaded: { dataLoaded: {
type: Boolean, type: Boolean,
bindNuclear: syncGetters.isDataLoaded, bindNuclear: hass => hass.syncGetters.isDataLoaded,
}, },
iconsLoaded: { iconsLoaded: {
type: Boolean, type: Boolean,
@ -65,26 +67,6 @@ export default new Polymer({
}, },
created() { created() {
this.registerServiceWorker();
},
ready() {
reactor.batch(() => {
// if auth was given, tell the backend
if (this.auth) {
validateAuth(this.auth, false);
} else if (localStoragePreferences.authToken) {
validateAuth(localStoragePreferences.authToken, true);
}
navigationActions.showSidebar(localStoragePreferences.showSidebar);
});
startLocalStoragePreferencesSync();
this.loadIcons();
},
registerServiceWorker() {
if (!('serviceWorker' in navigator)) { if (!('serviceWorker' in navigator)) {
return; return;
} }
@ -97,4 +79,21 @@ export default new Polymer({
} }
}); });
}, },
ready() {
const hass = this.hass;
hass.reactor.batch(() => {
// if auth was given, tell the backend
if (this.auth) {
validateAuth(this.hass, this.auth, false);
} else if (hass.localStoragePreferences.authToken) {
validateAuth(this.hass, hass.localStoragePreferences.authToken, true);
}
hass.navigationActions.showSidebar(hass.localStoragePreferences.showSidebar);
});
hass.startLocalStoragePreferencesSync();
this.loadIcons();
},
}); });

View File

@ -18,9 +18,9 @@
<dom-module id='home-assistant-main'> <dom-module id='home-assistant-main'>
<template> <template>
<notification-manager></notification-manager> <notification-manager hass='[[hass]]'></notification-manager>
<more-info-dialog></more-info-dialog> <more-info-dialog hass='[[hass]]'></more-info-dialog>
<ha-voice-command-dialog></ha-voice-command-dialog> <ha-voice-command-dialog hass='[[hass]]'></ha-voice-command-dialog>
<iron-media-query query="(max-width: 870px)" query-matches="{{narrow}}"> <iron-media-query query="(max-width: 870px)" query-matches="{{narrow}}">
</iron-media-query> </iron-media-query>
@ -28,34 +28,34 @@
force-narrow='[[computeForceNarrow(narrow, showSidebar)]]' force-narrow='[[computeForceNarrow(narrow, showSidebar)]]'
responsive-width='0' disable-swipe='[[isSelectedMap]]' responsive-width='0' disable-swipe='[[isSelectedMap]]'
disable-edge-swipe='[[isSelectedMap]]'> disable-edge-swipe='[[isSelectedMap]]'>
<ha-sidebar drawer narrow='[[narrow]]'></ha-sidebar> <ha-sidebar drawer narrow='[[narrow]]' hass='[[hass]]'></ha-sidebar>
<template is='dom-if' if='[[isSelectedStates]]'> <template is='dom-if' if='[[isSelectedStates]]'>
<partial-cards main narrow='[[narrow]]' show-menu='[[showSidebar]]'></partial-cards> <partial-cards main narrow='[[narrow]]' hass='[[hass]]' show-menu='[[showSidebar]]'></partial-cards>
</template> </template>
<template is='dom-if' if='[[isSelectedLogbook]]'> <template is='dom-if' if='[[isSelectedLogbook]]'>
<partial-logbook main narrow='[[narrow]]' show-menu='[[showSidebar]]'></partial-logbook> <partial-logbook main narrow='[[narrow]]' hass='[[hass]]' show-menu='[[showSidebar]]'></partial-logbook>
</template> </template>
<template is='dom-if' if='[[isSelectedHistory]]'> <template is='dom-if' if='[[isSelectedHistory]]'>
<partial-history main narrow='[[narrow]]' show-menu='[[showSidebar]]'></partial-history> <partial-history main narrow='[[narrow]]' hass='[[hass]]' show-menu='[[showSidebar]]'></partial-history>
</template> </template>
<template is='dom-if' if='[[isSelectedMap]]'> <template is='dom-if' if='[[isSelectedMap]]'>
<partial-map main narrow='[[narrow]]' show-menu='[[showSidebar]]'></partial-map> <partial-map main narrow='[[narrow]]' hass='[[hass]]' show-menu='[[showSidebar]]'></partial-map>
</template> </template>
<template is='dom-if' if='[[isSelectedDevService]]'> <template is='dom-if' if='[[isSelectedDevService]]'>
<partial-dev-call-service main narrow='[[narrow]]' show-menu='[[showSidebar]]'></partial-dev-call-service> <partial-dev-call-service main narrow='[[narrow]]' hass='[[hass]]' show-menu='[[showSidebar]]'></partial-dev-call-service>
</template> </template>
<template is='dom-if' if='[[isSelectedDevEvent]]'> <template is='dom-if' if='[[isSelectedDevEvent]]'>
<partial-dev-fire-event main narrow='[[narrow]]' show-menu='[[showSidebar]]'></partial-dev-fire-event> <partial-dev-fire-event main narrow='[[narrow]]' hass='[[hass]]' show-menu='[[showSidebar]]'></partial-dev-fire-event>
</template> </template>
<template is='dom-if' if='[[isSelectedDevState]]'> <template is='dom-if' if='[[isSelectedDevState]]'>
<partial-dev-set-state main narrow='[[narrow]]' show-menu='[[showSidebar]]'></partial-dev-set-state> <partial-dev-set-state main narrow='[[narrow]]' hass='[[hass]]' show-menu='[[showSidebar]]'></partial-dev-set-state>
</template> </template>
<template is='dom-if' if='[[isSelectedDevTemplate]]'> <template is='dom-if' if='[[isSelectedDevTemplate]]'>
<partial-dev-template main narrow='[[narrow]]' show-menu='[[showSidebar]]'></partial-dev-template> <partial-dev-template main narrow='[[narrow]]' hass='[[hass]]' show-menu='[[showSidebar]]'></partial-dev-template>
</template> </template>
<template is='dom-if' if='[[isSelectedDevInfo]]'> <template is='dom-if' if='[[isSelectedDevInfo]]'>
<partial-dev-info main narrow='[[narrow]]' show-menu='[[showSidebar]]'></partial-dev-info> <partial-dev-info main narrow='[[narrow]]' hass='[[hass]]' show-menu='[[showSidebar]]'></partial-dev-info>
</template> </template>
</paper-drawer-panel> </paper-drawer-panel>

View File

@ -1,7 +1,5 @@
import Polymer from '../polymer'; import Polymer from '../polymer';
import hass from '../util/home-assistant-js-instance';
import nuclearObserver from '../util/bound-nuclear-behavior';
import removeInitMsg from '../util/remove-init-message'; import removeInitMsg from '../util/remove-init-message';
require('../components/ha-sidebar'); require('../components/ha-sidebar');
@ -18,19 +16,23 @@ require('../managers/notification-manager');
require('../dialogs/more-info-dialog'); require('../dialogs/more-info-dialog');
require('../dialogs/ha-voice-command-dialog'); require('../dialogs/ha-voice-command-dialog');
const { // const {
navigationActions, // navigationActions,
navigationGetters, // navigationGetters,
startUrlSync, // startUrlSync,
stopUrlSync, // stopUrlSync,
} = hass; // } = hass;
export default new Polymer({ export default new Polymer({
is: 'home-assistant-main', is: 'home-assistant-main',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
hass: {
type: Object,
},
narrow: { narrow: {
type: Boolean, type: Boolean,
value: false, value: false,
@ -38,58 +40,58 @@ export default new Polymer({
activePane: { activePane: {
type: String, type: String,
bindNuclear: navigationGetters.activePane, bindNuclear: hass => hass.navigationGetters.activePane,
observer: 'activePaneChanged', observer: 'activePaneChanged',
}, },
isSelectedStates: { isSelectedStates: {
type: Boolean, type: Boolean,
bindNuclear: navigationGetters.isActivePane('states'), bindNuclear: hass => hass.navigationGetters.isActivePane('states'),
}, },
isSelectedHistory: { isSelectedHistory: {
type: Boolean, type: Boolean,
bindNuclear: navigationGetters.isActivePane('history'), bindNuclear: hass => hass.navigationGetters.isActivePane('history'),
}, },
isSelectedMap: { isSelectedMap: {
type: Boolean, type: Boolean,
bindNuclear: navigationGetters.isActivePane('map'), bindNuclear: hass => hass.navigationGetters.isActivePane('map'),
}, },
isSelectedLogbook: { isSelectedLogbook: {
type: Boolean, type: Boolean,
bindNuclear: navigationGetters.isActivePane('logbook'), bindNuclear: hass => hass.navigationGetters.isActivePane('logbook'),
}, },
isSelectedDevEvent: { isSelectedDevEvent: {
type: Boolean, type: Boolean,
bindNuclear: navigationGetters.isActivePane('devEvent'), bindNuclear: hass => hass.navigationGetters.isActivePane('devEvent'),
}, },
isSelectedDevState: { isSelectedDevState: {
type: Boolean, type: Boolean,
bindNuclear: navigationGetters.isActivePane('devState'), bindNuclear: hass => hass.navigationGetters.isActivePane('devState'),
}, },
isSelectedDevTemplate: { isSelectedDevTemplate: {
type: Boolean, type: Boolean,
bindNuclear: navigationGetters.isActivePane('devTemplate'), bindNuclear: hass => hass.navigationGetters.isActivePane('devTemplate'),
}, },
isSelectedDevService: { isSelectedDevService: {
type: Boolean, type: Boolean,
bindNuclear: navigationGetters.isActivePane('devService'), bindNuclear: hass => hass.navigationGetters.isActivePane('devService'),
}, },
isSelectedDevInfo: { isSelectedDevInfo: {
type: Boolean, type: Boolean,
bindNuclear: navigationGetters.isActivePane('devInfo'), bindNuclear: hass => hass.navigationGetters.isActivePane('devInfo'),
}, },
showSidebar: { showSidebar: {
type: Boolean, type: Boolean,
bindNuclear: navigationGetters.showSidebar, bindNuclear: hass => hass.navigationGetters.showSidebar,
}, },
}, },
@ -102,14 +104,14 @@ export default new Polymer({
if (this.narrow) { if (this.narrow) {
this.$.drawer.openDrawer(); this.$.drawer.openDrawer();
} else { } else {
navigationActions.showSidebar(true); this.hass.navigationActions.showSidebar(true);
} }
}, },
closeMenu() { closeMenu() {
this.$.drawer.closeDrawer(); this.$.drawer.closeDrawer();
if (this.showSidebar) { if (this.showSidebar) {
navigationActions.showSidebar(false); this.hass.navigationActions.showSidebar(false);
} }
}, },
@ -121,7 +123,7 @@ export default new Polymer({
attached() { attached() {
removeInitMsg(); removeInitMsg();
startUrlSync(); this.hass.startUrlSync();
}, },
computeForceNarrow(narrow, showSidebar) { computeForceNarrow(narrow, showSidebar) {
@ -129,6 +131,6 @@ export default new Polymer({
}, },
detached() { detached() {
stopUrlSync(); this.hass.stopUrlSync();
}, },
}); });

View File

@ -1,33 +1,32 @@
import Polymer from '../polymer'; import Polymer from '../polymer';
import hass from '../util/home-assistant-js-instance';
import nuclearObserver from '../util/bound-nuclear-behavior';
import validateAuth from '../util/validate-auth'; import validateAuth from '../util/validate-auth';
import removeInitMsg from '../util/remove-init-message'; import removeInitMsg from '../util/remove-init-message';
const { authGetters } = hass;
export default new Polymer({ export default new Polymer({
is: 'login-form', is: 'login-form',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
hass: {
type: Object,
},
errorMessage: { errorMessage: {
type: String, type: String,
bindNuclear: authGetters.attemptErrorMessage, bindNuclear: hass => hass.authGetters.attemptErrorMessage,
}, },
isInvalid: { isInvalid: {
type: Boolean, type: Boolean,
bindNuclear: authGetters.isInvalidAttempt, bindNuclear: hass => hass.authGetters.isInvalidAttempt,
}, },
isValidating: { isValidating: {
type: Boolean, type: Boolean,
observer: 'isValidatingChanged', observer: 'isValidatingChanged',
bindNuclear: authGetters.isValidating, bindNuclear: hass => hass.authGetters.isValidating,
}, },
loadingResources: { loadingResources: {
@ -89,6 +88,6 @@ export default new Polymer({
validatePassword() { validatePassword() {
this.$.hideKeyboardOnFocus.focus(); this.$.hideKeyboardOnFocus.focus();
validateAuth(this.$.passwordInput.value, this.$.rememberLogin.checked); validateAuth(this.hass, this.$.passwordInput.value, this.$.rememberLogin.checked);
}, },
}); });

View File

@ -65,14 +65,14 @@
<template is='dom-if' if='[[hasViews]]'> <template is='dom-if' if='[[hasViews]]'>
<div class='fit bottom views'> <div class='fit bottom views'>
<ha-view-tabs on-view-tapped='scrollToTop'></ha-view-tabs> <ha-view-tabs hass='[[hass]]' on-view-tapped='scrollToTop'></ha-view-tabs>
</div> </div>
</template> </template>
</paper-toolbar> </paper-toolbar>
<ha-cards <ha-cards
show-introduction='[[computeShowIntroduction(currentView, introductionLoaded, states)]]' show-introduction='[[computeShowIntroduction(currentView, introductionLoaded, states)]]'
states='[[states]]' columns='[[columns]]'></ha-cards> states='[[states]]' columns='[[columns]]' hass='[[hass]]'></ha-cards>
</paper-header-panel> </paper-header-panel>
</template> </template>

View File

@ -1,28 +1,19 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import nuclearObserver from '../util/bound-nuclear-behavior';
require('./partial-base'); require('./partial-base');
require('../components/ha-cards'); require('../components/ha-cards');
require('../components/ha-view-tabs'); require('../components/ha-view-tabs');
const {
configGetters,
viewGetters,
voiceGetters,
streamGetters,
syncGetters,
syncActions,
voiceActions,
} = hass;
export default new Polymer({ export default new Polymer({
is: 'partial-cards', is: 'partial-cards',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
hass: {
type: Object,
},
narrow: { narrow: {
type: Boolean, type: Boolean,
value: false, value: false,
@ -30,31 +21,31 @@ export default new Polymer({
isFetching: { isFetching: {
type: Boolean, type: Boolean,
bindNuclear: syncGetters.isFetching, bindNuclear: hass => hass.syncGetters.isFetching,
}, },
isStreaming: { isStreaming: {
type: Boolean, type: Boolean,
bindNuclear: streamGetters.isStreamingEvents, bindNuclear: hass => hass.streamGetters.isStreamingEvents,
}, },
canListen: { canListen: {
type: Boolean, type: Boolean,
bindNuclear: [ bindNuclear: hass => [
voiceGetters.isVoiceSupported, hass.voiceGetters.isVoiceSupported,
configGetters.isComponentLoaded('conversation'), hass.configGetters.isComponentLoaded('conversation'),
(isVoiceSupported, componentLoaded) => isVoiceSupported && componentLoaded, (isVoiceSupported, componentLoaded) => isVoiceSupported && componentLoaded,
], ],
}, },
introductionLoaded: { introductionLoaded: {
type: Boolean, type: Boolean,
bindNuclear: configGetters.isComponentLoaded('introduction'), bindNuclear: hass => hass.configGetters.isComponentLoaded('introduction'),
}, },
locationName: { locationName: {
type: String, type: String,
bindNuclear: configGetters.locationName, bindNuclear: hass => hass.configGetters.locationName,
}, },
showMenu: { showMenu: {
@ -65,23 +56,23 @@ export default new Polymer({
currentView: { currentView: {
type: String, type: String,
bindNuclear: [ bindNuclear: hass => [
viewGetters.currentView, hass.viewGetters.currentView,
view => view || '', view => view || '',
], ],
}, },
hasViews: { hasViews: {
type: Boolean, type: Boolean,
bindNuclear: [ bindNuclear: hass => [
viewGetters.views, hass.viewGetters.views,
views => views.size > 0, views => views.size > 0,
], ],
}, },
states: { states: {
type: Object, type: Object,
bindNuclear: viewGetters.currentViewEntities, bindNuclear: hass => hass.viewGetters.currentViewEntities,
}, },
columns: { columns: {
@ -136,11 +127,11 @@ export default new Polymer({
}, },
handleRefresh() { handleRefresh() {
syncActions.fetchAll(); this.hass.syncActions.fetchAll();
}, },
handleListenClick() { handleListenClick() {
voiceActions.listen(); this.hass.voiceActions.listen();
}, },
headerScrollAdjust(ev) { headerScrollAdjust(ev) {

View File

@ -1,20 +1,16 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
require('./partial-base'); require('./partial-base');
require('../components/services-list'); require('../components/services-list');
const {
reactor,
serviceActions,
serviceGetters,
} = hass;
export default new Polymer({ export default new Polymer({
is: 'partial-dev-call-service', is: 'partial-dev-call-service',
properties: { properties: {
hass: {
type: Object,
},
narrow: { narrow: {
type: Boolean, type: Boolean,
value: false, value: false,
@ -42,13 +38,13 @@ export default new Polymer({
description: { description: {
type: String, type: String,
computed: 'computeDescription(domain, service)', computed: 'computeDescription(hass, domain, service)',
}, },
}, },
computeDescription(domain, service) { computeDescription(hass, domain, service) {
return reactor.evaluate([ return hass.reactor.evaluate([
serviceGetters.entityMap, hass.serviceGetters.entityMap,
map => (map.has(domain) && map.get(domain).get('services').has(service) ? map => (map.has(domain) && map.get(domain).get('services').has(service) ?
JSON.stringify(map.get(domain).get('services').get(service).toJS(), null, 2) : JSON.stringify(map.get(domain).get('services').get(service).toJS(), null, 2) :
'No description available'), 'No description available'),
@ -71,7 +67,7 @@ export default new Polymer({
return; return;
} }
serviceActions.callService(this.domain, this.service, serviceData); this.hass.serviceActions.callService(this.domain, this.service, serviceData);
}, },
computeFormClasses(narrow) { computeFormClasses(narrow) {

View File

@ -1,16 +1,16 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
require('./partial-base'); require('./partial-base');
require('../components/events-list'); require('../components/events-list');
const { eventActions } = hass;
export default new Polymer({ export default new Polymer({
is: 'partial-dev-fire-event', is: 'partial-dev-fire-event',
properties: { properties: {
hass: {
type: Object,
},
narrow: { narrow: {
type: Boolean, type: Boolean,
value: false, value: false,
@ -48,7 +48,7 @@ export default new Polymer({
return; return;
} }
eventActions.fireEvent(this.eventType, eventData); this.hass.eventActions.fireEvent(this.eventType, eventData);
}, },
computeFormClasses(narrow) { computeFormClasses(narrow) {

View File

@ -1,21 +1,17 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import nuclearObserver from '../util/bound-nuclear-behavior';
require('./partial-base'); require('./partial-base');
const {
configGetters,
errorLogActions,
} = hass;
export default new Polymer({ export default new Polymer({
is: 'partial-dev-info', is: 'partial-dev-info',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
hass: {
type: Object,
},
narrow: { narrow: {
type: Boolean, type: Boolean,
value: false, value: false,
@ -28,7 +24,7 @@ export default new Polymer({
hassVersion: { hassVersion: {
type: String, type: String,
bindNuclear: configGetters.serverVersion, bindNuclear: hass => hass.configGetters.serverVersion,
}, },
polymerVersion: { polymerVersion: {
@ -56,7 +52,7 @@ export default new Polymer({
this.errorLog = 'Loading error log…'; this.errorLog = 'Loading error log…';
errorLogActions.fetchErrorLog().then( this.hass.errorLogActions.fetchErrorLog().then(
log => { this.errorLog = log || 'No errors have been reported.'; }); log => { this.errorLog = log || 'No errors have been reported.'; });
}, },
}); });

View File

@ -1,16 +1,16 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
require('./partial-base'); require('./partial-base');
require('../components/entity-list'); require('../components/entity-list');
const { reactor, entityGetters, entityActions } = hass;
export default new Polymer({ export default new Polymer({
is: 'partial-dev-set-state', is: 'partial-dev-set-state',
properties: { properties: {
hass: {
type: Object,
},
narrow: { narrow: {
type: Boolean, type: Boolean,
value: false, value: false,
@ -47,7 +47,7 @@ export default new Polymer({
}, },
entitySelected(ev) { entitySelected(ev) {
const state = reactor.evaluate(entityGetters.byId(ev.detail.entityId)); const state = this.hass.reactor.evaluate(this.hass.entityGetters.byId(ev.detail.entityId));
this.entityId = state.entityId; this.entityId = state.entityId;
this.state = state.state; this.state = state.state;
@ -65,7 +65,7 @@ export default new Polymer({
return; return;
} }
entityActions.save({ this.hass.entityActions.save({
entityId: this.entityId, entityId: this.entityId,
state: this.state, state: this.state,
attributes: attr, attributes: attr,

View File

@ -1,20 +1,17 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import nuclearObserver from '../util/bound-nuclear-behavior';
require('./partial-base'); require('./partial-base');
const {
templateActions,
} = hass;
export default new Polymer({ export default new Polymer({
is: 'partial-dev-template', is: 'partial-dev-template',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
hass: {
type: Object,
},
narrow: { narrow: {
type: Boolean, type: Boolean,
value: false, value: false,
@ -84,7 +81,7 @@ export default new Polymer({
renderTemplate() { renderTemplate() {
this.rendering = true; this.rendering = true;
templateActions.render(this.template).then(processed => { this.hass.templateActions.render(this.template).then(processed => {
this.processed = processed; this.processed = processed;
this.rendering = false; this.rendering = false;
}, error => { }, error => {

View File

@ -1,22 +1,18 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import nuclearObserver from '../util/bound-nuclear-behavior';
require('./partial-base'); require('./partial-base');
require('../components/state-history-charts'); require('../components/state-history-charts');
const {
entityHistoryGetters,
entityHistoryActions,
} = hass;
export default new Polymer({ export default new Polymer({
is: 'partial-history', is: 'partial-history',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
hass: {
type: Object,
},
narrow: { narrow: {
type: Boolean, type: Boolean,
}, },
@ -28,35 +24,35 @@ export default new Polymer({
isDataLoaded: { isDataLoaded: {
type: Boolean, type: Boolean,
bindNuclear: entityHistoryGetters.hasDataForCurrentDate, bindNuclear: hass => hass.entityHistoryGetters.hasDataForCurrentDate,
observer: 'isDataLoadedChanged', observer: 'isDataLoadedChanged',
}, },
stateHistory: { stateHistory: {
type: Object, type: Object,
bindNuclear: entityHistoryGetters.entityHistoryForCurrentDate, bindNuclear: hass => hass.entityHistoryGetters.entityHistoryForCurrentDate,
}, },
isLoadingData: { isLoadingData: {
type: Boolean, type: Boolean,
bindNuclear: entityHistoryGetters.isLoadingEntityHistory, bindNuclear: hass => hass.entityHistoryGetters.isLoadingEntityHistory,
}, },
selectedDate: { selectedDate: {
type: String, type: String,
value: null, value: null,
bindNuclear: entityHistoryGetters.currentDate, bindNuclear: hass => hass.entityHistoryGetters.currentDate,
}, },
}, },
isDataLoadedChanged(newVal) { isDataLoadedChanged(newVal) {
if (!newVal) { if (!newVal) {
this.async(() => entityHistoryActions.fetchSelectedDate(), 1); this.async(() => this.hass.entityHistoryActions.fetchSelectedDate(), 1);
} }
}, },
handleRefreshClick() { handleRefreshClick() {
entityHistoryActions.fetchSelectedDate(); this.hass.entityHistoryActions.fetchSelectedDate();
}, },
datepickerFocus() { datepickerFocus() {
@ -66,7 +62,7 @@ export default new Polymer({
attached() { attached() {
this.datePicker = new window.Pikaday({ this.datePicker = new window.Pikaday({
field: this.$.datePicker.inputElement, field: this.$.datePicker.inputElement,
onSelect: entityHistoryActions.changeCurrentDate, onSelect: this.hass.entityHistoryActions.changeCurrentDate,
}); });
}, },

View File

@ -1,20 +1,19 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import nuclearObserver from '../util/bound-nuclear-behavior';
require('./partial-base'); require('./partial-base');
require('../components/ha-logbook'); require('../components/ha-logbook');
require('../components/loading-box'); require('../components/loading-box');
const { logbookGetters, logbookActions } = hass;
export default new Polymer({ export default new Polymer({
is: 'partial-logbook', is: 'partial-logbook',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
hass: {
type: Object,
},
narrow: { narrow: {
type: Boolean, type: Boolean,
value: false, value: false,
@ -27,24 +26,24 @@ export default new Polymer({
selectedDate: { selectedDate: {
type: String, type: String,
bindNuclear: logbookGetters.currentDate, bindNuclear: hass => hass.logbookGetters.currentDate,
}, },
isLoading: { isLoading: {
type: Boolean, type: Boolean,
bindNuclear: logbookGetters.isLoadingEntries, bindNuclear: hass => hass.logbookGetters.isLoadingEntries,
}, },
isStale: { isStale: {
type: Boolean, type: Boolean,
bindNuclear: logbookGetters.isCurrentStale, bindNuclear: hass => hass.logbookGetters.isCurrentStale,
observer: 'isStaleChanged', observer: 'isStaleChanged',
}, },
entries: { entries: {
type: Array, type: Array,
bindNuclear: [ bindNuclear: hass => [
logbookGetters.currentEntries, hass.logbookGetters.currentEntries,
(entries) => entries.reverse().toArray(), (entries) => entries.reverse().toArray(),
], ],
}, },
@ -56,12 +55,12 @@ export default new Polymer({
isStaleChanged(newVal) { isStaleChanged(newVal) {
if (newVal) { if (newVal) {
this.async(() => logbookActions.fetchDate(this.selectedDate), 1); this.async(() => this.hass.logbookActions.fetchDate(this.selectedDate), 1);
} }
}, },
handleRefresh() { handleRefresh() {
logbookActions.fetchDate(this.selectedDate); this.hass.logbookActions.fetchDate(this.selectedDate);
}, },
datepickerFocus() { datepickerFocus() {
@ -71,7 +70,7 @@ export default new Polymer({
attached() { attached() {
this.datePicker = new window.Pikaday({ this.datePicker = new window.Pikaday({
field: this.$.datePicker.inputElement, field: this.$.datePicker.inputElement,
onSelect: logbookActions.changeCurrentDate, onSelect: this.hass.logbookActions.changeCurrentDate,
}); });
}, },

View File

@ -62,7 +62,8 @@
<template is='dom-repeat' items='[[locationEntities]]'> <template is='dom-repeat' items='[[locationEntities]]'>
<leaflet-divicon id="[[item.entityId]]" icon-height="45" icon-width="45"> <leaflet-divicon id="[[item.entityId]]" icon-height="45" icon-width="45">
<ha-entity-marker entity-id$="[[item.entityId]]"></ha-entity-marker> <ha-entity-marker hass='[[hass]]'
entity-id="[[item.entityId]]"></ha-entity-marker>
</leaflet-divicon> </leaflet-divicon>
<leaflet-marker latitude="[[item.attributes.latitude]]" icon="[[item.entityId]]" <leaflet-marker latitude="[[item.attributes.latitude]]" icon="[[item.entityId]]"

View File

@ -1,37 +1,33 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import nuclearObserver from '../util/bound-nuclear-behavior';
require('../components/entity/ha-entity-marker'); require('../components/entity/ha-entity-marker');
const {
configGetters,
entityGetters,
} = hass;
window.L.Icon.Default.imagePath = '/static/images/leaflet'; window.L.Icon.Default.imagePath = '/static/images/leaflet';
export default new Polymer({ export default new Polymer({
is: 'partial-map', is: 'partial-map',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
hass: {
type: Object,
},
locationGPS: { locationGPS: {
type: Number, type: Number,
bindNuclear: configGetters.locationGPS, bindNuclear: hass => hass.configGetters.locationGPS,
}, },
locationName: { locationName: {
type: String, type: String,
bindNuclear: configGetters.locationName, bindNuclear: hass => hass.configGetters.locationName,
}, },
locationEntities: { locationEntities: {
type: Array, type: Array,
bindNuclear: [ bindNuclear: hass => [
entityGetters.visibleEntityMap, hass.entityGetters.visibleEntityMap,
entities => entities.valueSeq().filter( entities => entities.valueSeq().filter(
entity => entity.attributes.latitude && entity.state !== 'home' entity => entity.attributes.latitude && entity.state !== 'home'
).toArray(), ).toArray(),
@ -40,8 +36,8 @@ export default new Polymer({
zoneEntities: { zoneEntities: {
type: Array, type: Array,
bindNuclear: [ bindNuclear: hass => [
entityGetters.entityMap, hass.entityGetters.entityMap,
entities => entities.valueSeq() entities => entities.valueSeq()
.filter(entity => entity.domain === 'zone' && .filter(entity => entity.domain === 'zone' &&
!entity.attributes.passive) !entity.attributes.passive)

View File

@ -1,16 +1,15 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import nuclearObserver from '../util/bound-nuclear-behavior';
const { notificationGetters } = hass;
export default new Polymer({ export default new Polymer({
is: 'notification-manager', is: 'notification-manager',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
hass: {
type: Object,
},
// Otherwise we cannot close a modal when a notification is being shown. // Otherwise we cannot close a modal when a notification is being shown.
neg: { neg: {
type: Boolean, type: Boolean,
@ -19,7 +18,7 @@ export default new Polymer({
text: { text: {
type: String, type: String,
bindNuclear: notificationGetters.lastNotificationMessage, bindNuclear: hass => hass.notificationGetters.lastNotificationMessage,
observer: 'showNotification', observer: 'showNotification',
}, },
}, },

View File

@ -1,9 +1,5 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
const { serviceActions } = hass;
export default new Polymer({ export default new Polymer({
is: 'more-info-alarm_control_panel', is: 'more-info-alarm_control_panel',
handleDisarmTap() { handleDisarmTap() {
@ -16,6 +12,10 @@ export default new Polymer({
this.callService('alarm_arm_away', { code: this.enteredCode }); this.callService('alarm_arm_away', { code: this.enteredCode });
}, },
properties: { properties: {
hass: {
type: Object,
},
stateObj: { stateObj: {
type: Object, type: Object,
observer: 'stateObjChanged', observer: 'stateObjChanged',
@ -83,6 +83,6 @@ export default new Polymer({
callService(service, data) { callService(service, data) {
const serviceData = data || {}; const serviceData = data || {};
serviceData.entity_id = this.stateObj.entityId; serviceData.entity_id = this.stateObj.entityId;
serviceActions.callService('alarm_control_panel', service, serviceData); this.hass.serviceActions.callService('alarm_control_panel', service, serviceData);
}, },
}); });

View File

@ -1,20 +1,11 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import nuclearObserver from '../util/bound-nuclear-behavior';
require('../components/loading-box'); require('../components/loading-box');
const {
streamGetters,
syncActions,
serviceActions,
} = hass;
export default new Polymer({ export default new Polymer({
is: 'more-info-configurator', is: 'more-info-configurator',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
stateObj: { stateObj: {
@ -28,7 +19,7 @@ export default new Polymer({
isStreaming: { isStreaming: {
type: Boolean, type: Boolean,
bindNuclear: streamGetters.isStreamingEvents, bindNuclear: hass => hass.streamGetters.isStreamingEvents,
}, },
isConfigurable: { isConfigurable: {
@ -72,12 +63,12 @@ export default new Polymer({
fields: this.fieldInput, fields: this.fieldInput,
}; };
serviceActions.callService('configurator', 'configure', data).then( this.hass.serviceActions.callService('configurator', 'configure', data).then(
() => { () => {
this.isConfiguring = false; this.isConfiguring = false;
if (!this.isStreaming) { if (!this.isStreaming) {
syncActions.fetchAll(); this.hass.syncActions.fetchAll();
} }
}, },
() => { () => {

View File

@ -21,6 +21,10 @@ export default new Polymer({
is: 'more-info-content', is: 'more-info-content',
properties: { properties: {
hass: {
type: Object,
},
stateObj: { stateObj: {
type: Object, type: Object,
observer: 'stateObjChanged', observer: 'stateObjChanged',
@ -31,6 +35,7 @@ export default new Polymer({
if (!stateObj) return; if (!stateObj) return;
dynamicContentUpdater( dynamicContentUpdater(
this, `MORE-INFO-${stateMoreInfoType(stateObj).toUpperCase()}`, { stateObj }); this, `MORE-INFO-${stateMoreInfoType(stateObj).toUpperCase()}`,
{ hass: this.hass, stateObj });
}, },
}); });

View File

@ -17,7 +17,7 @@
<div id="groupedControlDetails"></div> <div id="groupedControlDetails"></div>
<template is='dom-repeat' items="[[states]]" as='state'> <template is='dom-repeat' items="[[states]]" as='state'>
<div class='child-card'> <div class='child-card'>
<state-card-content state-obj="[[state]]"></state-card-content> <state-card-content state-obj="[[state]]" hass='[[hass]]'></state-card-content>
</div> </div>
</template> </template>
</template> </template>

View File

@ -1,32 +1,28 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import nuclearObserver from '../util/bound-nuclear-behavior';
import dynamicContentUpdater from '../util/dynamic-content-updater'; import dynamicContentUpdater from '../util/dynamic-content-updater';
import stateMoreInfoType from '../util/state-more-info-type'; import stateMoreInfoType from '../util/state-more-info-type';
require('../state-summary/state-card-content'); require('../state-summary/state-card-content');
const {
entityGetters,
moreInfoGetters,
} = hass;
export default new Polymer({ export default new Polymer({
is: 'more-info-group', is: 'more-info-group',
behaviors: [nuclearObserver], behaviors: [window.hassBehavior],
properties: { properties: {
hass: {
type: Object,
},
stateObj: { stateObj: {
type: Object, type: Object,
}, },
states: { states: {
type: Array, type: Array,
bindNuclear: [ bindNuclear: hass => [
moreInfoGetters.currentEntity, hass.moreInfoGetters.currentEntity,
entityGetters.entityMap, hass.entityGetters.entityMap,
(currentEntity, entities) => { (currentEntity, entities) => {
// weird bug?? // weird bug??
if (!currentEntity) { if (!currentEntity) {

View File

@ -1,9 +1,6 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import attributeClassNames from '../util/attribute-class-names'; import attributeClassNames from '../util/attribute-class-names';
const { serviceActions } = hass;
const ATTRIBUTE_CLASSES = [ const ATTRIBUTE_CLASSES = [
'away_mode', 'away_mode',
'aux_heat', 'aux_heat',
@ -18,6 +15,10 @@ export default new Polymer({
is: 'more-info-hvac', is: 'more-info-hvac',
properties: { properties: {
hass: {
type: Object,
},
stateObj: { stateObj: {
type: Object, type: Object,
observer: 'stateObjChanged', observer: 'stateObjChanged',
@ -154,7 +155,7 @@ export default new Polymer({
/* eslint-disable no-param-reassign */ /* eslint-disable no-param-reassign */
data.entity_id = this.stateObj.entityId; data.entity_id = this.stateObj.entityId;
/* eslint-enable no-param-reassign */ /* eslint-enable no-param-reassign */
serviceActions.callService('hvac', service, data) this.hass.serviceActions.callService('hvac', service, data)
.then(() => this.stateObjChanged(this.stateObj)); .then(() => this.stateObjChanged(this.stateObj));
}, },
}); });

View File

@ -1,15 +1,12 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import attributeClassNames from '../util/attribute-class-names'; import attributeClassNames from '../util/attribute-class-names';
require('../components/ha-color-picker'); require('../components/ha-color-picker');
const { serviceActions } = hass;
const ATTRIBUTE_CLASSES = ['brightness', 'rgb_color', 'color_temp']; const ATTRIBUTE_CLASSES = ['brightness', 'rgb_color', 'color_temp'];
function pickColor(entityId, color) { function pickColor(hass, entityId, color) {
serviceActions.callService('light', 'turn_on', { hass.serviceActions.callService('light', 'turn_on', {
entity_id: entityId, entity_id: entityId,
rgb_color: [color.r, color.g, color.b], rgb_color: [color.r, color.g, color.b],
}); });
@ -19,6 +16,10 @@ export default new Polymer({
is: 'more-info-light', is: 'more-info-light',
properties: { properties: {
hass: {
type: Object,
},
stateObj: { stateObj: {
type: Object, type: Object,
observer: 'stateObjChanged', observer: 'stateObjChanged',
@ -54,9 +55,9 @@ export default new Polymer({
if (isNaN(bri)) return; if (isNaN(bri)) return;
if (bri === 0) { if (bri === 0) {
serviceActions.callTurnOff(this.stateObj.entityId); this.hass.serviceActions.callTurnOff(this.stateObj.entityId);
} else { } else {
serviceActions.callService('light', 'turn_on', { this.hass.serviceActions.callService('light', 'turn_on', {
entity_id: this.stateObj.entityId, entity_id: this.stateObj.entityId,
brightness: bri, brightness: bri,
}); });
@ -68,7 +69,7 @@ export default new Polymer({
if (isNaN(ct)) return; if (isNaN(ct)) return;
serviceActions.callService('light', 'turn_on', { this.hass.serviceActions.callService('light', 'turn_on', {
entity_id: this.stateObj.entityId, entity_id: this.stateObj.entityId,
color_temp: ct, color_temp: ct,
}); });
@ -86,14 +87,14 @@ export default new Polymer({
this.color = ev.detail.rgb; this.color = ev.detail.rgb;
pickColor(this.stateObj.entityId, this.color); pickColor(this.hass, this.stateObj.entityId, this.color);
this.colorChanged = false; this.colorChanged = false;
this.skipColorPicked = true; this.skipColorPicked = true;
this.colorDebounce = setTimeout(() => { this.colorDebounce = setTimeout(() => {
if (this.colorChanged) { if (this.colorChanged) {
pickColor(this.stateObj.entityId, this.color); pickColor(this.hass, this.stateObj.entityId, this.color);
} }
this.skipColorPicked = false; this.skipColorPicked = false;
}, 500); }, 500);

View File

@ -1,12 +1,12 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
const { serviceActions } = hass;
export default new Polymer({ export default new Polymer({
is: 'more-info-lock', is: 'more-info-lock',
properties: { properties: {
hass: {
type: Object,
},
stateObj: { stateObj: {
type: Object, type: Object,
observer: 'stateObjChanged', observer: 'stateObjChanged',
@ -35,6 +35,6 @@ export default new Polymer({
callService(service, data) { callService(service, data) {
const serviceData = data || {}; const serviceData = data || {};
serviceData.entity_id = this.stateObj.entityId; serviceData.entity_id = this.stateObj.entityId;
serviceActions.callService('lock', service, serviceData); this.hass.serviceActions.callService('lock', service, serviceData);
}, },
}); });

View File

@ -1,15 +1,16 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import attributeClassNames from '../util/attribute-class-names'; import attributeClassNames from '../util/attribute-class-names';
const { serviceActions } = hass;
const ATTRIBUTE_CLASSES = ['volume_level']; const ATTRIBUTE_CLASSES = ['volume_level'];
export default new Polymer({ export default new Polymer({
is: 'more-info-media_player', is: 'more-info-media_player',
properties: { properties: {
hass: {
type: Object,
},
stateObj: { stateObj: {
type: Object, type: Object,
observer: 'stateObjChanged', observer: 'stateObjChanged',
@ -232,6 +233,6 @@ export default new Polymer({
callService(service, data) { callService(service, data) {
const serviceData = data || {}; const serviceData = data || {};
serviceData.entity_id = this.stateObj.entityId; serviceData.entity_id = this.stateObj.entityId;
serviceActions.callService('media_player', service, serviceData); this.hass.serviceActions.callService('media_player', service, serviceData);
}, },
}); });

View File

@ -1,10 +1,7 @@
import Polymer from '../polymer'; import Polymer from '../polymer';
import hass from '../util/home-assistant-js-instance';
import formatTime from '../util/format-time'; import formatTime from '../util/format-time';
const { util: { parseDateTime } } = hass;
export default new Polymer({ export default new Polymer({
is: 'more-info-sun', is: 'more-info-sun',
@ -25,11 +22,11 @@ export default new Polymer({
}, },
computeRising(stateObj) { computeRising(stateObj) {
return parseDateTime(stateObj.attributes.next_rising); return new Date(stateObj.attributes.next_rising);
}, },
computeSetting(stateObj) { computeSetting(stateObj) {
return parseDateTime(stateObj.attributes.next_setting); return new Date(stateObj.attributes.next_setting);
}, },
computeOrder(risingDate, settingDate) { computeOrder(risingDate, settingDate) {

View File

@ -1,15 +1,16 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
import attributeClassNames from '../util/attribute-class-names'; import attributeClassNames from '../util/attribute-class-names';
const { serviceActions } = hass;
const ATTRIBUTE_CLASSES = ['away_mode']; const ATTRIBUTE_CLASSES = ['away_mode'];
export default new Polymer({ export default new Polymer({
is: 'more-info-thermostat', is: 'more-info-thermostat',
properties: { properties: {
hass: {
type: Object,
},
stateObj: { stateObj: {
type: Object, type: Object,
observer: 'stateObjChanged', observer: 'stateObjChanged',
@ -45,7 +46,7 @@ export default new Polymer({
}, },
targetTemperatureSliderChanged(ev) { targetTemperatureSliderChanged(ev) {
serviceActions.callService('thermostat', 'set_temperature', { this.hass.serviceActions.callService('thermostat', 'set_temperature', {
entity_id: this.stateObj.entityId, entity_id: this.stateObj.entityId,
temperature: ev.target.value, temperature: ev.target.value,
}); });
@ -66,7 +67,7 @@ export default new Polymer({
// with the state. It will be out of sync if our service call did not // with the state. It will be out of sync if our service call did not
// result in the entity to be turned on. Since the state is not changing, // result in the entity to be turned on. Since the state is not changing,
// the resync is not called automatic. // the resync is not called automatic.
serviceActions.callService( this.hass.serviceActions.callService(
'thermostat', 'set_away_mode', 'thermostat', 'set_away_mode',
{ away_mode: awayMode, entity_id: this.stateObj.entityId }) { away_mode: awayMode, entity_id: this.stateObj.entityId })

View File

@ -20,6 +20,10 @@ export default new Polymer({
is: 'state-card-content', is: 'state-card-content',
properties: { properties: {
hass: {
type: Object,
},
inDialog: { inDialog: {
type: Boolean, type: Boolean,
value: false, value: false,
@ -31,13 +35,14 @@ export default new Polymer({
}, },
observers: [ observers: [
'inputChanged(inDialog, stateObj)', 'inputChanged(hass, inDialog, stateObj)',
], ],
inputChanged(inDialog, stateObj) { inputChanged(hass, inDialog, stateObj) {
if (!stateObj) return; if (!stateObj) return;
dynamicContentUpdater( dynamicContentUpdater(
this, `STATE-CARD-${stateCardType(stateObj).toUpperCase()}`, { stateObj, inDialog }); this, `STATE-CARD-${stateCardType(this.hass, stateObj).toUpperCase()}`,
{ hass, stateObj, inDialog });
}, },
}); });

View File

@ -1,14 +1,15 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
require('../components/state-info'); require('../components/state-info');
const { serviceActions } = hass;
export default new Polymer({ export default new Polymer({
is: 'state-card-input_select', is: 'state-card-input_select',
properties: { properties: {
hass: {
type: Object,
},
inDialog: { inDialog: {
type: Boolean, type: Boolean,
value: false, value: false,
@ -33,7 +34,7 @@ export default new Polymer({
if (option === '' || option === this.stateObj.state) { if (option === '' || option === this.stateObj.state) {
return; return;
} }
serviceActions.callService('input_select', 'select_option', { this.hass.serviceActions.callService('input_select', 'select_option', {
option, option,
entity_id: this.stateObj.entityId, entity_id: this.stateObj.entityId,
}); });

View File

@ -1,14 +1,15 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
require('../components/state-info'); require('../components/state-info');
const { serviceActions } = hass;
export default new Polymer({ export default new Polymer({
is: 'state-card-input_slider', is: 'state-card-input_slider',
properties: { properties: {
hass: {
type: Object,
},
inDialog: { inDialog: {
type: Boolean, type: Boolean,
value: false, value: false,
@ -41,7 +42,7 @@ export default new Polymer({
if (this.value === Number(this.stateObj.state)) { if (this.value === Number(this.stateObj.state)) {
return; return;
} }
serviceActions.callService('input_slider', 'select_value', { this.hass.serviceActions.callService('input_slider', 'select_value', {
value: this.value, value: this.value,
entity_id: this.stateObj.entityId, entity_id: this.stateObj.entityId,
}); });

View File

@ -1,15 +1,15 @@
import hass from '../util/home-assistant-js-instance';
import Polymer from '../polymer'; import Polymer from '../polymer';
require('../components/state-info'); require('../components/state-info');
const { serviceActions } = hass;
export default new Polymer({ export default new Polymer({
is: 'state-card-rollershutter', is: 'state-card-rollershutter',
properties: { properties: {
hass: {
type: Object,
},
inDialog: { inDialog: {
type: Boolean, type: Boolean,
value: false, value: false,
@ -29,17 +29,17 @@ export default new Polymer({
}, },
onMoveUpTap() { onMoveUpTap() {
serviceActions.callService('rollershutter', 'move_up', this.hass.serviceActions.callService('rollershutter', 'move_up',
{ entity_id: this.stateObj.entityId }); { entity_id: this.stateObj.entityId });
}, },
onMoveDownTap() { onMoveDownTap() {
serviceActions.callService('rollershutter', 'move_down', this.hass.serviceActions.callService('rollershutter', 'move_down',
{ entity_id: this.stateObj.entityId }); { entity_id: this.stateObj.entityId });
}, },
onStopTap() { onStopTap() {
serviceActions.callService('rollershutter', 'stop', this.hass.serviceActions.callService('rollershutter', 'stop',
{ entity_id: this.stateObj.entityId }); { entity_id: this.stateObj.entityId });
}, },
}); });

View File

@ -1,14 +1,15 @@
import Polymer from '../polymer'; import Polymer from '../polymer';
import hass from '../util/home-assistant-js-instance';
require('../components/state-info.js'); require('../components/state-info.js');
const { serviceActions } = hass;
export default new Polymer({ export default new Polymer({
is: 'state-card-scene', is: 'state-card-scene',
properties: { properties: {
hass: {
type: Object,
},
inDialog: { inDialog: {
type: Boolean, type: Boolean,
value: false, value: false,
@ -21,6 +22,6 @@ export default new Polymer({
activateScene(ev) { activateScene(ev) {
ev.stopPropagation(); ev.stopPropagation();
serviceActions.callTurnOn(this.stateObj.entityId); this.hass.serviceActions.callTurnOn(this.stateObj.entityId);
}, },
}); });

View File

@ -19,7 +19,7 @@
<div class='horizontal justified layout'> <div class='horizontal justified layout'>
<state-info state-obj="[[stateObj]]" in-dialog='[[inDialog]]'></state-info> <state-info state-obj="[[stateObj]]" in-dialog='[[inDialog]]'></state-info>
<template is='dom-if' if='[[stateObj.attributes.can_cancel]]'> <template is='dom-if' if='[[stateObj.attributes.can_cancel]]'>
<ha-entity-toggle state-obj='[[stateObj]]'></ha-entity-toggle> <ha-entity-toggle state-obj='[[stateObj]]' hass='[[hass]]'></ha-entity-toggle>
</template> </template>
<template is='dom-if' if='[[!stateObj.attributes.can_cancel]]'> <template is='dom-if' if='[[!stateObj.attributes.can_cancel]]'>
<paper-button on-tap='fireScript'>ACTIVATE</paper-button> <paper-button on-tap='fireScript'>ACTIVATE</paper-button>

View File

@ -1,11 +1,8 @@
import Polymer from '../polymer'; import Polymer from '../polymer';
import hass from '../util/home-assistant-js-instance';
require('../components/state-info'); require('../components/state-info');
require('../components/entity/ha-entity-toggle'); require('../components/entity/ha-entity-toggle');
const { serviceActions } = hass;
export default new Polymer({ export default new Polymer({
is: 'state-card-script', is: 'state-card-script',
@ -22,6 +19,6 @@ export default new Polymer({
fireScript(ev) { fireScript(ev) {
ev.stopPropagation(); ev.stopPropagation();
serviceActions.callTurnOn(this.stateObj.entityId); this.hass.serviceActions.callTurnOn(this.stateObj.entityId);
}, },
}); });

View File

@ -13,7 +13,7 @@
<template> <template>
<div class='horizontal justified layout'> <div class='horizontal justified layout'>
<state-info state-obj="[[stateObj]]" in-dialog='[[inDialog]]'></state-info> <state-info state-obj="[[stateObj]]" in-dialog='[[inDialog]]'></state-info>
<ha-entity-toggle state-obj="[[stateObj]]"></ha-entity-toggle> <ha-entity-toggle state-obj="[[stateObj]]" hass='[[hass]]'></ha-entity-toggle>
</div> </div>
</template> </template>

View File

@ -1,5 +0,0 @@
import hass from './home-assistant-js-instance';
import nuclearObserver from './nuclear-behavior';
export default nuclearObserver(hass.reactor);

View File

@ -1,11 +1,4 @@
import hass from './home-assistant-js-instance';
const {
reactor,
serviceGetters,
} = hass;
// Return boolean if entity can be toggled. // Return boolean if entity can be toggled.
export default function canToggle(entityId) { export default function canToggle(hass, entityId) {
return reactor.evaluate(serviceGetters.canToggleEntity(entityId)); return hass.reactor.evaluate(hass.serviceGetters.canToggleEntity(entityId));
} }

View File

@ -91,9 +91,11 @@ export default function domainIcon(domain, state) {
return 'mdi:open-in-new'; return 'mdi:open-in-new';
default: default:
/* eslint-disable no-console */ if (__DEV__) {
console.warn(`Unable to find icon for domain ${domain} (${state})`); /* eslint-disable no-console */
/* eslint-enable no-console */ console.warn(`Unable to find icon for domain ${domain} (${state})`);
/* eslint-enable no-console */
}
return defaultIcon; return defaultIcon;
} }
} }

View File

@ -1,5 +1,3 @@
import moment from 'moment';
export default function formatDateTime(dateObj) { export default function formatDateTime(dateObj) {
return moment(dateObj).format('lll'); return window.moment(dateObj).format('lll');
} }

View File

@ -1,5 +1,3 @@
import moment from 'moment';
export default function formatDate(dateObj) { export default function formatDate(dateObj) {
return moment(dateObj).format('ll'); return window.moment(dateObj).format('ll');
} }

View File

@ -1,5 +1,3 @@
import moment from 'moment';
export default function formatTime(dateObj) { export default function formatTime(dateObj) {
return moment(dateObj).format('LT'); return window.moment(dateObj).format('LT');
} }

44
src/util/hass-behavior.js Normal file
View File

@ -0,0 +1,44 @@
export default {
attached() {
const hass = this.hass;
if (!hass) {
throw new Error(`No hass property found on ${this.nodeName}`);
}
this.nuclearUnwatchFns = Object.keys(this.properties).reduce(
(unwatchFns, key) => {
if (!('bindNuclear' in this.properties[key])) {
return unwatchFns;
}
let getter = this.properties[key].bindNuclear;
if (typeof getter !== 'function') {
/* eslint-disable no-console */
console.warn(`Component ${this.nodeName} uses old style bindNuclear`);
/* eslint-enable no-console */
} else {
getter = getter(hass);
}
if (!getter) {
throw new Error(`Undefined getter specified for key ${key}`);
}
this[key] = hass.reactor.evaluate(getter);
return unwatchFns.concat(hass.reactor.observe(getter, (val) => {
this[key] = val;
}));
}, []);
},
detached() {
while (this.nuclearUnwatchFns.length) {
this.nuclearUnwatchFns.shift()();
}
},
};

View File

@ -1,3 +0,0 @@
import HomeAssistant from 'home-assistant-js';
export default new HomeAssistant();

View File

@ -1,29 +0,0 @@
export default function NuclearObserver(reactor) {
return {
attached() {
this.nuclearUnwatchFns = Object.keys(this.properties).reduce(
(unwatchFns, key) => {
if (!('bindNuclear' in this.properties[key])) {
return unwatchFns;
}
const getter = this.properties[key].bindNuclear;
if (!getter) {
throw new Error(`Undefined getter specified for key ${key}`);
}
this[key] = reactor.evaluate(getter);
return unwatchFns.concat(reactor.observe(getter, (val) => {
this[key] = val;
}));
}, []);
},
detached() {
while (this.nuclearUnwatchFns.length) {
this.nuclearUnwatchFns.shift()();
}
},
};
}

View File

@ -13,12 +13,12 @@ const DOMAINS_WITH_CARD = [
'weblink', 'weblink',
]; ];
export default function stateCardType(state) { export default function stateCardType(hass, state) {
if (state.state === 'unavailable') { if (state.state === 'unavailable') {
return 'display'; return 'display';
} else if (DOMAINS_WITH_CARD.indexOf(state.domain) !== -1) { } else if (DOMAINS_WITH_CARD.indexOf(state.domain) !== -1) {
return state.domain; return state.domain;
} else if (canToggle(state.entityId)) { } else if (canToggle(hass, state.entityId)) {
return 'toggle'; return 'toggle';
} }
return 'display'; return 'display';

View File

@ -1,8 +1,5 @@
import defaultIcon from './default-icon'; import defaultIcon from './default-icon';
import domainIcon from './domain-icon.js'; import domainIcon from './domain-icon.js';
import hass from './home-assistant-js-instance';
const { util: { temperatureUnits } } = hass;
function binarySensorIcon(state) { function binarySensorIcon(state) {
const activated = state.state && state.state === 'off'; const activated = state.state && state.state === 'off';
@ -42,8 +39,7 @@ export default function stateIcon(state) {
const unit = state.attributes.unit_of_measurement; const unit = state.attributes.unit_of_measurement;
if (unit && state.domain === 'sensor') { if (unit && state.domain === 'sensor') {
if (unit === temperatureUnits.UNIT_TEMP_C || if (unit === '°C' || unit === '°F') {
unit === temperatureUnits.UNIT_TEMP_F) {
return 'mdi:thermometer'; return 'mdi:thermometer';
} else if (unit === 'Mice') { } else if (unit === 'Mice') {
return 'mdi:mouse-variant'; return 'mdi:mouse-variant';

View File

@ -1,10 +1,6 @@
import hass from '../util/home-assistant-js-instance'; export default function (hass, authToken, rememberAuth) {
hass.authActions.validate(authToken, {
const { authActions, localStoragePreferences } = hass;
export default function (authToken, rememberAuth) {
authActions.validate(authToken, {
rememberAuth, rememberAuth,
useStreaming: localStoragePreferences.useStreaming, useStreaming: hass.localStoragePreferences.useStreaming,
}); });
} }