Added a drawer to the UI

This commit is contained in:
Paulus Schoutsen 2015-02-05 08:52:46 -08:00
parent b31668fba9
commit ce7b8b5e08
19 changed files with 471 additions and 427 deletions

View File

@ -1,2 +1,2 @@
""" DO NOT MODIFY. Auto-generated by build_frontend script """
VERSION = "630b1c573a3a1914ce7975f63264e796"
VERSION = "9e0bb62c1e6376f8aa0dfdc17f9dfa7a"

File diff suppressed because one or more lines are too long

View File

@ -13,10 +13,10 @@
"dependencies": {
"webcomponentsjs": "Polymer/webcomponentsjs#~0.5.4",
"font-roboto": "Polymer/font-roboto#~0.5.4",
"core-header-panel": "Polymer/core-header-panel#~0.5.4",
"core-toolbar": "Polymer/core-toolbar#~0.5.4",
"core-header-panel": "polymer/core-header-panel#~0.5.4",
"core-toolbar": "polymer/core-toolbar#~0.5.4",
"core-tooltip": "Polymer/core-tooltip#~0.5.4",
"core-menu": "Polymer/core-menu#~0.5.4",
"core-menu": "polymer/core-menu#~0.5.4",
"core-item": "Polymer/core-item#~0.5.4",
"core-input": "Polymer/core-input#~0.5.4",
"core-icons": "polymer/core-icons#~0.5.4",
@ -35,6 +35,8 @@
"paper-item": "polymer/paper-item#~0.5.4",
"paper-slider": "polymer/paper-slider#~0.5.4",
"color-picker-element": "~0.0.2",
"google-apis": "GoogleWebComponents/google-apis#~0.4.2"
"google-apis": "GoogleWebComponents/google-apis#~0.4.2",
"core-drawer-panel": "polymer/core-drawer-panel#~0.5.4",
"core-scroll-header-panel": "polymer/core-scroll-header-panel#~0.5.4"
}
}

View File

@ -22,6 +22,8 @@ Polymer({
this.$.card.removeChild(this.$.card.lastChild);
}
if (!this.stateObj.cardType) return;
var stateCard = document.createElement("state-card-" + this.stateObj.cardType);
stateCard.api = this.api;
stateCard.stateObj = this.stateObj;

View File

@ -10,9 +10,9 @@
width: 100%;
}
@media all and (min-width: 764px) {
@media all and (min-width: 1020px) {
:host {
padding-bottom: 8px;
/*padding-bottom: 8px;*/
}
.state-card {
@ -21,14 +21,14 @@
}
}
@media all and (min-width: 1100px) {
@media all and (min-width: 1356px) {
.state-card {
width: calc(33% - 38px);
}
}
@media all and (min-width: 1450px) {
@media all and (min-width: 1706px) {
.state-card {
width: calc(25% - 42px);
}

View File

@ -1,37 +0,0 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="ha-action-dialog.html">
<link rel="import" href="../components/state-timeline.html">
<polymer-element name="history-dialog" attributes="api">
<template>
<ha-action-dialog id="dialog" heading="History">
<style>
#timeline {
width: 614px;
height: auto;
display: block;
}
</style>
<state-timeline id='timeline' api="{{api}}"></state-timeline>
</ha-action-dialog>
</template>
<script>
Polymer({
show: function() {
this.$.dialog.toggle();
this.job('repositionDialogAfterRender', function() {
this.$.timeline.fetchData();
this.job('repositionDialogAfterRender', function() {
this.$.dialog.resizeHandler();
}.bind(this), 1000);
}.bind(this));
},
});
</script>
</polymer-element>

View File

@ -22,8 +22,8 @@
<more-info-content stateObj="{{stateObj}}"></more-info-content>
</div>
<paper-button dismissive on-click={{editClicked}}>Debug</paper-button>
<paper-button affirmative>Dismiss</paper-button>
<!-- <paper-button dismissive on-click={{editClicked}}>Debug</paper-button>
<paper-button affirmative>Dismiss</paper-button> -->
</ha-action-dialog>
</template>

View File

@ -1,105 +0,0 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/paper-button/paper-button.html">
<link rel="import" href="../bower_components/paper-input/paper-input.html">
<link rel="import" href="../bower_components/paper-input/paper-input-decorator.html">
<link rel="import" href="../bower_components/paper-input/paper-autogrow-textarea.html">
<link rel="import" href="ha-action-dialog.html">
<link rel="import" href="../components/entity-list.html">
<polymer-element name="state-set-dialog" attributes="api">
<template>
<ha-action-dialog
id="dialog"
heading="Set State"
closeSelector='[dismissive]'>
<core-style ref='ha-dialog'></core-style>
<p>
This dialog will update the representation of the device within Home Assistant.<br />
This will not communicate with the actual device.
</p>
<div layout horizontal>
<div class='ha-form'>
<paper-input id="inputEntityID" label="Entity ID" floatingLabel="true" autofocus required></paper-input>
<paper-input id="inputState" label="State" floatingLabel="true" required></paper-input>
<paper-input-decorator
label="State attributes (JSON, optional)"
floatingLabel="true">
<!--
<paper-autogrow-textarea id="inputDataWrapper">
<textarea id="inputData"></textarea>
</paper-autogrow-textarea>
-->
<textarea id="inputData" rows="5"></textarea>
</paper-input-decorator>
</div>
<div class='sidebar'>
<b>Current entities:</b>
<entity-list api={{api}} cbEntityClicked={{entitySelected}}></entity-list>
</div>
</div>
<paper-button dismissive>Cancel</paper-button>
<paper-button affirmative on-click={{clickSetState}}>Set State</paper-button>
</ha-action-dialog>
</template>
<script>
Polymer({
ready: function() {
// to ensure callback methods work..
this.entitySelected = this.entitySelected.bind(this);
},
show: function(entityId, state, stateData) {
this.setEntityId(entityId);
this.setState(state);
this.setStateData(stateData);
this.job('showDialogAfterRender', function() {
this.$.dialog.toggle();
}.bind(this));
},
setEntityId: function(entityId) {
this.$.inputEntityID.value = entityId;
},
setState: function(state) {
this.$.inputState.value = state;
},
setStateData: function(stateData) {
var value = stateData ? JSON.stringify(stateData, null, ' ') : "";
this.$.inputData.value = value;
},
entitySelected: function(entityId) {
this.setEntityId(entityId);
var state = window.hass.stateStore.get(entityId);
this.setState(state.state);
this.setStateData(state.attributes);
},
clickSetState: function(ev) {
try {
window.hass.stateActions.set(
this.$.inputEntityID.value,
this.$.inputState.value,
this.$.inputData.value ? JSON.parse(this.$.inputData.value) : {}
);
this.$.dialog.close();
} catch (err) {
alert("Error parsing JSON: " + err);
}
}
});
</script>
</polymer-element>

View File

@ -1,10 +1,6 @@
<link rel="import" href="./bower_components/paper-toast/paper-toast.html">
<link rel="import" href="./dialogs/event-fire-dialog.html">
<link rel="import" href="./dialogs/service-call-dialog.html">
<link rel="import" href="./dialogs/state-set-dialog.html">
<link rel="import" href="./dialogs/more-info-dialog.html">
<link rel="import" href="./dialogs/history-dialog.html">
<script src="./home-assistant-js/dist/homeassistant.min.js"></script>
@ -21,11 +17,7 @@
<polymer-element name="home-assistant-api" attributes="auth">
<template>
<paper-toast id="toast" role="alert" text=""></paper-toast>
<event-fire-dialog id="eventDialog"></event-fire-dialog>
<service-call-dialog id="serviceDialog"></service-call-dialog>
<state-set-dialog id="stateSetDialog"></state-set-dialog>
<more-info-dialog id="moreInfoDialog"></more-info-dialog>
<history-dialog id="historyDialog"></history-dialog>
</template>
<script>
Polymer({
@ -36,10 +28,6 @@
var uiActions = window.hass.uiActions = {
ACTION_SHOW_TOAST: actions.ACTION_SHOW_TOAST,
ACTION_SHOW_DIALOG_CALL_SERVICE: 'ACTION_SHOW_DIALOG_CALL_SERVICE',
ACTION_SHOW_DIALOG_FIRE_EVENT: 'ACTION_SHOW_DIALOG_FIRE_EVENT',
ACTION_SHOW_DIALOG_SET_STATE: 'ACTION_SHOW_DIALOG_SET_STATE',
ACTION_SHOW_DIALOG_HISTORY: 'ACTION_SHOW_DIALOG_HISTORY',
ACTION_SHOW_DIALOG_MORE_INFO: 'ACTION_SHOW_DIALOG_MORE_INFO',
showMoreInfoDialog: function(entityId) {
@ -49,31 +37,6 @@
});
},
showSetStateDialog: function(entityId) {
dispatcher.dispatch({
actionType: this.ACTION_SHOW_DIALOG_SET_STATE,
entityId: entityId
});
},
showFireEventDialog: function() {
dispatcher.dispatch({
actionType: this.ACTION_SHOW_DIALOG_FIRE_EVENT,
});
},
showCallServiceDialog: function() {
dispatcher.dispatch({
actionType: this.ACTION_SHOW_DIALOG_CALL_SERVICE,
});
},
showHistoryDialog: function() {
dispatcher.dispatch({
actionType: this.ACTION_SHOW_DIALOG_HISTORY,
});
},
};
var getState = function(entityId) {
@ -87,35 +50,11 @@
this.$.toast.show();
break;
case uiActions.ACTION_SHOW_DIALOG_HISTORY:
this.$.historyDialog.show();
break;
case uiActions.ACTION_SHOW_DIALOG_MORE_INFO:
state = getState(payload.entityId);
this.$.moreInfoDialog.show(state);
break;
case uiActions.ACTION_SHOW_DIALOG_SET_STATE:
if (payload.entityId) {
state = getState(payload.entityId);
this.$.stateSetDialog.show(
state.entity_id, state.state, state.attributes);
} else {
this.$.stateSetDialog.show("", "");
}
break;
case uiActions.ACTION_SHOW_DIALOG_FIRE_EVENT:
this.$.eventDialog.show();
break;
case uiActions.ACTION_SHOW_DIALOG_CALL_SERVICE:
this.$.serviceDialog.show();
break;
}
}.bind(this));

View File

@ -12,6 +12,7 @@
:host {
font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial;
font-weight: 300;
}
</style>

View File

@ -1,145 +1,166 @@
<link rel="import" href="../bower_components/core-drawer-panel/core-drawer-panel.html">
<link rel="import" href="../bower_components/core-header-panel/core-header-panel.html">
<link rel="import" href="../bower_components/core-toolbar/core-toolbar.html">
<link rel="import" href="../bower_components/core-menu/core-menu.html">
<link rel="import" href="../bower_components/core-style/core-style.html">
<link rel="import" href="../bower_components/core-icon/core-icon.html">
<link rel="import" href="../bower_components/paper-tabs/paper-tabs.html">
<link rel="import" href="../bower_components/paper-tabs/paper-tab.html">
<link rel="import" href="../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="../bower_components/paper-menu-button/paper-menu-button.html">
<link rel="import" href="../bower_components/paper-dropdown/paper-dropdown.html">
<link rel="import" href="../bower_components/core-menu/core-menu.html">
<link rel="import" href="../bower_components/paper-item/paper-item.html">
<link rel="import" href="../layouts/partial-states.html">
<link rel="import" href="../layouts/partial-history.html">
<link rel="import" href="../layouts/partial-dev-fire-event.html">
<link rel="import" href="../layouts/partial-dev-call-service.html">
<link rel="import" href="../layouts/partial-dev-set-state.html">
<polymer-element name="home-assistant-main" attributes="api">
<template>
<style>
<template>
<core-style ref="ha-headers"></core-style>
core-header-panel {
-webkit-overflow-scrolling: touch;
background-color: #E5E5E5;
}
<style>
core-header-panel {
background: #fafafa;
box-shadow: 1px 0 1px rgba(0, 0, 0, 0.1);
color: #757575;
overflow: hidden;
}
core-toolbar {
background: #03a9f4;
color: white;
}
core-menu core-icon {
margin-right: 24px;
}
core-toolbar.tall {
/* 2x normal height */
height: 128px;
}
core-toolbar {
font-weight: normal;
padding-left: 24px;
}
core-toolbar .bottom {
opacity: 0;
transition: opacity 0.30s ease-out;
}
core-menu {
overflow: scroll;
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
}
core-toolbar.tall .bottom {
opacity: 1;
}
paper-item {
min-height: 53px;
}
paper-tab {
text-transform: uppercase;
}
.seperator {
padding: 16px;
font-size: 14px;
border-top: 1px solid #e0e0e0;
}
paper-menu-button {
margin-top: 5px !important;
}
.seperator ~ paper-item {
paper-dropdown {
border-radius: 3px;
}
paper-dropdown .menu {
margin: 0;
padding: 8px 0;
color: black;
}
paper-item {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
paper-item a {
text-decoration: none;
}
</style>
<core-header-panel fit>
}
</style>
<core-drawer-panel id="drawer" on-core-responsive-change="{{responsiveChanged}}">
<core-header-panel mode="scroll" drawer>
<core-toolbar>
<div flex>Home Assistant</div>
<paper-icon-button icon="refresh"
on-click="{{handleRefreshClick}}"></paper-icon-button>
<paper-icon-button icon="assessment"
on-click="{{handleHistoryClick}}"></paper-icon-button>
<paper-menu-button>
<paper-icon-button icon="more-vert" noink></paper-icon-button>
<paper-dropdown halign="right" duration="200" class="dropdown">
<core-menu class="menu">
<paper-item>
<a on-click={{handleServiceClick}}>
<!-- <core-icon icon="settings-remote"></core-icon> -->
Call Service
</a>
</paper-item>
<paper-item>
<a on-click={{handleAddStateClick}}>
Set State
</a>
</paper-item>
<paper-item>
<a on-click={{handleEventClick}}>
Trigger Event
</a>
</paper-item>
<paper-item>
<a on-click={{handleLogOutClick}}>
<!-- <core-icon icon="exit-to-app"></core-icon> -->
Log Out
</a>
</paper-item>
</core-menu>
</paper-dropdown>
</paper-menu-button>
Home Assistant
</core-toolbar>
<core-menu
selected="0" excludedLocalNames="div" on-core-select="{{menuSelect}}"
layout vertical>
<paper-item data-panel="states">
<core-icon icon="apps"></core-icon>
States
</paper-item>
<paper-item data-panel="group">
<core-icon icon="homeassistant-24:group"></core-icon>
Groups
</paper-item>
<paper-item data-panel="history">
<core-icon icon="assessment"></core-icon>
History
</paper-item>
<partial-states></partial-states>
<div flex></div>
<paper-item id="logout" on-click="{{handleLogOutClick}}">
<core-icon icon="exit-to-app"></core-icon>
Log Out
</paper-item>
<div class='seperator'>Developer Tools</div>
<paper-item data-panel="call-service">
<core-icon icon="settings-remote"></core-icon>
Call Service
</paper-item>
<paper-item data-panel="set-state">
<core-icon icon="settings-ethernet"></core-icon>
Set State
</paper-item>
<paper-item data-panel="fire-event">
<core-icon icon="settings-input-antenna"></core-icon>
Fire Event
</paper-item>
</core-menu>
</core-header-panel>
</template>
<script>
Polymer({
<template if="{{selected == 'states' || selected == 'group'}}">
<partial-states
main narrow="{{narrow}}"
togglePanel="{{togglePanel}}"
filter="{{selected == 'group' ? 'group' : null}}">
</partial-states>
</template>
<template if="{{selected == 'history'}}">
<partial-history main narrow="{{narrow}}" togglePanel="{{togglePanel}}"></partial-history>
</template>
<template if="{{selected == 'fire-event'}}">
<partial-dev-fire-event main narrow="{{narrow}}" togglePanel="{{togglePanel}}"></partial-dev-fire-event>
</template>
<template if="{{selected == 'set-state'}}">
<partial-dev-set-state main narrow="{{narrow}}" togglePanel="{{togglePanel}}"></partial-dev-set-state>
</template>
<template if="{{selected == 'call-service'}}">
<partial-dev-call-service main narrow="{{narrow}}" togglePanel="{{togglePanel}}"></partial-dev-call-service>
</template>
</core-drawer-panel>
handleRefreshClick: function() {
window.hass.syncActions.sync();
},
</template>
<script>
Polymer({
selected: "states",
narrow: false,
handleHistoryClick: function() {
window.hass.uiActions.showHistoryDialog();
},
ready: function() {
this.togglePanel = this.togglePanel.bind(this);
},
handleEventClick: function() {
window.hass.uiActions.showFireEventDialog();
},
menuSelect: function(ev, detail, sender) {
if (detail.isSelected) {
var newChoice = detail.item.dataset.panel;
handleServiceClick: function() {
window.hass.uiActions.showCallServiceDialog();
},
if(newChoice !== this.selected) {
this.togglePanel();
this.selected = newChoice;
}
}
},
handleAddStateClick: function() {
window.hass.uiActions.showSetStateDialog();
},
responsiveChanged: function(ev, detail, sender) {
this.narrow = detail.narrow;
},
handleLogOutClick: function() {
window.hass.authActions.logOut();
},
togglePanel: function() {
this.$.drawer.togglePanel();
},
});
</script>
handleLogOutClick: function() {
window.hass.authActions.logOut();
},
});
</script>
</polymer-element>

View File

@ -0,0 +1,34 @@
<link rel="import" href="../bower_components/core-scroll-header-panel/core-scroll-header-panel.html">
<link rel="import" href="../bower_components/core-toolbar/core-toolbar.html">
<link rel="import" href="../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="../bower_components/core-style/core-style.html">
<polymer-element name="partial-base" attributes="narrow togglePanel" noscript>
<template>
<core-style ref="ha-headers"></core-style>
<style>
.content {
background-color: white;
}
</style>
<core-scroll-header-panel fit fixed="{{!narrow}}">
<core-toolbar>
<paper-icon-button
id="navicon" icon="menu" hidden?="{{!narrow}}"
on-click="{{togglePanel}}"></paper-icon-button>
<div flex>
<content select="[header-title]"></content>
</div>
<content select="[header-buttons]"></content>
</core-toolbar>
<div class='content'>
<content></content>
</div>
</core-scroll-header-panel>
</template>
</polymer>

View File

@ -4,33 +4,36 @@
<link rel="import" href="../bower_components/paper-input/paper-input-decorator.html">
<link rel="import" href="../bower_components/paper-input/paper-autogrow-textarea.html">
<link rel="import" href="ha-action-dialog.html">
<link rel="import" href="./partial-base.html">
<link rel="import" href="../components/services-list.html">
<polymer-element name="service-call-dialog" attributes="api">
<polymer-element name="partial-dev-call-service" attributes="narrow togglePanel">
<template>
<ha-action-dialog
id="dialog"
heading="Call Service"
closeSelector='[dismissive]'>
<style>
.form {
padding: 24px;
}
</style>
<core-style ref='ha-dialog'></core-style>
<partial-base narrow="{{narrow}}" togglePanel="{{togglePanel}}">
<span header-title>Call Service</span>
<div layout horizontal>
<div layout horizontal?="{{!narrow}}" vertical?="{{narrow}}" class='form' flex?="{{!narrow}}">
<div class='ha-form'>
<paper-input id="inputDomain" label="Domain" floatingLabel="true" autofocus required></paper-input>
<paper-input id="inputService" label="Service" floatingLabel="true" required></paper-input>
<paper-input-decorator
label="Service Data (JSON, optional)"
floatingLabel="true">
<!--
<paper-autogrow-textarea id="inputDataWrapper">
<textarea id="inputData"></textarea>
</paper-autogrow-textarea>
-->
<textarea id="inputData" rows="5"></textarea>
</paper-input-decorator>
<paper-button on-click={{clickCallService}}>Call Service</paper-button>
</div>
<div class='sidebar'>
@ -39,9 +42,9 @@
</div>
</div>
<paper-button dismissive>Cancel</paper-button>
<paper-button affirmative on-click={{clickCallService}}>Call Service</paper-button>
</ha-action-dialog>
</partial-base>
</template>
<script>
@ -51,15 +54,6 @@ Polymer({
this.serviceSelected = this.serviceSelected.bind(this);
},
show: function(domain, service, serviceData) {
this.setService(domain, service);
this.$.inputData.value = serviceData || "";
// this.$.inputDataWrapper.update();
this.job('showDialogAfterRender', function() {
this.$.dialog.toggle();
}.bind(this));
},
setService: function(domain, service) {
this.$.inputDomain.value = domain;
this.$.inputService.value = service;
@ -75,13 +69,11 @@ Polymer({
this.$.inputDomain.value,
this.$.inputService.value,
this.$.inputData.value ? JSON.parse(this.$.inputData.value) : {});
this.$.dialog.close();
} catch (err) {
alert("Error parsing JSON: " + err);
}
}
});
</script>
</polymer-element>

View File

@ -4,33 +4,37 @@
<link rel="import" href="../bower_components/paper-input/paper-input-decorator.html">
<link rel="import" href="../bower_components/paper-input/paper-autogrow-textarea.html">
<link rel="import" href="ha-action-dialog.html">
<link rel="import" href="./partial-base.html">
<link rel="import" href="../components/events-list.html">
<polymer-element name="event-fire-dialog" attributes="api">
<polymer-element name="partial-dev-fire-event" attributes="narrow togglePanel">
<template>
<ha-action-dialog
id="dialog"
heading="Fire Event"
class='two-column'
closeSelector='[dismissive]'>
<style>
.form {
padding: 24px;
}
</style>
<div layout horizontal>
<div class='ha-form'>
<partial-base narrow="{{narrow}}" togglePanel="{{togglePanel}}">
<span header-title>Fire Event</span>
<div layout horizontal?="{{!narrow}}" vertical?="{{narrow}}" class='form' flex>
<div class='ha-form' flex?="{{!narrow}}">
<paper-input
id="inputType" label="Event Type" floatingLabel="true"
autofocus required></paper-input>
<paper-input-decorator
label="Event Data (JSON, optional)"
floatingLabel="true">
<!--
<paper-autogrow-textarea id="inputDataWrapper">
<textarea id="inputData"></textarea>
</paper-autogrow-textarea>
-->
<textarea id="inputData" rows="5"></textarea>
</paper-input-decorator>
<paper-button on-click={{clickFireEvent}}>Fire Event</paper-button>
</div>
<div class='sidebar'>
@ -39,9 +43,7 @@
</div>
</div>
<paper-button dismissive>Cancel</paper-button>
<paper-button affirmative on-click={{clickFireEvent}}>Fire Event</paper-button>
</ha-action-dialog>
</partial-base>
</template>
<script>
@ -51,26 +53,8 @@ Polymer({
this.eventSelected = this.eventSelected.bind(this);
},
show: function(eventType, eventData) {
this.setEventType(eventType);
this.setEventData(eventData);
this.job('showDialogAfterRender', function() {
this.$.dialog.toggle();
}.bind(this));
},
setEventType: function(eventType) {
this.$.inputType.value = eventType;
},
setEventData: function(eventData) {
this.$.inputData.value = eventData || "";
// this.$.inputDataWrapper.update();
},
eventSelected: function(eventType) {
this.setEventType(eventType);
this.$.inputType.value = eventType;
},
clickFireEvent: function() {
@ -78,7 +62,6 @@ Polymer({
window.hass.eventActions.fire(
this.$.inputType.value,
this.$.inputData.value ? JSON.parse(this.$.inputData.value) : {});
this.$.dialog.close();
} catch (err) {
alert("Error parsing JSON: " + err);

View File

@ -0,0 +1,101 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/paper-button/paper-button.html">
<link rel="import" href="../bower_components/paper-input/paper-input.html">
<link rel="import" href="../bower_components/paper-input/paper-input-decorator.html">
<link rel="import" href="../bower_components/paper-input/paper-autogrow-textarea.html">
<link rel="import" href="./partial-base.html">
<link rel="import" href="../components/entity-list.html">
<polymer-element name="partial-dev-set-state" attributes="narrow togglePanel">
<template>
<style>
.form {
padding: 24px;
}
</style>
<partial-base narrow="{{narrow}}" togglePanel="{{togglePanel}}">
<span header-title>Set State</span>
<div class='form'>
<div>
This dialog will update the representation of the device within Home Assistant.<br />
This will not communicate with the actual device.
</div>
<div layout horizontal?="{{!narrow}}" vertical?="{{narrow}}">
<div class='ha-form' flex?="{{!narrow}}">
<paper-input id="inputEntityID" label="Entity ID" floatingLabel="true" autofocus required></paper-input>
<paper-input id="inputState" label="State" floatingLabel="true" required></paper-input>
<paper-input-decorator
label="State attributes (JSON, optional)"
floatingLabel="true">
<paper-autogrow-textarea id="inputDataWrapper">
<textarea id="inputData"></textarea>
</paper-autogrow-textarea>
</paper-input-decorator>
<paper-button on-click={{clickSetState}}>Set State</paper-button>
</div>
<div class='sidebar'>
<b>Current entities:</b>
<entity-list api={{api}} cbEntityClicked={{entitySelected}}></entity-list>
</div>
</div>
</div>
</partial-base>
</template>
<script>
Polymer({
ready: function() {
// to ensure callback methods work..
this.entitySelected = this.entitySelected.bind(this);
},
setEntityId: function(entityId) {
this.$.inputEntityID.value = entityId;
},
setState: function(state) {
this.$.inputState.value = state;
},
setStateData: function(stateData) {
var value = stateData ? JSON.stringify(stateData, null, ' ') : "";
this.$.inputData.value = value;
// not according to the spec but it works...
this.$.inputDataWrapper.update(this.$.inputData);
},
entitySelected: function(entityId) {
this.setEntityId(entityId);
var state = window.hass.stateStore.get(entityId);
this.setState(state.state);
this.setStateData(state.attributes);
},
clickSetState: function(ev) {
try {
window.hass.stateActions.set(
this.$.inputEntityID.value,
this.$.inputState.value,
this.$.inputData.value ? JSON.parse(this.$.inputData.value) : {}
);
} catch (err) {
alert("Error parsing JSON: " + err);
}
}
});
</script>
</polymer-element>

View File

@ -0,0 +1,49 @@
<link rel="import" href="./partial-base.html">
<link rel="import" href="../components/state-timeline.html">
<polymer-element name="partial-history" attributes="narrow togglePanel">
<template>
<style>
state-timeline {
background-color: white;
}
</style>
<partial-base narrow="{{narrow}}" togglePanel="{{togglePanel}}">
<span header-title>History</span>
<span header-buttons>
<paper-icon-button icon="refresh"
on-click="{{handleRefreshClick}}"></paper-icon-button>
</span>
<state-timeline id='timeline'></state-timeline>
</partial-base>
</template>
<script>
Polymer({
ready: function() {
this.$.timeline.fetchData();
// this.stateStoreChanged = this.stateStoreChanged.bind(this);
// window.hass.stateStore.addChangeListener(this.stateStoreChanged);
// this.stateStoreChanged();
},
detached: function() {
// window.hass.stateStore.removeChangeListener(this.stateStoreChanged);
},
stateStoreChanged: function() {
// this.states = _.filter(window.hass.stateStore.all(), function(state) {
// return state.domain !== 'group';
// });
},
handleRefreshClick: function() {
this.$.timeline.fetchData();
},
});
</script>
</polymer>

View File

@ -1,7 +1,17 @@
<link rel="import" href="./partial-base.html">
<link rel="import" href="../components/state-cards.html">
<polymer-element name="partial-states">
<polymer-element name="partial-states" attributes="narrow togglePanel filter">
<template>
<partial-base narrow="{{narrow}}" togglePanel="{{togglePanel}}">
<span header-title>States</span>
<span header-buttons>
<paper-icon-button icon="refresh"
on-click="{{handleRefreshClick}}"></paper-icon-button>
</span>
<state-cards states="{{states}}">
<h3>Hi there!</h3>
<p>
@ -11,7 +21,7 @@
Please see the <a href='https://home-assistant.io/getting-started/' target='_blank'>Getting Started</a> section on how to setup your devices.
</p>
</state-cards>
</partial-base>
</template>
<script>
Polymer({
@ -21,7 +31,7 @@
this.stateStoreChanged = this.stateStoreChanged.bind(this);
window.hass.stateStore.addChangeListener(this.stateStoreChanged);
this.stateStoreChanged();
this.refreshStates();
},
detached: function() {
@ -29,9 +39,27 @@
},
stateStoreChanged: function() {
this.states = _.filter(window.hass.stateStore.all(), function(state) {
return state.domain !== 'group';
});
this.refreshStates();
},
filterChanged: function() {
this.refreshStates();
},
refreshStates: function() {
if (this.filter == 'group') {
this.states = _.filter(window.hass.stateStore.all(), function(state) {
return state.domain === 'group';
});
} else {
this.states = _.filter(window.hass.stateStore.all(), function(state) {
return state.domain !== 'group';
});
}
},
handleRefreshClick: function() {
window.hass.syncActions.sync();
},
});
</script>

View File

@ -29,6 +29,10 @@ Polymer({
this.$.moreInfo.removeChild(this.$.moreInfo.lastChild);
}
if (!this.stateObj.moreInfoType) {
return;
}
var moreInfo = document.createElement("more-info-" + this.stateObj.moreInfoType);
moreInfo.stateObj = this.stateObj;
this.$.moreInfo.appendChild(moreInfo);

View File

@ -3,6 +3,18 @@
<polymer-element name="home-assistant-style" noscript>
<template>
<core-style id="ha-headers">
core-scroll-header-panel, core-header-panel {
background-color: #E5E5E5;
}
core-toolbar {
background: #03a9f4;
color: white;
font-weight: normal;
}
</core-style>
<core-style id="ha-dialog">
:host {
font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial;