I like @thejeffreystone 's heavy breathing. [0094ce9b6a/config/packages/notify.yaml] for #758

This commit is contained in:
ccostan 2020-06-03 16:36:46 -04:00
parent 21524fe99d
commit 2345afd2a5
11 changed files with 866 additions and 11 deletions

View File

@ -27,6 +27,7 @@ homeassistant:
- type: trusted_networks
trusted_networks:
- 192.168.10.0/24
- !secret external_ip
allow_bypass_login: true
system_health:
@ -90,8 +91,8 @@ http:
server_port: !secret http_port
ssl_certificate: !secret ssl_certificate
ssl_key: !secret ssl_key
# ip_ban_enabled: True
# login_attempts_threshold: 2
ip_ban_enabled: True
login_attempts_threshold: 2
frontend:
javascript_version: latest
@ -255,7 +256,7 @@ tts:
region_name: 'us-east-1'
text_type: ssml
cache: True
base_url: !secret internal_url
# base_url: !secret external_url
# cache_dir: /data/tts
wink:

View File

@ -60,8 +60,7 @@ automation:
state: 'error'
action:
- wait_template: >-
{{ states.group.family.state == 'home' }}
- wait_template: "{{ states.group.family.state == 'home' }}"
- service: script.speech_engine
data_template:

View File

@ -74,15 +74,12 @@ speech_processing:
- service: tts.amazon_polly_say
data_template:
entity_id: >
{% if states.group.bed.state == 'off' %}
media_player.livingroomCC
{% else %}
media_player.livingroomCC
{% endif %}
entity_id: media_player.livingroomCC
message: >-
<speak>
<amazon:auto-breaths>
{{ value1 }}
</amazon:auto-breaths>
</speak>
cache: true

File diff suppressed because one or more lines are too long

View File

@ -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)
}
};

View File

@ -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.