I like @thejeffreystone 's heavy breathing. [0094ce9b6a/config/packages/notify.yaml
] for #758
This commit is contained in:
parent
21524fe99d
commit
2345afd2a5
|
@ -27,6 +27,7 @@ homeassistant:
|
||||||
- type: trusted_networks
|
- type: trusted_networks
|
||||||
trusted_networks:
|
trusted_networks:
|
||||||
- 192.168.10.0/24
|
- 192.168.10.0/24
|
||||||
|
- !secret external_ip
|
||||||
allow_bypass_login: true
|
allow_bypass_login: true
|
||||||
|
|
||||||
system_health:
|
system_health:
|
||||||
|
@ -90,8 +91,8 @@ http:
|
||||||
server_port: !secret http_port
|
server_port: !secret http_port
|
||||||
ssl_certificate: !secret ssl_certificate
|
ssl_certificate: !secret ssl_certificate
|
||||||
ssl_key: !secret ssl_key
|
ssl_key: !secret ssl_key
|
||||||
# ip_ban_enabled: True
|
ip_ban_enabled: True
|
||||||
# login_attempts_threshold: 2
|
login_attempts_threshold: 2
|
||||||
|
|
||||||
frontend:
|
frontend:
|
||||||
javascript_version: latest
|
javascript_version: latest
|
||||||
|
@ -255,7 +256,7 @@ tts:
|
||||||
region_name: 'us-east-1'
|
region_name: 'us-east-1'
|
||||||
text_type: ssml
|
text_type: ssml
|
||||||
cache: True
|
cache: True
|
||||||
base_url: !secret internal_url
|
# base_url: !secret external_url
|
||||||
# cache_dir: /data/tts
|
# cache_dir: /data/tts
|
||||||
|
|
||||||
wink:
|
wink:
|
||||||
|
|
|
@ -60,8 +60,7 @@ automation:
|
||||||
state: 'error'
|
state: 'error'
|
||||||
|
|
||||||
action:
|
action:
|
||||||
- wait_template: >-
|
- wait_template: "{{ states.group.family.state == 'home' }}"
|
||||||
{{ states.group.family.state == 'home' }}
|
|
||||||
|
|
||||||
- service: script.speech_engine
|
- service: script.speech_engine
|
||||||
data_template:
|
data_template:
|
||||||
|
|
|
@ -74,15 +74,12 @@ speech_processing:
|
||||||
|
|
||||||
- service: tts.amazon_polly_say
|
- service: tts.amazon_polly_say
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: >
|
entity_id: media_player.livingroomCC
|
||||||
{% if states.group.bed.state == 'off' %}
|
|
||||||
media_player.livingroomCC
|
|
||||||
{% else %}
|
|
||||||
media_player.livingroomCC
|
|
||||||
{% endif %}
|
|
||||||
message: >-
|
message: >-
|
||||||
<speak>
|
<speak>
|
||||||
|
<amazon:auto-breaths>
|
||||||
{{ value1 }}
|
{{ value1 }}
|
||||||
|
</amazon:auto-breaths>
|
||||||
</speak>
|
</speak>
|
||||||
cache: true
|
cache: true
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -0,0 +1,10 @@
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: './src/main.js',
|
||||||
|
mode: 'production',
|
||||||
|
output: {
|
||||||
|
filename: 'card-tools.js',
|
||||||
|
path: path.resolve(__dirname)
|
||||||
|
}
|
||||||
|
};
|
Binary file not shown.
|
@ -0,0 +1,193 @@
|
||||||
|
customElements.whenDefined('card-tools').then(() => {
|
||||||
|
var ct = customElements.get('card-tools');
|
||||||
|
|
||||||
|
const BUILTIN_ACTIONS = [
|
||||||
|
{
|
||||||
|
matches: '^((magnet:.*)|(.*\.torrent.*))$',
|
||||||
|
name: 'Add to Transmission',
|
||||||
|
icon: 'mdi:progress-download',
|
||||||
|
service: 'transmission.add_torrent',
|
||||||
|
service_data: {
|
||||||
|
torrent: '{1}'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const matchAndReplace = (text, matches) => {
|
||||||
|
for (var i = 0; i < matches.length; i++) {
|
||||||
|
text = text.replace('{' + i + '}', matches[i]);
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchCard extends ct.LitElement {
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
config: {},
|
||||||
|
hass: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
setConfig(config) {
|
||||||
|
this.results = [];
|
||||||
|
this.config = config;
|
||||||
|
|
||||||
|
this.active_actions = [];
|
||||||
|
this.max_results = this.config.max_results || 10;
|
||||||
|
|
||||||
|
this.actions = BUILTIN_ACTIONS.concat(this.config.actions || []);
|
||||||
|
}
|
||||||
|
|
||||||
|
getCardSize() {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
var results = this.results.slice(0, this.max_results).sort();
|
||||||
|
var rows = results.map((entity_id) => this._createResultRow(entity_id));
|
||||||
|
var actions = this.active_actions.map((x) => this._createActionRow(x[0], x[1]));
|
||||||
|
return ct.LitHtml `
|
||||||
|
<ha-card>
|
||||||
|
<div id="searchContainer">
|
||||||
|
<paper-input id="searchText"
|
||||||
|
@value-changed="${this._valueChanged}"
|
||||||
|
no-label-float
|
||||||
|
label="Type to search...">
|
||||||
|
<iron-icon icon="mdi:magnify"
|
||||||
|
slot="prefix"></iron-icon>
|
||||||
|
<paper-icon-button slot="suffix"
|
||||||
|
@click="${this._clearInput}"
|
||||||
|
icon="mdi:close"
|
||||||
|
alt="Clear"
|
||||||
|
title="Clear"></paper-icon-button>
|
||||||
|
</paper-input>
|
||||||
|
${results.length > 0 ?
|
||||||
|
ct.LitHtml `<div id="count">Showing ${results.length} of ${this.results.length} results</div>`
|
||||||
|
: ''}
|
||||||
|
</div>
|
||||||
|
${(rows.length > 0 || actions.length > 0) ?
|
||||||
|
ct.LitHtml `<div id="results">${actions}${rows}</div>`
|
||||||
|
: ''}
|
||||||
|
</ha-card>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
_createResultRow(entity_id) {
|
||||||
|
var row = ct.createEntityRow({entity: entity_id});
|
||||||
|
row.addEventListener("click", () => ct.moreInfo(entity_id));
|
||||||
|
row.hass = this.hass;
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_createActionRow(action, matches) {
|
||||||
|
var service_data = action.service_data;
|
||||||
|
for (var key in service_data) {
|
||||||
|
service_data[key] = matchAndReplace(service_data[key], matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
const elem = cardTools.createThing("service-row", {
|
||||||
|
type: "call",
|
||||||
|
name: matchAndReplace(action.name, matches),
|
||||||
|
icon: action.icon || 'mdi:lamp',
|
||||||
|
service: action.service,
|
||||||
|
service_data: service_data,
|
||||||
|
});
|
||||||
|
elem.hass = this.hass;
|
||||||
|
return elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_clearInput()
|
||||||
|
{
|
||||||
|
this.shadowRoot.getElementById('searchText').value = '';
|
||||||
|
super.update()
|
||||||
|
}
|
||||||
|
|
||||||
|
_valueChanged(ev) {
|
||||||
|
var searchText = ev.target.value;
|
||||||
|
|
||||||
|
this.results = [];
|
||||||
|
this.active_actions = [];
|
||||||
|
|
||||||
|
if (!this.config || !this.hass || searchText === "") {
|
||||||
|
this.update();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
var searchRegex = new RegExp(searchText, 'i');
|
||||||
|
for (var entity_id in this.hass.states) {
|
||||||
|
if (
|
||||||
|
(entity_id.search(searchRegex) >= 0) ||
|
||||||
|
(
|
||||||
|
"friendly_name" in this.hass.states[entity_id].attributes &&
|
||||||
|
this.hass.states[entity_id].attributes.friendly_name.search(searchRegex) >= 0
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
this.results.push(entity_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
}
|
||||||
|
|
||||||
|
this.active_actions = this._getActivatedActions(searchText);
|
||||||
|
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
_getActivatedActions(searchText) {
|
||||||
|
var active = [];
|
||||||
|
|
||||||
|
for (const action of this.actions) {
|
||||||
|
if (this._serviceExists(action.service)) {
|
||||||
|
var matches = searchText.match(action.matches);
|
||||||
|
if (matches != null) {
|
||||||
|
active.push([action, matches]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
_serviceExists(serviceCall) {
|
||||||
|
var [domain, service] = serviceCall.split('.');
|
||||||
|
var servicesForDomain = this.hass.services[domain];
|
||||||
|
return servicesForDomain && service in servicesForDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return ct.LitCSS `
|
||||||
|
#searchContainer {
|
||||||
|
width: 90%;
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
#count {
|
||||||
|
text-align: right;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
#results {
|
||||||
|
width: 90%;
|
||||||
|
display: block;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('search-card', SearchCard);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if(customElements.get('card-tools')) return;
|
||||||
|
customElements.define('search-card', class extends HTMLElement{
|
||||||
|
setConfig() { throw new Error("Can't find card-tools. See https://github.com/thomasloven/lovelace-card-tools");}
|
||||||
|
});
|
||||||
|
}, 2000);
|
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Loading…
Reference in New Issue