Compare commits

..

1 Commits

Author SHA1 Message Date
183d2a2ae9 New entity for controlling master bedroom climate modes 2025-06-13 21:06:51 -04:00
30 changed files with 46 additions and 876 deletions

View File

@ -1 +1 @@
2025.7.1
2025.6.0

1
.gitignore vendored
View File

@ -20,7 +20,6 @@
/glances/
/downloads/
/lightwand/
/bubble/Scratchpad/
# ignore any of these files no matter where they are using double *
**.DS_Store

View File

@ -5587,59 +5587,53 @@
- id: '1722386174249'
alias: Tina Meds Cleanup
description: Handles the setting/clearing of medication configs for Tina
triggers:
- entity_id:
trigger:
- platform: state
entity_id:
- input_boolean.tina_morning_meds_reminder
from: 'on'
to: 'off'
id: morning-reminders-off
alias: Morning reminders off
trigger: state
- alias: Night reminders off
platform: state
entity_id:
- input_boolean.tina_night_meds_reminder
from: 'on'
to: 'off'
id: night-reminders-off
trigger: state
- event_type: ios.notification_action_fired
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: TINA_MORNING_MEDS_TAKEN
id: morning-taken
alias: Morning taken
trigger: event
- alias: Night taken
platform: event
event_type: ios.notification_action_fired
event_data:
actionName: TINA_NIGHT_MEDS_TAKEN
id: night-taken
trigger: event
- alias: Morning skipped
platform: event
event_type: ios.notification_action_fired
event_data:
actionName: TINA_MORNING_MEDS_SKIPPED
id: morning-skipped
trigger: event
- alias: Night skipped
platform: event
event_type: ios.notification_action_fired
event_data:
actionName: TINA_NIGHT_MEDS_SKIPPED
id: night-skipped
trigger: event
- entity_id:
- platform: state
entity_id:
- person.christina_stork
from: home
id: left
alias: Left
trigger: state
- trigger: state
entity_id:
- person.christina_stork
to: Bob Evans
id: at-work
alias: At Work
conditions: []
actions:
condition: []
action:
- alias: Routing
choose:
- conditions:
@ -5648,19 +5642,19 @@
- morning-reminders-off
alias: Morning Reminders Off
sequence:
- metadata: {}
- service: counter.reset
metadata: {}
data: {}
target:
entity_id: counter.tina_morning_meds_reminder_count
alias: Reset morning reminder count
action: counter.reset
- data:
- service: script.text_notify
data:
type: alert
who: tina
message: clear_notification
tag: tina-morning-meds
alias: Clear morning notification
action: script.text_notify
- conditions:
- condition: trigger
id:
@ -5668,66 +5662,66 @@
alias: Night reminders off
sequence:
- alias: Reset night reminder count
service: counter.reset
metadata: {}
data: {}
target:
entity_id: counter.tina_night_meds_reminder_count
action: counter.reset
- data:
- service: script.text_notify
data:
type: alert
who: tina
message: clear_notification
tag: tina-night-meds
alias: Clear night notification
action: script.text_notify
- conditions:
- condition: trigger
id:
- morning-taken
alias: Morning taken
sequence:
- metadata: {}
- service: input_boolean.turn_on
metadata: {}
data: {}
target:
entity_id: input_boolean.tina_morning_meds_taken
alias: Turn on morning meds taken
action: input_boolean.turn_on
- conditions:
- condition: trigger
id:
- night-taken
alias: Night taken
sequence:
- metadata: {}
- service: input_boolean.turn_on
metadata: {}
data: {}
target:
entity_id: input_boolean.tina_night_meds_taken
alias: Turn on night meds taken
action: input_boolean.turn_on
- conditions:
- condition: trigger
id:
- morning-skipped
alias: Morning skipped
sequence:
- metadata: {}
- service: input_boolean.turn_off
metadata: {}
data: {}
target:
entity_id: input_boolean.tina_morning_meds_reminder
alias: Deactivate morning reminders
action: input_boolean.turn_off
- conditions:
- condition: trigger
id:
- night-skipped
alias: Night skipped
sequence:
- metadata: {}
- service: input_boolean.turn_off
metadata: {}
data: {}
target:
entity_id: input_boolean.tina_night_meds_reminder
alias: Deactivate night reminders
action: input_boolean.turn_off
- conditions:
- condition: trigger
id:
@ -5749,6 +5743,7 @@
alias: Night meds reminder active
then:
- alias: Send critical TTS notification
service: script.text_notify
metadata: {}
data:
type: critical
@ -5756,19 +5751,6 @@
title: HEY DUMBASS
message: YOU FORGOT TO TAKE YOUR MEDS!!!!!
tag: tina-left-meds
action: script.text_notify
- conditions:
- condition: trigger
id:
- at-work
alias: At Work
sequence:
- action: input_boolean.turn_off
metadata: {}
data: {}
target:
entity_id: input_boolean.tina_night_meds_taken
alias: Turn off Night Meds Taken
mode: queued
max: 10
- id: '1722387020007'

View File

@ -1,42 +0,0 @@
`${(() => {
const occupancy = hass?.states[this.config?.main_button_floors?.occupancy_entity]?.state || '';
const hot = hass?.states[this.config?.main_button_floors?.hot_entity]?.state || '';
const cold = hass?.states[this.config?.main_button_floors?.cold_entity]?.state || '';
let bg_color = 'var(--bubble-main-background-color)';
let occupied_color = 'var(--accent-color)';
let hot_color = 'var(--error-color)';
let cold_color = 'var(--purple-color)';
// Main button background
const mainButton = card?.querySelector('.bubble-button-background');
if (mainButton) {
mainButton.style.opacity = '1';
mainButton.style.backgroundColor = occupancy === 'on' ? occupied_color : bg_color;
mainButton.style.transition = 'background-color 1s';
}
// Sub button 1
const subButton1 = card?.querySelector('.bubble-sub-button-1');
if (subButton1) {
if (hot === 'on') {
subButton1.style.backgroundColor = hot_color;
} else if (cold === 'on') {
subButton1.style.backgroundColor = cold_color;
} else if (occupancy === 'on') {
subButton1.style.backgroundColor = occupied_color;
} else {
subButton1.style.backgroundColor = bg_color;
}
}
// Unavailable state
if (mainButton && occupancy === 'unavailable') {
mainButton.classList.add('is-unavailable');
} else if (mainButton) {
mainButton.classList.remove('is-unavailable');
}
// No CSS string needed
return '';
})()}`

View File

@ -1,22 +0,0 @@
- type: expandable
title: Entity Configuration
icon: mdi:format-list-bulleted
schema:
- name: occupancy_entity
label: Occupancy Entity
selector:
entity:
device_class: occupancy
required: false
- name: hot_entity
label: Hot Entity
selector:
entity:
device_class: heat
required: false
- name: cold_entity
label: Cold Entity
selector:
entity:
device_class: cold
required: false

View File

@ -1,73 +0,0 @@
main_button_floors:
name: Main Button Floors
version: '1.1'
creator: Tony Stork
supported:
- button
description: Module to provide theming for the main indoor floor buttons
code: |
${(() => {
const occupancy = hass?.states[this.config?.main_button_floors?.occupancy_entity]?.state || '';
const hot = hass?.states[this.config?.main_button_floors?.hot_entity]?.state || '';
const cold = hass?.states[this.config?.main_button_floors?.cold_entity]?.state || '';
let bg_color = 'var(--bubble-main-background-color)';
let occupied_color = 'var(--accent-color)';
let hot_color = 'var(--error-color)';
let cold_color = 'var(--purple-color)';
// Main button background
const mainButton = card?.querySelector('.bubble-button-background');
if (mainButton) {
mainButton.style.opacity = '1';
mainButton.style.backgroundColor = occupancy === 'on' ? occupied_color : bg_color;
mainButton.style.transition = 'background-color 1s';
}
// Sub button 1
const subButton1 = card?.querySelector('.bubble-sub-button-1');
if (subButton1) {
if (hot === 'on') {
subButton1.style.backgroundColor = hot_color;
} else if (cold === 'on') {
subButton1.style.backgroundColor = cold_color;
} else if (occupancy === 'on') {
subButton1.style.backgroundColor = occupied_color;
} else {
subButton1.style.backgroundColor = bg_color;
}
}
// Unavailable state
if (mainButton && occupancy === 'unavailable') {
mainButton.classList.add('is-unavailable');
} else if (mainButton) {
mainButton.classList.remove('is-unavailable');
}
// No CSS string needed
return '';
})()}
editor:
- type: expandable
title: Entity Configuration
icon: mdi:format-list-bulleted
schema:
- name: occupancy_entity
label: Occupancy Entity
selector:
entity:
device_class: occupancy
required: false
- name: hot_entity
label: Hot Entity
selector:
entity:
device_class: heat
required: false
- name: cold_entity
label: Cold Entity
selector:
entity:
device_class: cold
required: false

View File

@ -1,24 +0,0 @@
`${(() => {
const occupancy = hass?.states[this.config?.main_button_outdoors?.occupancy_entity]?.state || '';
let bg_color = 'var(--bubble-main-background-color)';
let occupied_color = 'var(--accent-color)';
// Main button background
const mainButton = card?.querySelector('.bubble-button-background');
if (mainButton) {
mainButton.style.opacity = '1';
mainButton.style.backgroundColor = occupancy === 'on' ? occupied_color : bg_color;
mainButton.style.transition = 'background-color 1s';
}
// Unavailable state
if (mainButton && occupancy === 'unavailable') {
mainButton.classList.add('is-unavailable');
} else if (mainButton) {
mainButton.classList.remove('is-unavailable');
}
// No CSS string needed
return '';
})()}`

View File

@ -1,10 +0,0 @@
- type: expandable
title: Entity Configuration
icon: mdi:format-list-bulleted
schema:
- name: occupancy_entity
label: Occupancy Entity
selector:
entity:
device_class: occupancy
required: false

View File

@ -1,43 +0,0 @@
main_button_outdoors:
name: Main Button Outdoors
version: '1.1'
creator: Tony Stork
supported:
- button
description: Module to provide theming for outdoor floor buttons
code: |
${(() => {
const occupancy = hass?.states[this.config?.main_button_outdoors?.occupancy_entity]?.state || '';
let bg_color = 'var(--bubble-main-background-color)';
let occupied_color = 'var(--accent-color)';
// Main button background
const mainButton = card?.querySelector('.bubble-button-background');
if (mainButton) {
mainButton.style.opacity = '1';
mainButton.style.backgroundColor = occupancy === 'on' ? occupied_color : bg_color;
mainButton.style.transition = 'background-color 1s';
}
// Unavailable state
if (mainButton && occupancy === 'unavailable') {
mainButton.classList.add('is-unavailable');
} else if (mainButton) {
mainButton.classList.remove('is-unavailable');
}
// No CSS string needed
return '';
})()}
editor:
- type: expandable
title: Entity Configuration
icon: mdi:format-list-bulleted
schema:
- name: occupancy_entity
label: Occupancy Entity
selector:
entity:
device_class: occupancy
required: false

View File

@ -1,24 +0,0 @@
`${(() => {
const state = hass?.states[this.config?.entity]?.state || '';
let bg_color = 'var(--background-color-2)';
let accent_color = 'var(--accent-color)';
// Main button background
const mainButton = card?.querySelector('.bubble-button-background');
if (mainButton) {
mainButton.style.opacity = '1';
mainButton.style.backgroundColor = state === 'on' ? accent_color : bg_color;
mainButton.style.transition = 'background-color 1s';
}
// Unavailable state
if (mainButton && state === 'unavailable') {
mainButton.classList.add('is-unavailable');
} else if (mainButton) {
mainButton.classList.remove('is-unavailable');
}
// No CSS string needed
return '';
})()}`

View File

@ -1,33 +0,0 @@
popup_accent_color_button:
name: Popup Accent Color Button
version: '1.0'
creator: Tony Stork
supported:
- button
description: Will turn the button to accent color variable if config entity is on, otherwise default style applies
code: |-
${(() => {
const state = hass?.states[this.config?.entity]?.state || '';
let bg_color = 'var(--background-color-2)';
let accent_color = 'var(--accent-color)';
// Main button background
const mainButton = card?.querySelector('.bubble-button-background');
if (mainButton) {
mainButton.style.opacity = '1';
mainButton.style.backgroundColor = state === 'on' ? accent_color : bg_color;
mainButton.style.transition = 'background-color 1s';
}
// Unavailable state
if (mainButton && state === 'unavailable') {
mainButton.classList.add('is-unavailable');
} else if (mainButton) {
mainButton.classList.remove('is-unavailable');
}
// No CSS string needed
return '';
})()}
editor: ''

View File

@ -1,24 +0,0 @@
`${(() => {
const state = hass?.states[this.config?.entity]?.state || '';
let bg_color = 'var(--background-color-2)';
let red_color = 'var(--error-color)';
// Main button background
const mainButton = card?.querySelector('.bubble-button-background');
if (mainButton) {
mainButton.style.opacity = '1';
mainButton.style.backgroundColor = state === 'on' ? red_color : bg_color;
mainButton.style.transition = 'background-color 1s';
}
// Unavailable state
if (mainButton && state === 'unavailable') {
mainButton.classList.add('is-unavailable');
} else if (mainButton) {
mainButton.classList.remove('is-unavailable');
}
// No CSS string needed
return '';
})()}`

View File

@ -1,33 +0,0 @@
popup_security_button:
name: Popup Security Button
version: '1.0'
creator: Tony Stork
supported:
- button
description: Will turn the button red if there is a security fault, otherwise default style applies
code: |-
${(() => {
const state = hass?.states[this.config?.entity]?.state || '';
let bg_color = 'var(--background-color-2)';
let red_color = 'var(--error-color)';
// Main button background
const mainButton = card?.querySelector('.bubble-button-background');
if (mainButton) {
mainButton.style.opacity = '1';
mainButton.style.backgroundColor = state === 'on' ? red_color : bg_color;
mainButton.style.transition = 'background-color 1s';
}
// Unavailable state
if (mainButton && state === 'unavailable') {
mainButton.classList.add('is-unavailable');
} else if (mainButton) {
mainButton.classList.remove('is-unavailable');
}
// No CSS string needed
return '';
})()}
editor: ''

View File

@ -1,32 +0,0 @@
`${(() => {
const hot = hass?.states[this.config?.popup_temperature_button?.hot_entity]?.state || '';
const cold = hass?.states[this.config?.popup_temperature_button?.cold_entity]?.state || '';
let bg_color = 'var(--background-color-2)';
let hot_color = 'var(--error-color)';
let cold_color = 'var(--cyan-color)';
// Main button background
const mainButton = card?.querySelector('.bubble-button-background');
if (mainButton) {
mainButton.style.opacity = '1';
if (hot === 'on') {
mainButton.style.backgroundColor = hot_color;
} else if (cold === 'on') {
mainButton.style.backgroundColor = cold_color;
} else {
mainButton.style.backgroundColor = bg_color;
}
mainButton.style.transition = 'background-color 1s';
}
// Unavailable state
if (mainButton && state === 'unavailable') {
mainButton.classList.add('is-unavailable');
} else if (mainButton) {
mainButton.classList.remove('is-unavailable');
}
// No CSS string needed
return '';
})()}`

View File

@ -1,14 +0,0 @@
- type: expandable
title: Entity Configuration
icon: mdi:format-list-bulleted
schema:
- name: hot_entity
label: Hot Entity
selector:
entity:
device_class: heat
- name: cold_entity
label: Cold Entity
selector:
entity:
device_class: cold

View File

@ -1,55 +0,0 @@
popup_temperature_button:
name: Popup Temperature Button
version: '1.0'
creator: Tony Stork
supported:
- button
description: Will turn the button red if the room is too hot, cyan if too cold, otherwise default style applies
code: |-
${(() => {
const hot = hass?.states[this.config?.popup_temperature_button?.hot_entity]?.state || '';
const cold = hass?.states[this.config?.popup_temperature_button?.cold_entity]?.state || '';
let bg_color = 'var(--background-color-2)';
let hot_color = 'var(--error-color)';
let cold_color = 'var(--cyan-color)';
// Main button background
const mainButton = card?.querySelector('.bubble-button-background');
if (mainButton) {
mainButton.style.opacity = '1';
if (hot === 'on') {
mainButton.style.backgroundColor = hot_color;
} else if (cold === 'on') {
mainButton.style.backgroundColor = cold_color;
} else {
mainButton.style.backgroundColor = bg_color;
}
mainButton.style.transition = 'background-color 1s';
}
// Unavailable state
if (mainButton && state === 'unavailable') {
mainButton.classList.add('is-unavailable');
} else if (mainButton) {
mainButton.classList.remove('is-unavailable');
}
// No CSS string needed
return '';
})()}
editor:
- type: expandable
title: Entity Configuration
icon: mdi:format-list-bulleted
schema:
- name: hot_entity
label: Hot Entity
selector:
entity:
device_class: heat
- name: cold_entity
label: Cold Entity
selector:
entity:
device_class: cold

View File

@ -1,92 +0,0 @@
:host{
--circle-color: var(--bubble-accent-color, var(--accent-color));
--percentage: ${(() => {
card.timerEntity = hass.states[entity];
const now = new Date();
const endTime = new Date(card.timerEntity.attributes.finishes_at);
const runningTime = Math.round((endTime - now) / 1000);
const maxtime = Math.round(new Date("1970-01-01 " + card.timerEntity.attributes.duration + " UTC") / 1000);
const remainingTime = Math.round(new Date("1970-01-01 " + card.timerEntity.attributes.remaining + " UTC") / 1000);
var percentage = 0;
if (isNaN(runningTime)) {
percentage = 100 - Math.round( 100.0 * remainingTime / maxtime);
} else {
percentage = 100 - Math.round( 100.0 * runningTime / maxtime);
}
if (isNaN(percentage)) {
return "0%";
} else {
return "" + percentage +"%";
}
})()};
}
.bubble-icon-container {
background: radial-gradient(
var(--card-background-color) 60%,
transparent 0%
), conic-gradient(
var(--circle-color) var(--percentage) 0%,
var(--card-background-color) 0% 100%
) !important;
}
.bubble-icon-container:after {
content: "" !important;
height: 100% !important;
width: 100% !important;
position: absolute !important;
border-radius: 50% !important;
background: (var(--bubble-button-icon-background-color), 0.1) !important;
}
${(() => {
function UpdateState(){
try {
let now = new Date();
let endTime = new Date(card.timerEntity.attributes.finishes_at);
let runningTime = Math.round((endTime - now)/1000);
let hours = Math.floor(runningTime / 3600);
let minutes = Math.floor((runningTime - (hours * 3600)) / 60);
let remainingSeconds = runningTime % 60;
card.querySelector('.bubble-state').innerText =
(hours > 0 ? (hours + ":") : "") +
("0" + minutes).slice(-2) + ":" +
("0" + remainingSeconds).slice(-2);
} catch (error) {
card.querySelector('.bubble-state').innerText = card.timerEntity.attributes.duration;
}
};
if (card.timer == null && card.timerEntity.state === 'active') {
card.timer = setInterval(()=>{UpdateState()}, 500);
}else if (card.timerEntity.state != 'active'){
clearInterval(card.timer);
card.timer = null;
if (card.timerEntity.state !='paused') {
card.querySelector('.bubble-state').innerText = card.timerEntity.attributes.duration;
} else if(card.timerEntity.state==='paused') {
card.querySelector('.bubble-state').innerText = card.timerEntity.attributes.remaining;
}
}
})()}
${(() => {
subButtonIcon[0].setAttribute("icon",card.timerEntity.state != 'active' ?'mdi:play' : 'mdi:replay');
})()}
${(() => {
if (card.timerEntity.state != 'active') {
card.querySelector('.bubble-sub-button-2').classList.add("hidden");
}
})()}
${(() => {
if (card.timerEntity.state === 'idle') {
card.querySelector('.bubble-sub-button-3').classList.add("hidden");
}
})()}
${(() => {
if (card.timerEntity.state === 'idle') {
card.querySelector('.bubble-sub-button-4').classList.add("hidden");
}
})()}

View File

@ -1,101 +0,0 @@
popup_timer_card:
name: Popup Timer Card
version: '1.0'
creator: Tony Stork
supported:
- button
description: Will turn the button red if the entity state is on, otherwise default style applies
code: |-
:host{
--circle-color: var(--bubble-accent-color, var(--accent-color));
--percentage: ${(() => {
card.timerEntity = hass.states[entity];
const now = new Date();
const endTime = new Date(card.timerEntity.attributes.finishes_at);
const runningTime = Math.round((endTime - now) / 1000);
const maxtime = Math.round(new Date("1970-01-01 " + card.timerEntity.attributes.duration + " UTC") / 1000);
const remainingTime = Math.round(new Date("1970-01-01 " + card.timerEntity.attributes.remaining + " UTC") / 1000);
var percentage = 0;
if (isNaN(runningTime)) {
percentage = 100 - Math.round( 100.0 * remainingTime / maxtime);
} else {
percentage = 100 - Math.round( 100.0 * runningTime / maxtime);
}
if (isNaN(percentage)) {
return "0%";
} else {
return "" + percentage +"%";
}
})()};
}
.bubble-icon-container {
background: radial-gradient(
var(--card-background-color) 60%,
transparent 0%
), conic-gradient(
var(--circle-color) var(--percentage) 0%,
var(--card-background-color) 0% 100%
) !important;
}
.bubble-icon-container:after {
content: "" !important;
height: 100% !important;
width: 100% !important;
position: absolute !important;
border-radius: 50% !important;
background: (var(--bubble-button-icon-background-color), 0.1) !important;
}
${(() => {
function UpdateState(){
try {
let now = new Date();
let endTime = new Date(card.timerEntity.attributes.finishes_at);
let runningTime = Math.round((endTime - now)/1000);
let hours = Math.floor(runningTime / 3600);
let minutes = Math.floor((runningTime - (hours * 3600)) / 60);
let remainingSeconds = runningTime % 60;
card.querySelector('.bubble-state').innerText =
(hours > 0 ? (hours + ":") : "") +
("0" + minutes).slice(-2) + ":" +
("0" + remainingSeconds).slice(-2);
} catch (error) {
card.querySelector('.bubble-state').innerText = card.timerEntity.attributes.duration;
}
};
if (card.timer == null && card.timerEntity.state === 'active') {
card.timer = setInterval(()=>{UpdateState()}, 500);
}else if (card.timerEntity.state != 'active'){
clearInterval(card.timer);
card.timer = null;
if (card.timerEntity.state !='paused') {
card.querySelector('.bubble-state').innerText = card.timerEntity.attributes.duration;
} else if(card.timerEntity.state==='paused') {
card.querySelector('.bubble-state').innerText = card.timerEntity.attributes.remaining;
}
}
})()}
${(() => {
subButtonIcon[0].setAttribute("icon",card.timerEntity.state != 'active' ?'mdi:play' : 'mdi:replay');
})()}
${(() => {
if (card.timerEntity.state != 'active') {
card.querySelector('.bubble-sub-button-2').classList.add("hidden");
}
})()}
${(() => {
if (card.timerEntity.state === 'idle') {
card.querySelector('.bubble-sub-button-3').classList.add("hidden");
}
})()}
${(() => {
if (card.timerEntity.state === 'idle') {
card.querySelector('.bubble-sub-button-4').classList.add("hidden");
}
})()}
editor: ''

View File

@ -1,21 +0,0 @@
rotating_icon:
name: Rotating Icon
version: '0.1'
creator: Tony Stork
supported:
- button
- climate
- media-player
- pop-up
- separator
- horizontal-buttons-stack
description: Simple, make the icon rotate when the config entity is on
code: |-
.bubble-icon {
animation: ${state === 'on' ? 'slow-rotate 2s linear infinite' : ''};
}
@keyframes slow-rotate {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
editor: ''

View File

@ -1,34 +0,0 @@
`${(() => {
let state;
if (this.config?.state_color_button?.alt_entity) {
state = hass?.states[this.config?.state_color_button?.alt_entity]?.state || '';
} else {
state = hass?.states[this.config?.entity]?.state || '';
}
let bg_color = 'var(--bubble-main-background-color)';
// Use the configured color or default to accent color
let on_color = this.config?.state_color_button?.color
? `var(--${this.config.state_color_button.color})`
: 'var(--accent-color)';
// Main button background
const mainButton = card?.querySelector('.bubble-button-background');
if (mainButton) {
mainButton.style.opacity = '1';
mainButton.style.backgroundColor = state === 'on' ? on_color : bg_color;
mainButton.style.transition = 'background-color 1s';
}
// Unavailable state
if (mainButton && state === 'unavailable') {
mainButton.style.opacity = '0.5';
mainButton.classList.add('is-unavailable');
} else if (mainButton) {
mainButton.classList.remove('is-unavailable');
}
// No CSS string needed
return '';
})()}`

View File

@ -1,10 +0,0 @@
- name: color
label: Color (CSS Variable)
selector:
text: {}
required: false
- name: alt_entity
label: Entity (Optional, overrides main config)
selector:
entity: {}
required: false

View File

@ -1,61 +0,0 @@
state_color_button:
name: State Color Button
version: 1.1.2
creator: Tony Stork
supported:
- button
description: |-
Module for status buttons that turn a color based on the state of the config entity. Will default to the accent color in your theme. Use the name of a CSS variable. You can also specify an alternate entity to get state from, this will override the main card config.
<br><br>
Example:
<br><br>
<code-block><pre>
color: error-color
alt_entity: sensor.your_face
</pre></code-block>
code: |-
${(() => {
let state;
if (this.config?.state_color_button?.alt_entity) {
state = hass?.states[this.config?.state_color_button?.alt_entity]?.state || '';
} else {
state = hass?.states[this.config?.entity]?.state || '';
}
let bg_color = 'var(--bubble-main-background-color)';
// Use the configured color or default to accent color
let on_color = this.config?.state_color_button?.color
? `var(--${this.config.state_color_button.color})`
: 'var(--accent-color)';
// Main button background
const mainButton = card?.querySelector('.bubble-button-background');
if (mainButton) {
mainButton.style.opacity = '1';
mainButton.style.backgroundColor = state === 'on' ? on_color : bg_color;
mainButton.style.transition = 'background-color 1s';
}
// Unavailable state
if (mainButton && state === 'unavailable') {
mainButton.style.opacity = '0.5';
mainButton.classList.add('is-unavailable');
} else if (mainButton) {
mainButton.classList.remove('is-unavailable');
}
// No CSS string needed
return '';
})()}
editor:
- name: color
label: Color (CSS Variable)
selector:
text: {}
required: false
- name: alt_entity
label: Entity (Optional, overrides main config)
selector:
entity: {}
required: false

View File

@ -825,21 +825,7 @@
'ottobre',
'novembre',
'dicembre',
],
'time_of_hour':{
0: '{hour}',
1: '{hour} e un minuto',
15: '{hour} ed un quarto',
30: '{hour} e mezzo',
45: '15 minuti alle {hour}',
59: 'un minuto alle {hour}',
'past_hour': '{hour} e {minute}',
'to_hour': '{hour} meno {minute}',
},
'time_of_day':{
'midnight': 'mezzanotte',
'noon': 'mezzogiorno',
}
]
},
'pt':{
'_language': 'Português',
@ -1055,21 +1041,7 @@
'Październik',
'Listopad',
'Grudzień',
],
'time_of_hour': {
0: '{hour}',
1: 'minuta po {hour}',
15: 'kwadrans po {hour}',
30: 'pół godziny po {hour}',
45: 'za kwadrans {hour}',
59: 'za minutę {hour}',
'past_hour': '{minute} po {hour}',
'to_hour': '{minute} do {hour}'
},
'time_of_day': {
'midnight': 'północ',
'noon': 'południe'
}
]
},
'ru':{
'_language': 'Русский',
@ -1807,9 +1779,9 @@
{%- else %}
{%- set t = translate('ago', language=language) %}
{%- if '%s' in t %}
{{- t % items }}
{{ t % items }}
{%- else %}
{{- items }} {{ t }}
{{- items }} {{ translate('ago', language=language) }}
{%- endif %}
{%- endif %}
{%- else %}
@ -2073,7 +2045,7 @@
{%- if '%s' in t %}
{{- t % ret }}
{%- else %}
{{- ret }} {{ t }}
{{- ret }} {{ translate('ago', language=language) }}
{%- endif %}
{%- endif %}
{%- endif %}

View File

@ -236,7 +236,7 @@
'hour': ['ч', 'час', 'часа', 'часов'],
'minute': ['м', 'минута', 'минуты', 'минут'],
'second': ['с', 'секунда', 'секунды', 'секунд'],
'millisecond': ['мс', 'миллисекунда', 'миллисекунды', 'миллисекунд'],
'millisecond': ['мс', 'милисекунда', 'милисекунды', 'милисекунд'],
'combine': 'и',
'error': 'Неверная дата',
}
@ -337,22 +337,6 @@
'error': 'Érvénytelen dátum',
}
},
{
'language': 'tr',
'plural_form': 'english',
'phrases': {
'year': ['yıl', 'yıl', 'yıl'],
'month': ['ay', 'ay', 'ay'],
'week': ['hf', 'hafta', 'hafta'],
'day': ['gün', 'gün', 'gün'],
'hour': ['sa', 'saat', 'saat'],
'minute': ['dk', 'dakika', 'dakika'],
'second': ['sn', 'saniye', 'saniye'],
'millisecond': ['ms', 'milisaniye', 'milisaniye'],
'combine': 've',
'error': 'Geçersiz tarih',
}
},
] -%}
{# macro to convert the abbreviated input for the not_use and always_show lists to the full time part names #}

View File

@ -27,15 +27,8 @@
{% set period_str = period_str(team) %}
{% set game_clock = state_attr(team,'clock') | lower %}
{% if state_attr(team,'league') == 'MLB' %}
{% if 'rain delay' in game_clock %}
{# Handle cases like "Rain Delay, Top 1st" #}
{% set status, inning = game_clock.split(',', 1) %}
{% set inning_parts = inning.split(' ') %}
in a {{ status | trim }} in the {{ inning_parts[1] ~ ' of the ' ~ inning_parts[2] }} {{ period_str }}
{% else %}
{% set inning_parts = game_clock.split(' ') %}
in the {{ inning_parts[0] ~ ' of the ' ~ inning_parts[1] ~ ' ' ~ period_str }}
{% endif %}
{% set inning_parts = game_clock.split(' ') %}
in the {{ inning_parts[0] ~ ' of the ' ~ inning_parts[1] ~ ' ' ~ period_str }}
{% else %}
{% if ' - ' in game_clock %}
{% set clock_time, quarter = game_clock.split(' - ') %}

View File

@ -239,9 +239,6 @@ script:
server_maintenance_annc:
alias: Server Maintenance Announcement
sequence:
- service: input_boolean.turn_on
target:
entity_id: input_boolean.server_maintenance
- service: script.status_annc
data:
who: "{{ who|default('everywhere') }}"
@ -251,9 +248,6 @@ script:
server_maintenance_done_annc:
alias: Server Maintenance Done Announcement
sequence:
- service: input_boolean.turn_off
target:
entity_id: input_boolean.server_maintenance
- service: script.status_annc
data:
who: "{{ who|default('everywhere') }}"

View File

@ -273,6 +273,14 @@ input_select:
- White Noise
- N/A
icon: mdi:home-thermometer
current_climate_mode_master_bedroom:
name: Current Climate Mode - Master Bedroom
options:
- None
- Day Mode
- Night Mode
- Bedtime Mode
- Shower Mode
input_number:
master_bedroom_daytime_temp:

View File

@ -13,10 +13,3 @@ sensor:
state_characteristic: mean
max_age:
hours: 24
binary_sensor:
- platform: trend
sensors:
local_average_gas_trend:
entity_id: sensor.local_average_gas_price
friendly_name: Local Average Gas Trend
unique_id: 3405a536-1e02-412f-916b-1a62c9cb8a2e

View File

@ -1,8 +1,3 @@
input_boolean:
server_maintenance:
name: Server Maintenance
icon: mdi:wrench-clock
input_select:
log_level:
name: Log Level

View File

@ -57,7 +57,6 @@ ## HACS Components
- [GasBuddy](https://github.com/firstof9/ha-gasbuddy)
- [Union Pacific Big Boy Tracker](https://github.com/jheizer/up_4014_tracker)
- [WeatherFlow Forecast](https://github.com/briis/weatherflow_forecast)
- [NWS SPC Outlook](https://github.com/sedward5/nws_spc_outlook)
</details>
@ -112,7 +111,6 @@ ## HACS Lovelace Cards
- [Weather Chart Card](https://github.com/mlamberts78/weather-chart-card)
- [Comfortable Environment Card](https://github.com/argaar/comfortable-environment-card)
- [Versatile Thermostat UI Card](https://github.com/jmcollin78/versatile-thermostat-ui-card)
- [Gauge Card Pro](https://github.com/benjamin-dcs/gauge-card-pro)
</details>