From 065bc57cf2b668e2f74b6bcc5136902b9ad4200e Mon Sep 17 00:00:00 2001 From: Andrew Neisch Date: Sat, 2 Dec 2023 21:16:11 -0600 Subject: [PATCH] Updates, tweaks --- README.md | 10 ++++----- automations.yaml | 2 +- .../alexa_media/.translations/de.json | 2 +- custom_components/alexa_media/__init__.py | 6 +++--- custom_components/alexa_media/alexa_entity.py | 4 ++-- custom_components/alexa_media/const.py | 4 ++-- custom_components/alexa_media/manifest.json | 8 ++++---- custom_components/alexa_media/media_player.py | 2 +- custom_components/alexa_media/sensor.py | 2 +- .../alexa_media/translations/de.json | 2 +- .../alexa_media/translations/pt_BR.json | 2 +- .../alexa_media/translations/pt_PT.json | 2 +- extras/appdaemon/apps/apps.yaml | 4 ++-- .../docker-compose/other/docker-compose.yml | 2 +- .../docker-compose/unified/docker-compose.yml | 2 +- packages/blinds.yaml | 19 ++++-------------- .../numberbox-card/numberbox-card.js | 8 ++++---- .../numberbox-card/numberbox-card.js.gz | Bin 5715 -> 5719 bytes 18 files changed, 35 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 52b31296..d1aac392 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Also using Grafana/Influx for graphing, both running in Docker containers on NUC Description | value -- | -- Lines of ESPHome YAML | 2774 -Lines of Home Assistant YAML | 8350 +Lines of Home Assistant YAML | 8339 [Integrations](https://www.home-assistant.io/integrations/) in use | 51 Zigbee devices in [`zha`](https://www.home-assistant.io/integrations/zha/) | 26 Z-Wave devices in [`zwave_js`](https://www.home-assistant.io/integrations/zwave_js/) | 37 @@ -66,7 +66,7 @@ Description | value Entities in the [`alarm_control_panel`](https://www.home-assistant.io/components/alarm_control_panel) domain | 1 Entities in the [`automation`](https://www.home-assistant.io/components/automation) domain | 114 Entities in the [`binary_sensor`](https://www.home-assistant.io/components/binary_sensor) domain | 135 -Entities in the [`button`](https://www.home-assistant.io/components/button) domain | 12 +Entities in the [`button`](https://www.home-assistant.io/components/button) domain | 13 Entities in the [`camera`](https://www.home-assistant.io/components/camera) domain | 18 Entities in the [`climate`](https://www.home-assistant.io/components/climate) domain | 1 Entities in the [`counter`](https://www.home-assistant.io/components/counter) domain | 1 @@ -90,17 +90,17 @@ Entities in the [`remote`](https://www.home-assistant.io/components/remote) doma Entities in the [`scene`](https://www.home-assistant.io/components/scene) domain | 2 Entities in the [`script`](https://www.home-assistant.io/components/script) domain | 42 Entities in the [`select`](https://www.home-assistant.io/components/select) domain | 2 -Entities in the [`sensor`](https://www.home-assistant.io/components/sensor) domain | 386 +Entities in the [`sensor`](https://www.home-assistant.io/components/sensor) domain | 392 Entities in the [`siren`](https://www.home-assistant.io/components/siren) domain | 1 Entities in the [`sun`](https://www.home-assistant.io/components/sun) domain | 1 -Entities in the [`switch`](https://www.home-assistant.io/components/switch) domain | 163 +Entities in the [`switch`](https://www.home-assistant.io/components/switch) domain | 164 Entities in the [`timer`](https://www.home-assistant.io/components/timer) domain | 2 Entities in the [`tts`](https://www.home-assistant.io/components/tts) domain | 1 Entities in the [`update`](https://www.home-assistant.io/components/update) domain | 3 Entities in the [`vacuum`](https://www.home-assistant.io/components/vacuum) domain | 1 Entities in the [`weather`](https://www.home-assistant.io/components/weather) domain | 2 Entities in the [`zone`](https://www.home-assistant.io/components/zone) domain | 6 -**Total state objects** | **1143** +**Total state objects** | **1151** ## The HACS integrations/plugins that I use: **Appdaemon**:
[aneisch/follow_me_appdaemon](https://github.com/aneisch/follow_me_appdaemon)
diff --git a/automations.yaml b/automations.yaml index e0a5d7db..e7921e03 100644 --- a/automations.yaml +++ b/automations.yaml @@ -1032,8 +1032,8 @@ trigger: - platform: state entity_id: light.plant_light_corner - from: "off" to: "on" + for: "00:00:10" action: - repeat: count: 3 diff --git a/custom_components/alexa_media/.translations/de.json b/custom_components/alexa_media/.translations/de.json index bef4e25c..1c50b00b 100644 --- a/custom_components/alexa_media/.translations/de.json +++ b/custom_components/alexa_media/.translations/de.json @@ -91,7 +91,7 @@ "name": "E-Mail Adresse" } }, - "name": "Aktualisiere letzten aufgerufenen Sensor" + "name": "Aktualisiere den zuletzt aufgerufenen Sensor" } } } diff --git a/custom_components/alexa_media/__init__.py b/custom_components/alexa_media/__init__.py index 293faf7e..a41040a0 100644 --- a/custom_components/alexa_media/__init__.py +++ b/custom_components/alexa_media/__init__.py @@ -693,7 +693,7 @@ async def process_notifications(login_obj, raw_notifications=None): n_dev_id = notification.get("deviceSerialNumber") if n_dev_id is None: # skip notifications untied to a device for now - # https://github.com/custom-components/alexa_media_player/issues/633#issuecomment-610705651 + # https://github.com/alandtse/alexa_media_player/issues/633#issuecomment-610705651 continue n_type = notification.get("type") if n_type is None: @@ -1038,11 +1038,11 @@ async def http2_handler(message_obj): ) elif command in [ "PUSH_DELETE_DOPPLER_ACTIVITIES", # delete Alexa history - "PUSH_LIST_CHANGE", # clear a shopping list https://github.com/custom-components/alexa_media_player/issues/1190 + "PUSH_LIST_CHANGE", # clear a shopping list https://github.com/alandtse/alexa_media_player/issues/1190 "PUSH_LIST_ITEM_CHANGE", # update shopping list "PUSH_CONTENT_FOCUS_CHANGE", # likely prime related refocus "PUSH_DEVICE_SETUP_STATE_CHANGE", # likely device changes mid setup - "PUSH_MEDIA_PREFERENCE_CHANGE", # disliking or liking songs, https://github.com/custom-components/alexa_media_player/issues/1599 + "PUSH_MEDIA_PREFERENCE_CHANGE", # disliking or liking songs, https://github.com/alandtse/alexa_media_player/issues/1599 ]: pass else: diff --git a/custom_components/alexa_media/alexa_entity.py b/custom_components/alexa_media/alexa_entity.py index 00fc70ab..2379157c 100644 --- a/custom_components/alexa_media/alexa_entity.py +++ b/custom_components/alexa_media/alexa_entity.py @@ -73,9 +73,9 @@ def is_local(appliance: dict[str, Any]) -> bool: if "ALEXA_VOICE_ENABLED" in appliance.get("applianceTypes", []): return not is_skill(appliance) - # Ledvance bulbs connected via bluetooth are hard to detect as locally connected + # Ledvance/Sengled bulbs connected via bluetooth are hard to detect as locally connected # There is probably a better way, but this works for now. - if appliance.get("manufacturerName") == "Ledvance": + if appliance.get("manufacturerName") == "Ledvance" or appliance.get("manufacturerName") == "Sengled": return not is_skill(appliance) # Zigbee devices are guaranteed to be local and have a particular pattern of id diff --git a/custom_components/alexa_media/const.py b/custom_components/alexa_media/const.py index 61282a8f..929a57b0 100644 --- a/custom_components/alexa_media/const.py +++ b/custom_components/alexa_media/const.py @@ -14,8 +14,8 @@ PERCENTAGE, ) -__version__ = "4.7.9" -PROJECT_URL = "https://github.com/custom-components/alexa_media_player/" +__version__ = "4.8.0" +PROJECT_URL = "https://github.com/alandtse/alexa_media_player/" ISSUE_URL = f"{PROJECT_URL}issues" NOTIFY_URL = f"{PROJECT_URL}wiki/Configuration%3A-Notification-Component#use-the-notifyalexa_media-service" diff --git a/custom_components/alexa_media/manifest.json b/custom_components/alexa_media/manifest.json index 9f67af45..833df0d7 100644 --- a/custom_components/alexa_media/manifest.json +++ b/custom_components/alexa_media/manifest.json @@ -4,10 +4,10 @@ "codeowners": ["@alandtse", "@keatontaylor"], "config_flow": true, "dependencies": ["persistent_notification", "http"], - "documentation": "https://github.com/custom-components/alexa_media_player/wiki", + "documentation": "https://github.com/alandtse/alexa_media_player/wiki", "iot_class": "cloud_polling", - "issue_tracker": "https://github.com/custom-components/alexa_media_player/issues", + "issue_tracker": "https://github.com/alandtse/alexa_media_player/issues", "loggers": ["alexapy", "authcaptureproxy"], - "requirements": ["alexapy==1.27.8", "packaging>=20.3", "wrapt>=1.14.0"], - "version": "4.7.9" + "requirements": ["alexapy==1.27.10", "packaging>=20.3", "wrapt>=1.14.0"], + "version": "4.8.0" } diff --git a/custom_components/alexa_media/media_player.py b/custom_components/alexa_media/media_player.py index 68f047aa..24b0761e 100644 --- a/custom_components/alexa_media/media_player.py +++ b/custom_components/alexa_media/media_player.py @@ -1430,7 +1430,7 @@ async def async_play_media(self, media_type, media_id, enqueue=None, **kwargs): _LOGGER.warning( "To send TTS, set public url in integration configuration" " Please see the alexa_media wiki for details." - "https://github.com/custom-components/alexa_media_player/wiki/Configuration%3A-Notification-Component#use-the-notifyalexa_media-service" + "https://github.com/alandtse/alexa_media_player/wiki/Configuration%3A-Notification-Component#use-the-notifyalexa_media-service" ) elif media_type == "sequence": _LOGGER.debug( diff --git a/custom_components/alexa_media/sensor.py b/custom_components/alexa_media/sensor.py index 4f128ba0..0bb552c7 100644 --- a/custom_components/alexa_media/sensor.py +++ b/custom_components/alexa_media/sensor.py @@ -494,7 +494,7 @@ def _update_recurring_alarm(self, value): r_rule_data = next_item.get("rRuleData") if ( r_rule_data - ): # the new recurrence pattern; https://github.com/custom-components/alexa_media_player/issues/1608 + ): # the new recurrence pattern; https://github.com/alandtse/alexa_media_player/issues/1608 next_trigger_times = r_rule_data.get("nextTriggerTimes") weekdays = r_rule_data.get("byWeekDays") if next_trigger_times: diff --git a/custom_components/alexa_media/translations/de.json b/custom_components/alexa_media/translations/de.json index bef4e25c..1c50b00b 100644 --- a/custom_components/alexa_media/translations/de.json +++ b/custom_components/alexa_media/translations/de.json @@ -91,7 +91,7 @@ "name": "E-Mail Adresse" } }, - "name": "Aktualisiere letzten aufgerufenen Sensor" + "name": "Aktualisiere den zuletzt aufgerufenen Sensor" } } } diff --git a/custom_components/alexa_media/translations/pt_BR.json b/custom_components/alexa_media/translations/pt_BR.json index 2e8d00b0..1d41149c 100644 --- a/custom_components/alexa_media/translations/pt_BR.json +++ b/custom_components/alexa_media/translations/pt_BR.json @@ -96,7 +96,7 @@ "securitycode": "Código 2FA (recomendado para evitar problemas de login)", "url": "Domínio regional da amazon (ex: amazon.co.uk)" }, - "description": "Por favor insira sua [informação](https://github.com/custom-components/alexa_media_player/wiki/Configuration#integrations-page). **[Cookie import](https://github.com/custom-components/alexa_media_player/wiki/Configuration#cookie-import) pode ser mais fácil!** \n**AVISO! A amazon reporta incorretamente 'Insira um email ou número de telefone válido' quando [Código de 2FA é requirido](https://github.com/custom-components/alexa_media_player/wiki/Configuration#enable-two-factor-authentication-for-your-amazon-account).** \n>{message}", + "description": "Por favor insira sua [informação](https://github.com/alandtse/alexa_media_player/wiki/Configuration#integrations-page). **[Cookie import](https://github.com/alandtse/alexa_media_player/wiki/Configuration#cookie-import) pode ser mais fácil!** \n**AVISO! A amazon reporta incorretamente 'Insira um email ou número de telefone válido' quando [Código de 2FA é requirido](https://github.com/alandtse/alexa_media_player/wiki/Configuration#enable-two-factor-authentication-for-your-amazon-account).** \n>{message}", "title": "Alexa Media Player - Configurações legado" } } diff --git a/custom_components/alexa_media/translations/pt_PT.json b/custom_components/alexa_media/translations/pt_PT.json index 2d7b4382..656ba5c8 100644 --- a/custom_components/alexa_media/translations/pt_PT.json +++ b/custom_components/alexa_media/translations/pt_PT.json @@ -96,7 +96,7 @@ "securitycode": "Código 2FA (recomendado para evitar problemas de login)", "url": "Região do domínio Amazon (ex. amazon.com.br)" }, - "description": "Por favor, introduza a sua [informação](https://github.com/custom-components/alexa_media_player/wiki/Configuration#integrations-page). **[Cookie import](https://github.com/custom-components/alexa_media_player/wiki/Configuration#cookie-import) pode ser mais fácil!** \n**Aviso: a Amazon informa incorretamente 'Insira um e-mail ou número de celular válido' quando [2FA Code é necessário](https://github.com/custom-components/alexa_media_player/wiki/Configuration#enable-two-factor-authentication-for-your-amazon-account).** \n>{message}", + "description": "Por favor, introduza a sua [informação](https://github.com/alandtse/alexa_media_player/wiki/Configuration#integrations-page). **[Cookie import](https://github.com/alandtse/alexa_media_player/wiki/Configuration#cookie-import) pode ser mais fácil!** \n**Aviso: a Amazon informa incorretamente 'Insira um e-mail ou número de celular válido' quando [2FA Code é necessário](https://github.com/alandtse/alexa_media_player/wiki/Configuration#enable-two-factor-authentication-for-your-amazon-account).** \n>{message}", "title": "Alexa Media Player - Configuração de Compatibilidade" } } diff --git a/extras/appdaemon/apps/apps.yaml b/extras/appdaemon/apps/apps.yaml index d46b02ad..672a28b8 100644 --- a/extras/appdaemon/apps/apps.yaml +++ b/extras/appdaemon/apps/apps.yaml @@ -413,8 +413,8 @@ Front Porch Lights Sunset: Plant Light: module: entity_timer class: Timer - time_on: "09:30:00" - time_off: "21:00:00" + time_on: sunrise + time_off: sunset entities: switch.plant_light Plant Light Corner: diff --git a/extras/docker-compose/other/docker-compose.yml b/extras/docker-compose/other/docker-compose.yml index 5a9dabbd..697f0f4d 100644 --- a/extras/docker-compose/other/docker-compose.yml +++ b/extras/docker-compose/other/docker-compose.yml @@ -344,7 +344,7 @@ services: privileged: true restart: always #image: ghcr.io/blakeblackshear/frigate:stable - image: ghcr.io/blakeblackshear/frigate:0.13.0-beta5 + image: ghcr.io/blakeblackshear/frigate:0.13.0-beta6 shm_size: "128mb" devices: - /dev/bus/usb:/dev/bus/usb diff --git a/extras/docker-compose/unified/docker-compose.yml b/extras/docker-compose/unified/docker-compose.yml index 9a20bffd..ea66d98d 100644 --- a/extras/docker-compose/unified/docker-compose.yml +++ b/extras/docker-compose/unified/docker-compose.yml @@ -521,7 +521,7 @@ services: privileged: true restart: always #image: ghcr.io/blakeblackshear/frigate:stable - image: ghcr.io/blakeblackshear/frigate:0.13.0-beta5 + image: ghcr.io/blakeblackshear/frigate:0.13.0-beta6 shm_size: "128mb" devices: - /dev/bus/usb:/dev/bus/usb diff --git a/packages/blinds.yaml b/packages/blinds.yaml index 0eb7a753..58a90de6 100644 --- a/packages/blinds.yaml +++ b/packages/blinds.yaml @@ -158,21 +158,6 @@ script: {% elif group == "office" %} {{ expand('group.office_blinds') | map(attribute='entity_id') | list}} {% endif %} - # Prevent stuck "opening" or "closing" - # - repeat: - # count: "13" - # sequence: - # - delay: 5 - # - service: homeassistant.update_entity - # target: - # entity_id: > - # {% if group == "guest_bedroom" %} - # {{ expand('group.guest_bedroom_blinds') | map(attribute='entity_id') | list}} - # {% elif group == "dining_room" %} - # {{ expand('group.dining_room_blinds') | map(attribute='entity_id') | list}} - # {% elif group == "office" %} - # {{ expand('group.office_blinds') | map(attribute='entity_id') | list}} - # {% endif %} automation: - alias: "Lower and Raise Blinds" @@ -254,6 +239,10 @@ automation: - service: homeassistant.update_entity target: entity_id: "{{ trigger.entity_id }}" + - delay: "00:00:30" + - service: homeassistant.update_entity + target: + entity_id: "{{ trigger.entity_id }}" - alias: "Guest Bedroom Blinds with Remote" id: guest_bedroom_blinds_remote diff --git a/www/community/numberbox-card/numberbox-card.js b/www/community/numberbox-card/numberbox-card.js index d6041f61..56b383db 100644 --- a/www/community/numberbox-card/numberbox-card.js +++ b/www/community/numberbox-card/numberbox-card.js @@ -1,6 +1,6 @@ ((LitElement) => { -console.info('NUMBERBOX_CARD 4.15'); +console.info('NUMBERBOX_CARD 4.17'); const html = LitElement.prototype.html; const css = LitElement.prototype.css; class NumberBox extends LitElement { @@ -11,7 +11,7 @@ constructor() { this.pending = false; this.rolling = false; this.state = 0; - this.old = {state: undefined, t:{}, h:''}; + this.old = {state: NaN, t:{}, h:''}; } render() { @@ -116,7 +116,7 @@ secondaryInfo(){ } } } - ret += (typeof b !== 'object')? (isNaN(f)?b:b.toFixed(f)) : t; + ret += (typeof b !== 'object')? (isNaN(f)?b:b.toFixed(f)) : '?'; }else{ ret += t; } @@ -252,7 +252,7 @@ niceNum(){ let t = this.numTime(fix,0,u); return html`${t}`; } - if(isNaN(Number(fix))){return fix;} + if(isNaN(Number(fix))){return '?';} if(typeof u == 'string' && u.startsWith('(')){ let value = fix; value = eval(u); return html`${value}`; diff --git a/www/community/numberbox-card/numberbox-card.js.gz b/www/community/numberbox-card/numberbox-card.js.gz index f0c6a60d69512045a6fe4c1cdb5bb34fdb56388d..d4b87a02b85c4274dcc9d94790f49b4303070661 100644 GIT binary patch literal 5719 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 J@$8pK002|A2$ui= literal 5715 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 F006Gx<%s|Q