1
0
mirror of https://github.com/home-assistant/frontend.git synced 2026-02-15 07:25:54 +00:00
Files
frontend/panels/dev-service/ha-panel-dev-service.html
2017-11-26 10:05:07 -08:00

310 lines
8.3 KiB
HTML

<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
<link rel='import' href='../../bower_components/paper-button/paper-button.html'>
<link rel='import' href='../../bower_components/paper-input/paper-textarea.html'>
<link rel='import' href='../../bower_components/app-layout/app-header-layout/app-header-layout.html'>
<link rel='import' href='../../bower_components/app-layout/app-header/app-header.html'>
<link rel='import' href='../../bower_components/app-layout/app-toolbar/app-toolbar.html'>
<link rel="import" href="../../bower_components/app-storage/app-localstorage/app-localstorage-document.html">
<link rel='import' href='../../src/components/ha-menu-button.html'>
<link rel='import' href='../../src/components/entity/ha-entity-picker.html'>
<link rel='import' href='../../src/components/ha-service-picker.html'>
<link rel='import' href='../../src/resources/ha-style.html'>
<dom-module id='ha-panel-dev-service'>
<template>
<style include='ha-style'>
:host {
-ms-user-select: initial;
-webkit-user-select: initial;
-moz-user-select: initial;
}
.content {
padding: 16px;
}
.ha-form {
margin-right: 16px;
max-width: 400px;
}
.description {
margin-top: 24px;
white-space: pre-wrap;
}
.header {
@apply(--paper-font-title);
}
.attributes th {
text-align: left;
}
.attributes tr {
vertical-align: top;
}
.attributes tr:nth-child(odd) {
background-color: var(--table-row-background-color,#eee)
}
.attributes tr:nth-child(even) {
background-color: var(--table-row-alternative-background-color,#eee)
}
.attributes td:nth-child(3) {
white-space: pre-wrap;
word-break: break-word;
}
pre {
margin: 0;
}
h1 {
white-space: normal;
}
td {
padding: 4px;
}
.error {
color: var(--google-red-500);
}
</style>
<app-header-layout has-scrolling-region>
<app-header slot="header" fixed>
<app-toolbar>
<ha-menu-button narrow='[[narrow]]' show-menu='[[showMenu]]'></ha-menu-button>
<div main-title>Services</div>
</app-toolbar>
</app-header>
<app-localstorage-document
key='panel-dev-service-state-domain-service'
data='{{domainService}}'>
</app-localstorage-document>
<app-localstorage-document
key='[[_computeServicedataKey(domainService)]]'
data='{{serviceData}}'>
</app-localstorage-document>
<div class='content'>
<p>
The service dev tool allows you to call any available service in Home Assistant.
</p>
<div class='ha-form'>
<ha-service-picker
hass='[[hass]]'
value='{{domainService}}'
></ha-service-picker>
<template is='dom-if' if='[[_computeHasEntity(_attributes)]]'>
<ha-entity-picker
hass='[[hass]]'
value='[[_computeEntityValue(parsedJSON)]]'
on-change='_entityPicked'
disabled='[[!validJSON]]'
domain-filter='[[_computeEntityDomainFilter(_domain)]]'
allow-custom-entity
></ha-entity-picker>
</template>
<paper-textarea
always-float-label
label='Service Data (JSON, optional)'
value='{{serviceData}}'
></paper-textarea>
<paper-button
on-tap='_callService'
raised
disabled='[[!validJSON]]'
>Call Service</paper-button>
<template is='dom-if' if='[[!validJSON]]'>
<span class='error'>Invalid JSON</span>
</template>
</div>
<template is='dom-if' if='[[!domainService]]'>
<h1>Select a service to see the description</h1>
</template>
<template is='dom-if' if='[[domainService]]'>
<template is='dom-if' if='[[!_description]]'>
<h1>No description is available</h1>
</template>
<template is='dom-if' if='[[_description]]'>
<h3>[[_description]]</h3>
<table class='attributes'>
<tr>
<th>Parameter</th>
<th>Description</th>
<th>Example</th>
</tr>
<template is='dom-if' if='[[!_attributes.length]]'>
<tr><td colspan='3'>This service takes no parameters.</td></tr>
</template>
<template is='dom-repeat' items='[[_attributes]]' as='attribute'>
<tr>
<td><pre>[[attribute.key]]</pre></td>
<td>[[attribute.description]]</td>
<td>[[attribute.example]]</td>
</tr>
</template>
</table>
</template>
</template>
</div>
</app-header-layout>
</template>
</dom-module>
<script>
{
const ERROR_SENTINEL = {};
class HaPanelDevService extends Polymer.Element {
static get is() { return 'ha-panel-dev-service'; }
static get properties() {
return {
hass: {
type: Object,
},
narrow: {
type: Boolean,
value: false,
},
showMenu: {
type: Boolean,
value: false,
},
domainService: {
type: String,
observer: '_domainServiceChanged',
},
_domain: {
type: String,
computed: '_computeDomain(domainService)',
},
_service: {
type: String,
computed: '_computeService(domainService)',
},
serviceData: {
type: String,
value: '',
},
parsedJSON: {
type: Object,
computed: '_computeParsedServiceData(serviceData)'
},
validJSON: {
type: Boolean,
computed: '_computeValidJSON(parsedJSON)',
},
_attributes: {
type: Array,
computed: '_computeAttributesArray(hass, _domain, _service)',
},
_description: {
type: String,
computed: '_computeDescription(hass, _domain, _service)',
},
};
}
_domainServiceChanged() {
this.serviceData = '';
}
_computeAttributesArray(hass, domain, service) {
const serviceDomains = hass.config.services;
if (!(domain in serviceDomains)) return [];
if (!(service in serviceDomains[domain])) return [];
const fields = serviceDomains[domain][service].fields;
return Object.keys(fields).map(function (field) {
return Object.assign({ key: field }, fields[field]);
});
}
_computeDescription(hass, domain, service) {
const serviceDomains = hass.config.services;
if (!(domain in serviceDomains)) return undefined;
if (!(service in serviceDomains[domain])) return undefined;
return serviceDomains[domain][service].description;
}
_computeServicedataKey(domainService) {
return `panel-dev-service-state-servicedata.${domainService}`;
}
_computeDomain(domainService) {
return domainService.split('.', 1)[0];
}
_computeService(domainService) {
return domainService.split('.', 2)[1] || null;
}
_computeParsedServiceData(serviceData) {
try {
return serviceData ? JSON.parse(serviceData) : {};
} catch (err) {
return ERROR_SENTINEL;
}
}
_computeValidJSON(parsedJSON) {
return parsedJSON !== ERROR_SENTINEL;
}
_computeHasEntity(attributes) {
return attributes.some(attr => attr.key === 'entity_id');
}
_computeEntityValue(parsedJSON) {
return parsedJSON === ERROR_SENTINEL ? '' : parsedJSON.entity_id;
}
_computeEntityDomainFilter(domain) {
return domain === 'homeassistant' ? null : domain;
}
_callService() {
if (this.parsedJSON === ERROR_SENTINEL) {
// eslint-disable-next-line
alert(`Error parsing JSON: ${this.serviceData}`);
}
this.hass.callService(this._domain, this._service, this.parsedJSON);
}
_entityPicked(ev) {
this.serviceData = JSON.stringify(Object.assign({}, this.parsedJSON, {
entity_id: ev.target.value
}), null, 2);
}
}
customElements.define(HaPanelDevService.is, HaPanelDevService);
}
</script>