Compare commits

...

2 Commits

Author SHA1 Message Date
29a74e2546 backup 2023-02-26 11:43:30 +01:00
5128fa7358 updated atom 2022-12-31 09:31:55 +01:00
375 changed files with 18660 additions and 15406 deletions

View File

@@ -1 +1 @@
2022.12.6 2023.2.5

3
.gitignore vendored
View File

@@ -9,6 +9,9 @@
home-assistant.log home-assistant.log
home-assistant.log.1 home-assistant.log.1
home-assistant.log.fault home-assistant.log.fault
/custom_components/*
/tts/*
/blueprints/*
# Example .gitignore file for your config dir. # Example .gitignore file for your config dir.
# An * ensures that everything will be ignored. # An * ensures that everything will be ignored.

35
airsonos.xml Normal file
View File

@@ -0,0 +1,35 @@
<?xml version="1.0"?>
<main_log>info</main_log>
<upnp_log>info</upnp_log>
<util_log>warn</util_log>
<raop_log>info</raop_log>
<log_limit>-1</log_limit>
<max_players>32</max_players>
<binding>?</binding>
<ports>0:0</ports>
<enabled>1</enabled>
<max_volume>100</max_volume>
<http_length>-1</http_length>
<upnp_max>1</upnp_max>
<codec>flc</codec>
<metadata>1</metadata>
<flush>1</flush>
<artwork></artwork>
<latency>1000:2000</latency>
<drift>0</drift>
<pcm>http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=00;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=0d500000000000000000000000000000</pcm>
<wav>http-get:*:audio/wav:DLNA.ORG_OP=00;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=0d500000000000000000000000000000</wav>
<flac>http-get:*:audio/flac:DLNA.ORG_OP=00;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=0d500000000000000000000000000000</flac>
<mp3>http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=00;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=0d500000000000000000000000000000</mp3>
<device>
<udn>uuid:RINCON_38420B93464001400</udn>
<name>Keuken+</name>
<mac>bb:bb:0b:93:46:40</mac>
<enabled>1</enabled>
</device>
<device>
<udn>uuid:BO5EBO5E-F00D-F00D-FEED-506583CEC197</udn>
<name>Bose woonkamer+</name>
<mac>bb:bb:7f:f3:34:e1</mac>
<enabled>1</enabled>
</device>

View File

@@ -36,9 +36,9 @@
input: input:
motion_sensor: binary_sensor.beweging_hal_motion_detection motion_sensor: binary_sensor.beweging_hal_motion_detection
target_entity: scene.hal_aan target_entity: scene.hal_aan
illuminance_sensor: sensor.hal_beweging_2_illuminance illuminance_sensor: sensor.beweging_hal_illuminance
illuminance_cutoff: input_number.hal_luminance_threshold illuminance_cutoff: input_number.hal_luminance_threshold
target_off_entity: switch.hal_lamp_hal_switch target_off_entity: light.lamp_hal
no_motion_wait: input_number.hal_beweging_timer no_motion_wait: input_number.hal_beweging_timer
time_limit_after: input_datetime.hal_beweging_active time_limit_after: input_datetime.hal_beweging_active
time_limit_before: input_datetime.hal_beweging_inactive time_limit_before: input_datetime.hal_beweging_inactive
@@ -48,10 +48,10 @@
use_blueprint: use_blueprint:
path: freakshock88/motion_illuminance_activated_entity.yaml path: freakshock88/motion_illuminance_activated_entity.yaml
input: input:
motion_sensor: binary_sensor.beweging_keuken_motion_detection motion_sensor: binary_sensor.beweging_keuken_sensor_state_motion
target_entity: scene.keuken_verlichting_aan_beweging target_entity: scene.keuken_verlichting_aan_beweging
no_motion_wait: input_number.keuken_timer_off no_motion_wait: input_number.keuken_timer_off
target_off_entity: light.lamp_aanrecht_keuken target_off_entity: light.lamp_aanrecht
time_limit_after: input_datetime.keuken_beweging_active time_limit_after: input_datetime.keuken_beweging_active
time_limit_before: input_datetime.keuken_beweging_inactive time_limit_before: input_datetime.keuken_beweging_inactive
- id: '1659077789477' - id: '1659077789477'
@@ -77,7 +77,7 @@
domain: select domain: select
entity_id: select.harmony_hub_activities entity_id: select.harmony_hub_activities
type: current_option_changed type: current_option_changed
from: PowerOff from: power_off
to: Apple TV kijken 2 to: Apple TV kijken 2
for: for:
hours: 0 hours: 0
@@ -100,6 +100,10 @@
data: {} data: {}
target: target:
entity_id: scene.avond_stand entity_id: scene.avond_stand
- type: turn_off
device_id: 9f4dd21a83f9473a5350876da52296d6
entity_id: light.lamp_bank_light
domain: light
mode: single mode: single
- id: '1660333123289' - id: '1660333123289'
alias: Badkamer - beweging sensor ochtend alias: Badkamer - beweging sensor ochtend
@@ -121,11 +125,11 @@
use_blueprint: use_blueprint:
path: freakshock88/motion_illuminance_activated_entity.yaml path: freakshock88/motion_illuminance_activated_entity.yaml
input: input:
motion_sensor: binary_sensor.beweging_toilet_occupancy motion_sensor: binary_sensor.lumi_lumi_sensor_motion_aq2_occupancy
target_entity: light.lamp_toilet target_entity: light.lamp_wc_beneden_light
illuminance_sensor: sensor.beweging_toilet_illuminance_lux illuminance_sensor: sensor.lumi_lumi_sensor_motion_aq2_illuminance
no_motion_wait: input_number.beweging_toilet_timer no_motion_wait: input_number.beweging_toilet_timer
target_off_entity: light.lamp_toilet target_off_entity: light.lamp_wc_beneden_light
illuminance_cutoff: input_number.beweging_toilet_helderheid illuminance_cutoff: input_number.beweging_toilet_helderheid
- id: '1660502406213' - id: '1660502406213'
alias: Tuin - Lights On At Sunset alias: Tuin - Lights On At Sunset
@@ -133,21 +137,21 @@
use_blueprint: use_blueprint:
path: CyanAutomation/lights_on_at_sunset.yaml path: CyanAutomation/lights_on_at_sunset.yaml
input: input:
target_brightness: 40
target_light: target_light:
area_id: tuin area_id: tuin
target_brightness: 65
- id: '1660507765057' - id: '1660507765057'
alias: woonkamer - alles uit alias: woonkamer - alles uit
description: '' description: ''
trigger: trigger:
- platform: device - platform: device
type: turned_off type: turned_off
device_id: 800c3462cb0da0ee95bfcf8c5154278c device_id: bc61b8f4ddf2fc04d3a0a6001ea7c7c8
entity_id: light.lamp_sfeer_dimmer_1 entity_id: light.lamp_sfeer_woonkamer
domain: light domain: light
condition: condition:
- condition: time - condition: time
after: '22:00:00' after: '21:30:00'
weekday: weekday:
- mon - mon
- tue - tue
@@ -156,6 +160,7 @@
- fri - fri
- sat - sat
- sun - sun
before: 04:00:00
action: action:
- service: scene.turn_on - service: scene.turn_on
target: target:
@@ -166,58 +171,37 @@
alias: Slaapkamer - bedlamp aan lage helderheid alias: Slaapkamer - bedlamp aan lage helderheid
description: '' description: ''
trigger: trigger:
- platform: device - device_id: dc42e9871d6dfc0ce76c594054038cd9
domain: mqtt domain: zha
device_id: adc076a39e1a0df058ab1423acca5dde platform: device
type: action type: remote_button_short_press
subtype: single_right subtype: button_1
discovery_id: 0x00158d0002ec3873 action_single_right condition: []
condition: action:
- choose:
- conditions:
- condition: device - condition: device
type: is_off type: is_off
device_id: d6fde94fb152332d9abf7e59c93fb32c device_id: 01b9a993ffea323f6f094e9c231f6d3c
entity_id: light.lamp_bed_slaapkamer entity_id: light.lamp_bed_willem_light
domain: light domain: light
action: sequence:
- type: turn_on - type: turn_on
device_id: d6fde94fb152332d9abf7e59c93fb32c device_id: 01b9a993ffea323f6f094e9c231f6d3c
entity_id: light.lamp_bed_slaapkamer entity_id: light.lamp_bed_willem_light
domain: light domain: light
brightness_pct: 10 brightness_pct: 10
mode: single - conditions:
- id: '1661103772228' - condition: device
alias: zolder knoppen werken (2) aan type: is_on
description: '' device_id: 01b9a993ffea323f6f094e9c231f6d3c
trigger: entity_id: light.lamp_bed_willem_light
- platform: device domain: light
domain: mqtt sequence:
device_id: a7bc75c4ece60567f111d2ec6dfd1fe8 - type: turn_off
type: action device_id: 01b9a993ffea323f6f094e9c231f6d3c
subtype: on_2 entity_id: light.lamp_bed_willem_light
discovery_id: 0xbc33acfffe6f8eca action_on_2 domain: light
condition: []
action:
- service: scene.turn_on
target:
entity_id: scene.werken_op_zolder
metadata: {}
mode: single
- id: '1661103922881'
alias: zolder knoppen werken (2) uit
description: ''
trigger:
- platform: device
domain: mqtt
device_id: a7bc75c4ece60567f111d2ec6dfd1fe8
type: action
subtype: off_2
discovery_id: 0xbc33acfffe6f8eca action_off_2
condition: []
action:
- service: scene.turn_on
target:
entity_id: scene.klaar_met_werken_op_zolder
metadata: {}
mode: single mode: single
- id: '1661107342293' - id: '1661107342293'
alias: Zolder - Wasdroger cycle alias: Zolder - Wasdroger cycle
@@ -292,111 +276,57 @@
entity_id: switch.waterklep entity_id: switch.waterklep
domain: switch domain: switch
mode: restart mode: restart
- id: '1661802357554'
alias: Tuin - Knop verlichting aan
description: ''
trigger:
- platform: device
domain: mqtt
device_id: c976ab1909dcc67895eccdce5708b0dc
type: action
subtype: on_4
discovery_id: 0x60a423fffe28320f action_on_4
condition: []
action:
- service: scene.turn_on
data: {}
target:
entity_id: scene.tuin_avond
mode: single
- id: '1661802390986'
alias: Tuin - Knop tuin verlichting uit
description: ''
trigger:
- platform: device
domain: mqtt
device_id: c976ab1909dcc67895eccdce5708b0dc
type: action
subtype: off_4
discovery_id: 0x60a423fffe28320f action_off_4
condition: []
action:
- service: scene.turn_on
data:
transition: 11
target:
entity_id: scene.tuin_uit
mode: single
- id: '1661802536602'
alias: Woonkamer - Knop screen open
description: ''
trigger:
- platform: device
domain: mqtt
device_id: c976ab1909dcc67895eccdce5708b0dc
type: action
subtype: off_2
discovery_id: 0x60a423fffe28320f action_off_2
condition: []
action:
- device_id: a811912be259da54b0aa6a3779e0b3f3
domain: cover
entity_id: cover.nodeid_31_position
type: set_position
position: 100
mode: single
- id: '1661802562810'
alias: Woonkamer - Knop screen dicht
description: ''
trigger:
- platform: device
domain: mqtt
device_id: c976ab1909dcc67895eccdce5708b0dc
type: action
subtype: on_2
discovery_id: 0x60a423fffe28320f action_on_2
condition:
- type: is_not_open
condition: device
device_id: 3a24020f2cc036b7a7ff1658e0dbd7d6
entity_id: binary_sensor.raam_eetkamer_contact
domain: binary_sensor
action:
- device_id: a811912be259da54b0aa6a3779e0b3f3
domain: cover
entity_id: cover.nodeid_31_position
type: set_position
position: 0
mode: single
- id: '1661802788925'
alias: Woonkamer - Knop screen Zon laag
description: ''
trigger:
- platform: device
domain: mqtt
device_id: c976ab1909dcc67895eccdce5708b0dc
type: action
subtype: brightness_stop_2
discovery_id: 0x60a423fffe28320f action_brightness_stop_2
condition: []
action:
- device_id: a811912be259da54b0aa6a3779e0b3f3
domain: cover
entity_id: cover.nodeid_31_position
type: set_position
position: 39
mode: single
- id: '1661803600011' - id: '1661803600011'
alias: Woonkamer - ochtend alias: Woonkamer - Beweging
description: '' description: ''
trigger: trigger:
- platform: time - type: motion
at: 00:07:30 platform: device
condition: [] device_id: dba81805bffdc5ab5eb183b0c2d845dc
entity_id: binary_sensor.beweging_woonkamer2_iaszone
domain: binary_sensor
for:
hours: 0
minutes: 0
seconds: 3
condition:
- condition: or
conditions:
- condition: time
after: 06:30:00
before: 08:00:00
weekday:
- sun
- mon
- tue
- wed
- thu
- sat
- fri
- condition: time
after: '17:30:00'
before: '23:00:00'
weekday:
- sun
- mon
- tue
- wed
- thu
- fri
- sat
- condition: device
type: is_off
device_id: bc61b8f4ddf2fc04d3a0a6001ea7c7c8
entity_id: light.lamp_sfeer_woonkamer
domain: light
for:
hours: 0
minutes: 10
seconds: 0
action: action:
- service: scene.turn_on - service: scene.turn_on
target: target:
entity_id: scene.woonkamer_ochtend_scene entity_id: scene.woonkamer_sfeer_verlichting_aan
metadata: {} metadata: {}
mode: single mode: single
- id: '1662235717886' - id: '1662235717886'
@@ -426,12 +356,11 @@
alias: Slaapkamer - toggle rgb lamp alias: Slaapkamer - toggle rgb lamp
description: '' description: ''
trigger: trigger:
- platform: device - device_id: dc42e9871d6dfc0ce76c594054038cd9
domain: mqtt domain: zha
device_id: adc076a39e1a0df058ab1423acca5dde platform: device
type: action type: remote_button_short_press
subtype: single_left subtype: button_2
discovery_id: 0x00158d0002ec3873 action_single_left
condition: [] condition: []
action: action:
- if: - if:
@@ -441,11 +370,6 @@
entity_id: light.lamp_rgb_slaapkamer entity_id: light.lamp_rgb_slaapkamer
domain: light domain: light
then: then:
- service: scene.turn_on
target:
entity_id: scene.slaapkamer_rgb_wit
metadata: {}
enabled: false
- service: scene.turn_on - service: scene.turn_on
target: target:
entity_id: scene.slaapkamer_dim_wit entity_id: scene.slaapkamer_dim_wit
@@ -456,22 +380,6 @@
entity_id: light.lamp_rgb_slaapkamer entity_id: light.lamp_rgb_slaapkamer
domain: light domain: light
mode: single mode: single
- id: '1665381406928'
alias: Keuken - Aanrecht S2 - keuken lamp
description: ''
trigger:
- platform: device
type: changed_states
device_id: d6af5907c10dd749aec17d4881e37f8c
entity_id: light.lamp_aanrecht_keuken_dimmer_2
domain: light
condition: []
action:
- type: toggle
device_id: 321e6c4fe63648395bb10ad472d79ebf
entity_id: light.lamp_keuken_dimmer_1
domain: light
mode: single
- id: '1666338442880' - id: '1666338442880'
alias: Tuin - melding poort alias: Tuin - melding poort
description: '' description: ''
@@ -498,136 +406,465 @@
alias: Slaapkamer - bed lamp feller alias: Slaapkamer - bed lamp feller
description: '' description: ''
trigger: trigger:
- platform: device - device_id: dc42e9871d6dfc0ce76c594054038cd9
domain: mqtt domain: zha
device_id: adc076a39e1a0df058ab1423acca5dde platform: device
type: action type: remote_button_long_press
subtype: hold_right subtype: button_2
discovery_id: 0x00158d0002ec3873 action_hold_right
condition: [] condition: []
action: action:
- device_id: d6fde94fb152332d9abf7e59c93fb32c - device_id: 01b9a993ffea323f6f094e9c231f6d3c
domain: light domain: light
entity_id: light.lamp_bed_slaapkamer entity_id: light.lamp_bed_willem_light
type: brightness_increase type: brightness_increase
mode: single mode: single
- id: '1666506798460'
alias: Slaapkamer - bedlamp uit (R single click)
description: ''
trigger:
- platform: device
domain: mqtt
device_id: adc076a39e1a0df058ab1423acca5dde
type: action
subtype: single_right
discovery_id: 0x00158d0002ec3873 action_single_right
condition:
- condition: device
type: is_on
device_id: d6fde94fb152332d9abf7e59c93fb32c
entity_id: light.lamp_bed_slaapkamer
domain: light
action:
- type: turn_off
device_id: d6fde94fb152332d9abf7e59c93fb32c
entity_id: light.lamp_bed_slaapkamer
domain: light
mode: single
- id: '1666506915317'
alias: Slaapkamer bedlamp max
description: ''
trigger:
- platform: device
domain: mqtt
device_id: adc076a39e1a0df058ab1423acca5dde
type: action
subtype: double_right
discovery_id: 0x00158d0002ec3873 action_double_right
condition:
- condition: device
type: is_on
device_id: d6fde94fb152332d9abf7e59c93fb32c
entity_id: light.lamp_bed_slaapkamer
domain: light
action:
- type: turn_on
device_id: d6fde94fb152332d9abf7e59c93fb32c
entity_id: light.lamp_bed_slaapkamer
domain: light
brightness_pct: 90
mode: single
- id: '1670606586705' - id: '1670606586705'
alias: schakers lamp bank alias: Woonkamer - lamp sfeer/ bank sync
description: '' description: ''
trigger: trigger:
- platform: device - platform: device
type: changed_states type: changed_states
device_id: 0366da9bdbe101d7da225ade40b958e6 device_id: bc61b8f4ddf2fc04d3a0a6001ea7c7c8
entity_id: light.lamp_woonkamer_2 entity_id: light.lamp_sfeer_woonkamer
domain: light domain: light
condition: [] condition:
- condition: device
device_id: e114f1eb7daa22b88511d015df1f12f7
domain: select
entity_id: select.harmony_hub_activities
type: selected_option
option: power_off
action: action:
- type: toggle - choose:
device_id: f9dbed5d9d5ff3cfbfd777f7ddd3fe3b - conditions:
entity_id: light.lamp_bank - condition: device
type: is_on
device_id: bc61b8f4ddf2fc04d3a0a6001ea7c7c8
entity_id: light.lamp_sfeer_woonkamer
domain: light
sequence:
- type: turn_on
device_id: 9f4dd21a83f9473a5350876da52296d6
entity_id: light.lamp_bank_light
domain: light
brightness_pct: 20
- type: turn_on
device_id: 4c2d45d53cd5318e416fdc1cc942f65a
entity_id: light.lamp_dressoir_light
domain: light
brightness_pct: 20
- conditions:
- condition: device
type: is_off
device_id: bc61b8f4ddf2fc04d3a0a6001ea7c7c8
entity_id: light.lamp_sfeer_woonkamer
domain: light
sequence:
- type: turn_off
device_id: 9f4dd21a83f9473a5350876da52296d6
entity_id: light.lamp_bank_light
domain: light
- type: turn_off
device_id: 4c2d45d53cd5318e416fdc1cc942f65a
entity_id: light.lamp_dressoir_light
domain: light domain: light
mode: single mode: single
- id: '1671052282402' - id: '1671052282402'
alias: slaapkamer bedlamp fel alias: slaapkamer bedlamp fel
description: '' description: ''
trigger: trigger:
- platform: device - device_id: dc42e9871d6dfc0ce76c594054038cd9
domain: mqtt domain: zha
device_id: adc076a39e1a0df058ab1423acca5dde platform: device
type: action type: remote_button_double_press
subtype: double_right subtype: button_2
discovery_id: 0x00158d0002ec3873 action_double_right
condition: condition:
- condition: device - condition: device
type: is_on type: is_on
device_id: d6fde94fb152332d9abf7e59c93fb32c device_id: 01b9a993ffea323f6f094e9c231f6d3c
entity_id: light.lamp_bed_slaapkamer entity_id: light.lamp_bed_willem_light
domain: light domain: light
action: action:
- type: turn_on - type: turn_on
device_id: d6fde94fb152332d9abf7e59c93fb32c device_id: 01b9a993ffea323f6f094e9c231f6d3c
entity_id: light.lamp_bed_slaapkamer entity_id: light.lamp_bed_willem_light
domain: light domain: light
brightness_pct: 85 brightness_pct: 100
mode: single mode: single
- id: '1671375517880' - id: '1671659606183'
alias: Woonkamer - knoppen 4(on) (tuin aan) alias: Alles uit
description: '' description: ''
trigger: trigger:
- platform: device - platform: device
domain: mqtt domain: mqtt
device_id: c976ab1909dcc67895eccdce5708b0dc device_id: c976ab1909dcc67895eccdce5708b0dc
type: action type: action
subtype: on_4 subtype: brightness_move_down_1
discovery_id: 0x60a423fffe28320f action_on_4 discovery_id: 0x60a423fffe28320f action_brightness_move_down_1
condition: [] condition: []
action: action:
- service: scene.turn_on - service: scene.turn_on
data: {}
target:
entity_id: scene.beneden_alles_uit
mode: single
- id: '1672424581965'
alias: slaapkamer tim - schakelaar (Actions)
description: ''
trigger:
- device_id: 3910ebf2dce7c5e241c9a0972c05d25f
domain: zha
platform: device
type: remote_button_short_press
subtype: left
id: arrow_left_click
- device_id: 3910ebf2dce7c5e241c9a0972c05d25f
domain: zha
platform: device
type: remote_button_short_press
subtype: right
id: arrow_right_click
- device_id: 3910ebf2dce7c5e241c9a0972c05d25f
domain: zha
platform: device
type: remote_button_short_press
subtype: turn_off
id: off_action
- device_id: 3910ebf2dce7c5e241c9a0972c05d25f
domain: zha
platform: device
type: remote_button_short_press
subtype: turn_on
id: on_action
- device_id: 3910ebf2dce7c5e241c9a0972c05d25f
domain: zha
platform: device
type: remote_button_long_release
subtype: dim_up
id: brightness_move_up
- device_id: 3910ebf2dce7c5e241c9a0972c05d25f
domain: zha
platform: device
type: remote_button_long_release
subtype: dim_down
id: brightness_move_down
condition: []
action:
- choose:
- conditions:
- condition: trigger
id: arrow_right_click
sequence:
- service: light.turn_on
target:
entity_id: light.rgb_slaapkamer_tim_light
data: data:
transition: 10 color_temp: '{% if state_attr("light.rgb_slaapkamer_tim_light","color_temp")
is none %} 454 {% elif state_attr("light.rgb_slaapkamer_tim_light","color_temp")|int
> 350 %} 333 {% elif state_attr("light.rgb_slaapkamer_tim_light","color_temp")|int
> 332 %} 285 {% elif state_attr("light.rgb_slaapkamer_tim_light","color_temp")|int
> 284 %} 244 {% else %} 370 {% endif %}
'
- conditions:
- condition: trigger
id: off_action
sequence:
- type: turn_off
device_id: 1834f301f21c8a1d8a7a16fe8ee2b6b2
entity_id: light.rgb_slaapkamer_tim_light
domain: light
- conditions:
- condition: trigger
id: arrow_left_click
sequence:
- service: light.turn_on
data:
rgb_color:
- '{{ (range(0, 255)|random) }}'
- '{{ (range(0, 255)|random) }}'
- '{{ (range(0, 255)|random) }}'
target:
entity_id: light.rgb_slaapkamer_tim_light
- conditions:
- condition: trigger
id: on_action
sequence:
- type: turn_on
device_id: 1834f301f21c8a1d8a7a16fe8ee2b6b2
entity_id: light.rgb_slaapkamer_tim_light
domain: light
- conditions:
- condition: trigger
id: brightness_move_up
sequence:
- service: light.turn_on
target:
entity_id: light.rgb_slaapkamer_tim_light
data:
brightness: '{% if state_attr("light.rgb_slaapkamer_tim_light","brightness")
is none %} 8 {% elif state_attr("light.rgb_slaapkamer_tim_light","brightness")|int
< 9 %} 16 {% elif state_attr("light.rgb_slaapkamer_tim_light","brightness")|int
< 17 %} 32 {% elif state_attr("light.rgb_slaapkamer_tim_light","brightness")|int
< 33 %} 64 {% elif state_attr("light.rgb_slaapkamer_tim_light","brightness")|int
< 65 %} 128 {% elif state_attr("light.rgb_slaapkamer_tim_light","brightness")|int
< 129 %} 160 {% elif state_attr("light.rgb_slaapkamer_tim_light","brightness")|int
< 161 %} 192 {% elif state_attr("light.rgb_slaapkamer_tim_light","brightness")|int
< 193 %} 224 {% elif state_attr("light.rgb_slaapkamer_tim_light","brightness")|int
< 225 %} 255 {% else %} 10 {% endif %}
'
- conditions:
- condition: trigger
id: brightness_move_down
sequence:
- service: light.turn_on
target:
entity_id: light.rgb_slaapkamer_tim_light
data:
brightness: '{% if state_attr("light.rgb_slaapkamer_tim_light","brightness")
is none %} 32 {% elif state_attr("light.rgb_slaapkamer_tim_light","brightness")|int
> 254 %} 224 {% elif state_attr("light.rgb_slaapkamer_tim_light","brightness")|int
> 223 %} 192 {% elif state_attr("light.rgb_slaapkamer_tim_light","brightness")|int
> 191 %} 160 {% elif state_attr("light.rgb_slaapkamer_tim_light","brightness")|int
> 159 %} 128 {% elif state_attr("light.rgb_slaapkamer_tim_light","brightness")|int
> 127 %} 64 {% elif state_attr("light.rgb_slaapkamer_tim_light","brightness")|int
> 63 %} 32 {% elif state_attr("light.rgb_slaapkamer_tim_light","brightness")|int
> 31 %} 16 {% elif state_attr("light.rgb_slaapkamer_tim_light","brightness")|int
> 15 %} 8 {% else %} 128 {% endif %}
'
mode: single
- id: '1673030409002'
alias: Hal - voordeur deurbel [BP]
description: ''
use_blueprint:
path: AngellusMortis/notification_ring_event.yaml
input:
doorbell_sensor:
- binary_sensor.voordeur_doorbell
cooldown: 29
notify_target_app: notify.notify
- id: '1674677403574'
alias: Keuken - Lamp S2 association Aanrecht
description: ''
trigger:
- platform: device
type: changed_states
device_id: 902cb3baf4ede5a269e89018c1ebd1cd
entity_id: light.lamp_keuken_2
domain: light
condition: []
action:
- type: toggle
device_id: 1281186f8b90c2b00053decdf33a6d72
entity_id: light.lamp_aanrecht
domain: light
mode: single
- id: '1674679921198'
alias: Woonkamer - knoppen (robsmart) [BP]
description: ''
use_blueprint:
path: Bekkie/robb-smart-8-switch-ROBB-ROB_200-007-0.yaml
input:
remote: b5245812a93ad1f15abe7ee901e5b43c
on_button_4_short:
- service: scene.turn_on
data: {}
target: target:
entity_id: scene.tuin_avond entity_id: scene.tuin_avond
mode: single off_button_4_short:
- id: '1671375563261' - service: scene.turn_on
alias: woonkamer - knoppen 4-off (tuin uit) data: {}
target:
entity_id: scene.tuin_uit
on_button_1_short:
- type: turn_on
device_id: 9f4dd21a83f9473a5350876da52296d6
entity_id: light.lamp_bank_light
domain: light
brightness_pct: 40
on_button_2_long: []
on_button_2_short:
- type: turn_on
device_id: 82e1a32555c372d3d5180521d1f84789
entity_id: switch.screens_woonkamer
domain: switch
off_button_2_short:
- type: turn_off
device_id: 82e1a32555c372d3d5180521d1f84789
entity_id: switch.screens_woonkamer
domain: switch
on_button_3_short:
- type: turn_on
device_id: 4ef8a164146ae2252807b12b461a9838
entity_id: switch.rolluik_woonkamer_2
domain: switch
off_button_3_short:
- type: turn_off
device_id: 4ef8a164146ae2252807b12b461a9838
entity_id: switch.rolluik_woonkamer_2
domain: switch
off_button_1_short:
- type: turn_off
device_id: 9f4dd21a83f9473a5350876da52296d6
entity_id: light.lamp_bank_light
domain: light
- id: '1674681637235'
alias: Slaapkamer i&w - knoppen bed willem [BP]
description: ''
use_blueprint:
path: andordavoti/zha-aqara-wireless-switch-WXKG02LM.yaml
input:
aqara_switch: dc42e9871d6dfc0ce76c594054038cd9
button_single_press_right:
- choose:
- conditions:
- condition: device
type: is_off
device_id: 01b9a993ffea323f6f094e9c231f6d3c
entity_id: light.lamp_bed_willem_light
domain: light
sequence:
- type: turn_on
device_id: 01b9a993ffea323f6f094e9c231f6d3c
entity_id: light.lamp_bed_willem_light
domain: light
brightness_pct: 10
- conditions:
- condition: device
type: is_on
device_id: 01b9a993ffea323f6f094e9c231f6d3c
entity_id: light.lamp_bed_willem_light
domain: light
sequence:
- type: turn_off
device_id: 01b9a993ffea323f6f094e9c231f6d3c
entity_id: light.lamp_bed_willem_light
domain: light
- id: '1675520145446'
alias: Zolder - knoppen bureau willem (BP)
description: ''
use_blueprint:
path: Bekkie/robb-smart-8-switch-ROBB-ROB_200-007-0.yaml
input:
remote: 7ed6c466f25f5b6aa59d9975cefc9e53
on_button_1_short:
- service: scene.turn_on
data: {}
target:
entity_id: scene.werken_op_zolder
off_button_1_short:
- service: scene.turn_on
data: {}
target:
entity_id: scene.klaar_met_werken_op_zolder
on_button_2_short:
- device_id: 9186cc61ae5a6d7206c02fc67cfdb878
domain: climate
entity_id: climate.ac_zolder
type: set_hvac_mode
hvac_mode: heat_cool
off_button_2_short:
- device_id: 9186cc61ae5a6d7206c02fc67cfdb878
domain: climate
entity_id: climate.ac_zolder
type: set_hvac_mode
hvac_mode: 'off'
- id: '1675628615548'
alias: Woonkamer - grover gaat smorgens poetsen
description: '' description: ''
trigger: trigger:
- platform: device - platform: time
domain: mqtt at: 00:01:00
device_id: c976ab1909dcc67895eccdce5708b0dc condition:
type: action - condition: or
subtype: off_4 conditions:
discovery_id: 0x60a423fffe28320f action_off_4 - condition: template
value_template: '{{ (as_timestamp(now()) - as_timestamp(states.sensor.roborock_vacuum_s5e_last_clean_end.last_updated)
)/3600 > 8}}'
- condition: and
conditions:
- condition: template
value_template: " - condition: template\n value_template: >-\n {{
(as_timestamp(now()) -\n as_timestamp(states.sensor.roborock_vacuum_s5e_last_clean_end.last_updated)\n
\ )/3600 > 1}}"
- condition: numeric_state
entity_id: sensor.roborock_vacuum_s5e_last_clean_area
below: 7
action:
- device_id: b99930765798a4796ca3ebb87e84299e
domain: vacuum
entity_id: vacuum.roborock_vacuum_s5e
type: clean
mode: single
- id: '1676053221891'
alias: Tuin - verlichting sunset
description: ''
trigger:
- platform: sun
event: sunset
offset: 0
condition: [] condition: []
action: action:
- service: scene.turn_on - service: scene.turn_on
data:
transition: 10
target: target:
entity_id: scene.tuin_uit entity_id: scene.tuin_avond
metadata: {}
mode: single mode: single
- id: '1677101568696'
alias: slaapstand
description: ''
trigger:
- device_id: dc42e9871d6dfc0ce76c594054038cd9
domain: zha
platform: device
type: remote_button_double_press
subtype: button_1
condition:
- type: is_no_motion
condition: device
device_id: dba81805bffdc5ab5eb183b0c2d845dc
entity_id: binary_sensor.beweging_woonkamer2_iaszone
domain: binary_sensor
for:
hours: 0
minutes: 1
seconds: 0
- condition: time
after: '22:00:00'
before: 05:00:00
- type: is_no_motion
condition: device
device_id: a55453469f5ec2003aa04648b125621d
entity_id: binary_sensor.beweging_hal_motion_detection
domain: binary_sensor
for:
hours: 0
minutes: 0
seconds: 30
action:
- type: turn_off
device_id: 1281186f8b90c2b00053decdf33a6d72
entity_id: light.lamp_aanrecht
domain: light
- type: turn_off
device_id: b6b1a8c1b1f73cb280f602415d0e836c
entity_id: switch.lamp_hal
domain: switch
- type: turn_off
device_id: 22f223be563ccfe1828f7837472fb18d
entity_id: light.lamp_wc_beneden_light
domain: light
mode: single
- id: '1677177131483'
alias: hass - lowbatt meliding sensors naar iphone willem
description: ''
use_blueprint:
path: gmlupatelli/low_battery_notification.yaml
input:
time: '19:40:00'
actions:
- service: notify.mobile_app_iphone_van_willem
data:
message: sensor batteries are low {{sensors}}

View File

@@ -1,8 +1,12 @@
script: !include scripts.yaml script: !include scripts.yaml
scene: !include scenes.yaml scene: !include scenes.yaml
frontend:
themes: !include_dir_merge_named themes/
homeassistant: homeassistant:
#packages: !include_dir_named packages/ #packages: !include_dir_named packages/
packages: !include_dir_named "integrations" packages: !include_dir_named "integrations"
media_dirs:
media: /media

View File

@@ -15,7 +15,7 @@ SENSOR_TYPES = {
SENSOR_LOCATIONS_TO_URL = { SENSOR_LOCATIONS_TO_URL = {
"trashapi": [ "trashapi": [
"http://trashapi.azurewebsites.net/trash?Location={0}&ZipCode={1}&HouseNumber={2}&HouseNumberSuffix={3}&DiftarCode={4}" "http://trashapi.azurewebsites.net/trash?Location={0}&ZipCode={1}&HouseNumber={2}&HouseNumberSuffix={3}&District={4}&DiftarCode={5}&ShowWholeYear={6}"
] ]
} }
@@ -66,6 +66,8 @@ CONF_LOCATION = "location"
CONF_POSTCODE = "postcode" CONF_POSTCODE = "postcode"
CONF_STREET_NUMBER = "streetnumber" CONF_STREET_NUMBER = "streetnumber"
CONF_STREET_NUMBER_SUFFIX = "streetnumbersuffix" CONF_STREET_NUMBER_SUFFIX = "streetnumbersuffix"
CONF_DISTRICT = "district"
CONF_GET_WHOLE_YEAR = "getwholeyear"
CONF_DATE_FORMAT = "dateformat" CONF_DATE_FORMAT = "dateformat"
CONF_TIMESPAN_IN_DAYS = "timespanindays" CONF_TIMESPAN_IN_DAYS = "timespanindays"
CONF_LOCALE = "locale" CONF_LOCALE = "locale"
@@ -82,6 +84,7 @@ ATTR_YEAR_MONTH_DAY_DATE = "year_month_day_date"
ATTR_FRIENDLY_NAME = "friendly_name" ATTR_FRIENDLY_NAME = "friendly_name"
ATTR_LAST_COLLECTION_DATE = "last_collection_date" ATTR_LAST_COLLECTION_DATE = "last_collection_date"
ATTR_TOTAL_COLLECTIONS_THIS_YEAR = "total_collections_this_year" ATTR_TOTAL_COLLECTIONS_THIS_YEAR = "total_collections_this_year"
ATTR_WHOLE_YEAR_DATES = "whole_year_dates"
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)

View File

@@ -16,38 +16,48 @@ class TrashApiAfval(object):
postcode, postcode,
street_number, street_number,
street_number_suffix, street_number_suffix,
district,
diftar_code, diftar_code,
get_whole_year,
resources, resources,
): ):
_LOGGER.debug("Updating Waste collection dates") _LOGGER.debug("Updating Waste collection dates")
try: try:
API_ENDPOINT = SENSOR_LOCATIONS_TO_URL["trashapi"][0].format( API_ENDPOINT = SENSOR_LOCATIONS_TO_URL["trashapi"][0].format(
location, postcode, street_number, street_number_suffix, diftar_code location,
postcode,
street_number,
street_number_suffix,
district,
diftar_code,
get_whole_year,
) )
r = requests.get(url=API_ENDPOINT) r = requests.get(url=API_ENDPOINT)
dataList = r.json() dataList = r.json()
# Place all possible values in the dictionary even if they are not necessary # Place all possible values in the dictionary even if they are not necessary
waste_dict = {} waste_array = []
# _LOGGER.warning(dataList) # _LOGGER.warning(dataList)
for data in dataList: for data in dataList:
# find gft. # find gft, kerstboom, papier, pbd, takken or textiel
if "gft" in resources and data["name"].lower() == "gft": if (
waste_dict["gft"] = data["date"].split("T")[0] ("gft" in resources and data["name"].lower() == "gft")
# find kerstboom. or (
if "kerstboom" in resources and data["name"].lower() == "kerstboom": "kerstboom" in resources and data["name"].lower() == "kerstboom"
waste_dict["kerstboom"] = data["date"].split("T")[0] )
# find papier or ("papier" in resources and data["name"].lower() == "papier")
if "papier" in resources and data["name"].lower() == "papier": or ("pbd" in resources and data["name"].lower() == "pbd")
waste_dict["papier"] = data["date"].split("T")[0] or ("takken" in resources and data["name"].lower() == "takken")
# find pbd. or ("textiel" in resources and data["name"].lower() == "textiel")
if "pbd" in resources and data["name"].lower() == "pbd": ):
waste_dict["pbd"] = data["date"].split("T")[0] waste_array.append(
{data["name"].lower(): data["date"].split("T")[0]}
)
# find restafval. # find restafval.
if "restafval" in resources and data["name"].lower() == "restafval": if "restafval" in resources and data["name"].lower() == "restafval":
if ( if (
@@ -56,18 +66,20 @@ class TrashApiAfval(object):
data["date"].split("T")[0], "%Y-%m-%d" data["date"].split("T")[0], "%Y-%m-%d"
).date() ).date()
): ):
waste_dict["restafval"] = data["date"].split("T")[0] waste_array.append(
{data["name"].lower(): data["date"].split("T")[0]}
)
else: else:
waste_dict["restafvaldiftardate"] = data["date"].split("T")[0] waste_array.append(
waste_dict["restafvaldiftarcollections"] = data["totalThisYear"] {"restafvaldiftardate": data["date"].split("T")[0]}
# find takken )
if "takken" in resources and data["name"].lower() == "takken": waste_array.append(
waste_dict["takken"] = data["date"].split("T")[0] {"restafvaldiftarcollections": data["totalThisYear"]}
# find textiel )
if "textiel" in resources and data["name"].lower() == "textiel":
waste_dict["textiel"] = data["date"].split("T")[0]
return waste_dict # _LOGGER.warning(waste_array)
return waste_array
except urllib.error.URLError as exc: except urllib.error.URLError as exc:
_LOGGER.error("Error occurred while fetching data: %r", exc.reason) _LOGGER.error("Error occurred while fetching data: %r", exc.reason)
return False return False

View File

@@ -1,7 +1,7 @@
{ {
"domain": "afvalinfo", "domain": "afvalinfo",
"name": "Afvalinfo", "name": "Afvalinfo",
"version": "1.0.9", "version": "1.1.0",
"documentation": "https://github.com/heyajohnny/afvalinfo", "documentation": "https://github.com/heyajohnny/afvalinfo",
"issue_tracker": "https://github.com/heyajohnny/afvalinfo/issues", "issue_tracker": "https://github.com/heyajohnny/afvalinfo/issues",
"dependencies": [], "dependencies": [],

View File

@@ -16,10 +16,12 @@ from .const.const import (
MIN_TIME_BETWEEN_UPDATES, MIN_TIME_BETWEEN_UPDATES,
_LOGGER, _LOGGER,
CONF_CITY, CONF_CITY,
CONF_DISTRICT,
CONF_LOCATION, CONF_LOCATION,
CONF_POSTCODE, CONF_POSTCODE,
CONF_STREET_NUMBER, CONF_STREET_NUMBER,
CONF_STREET_NUMBER_SUFFIX, CONF_STREET_NUMBER_SUFFIX,
CONF_GET_WHOLE_YEAR,
CONF_DATE_FORMAT, CONF_DATE_FORMAT,
CONF_TIMESPAN_IN_DAYS, CONF_TIMESPAN_IN_DAYS,
CONF_NO_TRASH_TEXT, CONF_NO_TRASH_TEXT,
@@ -36,6 +38,7 @@ from .const.const import (
ATTR_FRIENDLY_NAME, ATTR_FRIENDLY_NAME,
ATTR_LAST_COLLECTION_DATE, ATTR_LAST_COLLECTION_DATE,
ATTR_TOTAL_COLLECTIONS_THIS_YEAR, ATTR_TOTAL_COLLECTIONS_THIS_YEAR,
ATTR_WHOLE_YEAR_DATES,
SENSOR_TYPES, SENSOR_TYPES,
) )
@@ -57,12 +60,14 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
vol.Required(CONF_POSTCODE, default="3361AB"): cv.string, vol.Required(CONF_POSTCODE, default="3361AB"): cv.string,
vol.Required(CONF_STREET_NUMBER, default="1"): cv.string, vol.Required(CONF_STREET_NUMBER, default="1"): cv.string,
vol.Optional(CONF_STREET_NUMBER_SUFFIX, default=""): cv.string, vol.Optional(CONF_STREET_NUMBER_SUFFIX, default=""): cv.string,
vol.Optional(CONF_DISTRICT, default=""): cv.string,
vol.Optional(CONF_DATE_FORMAT, default="%d-%m-%Y"): cv.string, vol.Optional(CONF_DATE_FORMAT, default="%d-%m-%Y"): cv.string,
vol.Optional(CONF_TIMESPAN_IN_DAYS, default="365"): cv.string, vol.Optional(CONF_TIMESPAN_IN_DAYS, default="365"): cv.string,
vol.Optional(CONF_LOCALE, default="en"): cv.string, vol.Optional(CONF_LOCALE, default="en"): cv.string,
vol.Optional(CONF_ID, default=""): cv.string, vol.Optional(CONF_ID, default=""): cv.string,
vol.Optional(CONF_NO_TRASH_TEXT, default="none"): cv.string, vol.Optional(CONF_NO_TRASH_TEXT, default="none"): cv.string,
vol.Optional(CONF_DIFTAR_CODE, default=""): cv.string, vol.Optional(CONF_DIFTAR_CODE, default=""): cv.string,
vol.Optional(CONF_GET_WHOLE_YEAR, default="false"): cv.string,
} }
) )
@@ -76,12 +81,14 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
postcode = config.get(CONF_POSTCODE).strip() postcode = config.get(CONF_POSTCODE).strip()
street_number = config.get(CONF_STREET_NUMBER) street_number = config.get(CONF_STREET_NUMBER)
street_number_suffix = config.get(CONF_STREET_NUMBER_SUFFIX) street_number_suffix = config.get(CONF_STREET_NUMBER_SUFFIX)
district = config.get(CONF_DISTRICT)
date_format = config.get(CONF_DATE_FORMAT).strip() date_format = config.get(CONF_DATE_FORMAT).strip()
timespan_in_days = config.get(CONF_TIMESPAN_IN_DAYS) timespan_in_days = config.get(CONF_TIMESPAN_IN_DAYS)
locale = config.get(CONF_LOCALE) locale = config.get(CONF_LOCALE)
id_name = config.get(CONF_ID) id_name = config.get(CONF_ID)
no_trash_text = config.get(CONF_NO_TRASH_TEXT) no_trash_text = config.get(CONF_NO_TRASH_TEXT)
diftar_code = config.get(CONF_DIFTAR_CODE) diftar_code = config.get(CONF_DIFTAR_CODE)
get_whole_year = config.get(CONF_GET_WHOLE_YEAR)
try: try:
resources = config[CONF_RESOURCES].copy() resources = config[CONF_RESOURCES].copy()
@@ -102,7 +109,9 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
postcode, postcode,
street_number, street_number,
street_number_suffix, street_number_suffix,
district,
diftar_code, diftar_code,
get_whole_year,
resourcesMinusTodayAndTomorrow, resourcesMinusTodayAndTomorrow,
) )
except urllib.error.HTTPError as error: except urllib.error.HTTPError as error:
@@ -139,6 +148,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
timespan_in_days, timespan_in_days,
locale, locale,
id_name, id_name,
get_whole_year,
) )
) )
@@ -175,7 +185,9 @@ class AfvalinfoData(object):
postcode, postcode,
street_number, street_number,
street_number_suffix, street_number_suffix,
district,
diftar_code, diftar_code,
get_whole_year,
resources, resources,
): ):
self.data = None self.data = None
@@ -183,7 +195,9 @@ class AfvalinfoData(object):
self.postcode = postcode self.postcode = postcode
self.street_number = street_number self.street_number = street_number
self.street_number_suffix = street_number_suffix self.street_number_suffix = street_number_suffix
self.district = district
self.diftar_code = diftar_code self.diftar_code = diftar_code
self.get_whole_year = get_whole_year
self.resources = resources self.resources = resources
@Throttle(MIN_TIME_BETWEEN_UPDATES) @Throttle(MIN_TIME_BETWEEN_UPDATES)
@@ -194,7 +208,9 @@ class AfvalinfoData(object):
self.postcode, self.postcode,
self.street_number, self.street_number,
self.street_number_suffix, self.street_number_suffix,
self.district,
self.diftar_code, self.diftar_code,
self.get_whole_year,
self.resources, self.resources,
) )
@@ -209,6 +225,7 @@ class AfvalinfoSensor(Entity):
timespan_in_days, timespan_in_days,
locale, locale,
id_name, id_name,
get_whole_year,
): ):
self.data = data self.data = data
self.type = sensor_type self.type = sensor_type
@@ -217,6 +234,7 @@ class AfvalinfoSensor(Entity):
self.timespan_in_days = timespan_in_days self.timespan_in_days = timespan_in_days
self.locale = locale self.locale = locale
self._name = sensor_friendly_name self._name = sensor_friendly_name
self._get_whole_year = get_whole_year
self.entity_id = "sensor." + ( self.entity_id = "sensor." + (
( (
SENSOR_PREFIX SENSOR_PREFIX
@@ -241,6 +259,7 @@ class AfvalinfoSensor(Entity):
self._year_month_day_date = None self._year_month_day_date = None
self._last_collection_date = None self._last_collection_date = None
self._total_collections_this_year = None self._total_collections_this_year = None
self._whole_year_dates = None
@property @property
def name(self): def name(self):
@@ -266,16 +285,29 @@ class AfvalinfoSensor(Entity):
ATTR_IS_COLLECTION_DATE_TODAY: self._is_collection_date_today, ATTR_IS_COLLECTION_DATE_TODAY: self._is_collection_date_today,
ATTR_LAST_COLLECTION_DATE: self._last_collection_date, ATTR_LAST_COLLECTION_DATE: self._last_collection_date,
ATTR_TOTAL_COLLECTIONS_THIS_YEAR: self._total_collections_this_year, ATTR_TOTAL_COLLECTIONS_THIS_YEAR: self._total_collections_this_year,
ATTR_WHOLE_YEAR_DATES: self._whole_year_dates,
} }
@Throttle(MIN_TIME_BETWEEN_UPDATES) @Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self): def update(self):
self.data.update() self.data.update()
waste_data = self.data.data waste_array = self.data.data
self._error = False self._error = False
# Loop through all the dates to put the dates in the whole_year_dates attribute
if self._get_whole_year == "True":
whole_year_dates = []
for waste_data in waste_array:
if self.type in waste_data:
whole_year_dates.append(
datetime.strptime(waste_data[self.type], "%Y-%m-%d").date()
)
self._whole_year_dates = whole_year_dates
try: try:
if waste_data: if waste_array:
for waste_data in waste_array:
if self.type in waste_data: if self.type in waste_data:
collection_date = datetime.strptime( collection_date = datetime.strptime(
waste_data[self.type], "%Y-%m-%d" waste_data[self.type], "%Y-%m-%d"
@@ -286,10 +318,14 @@ class AfvalinfoSensor(Entity):
if collection_date: if collection_date:
# Set the values of the sensor # Set the values of the sensor
self._last_update = datetime.today().strftime("%d-%m-%Y %H:%M") self._last_update = datetime.today().strftime(
"%d-%m-%Y %H:%M"
)
# Is the collection date today? # Is the collection date today?
self._is_collection_date_today = date.today() == collection_date self._is_collection_date_today = (
date.today() == collection_date
)
if ( if (
self.type == "restafval" self.type == "restafval"
@@ -319,7 +355,9 @@ class AfvalinfoSensor(Entity):
and self.date_format.find("b") == -1 and self.date_format.find("b") == -1
and self.date_format.find("B") == -1 and self.date_format.find("B") == -1
): ):
self._state = collection_date.strftime(self.date_format) self._state = collection_date.strftime(
self.date_format
)
# else convert the named values to the locale names # else convert the named values to the locale names
else: else:
edited_date_format = self.date_format.replace( edited_date_format = self.date_format.replace(
@@ -352,12 +390,14 @@ class AfvalinfoSensor(Entity):
) )
self._state = locale_date self._state = locale_date
break # we have a result, break the loop
else: else:
self._hidden = True self._hidden = True
else: else:
# collection_date empty
raise ValueError() raise ValueError()
else: # else:
raise ValueError() # No matching result data for current waste type, no problem
else: else:
raise ValueError() raise ValueError()
except ValueError: except ValueError:
@@ -369,4 +409,5 @@ class AfvalinfoSensor(Entity):
# self._is_collection_date_today = False # self._is_collection_date_today = False
# self._last_collection_date = None # self._last_collection_date = None
# self._total_collections_this_year = None # self._total_collections_this_year = None
# self._whole_year_dates = None
self._last_update = datetime.today().strftime("%d-%m-%Y %H:%M") self._last_update = datetime.today().strftime("%d-%m-%Y %H:%M")

View File

@@ -12,8 +12,7 @@ def get_waste_data_raw(
postal_code, postal_code,
street_number, street_number,
suffix, suffix,
): # sourcery skip: avoid-builtin-shadow ):
if provider not in SENSOR_COLLECTORS_ICALENDAR.keys(): if provider not in SENSOR_COLLECTORS_ICALENDAR.keys():
raise ValueError(f"Invalid provider: {provider}, please verify") raise ValueError(f"Invalid provider: {provider}, please verify")

View File

@@ -17,6 +17,7 @@ def get_waste_data_raw(
try: try:
bag_id = None bag_id = None
suffix = suffix.strip().upper()
_verify = provider != "suez" _verify = provider != "suez"
url = f"{SENSOR_COLLECTORS_OPZET[provider]}/rest/adressen/{postal_code}-{street_number}" url = f"{SENSOR_COLLECTORS_OPZET[provider]}/rest/adressen/{postal_code}-{street_number}"
raw_response = requests.get(url, verify=_verify) raw_response = requests.get(url, verify=_verify)

View File

@@ -5,7 +5,7 @@ _LOGGER = logging.getLogger(__name__)
API = "api" API = "api"
NAME = "afvalwijzer" NAME = "afvalwijzer"
VERSION = "2022.11.02" VERSION = "2023.01.01"
ISSUE_URL = "https://github.com/xirixiz/homeassistant-afvalwijzer/issues" ISSUE_URL = "https://github.com/xirixiz/homeassistant-afvalwijzer/issues"
SENSOR_COLLECTOR_TO_URL = { SENSOR_COLLECTOR_TO_URL = {

View File

@@ -1,7 +1,7 @@
{ {
"domain": "afvalwijzer", "domain": "afvalwijzer",
"name": "Afvalwijzer", "name": "Afvalwijzer",
"version": "2022.11.02", "version": "2023.01.01",
"iot_class": "cloud_polling", "iot_class": "cloud_polling",
"documentation": "https://github.com/xirixiz/homeassistant-afvalwijzer/blob/master/README.md", "documentation": "https://github.com/xirixiz/homeassistant-afvalwijzer/blob/master/README.md",
"issue_tracker": "https://github.com/xirixiz/homeassistant-afvalwijzer/issues", "issue_tracker": "https://github.com/xirixiz/homeassistant-afvalwijzer/issues",

View File

@@ -40,7 +40,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
vol.Optional(CONF_SUFFIX, default=""): cv.string, vol.Optional(CONF_SUFFIX, default=""): cv.string,
vol.Optional(CONF_EXCLUDE_PICKUP_TODAY, default="true"): cv.string, vol.Optional(CONF_EXCLUDE_PICKUP_TODAY, default="true"): cv.string,
vol.Optional(CONF_EXCLUDE_LIST, default=""): cv.string, vol.Optional(CONF_EXCLUDE_LIST, default=""): cv.string,
vol.Optional(CONF_DEFAULT_LABEL, default="Geen"): cv.string, vol.Optional(CONF_DEFAULT_LABEL, default="geen"): cv.string,
vol.Optional(CONF_ID.strip().lower(), default=""): cv.string, vol.Optional(CONF_ID.strip().lower(), default=""): cv.string,
} }
) )
@@ -77,7 +77,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
except ValueError as err: except ValueError as err:
_LOGGER.error(f"Check afvalwijzer platform settings {err.args}") _LOGGER.error(f"Check afvalwijzer platform settings {err.args}")
fetch_data = AfvalwijzerData(config) fetch_data = AfvalwijzerData(hass, config)
waste_types_provider = collector.waste_types_provider waste_types_provider = collector.waste_types_provider
_LOGGER.debug(f"Generating waste_types_provider list = {waste_types_provider}") _LOGGER.debug(f"Generating waste_types_provider list = {waste_types_provider}")
@@ -98,7 +98,8 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
class AfvalwijzerData(object): class AfvalwijzerData(object):
def __init__(self, config): def __init__(self, hass, config):
self._hass = hass
self.config = config self.config = config
@Throttle(MIN_TIME_BETWEEN_UPDATES) @Throttle(MIN_TIME_BETWEEN_UPDATES)

View File

@@ -24,7 +24,7 @@ from ..collector.main_collector import MainCollector
# Common # Common
suffix = "" suffix = ""
exclude_pickup_today = "True" exclude_pickup_today = "True"
default_label = "Geen" default_label = "geen"
exclude_list = "" exclude_list = ""
# DeAfvalapp # DeAfvalapp
@@ -42,6 +42,11 @@ exclude_list = ""
# postal_code = "5146eg" # postal_code = "5146eg"
# street_number = "1" # street_number = "1"
provider = "rmn"
postal_code = "3701XK"
street_number = "24"
suffix = "b"
# Opzet # Opzet
# provider = "prezero" # provider = "prezero"
# postal_code = "6665CN" # postal_code = "6665CN"
@@ -54,9 +59,9 @@ exclude_list = ""
# suffix = "C" # suffix = "C"
# Ximmio # Ximmio
provider = "meerlanden" # provider = "meerlanden"
postal_code = "2121xt" # postal_code = "2121xt"
street_number = "38" # street_number = "38"
# Ximmio # Ximmio
# provider = "acv" # provider = "acv"

View File

@@ -25,6 +25,7 @@ import voluptuous as vol
from .base import HacsBase from .base import HacsBase
from .const import DOMAIN, MINIMUM_HA_VERSION, STARTUP from .const import DOMAIN, MINIMUM_HA_VERSION, STARTUP
from .data_client import HacsDataClient
from .enums import ConfigurationType, HacsDisabledReason, HacsStage, LovelaceMode from .enums import ConfigurationType, HacsDisabledReason, HacsStage, LovelaceMode
from .frontend import async_register_frontend from .frontend import async_register_frontend
from .utils.configuration_schema import hacs_config_combined from .utils.configuration_schema import hacs_config_combined
@@ -87,6 +88,10 @@ async def async_initialize_integration(
hacs.hass = hass hacs.hass = hass
hacs.queue = QueueManager(hass=hass) hacs.queue = QueueManager(hass=hass)
hacs.data = HacsData(hacs=hacs) hacs.data = HacsData(hacs=hacs)
hacs.data_client = HacsDataClient(
session=clientsession,
client_name=f"HACS/{integration.version}",
)
hacs.system.running = True hacs.system.running = True
hacs.session = clientsession hacs.session = clientsession
@@ -153,6 +158,7 @@ async def async_initialize_integration(
hacs.disable_hacs(HacsDisabledReason.RESTORE) hacs.disable_hacs(HacsDisabledReason.RESTORE)
return False return False
if not hacs.configuration.experimental:
can_update = await hacs.async_can_update() can_update = await hacs.async_can_update()
hacs.log.debug("Can update %s repositories", can_update) hacs.log.debug("Can update %s repositories", can_update)
@@ -168,7 +174,7 @@ async def async_initialize_integration(
hacs.log.info("Update entities are only supported when using UI configuration") hacs.log.info("Update entities are only supported when using UI configuration")
else: else:
hass.config_entries.async_setup_platforms( await hass.config_entries.async_forward_entry_setups(
config_entry, config_entry,
[Platform.SENSOR, Platform.UPDATE] [Platform.SENSOR, Platform.UPDATE]
if hacs.configuration.experimental if hacs.configuration.experimental

View File

@@ -28,11 +28,17 @@ from homeassistant.config_entries import ConfigEntry, ConfigEntryState
from homeassistant.const import EVENT_HOMEASSISTANT_FINAL_WRITE, Platform from homeassistant.const import EVENT_HOMEASSISTANT_FINAL_WRITE, Platform
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.issue_registry import async_create_issue, IssueSeverity from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.loader import Integration from homeassistant.loader import Integration
from homeassistant.util import dt from homeassistant.util import dt
from .const import DOMAIN, TV from custom_components.hacs.repositories.base import (
HACS_MANIFEST_KEYS_TO_EXPORT,
REPOSITORY_KEYS_TO_EXPORT,
)
from .const import DOMAIN, TV, URL_BASE
from .data_client import HacsDataClient
from .enums import ( from .enums import (
ConfigurationType, ConfigurationType,
HacsCategory, HacsCategory,
@@ -47,6 +53,7 @@ from .exceptions import (
HacsException, HacsException,
HacsExecutionStillInProgress, HacsExecutionStillInProgress,
HacsExpectedException, HacsExpectedException,
HacsNotModifiedException,
HacsRepositoryArchivedException, HacsRepositoryArchivedException,
HacsRepositoryExistException, HacsRepositoryExistException,
HomeAssistantCoreRepositoryException, HomeAssistantCoreRepositoryException,
@@ -164,6 +171,9 @@ class HacsStatus:
startup: bool = True startup: bool = True
new: bool = False new: bool = False
active_frontend_endpoint_plugin: bool = False
active_frontend_endpoint_theme: bool = False
inital_fetch_done: bool = False
@dataclass @dataclass
@@ -174,6 +184,7 @@ class HacsSystem:
running: bool = False running: bool = False
stage = HacsStage.SETUP stage = HacsStage.SETUP
action: bool = False action: bool = False
generator: bool = False
@property @property
def disabled(self) -> bool: def disabled(self) -> bool:
@@ -263,7 +274,7 @@ class HacsRepositories:
self._default_repositories.add(repo_id) self._default_repositories.add(repo_id)
def set_repository_id(self, repository, repo_id): def set_repository_id(self, repository: HacsRepository, repo_id: str):
"""Update a repository id.""" """Update a repository id."""
existing_repo_id = str(repository.data.id) existing_repo_id = str(repository.data.id)
if existing_repo_id == repo_id: if existing_repo_id == repo_id:
@@ -348,6 +359,7 @@ class HacsBase:
configuration = HacsConfiguration() configuration = HacsConfiguration()
core = HacsCore() core = HacsCore()
data: HacsData | None = None data: HacsData | None = None
data_client: HacsDataClient | None = None
frontend_version: str | None = None frontend_version: str | None = None
github: GitHub | None = None github: GitHub | None = None
githubapi: GitHubAPI | None = None githubapi: GitHubAPI | None = None
@@ -544,8 +556,6 @@ class HacsBase:
if check: if check:
try: try:
await repository.async_registration(ref) await repository.async_registration(ref)
if self.status.new:
repository.data.new = False
if repository.validate.errors: if repository.validate.errors:
self.common.skip.append(repository.data.full_name) self.common.skip.append(repository.data.full_name)
if not self.status.startup: if not self.status.startup:
@@ -559,7 +569,11 @@ class HacsBase:
repository.logger.info("%s Validation completed", repository.string) repository.logger.info("%s Validation completed", repository.string)
else: else:
repository.logger.info("%s Registration completed", repository.string) repository.logger.info("%s Registration completed", repository.string)
except (HacsRepositoryExistException, HacsRepositoryArchivedException): except (HacsRepositoryExistException, HacsRepositoryArchivedException) as exception:
if self.system.generator:
repository.logger.error(
"%s Registration Failed - %s", repository.string, exception
)
return return
except AIOGitHubAPIException as exception: except AIOGitHubAPIException as exception:
self.common.skip.append(repository.data.full_name) self.common.skip.append(repository.data.full_name)
@@ -567,6 +581,9 @@ class HacsBase:
f"Validation for {repository_full_name} failed with {exception}." f"Validation for {repository_full_name} failed with {exception}."
) from exception ) from exception
if self.status.new:
repository.data.new = False
if repository_id is not None: if repository_id is not None:
repository.data.id = repository_id repository.data.id = repository_id
@@ -586,34 +603,7 @@ class HacsBase:
async def startup_tasks(self, _=None) -> None: async def startup_tasks(self, _=None) -> None:
"""Tasks that are started after setup.""" """Tasks that are started after setup."""
self.set_stage(HacsStage.STARTUP) self.set_stage(HacsStage.STARTUP)
await self.async_load_hacs_from_github()
try:
repository = self.repositories.get_by_full_name(HacsGitHubRepo.INTEGRATION)
if repository is None:
await self.async_register_repository(
repository_full_name=HacsGitHubRepo.INTEGRATION,
category=HacsCategory.INTEGRATION,
default=True,
)
repository = self.repositories.get_by_full_name(HacsGitHubRepo.INTEGRATION)
if repository is None:
raise HacsException("Unknown error")
repository.data.installed = True
repository.data.installed_version = self.integration.version.string
repository.data.new = False
repository.data.releases = True
self.repository = repository.repository_object
self.repositories.mark_default(repository)
except HacsException as exception:
if "403" in str(exception):
self.log.critical(
"GitHub API is ratelimited, or the token is wrong.",
)
else:
self.log.critical("Could not load HACS! - %s", exception)
self.disable_hacs(HacsDisabledReason.LOAD_HACS)
if critical := await async_load_from_store(self.hass, "critical"): if critical := await async_load_from_store(self.hass, "critical"):
for repo in critical: for repo in critical:
@@ -624,16 +614,38 @@ class HacsBase:
) )
break break
if not self.configuration.experimental:
self.recuring_tasks.append( self.recuring_tasks.append(
self.hass.helpers.event.async_track_time_interval( self.hass.helpers.event.async_track_time_interval(
self.async_get_all_category_repositories, timedelta(hours=3) self.async_update_downloaded_repositories, timedelta(hours=48)
) )
) )
self.recuring_tasks.append( self.recuring_tasks.append(
self.hass.helpers.event.async_track_time_interval( self.hass.helpers.event.async_track_time_interval(
self.async_update_all_repositories, timedelta(hours=25) self.async_update_all_repositories,
timedelta(hours=96),
) )
) )
else:
self.recuring_tasks.append(
self.hass.helpers.event.async_track_time_interval(
self.async_load_hacs_from_github,
timedelta(hours=48),
)
)
self.recuring_tasks.append(
self.hass.helpers.event.async_track_time_interval(
self.async_update_downloaded_custom_repositories, timedelta(hours=48)
)
)
self.recuring_tasks.append(
self.hass.helpers.event.async_track_time_interval(
self.async_get_all_category_repositories, timedelta(hours=6)
)
)
self.recuring_tasks.append( self.recuring_tasks.append(
self.hass.helpers.event.async_track_time_interval( self.hass.helpers.event.async_track_time_interval(
self.async_check_rate_limit, timedelta(minutes=5) self.async_check_rate_limit, timedelta(minutes=5)
@@ -644,14 +656,10 @@ class HacsBase:
self.async_prosess_queue, timedelta(minutes=10) self.async_prosess_queue, timedelta(minutes=10)
) )
) )
self.recuring_tasks.append( self.recuring_tasks.append(
self.hass.helpers.event.async_track_time_interval( self.hass.helpers.event.async_track_time_interval(
self.async_update_downloaded_repositories, timedelta(hours=2) self.async_handle_critical_repositories, timedelta(hours=6)
)
)
self.recuring_tasks.append(
self.hass.helpers.event.async_track_time_interval(
self.async_handle_critical_repositories, timedelta(hours=2)
) )
) )
@@ -659,6 +667,8 @@ class HacsBase:
EVENT_HOMEASSISTANT_FINAL_WRITE, self.data.async_force_write EVENT_HOMEASSISTANT_FINAL_WRITE, self.data.async_force_write
) )
self.log.debug("There are %s scheduled recurring tasks", len(self.recuring_tasks))
self.status.startup = False self.status.startup = False
self.async_dispatch(HacsDispatchEvent.STATUS, {}) self.async_dispatch(HacsDispatchEvent.STATUS, {})
@@ -756,6 +766,42 @@ class HacsBase:
if self.configuration.netdaemon: if self.configuration.netdaemon:
self.enable_hacs_category(HacsCategory.NETDAEMON) self.enable_hacs_category(HacsCategory.NETDAEMON)
async def async_load_hacs_from_github(self, _=None) -> None:
"""Load HACS from GitHub."""
if self.configuration.experimental and self.status.inital_fetch_done:
return
try:
repository = self.repositories.get_by_full_name(HacsGitHubRepo.INTEGRATION)
if repository is None:
await self.async_register_repository(
repository_full_name=HacsGitHubRepo.INTEGRATION,
category=HacsCategory.INTEGRATION,
default=True,
)
repository = self.repositories.get_by_full_name(HacsGitHubRepo.INTEGRATION)
elif self.configuration.experimental and not self.status.startup:
self.log.error("Scheduling update of hacs/integration")
self.queue.add(repository.common_update())
if repository is None:
raise HacsException("Unknown error")
repository.data.installed = True
repository.data.installed_version = self.integration.version.string
repository.data.new = False
repository.data.releases = True
self.repository = repository.repository_object
self.repositories.mark_default(repository)
except HacsException as exception:
if "403" in str(exception):
self.log.critical(
"GitHub API is ratelimited, or the token is wrong.",
)
else:
self.log.critical("Could not load HACS! - %s", exception)
self.disable_hacs(HacsDisabledReason.LOAD_HACS)
async def async_get_all_category_repositories(self, _=None) -> None: async def async_get_all_category_repositories(self, _=None) -> None:
"""Get all category repositories.""" """Get all category repositories."""
if self.system.disabled: if self.system.disabled:
@@ -763,11 +809,62 @@ class HacsBase:
self.log.info("Loading known repositories") self.log.info("Loading known repositories")
await asyncio.gather( await asyncio.gather(
*[ *[
self.async_get_category_repositories(HacsCategory(category)) self.async_get_category_repositories_experimental(category)
if self.configuration.experimental
else self.async_get_category_repositories(HacsCategory(category))
for category in self.common.categories or [] for category in self.common.categories or []
] ]
) )
async def async_get_category_repositories_experimental(self, category: str) -> None:
"""Update all category repositories."""
self.log.debug("Fetching updated content for %s", category)
try:
category_data = await self.data_client.get_data(category)
except HacsNotModifiedException:
self.log.debug("No updates for %s", category)
return
except HacsException as exception:
self.log.error("Could not update %s - %s", category, exception)
return
await self.data.register_unknown_repositories(category_data, category)
for repo_id, repo_data in category_data.items():
repo = repo_data["full_name"]
if self.common.renamed_repositories.get(repo):
repo = self.common.renamed_repositories[repo]
if self.repositories.is_removed(repo):
continue
if repo in self.common.archived_repositories:
continue
if repository := self.repositories.get_by_full_name(repo):
self.repositories.set_repository_id(repository, repo_id)
self.repositories.mark_default(repository)
if repository.data.last_fetched is None or (
repository.data.last_fetched.timestamp() < repo_data["last_fetched"]
):
repository.data.update_data({**dict(REPOSITORY_KEYS_TO_EXPORT), **repo_data})
if (manifest := repo_data.get("manifest")) is not None:
repository.repository_manifest.update_data(
{**dict(HACS_MANIFEST_KEYS_TO_EXPORT), **manifest}
)
if category == "integration":
self.status.inital_fetch_done = True
if self.stage == HacsStage.STARTUP:
for repository in self.repositories.list_all:
if (
repository.data.category == category
and not repository.data.installed
and not self.repositories.is_default(repository.data.id)
):
repository.logger.debug(
"%s Unregister stale custom repository", repository.string
)
self.repositories.unregister(repository)
async def async_get_category_repositories(self, category: HacsCategory) -> None: async def async_get_category_repositories(self, category: HacsCategory) -> None:
"""Get repositories from category.""" """Get repositories from category."""
if self.system.disabled: if self.system.disabled:
@@ -843,7 +940,7 @@ class HacsBase:
return return
can_update = await self.async_can_update() can_update = await self.async_can_update()
self.log.debug( self.log.debug(
"Can update %s repositories, " "items in queue %s", "Can update %s repositories, items in queue %s",
can_update, can_update,
self.queue.pending_tasks, self.queue.pending_tasks,
) )
@@ -865,6 +962,9 @@ class HacsBase:
self.log.info("Loading removed repositories") self.log.info("Loading removed repositories")
try: try:
if self.configuration.experimental:
removed_repositories = await self.data_client.get_data("removed")
else:
removed_repositories = await self.async_github_get_hacs_default_file( removed_repositories = await self.async_github_get_hacs_default_file(
HacsCategory.REMOVED HacsCategory.REMOVED
) )
@@ -913,7 +1013,7 @@ class HacsBase:
async def async_update_downloaded_repositories(self, _=None) -> None: async def async_update_downloaded_repositories(self, _=None) -> None:
"""Execute the task.""" """Execute the task."""
if self.system.disabled: if self.system.disabled or self.configuration.experimental:
return return
self.log.info("Starting recurring background task for downloaded repositories") self.log.info("Starting recurring background task for downloaded repositories")
@@ -923,6 +1023,21 @@ class HacsBase:
self.log.debug("Recurring background task for downloaded repositories done") self.log.debug("Recurring background task for downloaded repositories done")
async def async_update_downloaded_custom_repositories(self, _=None) -> None:
"""Execute the task."""
if self.system.disabled or not self.configuration.experimental:
return
self.log.info("Starting recurring background task for downloaded custom repositories")
for repository in self.repositories.list_downloaded:
if (
repository.data.category in self.common.categories
and not self.repositories.is_default(repository.data.id)
):
self.queue.add(repository.update_repository(ignore_issues=True))
self.log.debug("Recurring background task for downloaded custom repositories done")
async def async_handle_critical_repositories(self, _=None) -> None: async def async_handle_critical_repositories(self, _=None) -> None:
"""Handle critical repositories.""" """Handle critical repositories."""
critical_queue = QueueManager(hass=self.hass) critical_queue = QueueManager(hass=self.hass)
@@ -931,8 +1046,11 @@ class HacsBase:
was_installed = False was_installed = False
try: try:
if self.configuration.experimental:
critical = await self.data_client.get_data("critical")
else:
critical = await self.async_github_get_hacs_default_file("critical") critical = await self.async_github_get_hacs_default_file("critical")
except GitHubNotModifiedException: except (GitHubNotModifiedException, HacsNotModifiedException):
return return
except HacsException: except HacsException:
pass pass
@@ -984,3 +1102,43 @@ class HacsBase:
if was_installed: if was_installed:
self.log.critical("Restarting Home Assistant") self.log.critical("Restarting Home Assistant")
self.hass.async_create_task(self.hass.async_stop(100)) self.hass.async_create_task(self.hass.async_stop(100))
@callback
def async_setup_frontend_endpoint_plugin(self) -> None:
"""Setup the http endpoints for plugins if its not already handled."""
if self.status.active_frontend_endpoint_plugin or not os.path.exists(
self.hass.config.path("www/community")
):
return
self.log.info("Setting up plugin endpoint")
use_cache = self.core.lovelace_mode == "storage"
self.log.info(
"<HacsFrontend> %s mode, cache for /hacsfiles/: %s",
self.core.lovelace_mode,
use_cache,
)
self.hass.http.register_static_path(
URL_BASE,
self.hass.config.path("www/community"),
cache_headers=use_cache,
)
self.status.active_frontend_endpoint_plugin = True
@callback
def async_setup_frontend_endpoint_themes(self) -> None:
"""Setup the http endpoints for themes if its not already handled."""
if (
self.configuration.experimental
or self.status.active_frontend_endpoint_theme
or not os.path.exists(self.hass.config.path("themes"))
):
return
self.log.info("Setting up themes endpoint")
# Register themes
self.hass.http.register_static_path(f"{URL_BASE}/themes", self.hass.config.path("themes"))
self.status.active_frontend_endpoint_theme = True

View File

@@ -6,7 +6,9 @@ from aiogithubapi.common.const import ACCEPT_HEADERS
NAME_SHORT = "HACS" NAME_SHORT = "HACS"
DOMAIN = "hacs" DOMAIN = "hacs"
CLIENT_ID = "395a8e669c5de9f7c6e8" CLIENT_ID = "395a8e669c5de9f7c6e8"
MINIMUM_HA_VERSION = "2022.10.0" MINIMUM_HA_VERSION = "2022.11.0"
URL_BASE = "/hacsfiles"
TV = TypeVar("TV") TV = TypeVar("TV")
@@ -15,6 +17,8 @@ PACKAGE_NAME = "custom_components.hacs"
DEFAULT_CONCURRENT_TASKS = 15 DEFAULT_CONCURRENT_TASKS = 15
DEFAULT_CONCURRENT_BACKOFF_TIME = 1 DEFAULT_CONCURRENT_BACKOFF_TIME = 1
HACS_REPOSITORY_ID = "172733314"
HACS_ACTION_GITHUB_API_HEADERS = { HACS_ACTION_GITHUB_API_HEADERS = {
"User-Agent": "HACS/action", "User-Agent": "HACS/action",
"Accept": ACCEPT_HEADERS["preview"], "Accept": ACCEPT_HEADERS["preview"],

View File

@@ -4,7 +4,7 @@ import sys
if sys.version_info.minor >= 11: if sys.version_info.minor >= 11:
# Needs Python 3.11 # Needs Python 3.11
from enum import StrEnum ## pylint: disable=no-name-in-module from enum import StrEnum # # pylint: disable=no-name-in-module
else: else:
try: try:
# https://github.com/home-assistant/core/blob/dev/homeassistant/backports/enum.py # https://github.com/home-assistant/core/blob/dev/homeassistant/backports/enum.py

View File

@@ -7,15 +7,13 @@ from aiohttp import web
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from .const import DOMAIN from .const import DOMAIN, URL_BASE
from .hacs_frontend import locate_dir, VERSION as FE_VERSION from .hacs_frontend import VERSION as FE_VERSION, locate_dir
from .hacs_frontend_experimental import ( from .hacs_frontend_experimental import (
locate_dir as experimental_locate_dir,
VERSION as EXPERIMENTAL_FE_VERSION, VERSION as EXPERIMENTAL_FE_VERSION,
locate_dir as experimental_locate_dir,
) )
URL_BASE = "/hacsfiles"
if TYPE_CHECKING: if TYPE_CHECKING:
from .base import HacsBase from .base import HacsBase
@@ -24,8 +22,8 @@ if TYPE_CHECKING:
def async_register_frontend(hass: HomeAssistant, hacs: HacsBase) -> None: def async_register_frontend(hass: HomeAssistant, hacs: HacsBase) -> None:
"""Register the frontend.""" """Register the frontend."""
# Register themes # Setup themes endpoint if needed
hass.http.register_static_path(f"{URL_BASE}/themes", hass.config.path("themes")) hacs.async_setup_frontend_endpoint_themes()
# Register frontend # Register frontend
if hacs.configuration.frontend_repo_url: if hacs.configuration.frontend_repo_url:
@@ -50,20 +48,6 @@ def async_register_frontend(hass: HomeAssistant, hacs: HacsBase) -> None:
hass.data["frontend_extra_module_url"] = set() hass.data["frontend_extra_module_url"] = set()
hass.data["frontend_extra_module_url"].add(f"{URL_BASE}/iconset.js") hass.data["frontend_extra_module_url"].add(f"{URL_BASE}/iconset.js")
# Register www/community for all other files
use_cache = hacs.core.lovelace_mode == "storage"
hacs.log.info(
"<HacsFrontend> %s mode, cache for /hacsfiles/: %s",
hacs.core.lovelace_mode,
use_cache,
)
hass.http.register_static_path(
URL_BASE,
hass.config.path("www/community"),
cache_headers=use_cache,
)
hacs.frontend_version = ( hacs.frontend_version = (
FE_VERSION if not hacs.configuration.experimental else EXPERIMENTAL_FE_VERSION FE_VERSION if not hacs.configuration.experimental else EXPERIMENTAL_FE_VERSION
) )
@@ -86,6 +70,9 @@ def async_register_frontend(hass: HomeAssistant, hacs: HacsBase) -> None:
require_admin=True, require_admin=True,
) )
# Setup plugin endpoint if needed
hacs.async_setup_frontend_endpoint_plugin()
class HacsFrontendDev(HomeAssistantView): class HacsFrontendDev(HomeAssistantView):
"""Dev View Class for HACS.""" """Dev View Class for HACS."""

View File

@@ -1 +0,0 @@
const t=(t,e,n)=>t(`component.${e}.title`)||(null==n?void 0:n.name)||e,e=(t,e)=>t.callWS({type:"manifest/get",integration:e});export{t as d,e as f};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,94 +0,0 @@
import{P as e,Q as t,_ as o,j as i,e as n,y as a,d as r,n as l}from"./main-c66a9a06.js";e({_template:t`
<style>
:host {
overflow: hidden; /* needed for text-overflow: ellipsis to work on ff */
@apply --layout-vertical;
@apply --layout-center-justified;
@apply --layout-flex;
}
:host([two-line]) {
min-height: var(--paper-item-body-two-line-min-height, 72px);
}
:host([three-line]) {
min-height: var(--paper-item-body-three-line-min-height, 88px);
}
:host > ::slotted(*) {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
:host > ::slotted([secondary]) {
@apply --paper-font-body1;
color: var(--paper-item-body-secondary-color, var(--secondary-text-color));
@apply --paper-item-body-secondary;
}
</style>
<slot></slot>
`,is:"paper-item-body"}),o([l("ha-settings-row")],(function(e,t){return{F:class extends t{constructor(...t){super(...t),e(this)}},d:[{kind:"field",decorators:[n({type:Boolean,reflect:!0})],key:"narrow",value:void 0},{kind:"field",decorators:[n({type:Boolean,attribute:"three-line"})],key:"threeLine",value:()=>!1},{kind:"method",key:"render",value:function(){return a`
<div class="prefix-wrap">
<slot name="prefix"></slot>
<paper-item-body
?two-line=${!this.threeLine}
?three-line=${this.threeLine}
>
<slot name="heading"></slot>
<div secondary><slot name="description"></slot></div>
</paper-item-body>
</div>
<div class="content"><slot></slot></div>
`}},{kind:"get",static:!0,key:"styles",value:function(){return r`
:host {
display: flex;
padding: 0 16px;
align-content: normal;
align-self: auto;
align-items: center;
}
paper-item-body {
padding: 8px 16px 8px 0;
}
paper-item-body[two-line] {
min-height: calc(
var(--paper-item-body-two-line-min-height, 72px) - 16px
);
flex: 1;
}
.content {
display: contents;
}
:host(:not([narrow])) .content {
display: var(--settings-row-content-display, flex);
justify-content: flex-end;
flex: 1;
padding: 16px 0;
}
.content ::slotted(*) {
width: var(--settings-row-content-width);
}
:host([narrow]) {
align-items: normal;
flex-direction: column;
border-top: 1px solid var(--divider-color);
padding-bottom: 8px;
}
::slotted(ha-switch) {
padding: 16px 0;
}
div[secondary] {
white-space: normal;
}
.prefix-wrap {
display: var(--settings-row-prefix-display);
}
:host([narrow]) .prefix-wrap {
display: flex;
align-items: center;
}
`}}]}}),i);

View File

@@ -1,6 +0,0 @@
import{_ as t,H as e,e as i,a7 as o,y as s,n as r}from"./main-c66a9a06.js";import{m as a}from"./c.ba59af11.js";import"./c.e8169f76.js";import"./c.73c7fa75.js";import"./c.743a15a1.js";import"./c.b914d43e.js";import"./c.8e28b461.js";let d=t([r("hacs-generic-dialog")],(function(t,e){return{F:class extends e{constructor(...e){super(...e),t(this)}},d:[{kind:"field",decorators:[i({type:Boolean})],key:"markdown",value:()=>!1},{kind:"field",decorators:[i()],key:"repository",value:void 0},{kind:"field",decorators:[i()],key:"header",value:void 0},{kind:"field",decorators:[i()],key:"content",value:void 0},{kind:"field",key:"_getRepository",value:()=>o(((t,e)=>null==t?void 0:t.find((t=>String(t.id)===e))))},{kind:"method",key:"render",value:function(){if(!this.active||!this.repository)return s``;const t=this._getRepository(this.hacs.repositories,this.repository);return s`
<hacs-dialog .active=${this.active} .narrow=${this.narrow} .hass=${this.hass}>
<div slot="header">${this.header||""}</div>
${this.markdown?this.repository?a.html(this.content||"",t):a.html(this.content||""):this.content||""}
</hacs-dialog>
`}}]}}),e);export{d as HacsGenericDialog};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
import{c as e}from"./c.6eb9fcd4.js";import{d as t}from"./c.a5550d10.js";import{bN as s,a7 as i}from"./main-c66a9a06.js";import{s as a}from"./c.874c8cfd.js";const n=(t,s,i)=>t.name_by_user||t.name||i&&((t,s)=>{for(const i of s||[]){const s="string"==typeof i?i:i.entity_id,a=t.states[s];if(a)return e(a)}})(s,i)||s.localize("ui.panel.config.devices.unnamed_device","type",s.localize(`ui.panel.config.devices.type.${t.entry_type||"device"}`)),r=e=>e.sendMessagePromise({type:"config/device_registry/list"}),c=(e,s)=>e.subscribeEvents(t((()=>r(e).then((e=>s.setState(e,!0)))),500,!0),"device_registry_updated"),o=(e,t)=>s("_dr",r,c,e,t),d=(e,t)=>{const s={};for(const i of t){const t=e[i.entity_id];null!=t&&t.domain&&null!==i.device_id&&(s[i.device_id]||(s[i.device_id]=[]),s[i.device_id].push(t.domain))}return s},_=(t,s)=>{if(s.name)return s.name;const i=t.states[s.entity_id];return i?e(i):s.original_name?s.original_name:s.entity_id},y=e=>e.sendMessagePromise({type:"config/entity_registry/list"}),m=(e,s)=>e.subscribeEvents(t((()=>y(e).then((e=>s.setState(e,!0)))),500,!0),"entity_registry_updated"),f=(e,t)=>s("_entityRegistry",y,m,e,t),g=i((e=>{const t={};for(const s of Object.values(e))t[s.id]=s;return t})),p=(e,t)=>e.callWS({type:"config/area_registry/create",...t}),u=e=>e.sendMessagePromise({type:"config/area_registry/list"}).then((e=>e.sort(((e,t)=>a(e.name,t.name))))),l=(e,s)=>e.subscribeEvents(t((()=>u(e).then((e=>s.setState(e,!0)))),500,!0),"area_registry_updated"),v=(e,t)=>s("_areaRegistry",u,l,e,t);export{n as a,v as b,_ as c,f as d,g as e,p as f,d as g,o as s};

View File

@@ -1,113 +0,0 @@
import{bw as a,bx as i,by as t,bz as e,bA as o,bB as l,bC as s,bD as d,bE as n,bF as r,bG as c,bH as u,bI as m,bJ as h,bK as v,bL as p,O as _,_ as b,j as g,e as y,t as k,y as f,k as x,aD as w,bM as $,d as z,n as j}from"./main-c66a9a06.js";import{s as U}from"./c.04ecc0ad.js";import{b as I,e as C}from"./c.07e395f8.js";import"./c.bbadaeea.js";const M=(a,i)=>a.callWS({type:"auth/sign_path",path:i}),q="browser",B={album:{icon:a,layout:"grid"},app:{icon:i,layout:"grid"},artist:{icon:t,layout:"grid",show_list_images:!0},channel:{icon:e,thumbnail_ratio:"portrait",layout:"grid"},composer:{icon:o,layout:"grid",show_list_images:!0},contributing_artist:{icon:t,layout:"grid",show_list_images:!0},directory:{icon:l,layout:"grid",show_list_images:!0},episode:{icon:e,layout:"grid",thumbnail_ratio:"portrait"},game:{icon:s,layout:"grid",thumbnail_ratio:"portrait"},genre:{icon:d,layout:"grid",show_list_images:!0},image:{icon:n,layout:"grid"},movie:{icon:r,thumbnail_ratio:"portrait",layout:"grid"},music:{icon:c},playlist:{icon:u,layout:"grid",show_list_images:!0},podcast:{icon:m,layout:"grid"},season:{icon:e,layout:"grid",thumbnail_ratio:"portrait"},track:{icon:h},tv_show:{icon:e,layout:"grid",thumbnail_ratio:"portrait"},url:{icon:v},video:{icon:p,layout:"grid"}},L=(a,i,t,e)=>a.callWS({type:"media_player/browse_media",entity_id:i,media_content_id:t,media_content_type:e}),W=[{name:"media_content_id",required:!1,selector:{text:{}}},{name:"media_content_type",required:!1,selector:{text:{}}}];let F=b([j("ha-selector-media")],(function(a,i){return{F:class extends i{constructor(...i){super(...i),a(this)}},d:[{kind:"field",decorators:[y({attribute:!1})],key:"hass",value:void 0},{kind:"field",decorators:[y({attribute:!1})],key:"selector",value:void 0},{kind:"field",decorators:[y({attribute:!1})],key:"value",value:void 0},{kind:"field",decorators:[y()],key:"label",value:void 0},{kind:"field",decorators:[y()],key:"helper",value:void 0},{kind:"field",decorators:[y({type:Boolean,reflect:!0})],key:"disabled",value:()=>!1},{kind:"field",decorators:[y({type:Boolean,reflect:!0})],key:"required",value:()=>!0},{kind:"field",decorators:[k()],key:"_thumbnailUrl",value:void 0},{kind:"method",key:"willUpdate",value:function(a){if(a.has("value")){var i,t,e,o;const s=null===(i=this.value)||void 0===i||null===(t=i.metadata)||void 0===t?void 0:t.thumbnail;if(s===(null===(e=a.get("value"))||void 0===e||null===(o=e.metadata)||void 0===o?void 0:o.thumbnail))return;if(s&&s.startsWith("/"))this._thumbnailUrl=void 0,M(this.hass,s).then((a=>{this._thumbnailUrl=a.path}));else if(s&&s.startsWith("https://brands.home-assistant.io")){var l;this._thumbnailUrl=I({domain:C(s),type:"icon",useFallback:!0,darkOptimized:null===(l=this.hass.themes)||void 0===l?void 0:l.darkMode})}else this._thumbnailUrl=s}}},{kind:"method",key:"render",value:function(){var a,i,t,e,o,l,s,d,n,r,c,u,m;const h=null!==(a=this.value)&&void 0!==a&&a.entity_id?this.hass.states[this.value.entity_id]:void 0,v=!(null!==(i=this.value)&&void 0!==i&&i.entity_id)||h&&U(h,131072);return f`<ha-entity-picker
.hass=${this.hass}
.value=${null===(t=this.value)||void 0===t?void 0:t.entity_id}
.label=${this.label||this.hass.localize("ui.components.selectors.media.pick_media_player")}
.disabled=${this.disabled}
.helper=${this.helper}
.required=${this.required}
include-domains='["media_player"]'
allow-custom-entity
@value-changed=${this._entityChanged}
></ha-entity-picker>
${v?f`<ha-card
outlined
@click=${this._pickMedia}
class=${this.disabled||null===(e=this.value)||void 0===e||!e.entity_id?"disabled":""}
>
<div
class="thumbnail ${x({portrait:!(null===(o=this.value)||void 0===o||null===(l=o.metadata)||void 0===l||!l.media_class)&&"portrait"===B[this.value.metadata.children_media_class||this.value.metadata.media_class].thumbnail_ratio})}"
>
${null!==(s=this.value)&&void 0!==s&&null!==(d=s.metadata)&&void 0!==d&&d.thumbnail?f`
<div
class="${x({"centered-image":!!this.value.metadata.media_class&&["app","directory"].includes(this.value.metadata.media_class)})}
image"
style=${this._thumbnailUrl?`background-image: url(${this._thumbnailUrl});`:""}
></div>
`:f`
<div class="icon-holder image">
<ha-svg-icon
class="folder"
.path=${null!==(n=this.value)&&void 0!==n&&n.media_content_id?null!==(r=this.value)&&void 0!==r&&null!==(c=r.metadata)&&void 0!==c&&c.media_class?B["directory"===this.value.metadata.media_class&&this.value.metadata.children_media_class||this.value.metadata.media_class].icon:$:w}
></ha-svg-icon>
</div>
`}
</div>
<div class="title">
${null!==(u=this.value)&&void 0!==u&&u.media_content_id?(null===(m=this.value.metadata)||void 0===m?void 0:m.title)||this.value.media_content_id:this.hass.localize("ui.components.selectors.media.pick_media")}
</div>
</ha-card>`:f`<ha-alert>
${this.hass.localize("ui.components.selectors.media.browse_not_supported")}
</ha-alert>
<ha-form
.hass=${this.hass}
.data=${this.value}
.schema=${W}
.computeLabel=${this._computeLabelCallback}
></ha-form>`}`}},{kind:"field",key:"_computeLabelCallback",value(){return a=>this.hass.localize(`ui.components.selectors.media.${a.name}`)}},{kind:"method",key:"_entityChanged",value:function(a){a.stopPropagation(),_(this,"value-changed",{value:{entity_id:a.detail.value,media_content_id:"",media_content_type:""}})}},{kind:"method",key:"_pickMedia",value:function(){var a,i,t;i=this,t={action:"pick",entityId:this.value.entity_id,navigateIds:null===(a=this.value.metadata)||void 0===a?void 0:a.navigateIds,mediaPickedCallback:a=>{var i;_(this,"value-changed",{value:{...this.value,media_content_id:a.item.media_content_id,media_content_type:a.item.media_content_type,metadata:{title:a.item.title,thumbnail:a.item.thumbnail,media_class:a.item.media_class,children_media_class:a.item.children_media_class,navigateIds:null===(i=a.navigateIds)||void 0===i?void 0:i.map((a=>({media_content_type:a.media_content_type,media_content_id:a.media_content_id})))}}})}},_(i,"show-dialog",{dialogTag:"dialog-media-player-browse",dialogImport:()=>import("./c.06557919.js").then((function(a){return a.d})),dialogParams:t})}},{kind:"get",static:!0,key:"styles",value:function(){return z`
ha-entity-picker {
display: block;
margin-bottom: 16px;
}
mwc-button {
margin-top: 8px;
}
ha-alert {
display: block;
margin-bottom: 16px;
}
ha-card {
position: relative;
width: 200px;
box-sizing: border-box;
cursor: pointer;
}
ha-card.disabled {
pointer-events: none;
color: var(--disabled-text-color);
}
ha-card .thumbnail {
width: 100%;
position: relative;
box-sizing: border-box;
transition: padding-bottom 0.1s ease-out;
padding-bottom: 100%;
}
ha-card .thumbnail.portrait {
padding-bottom: 150%;
}
ha-card .image {
border-radius: 3px 3px 0 0;
}
.folder {
--mdc-icon-size: calc(var(--media-browse-item-size, 175px) * 0.4);
}
.title {
font-size: 16px;
padding-top: 16px;
overflow: hidden;
text-overflow: ellipsis;
margin-bottom: 16px;
padding-left: 16px;
padding-right: 4px;
white-space: nowrap;
}
.image {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
.centered-image {
margin: 0 8px;
background-size: contain;
}
.icon-holder {
display: flex;
justify-content: center;
align-items: center;
}
`}}]}}),g);var O=Object.freeze({__proto__:null,HaMediaSelector:F});export{q as B,B as M,L as b,M as g,O as h};

File diff suppressed because one or more lines are too long

View File

@@ -1,16 +0,0 @@
import{_ as e,j as a,e as i,y as l,bn as t,O as o,d,n as s}from"./main-c66a9a06.js";import{a as r}from"./c.31caccfc.js";import{f as n}from"./c.d9d8b90e.js";import"./c.a5550d10.js";const c=()=>import("./c.b5117688.js");e([s("ha-date-input")],(function(e,a){return{F:class extends a{constructor(...a){super(...a),e(this)}},d:[{kind:"field",decorators:[i({attribute:!1})],key:"locale",value:void 0},{kind:"field",decorators:[i()],key:"value",value:void 0},{kind:"field",decorators:[i({type:Boolean})],key:"disabled",value:()=>!1},{kind:"field",decorators:[i({type:Boolean})],key:"required",value:()=>!1},{kind:"field",decorators:[i()],key:"label",value:void 0},{kind:"field",decorators:[i()],key:"helper",value:void 0},{kind:"method",key:"render",value:function(){return l`<ha-textfield
.label=${this.label}
.helper=${this.helper}
.disabled=${this.disabled}
iconTrailing
helperPersistent
@click=${this._openDialog}
.value=${this.value?r(new Date(this.value),this.locale):""}
.required=${this.required}
>
<ha-svg-icon slot="trailingIcon" .path=${t}></ha-svg-icon>
</ha-textfield>`}},{kind:"method",key:"_openDialog",value:function(){var e,a;this.disabled||(e=this,a={min:"1970-01-01",value:this.value,onChange:e=>this._valueChanged(e),locale:this.locale.language,firstWeekday:n(this.locale)},o(e,"show-dialog",{dialogTag:"ha-dialog-date-picker",dialogImport:c,dialogParams:a}))}},{kind:"method",key:"_valueChanged",value:function(e){this.value!==e&&(this.value=e,o(this,"change"),o(this,"value-changed",{value:e}))}},{kind:"get",static:!0,key:"styles",value:function(){return d`
ha-svg-icon {
color: var(--secondary-text-color);
}
`}}]}}),a);

View File

@@ -1,17 +0,0 @@
import{_ as e,j as a,e as t,y as i,O as d,d as l,n as s}from"./main-c66a9a06.js";import"./c.bbadaeea.js";import"./c.6912e15e.js";import"./c.a5550d10.js";import"./c.8e28b461.js";import"./c.41d13611.js";import"./c.930daaba.js";let o=e([s("ha-selector-boolean")],(function(e,a){return{F:class extends a{constructor(...a){super(...a),e(this)}},d:[{kind:"field",decorators:[t()],key:"hass",value:void 0},{kind:"field",decorators:[t()],key:"value",value:void 0},{kind:"field",decorators:[t()],key:"label",value:void 0},{kind:"field",decorators:[t()],key:"helper",value:void 0},{kind:"field",decorators:[t({type:Boolean})],key:"disabled",value:()=>!1},{kind:"method",key:"render",value:function(){return i`
<ha-formfield alignEnd spaceBetween .label=${this.label}>
<ha-switch
.checked=${this.value}
@change=${this._handleChange}
.disabled=${this.disabled}
></ha-switch>
</ha-formfield>
${this.helper?i`<ha-input-helper-text>${this.helper}</ha-input-helper-text>`:""}
`}},{kind:"method",key:"_handleChange",value:function(e){const a=e.target.checked;this.value!==a&&d(this,"value-changed",{value:a})}},{kind:"get",static:!0,key:"styles",value:function(){return l`
ha-formfield {
display: flex;
height: 56px;
align-items: center;
--mdc-typography-body2-font-size: 1em;
}
`}}]}}),a);export{o as HaBooleanSelector};

View File

@@ -1,13 +0,0 @@
import{_ as e,j as a,e as l,y as i,O as d,n as o}from"./main-c66a9a06.js";let r=e([o("ha-selector-icon")],(function(e,a){return{F:class extends a{constructor(...a){super(...a),e(this)}},d:[{kind:"field",decorators:[l()],key:"hass",value:void 0},{kind:"field",decorators:[l()],key:"selector",value:void 0},{kind:"field",decorators:[l()],key:"value",value:void 0},{kind:"field",decorators:[l()],key:"label",value:void 0},{kind:"field",decorators:[l()],key:"helper",value:void 0},{kind:"field",decorators:[l({type:Boolean,reflect:!0})],key:"disabled",value:()=>!1},{kind:"field",decorators:[l({type:Boolean})],key:"required",value:()=>!0},{kind:"method",key:"render",value:function(){var e,a;return i`
<ha-icon-picker
.hass=${this.hass}
.label=${this.label}
.value=${this.value}
.required=${this.required}
.disabled=${this.disabled}
.helper=${this.helper}
.fallbackPath=${null===(e=this.selector.icon)||void 0===e?void 0:e.fallbackPath}
.placeholder=${null===(a=this.selector.icon)||void 0===a?void 0:a.placeholder}
@value-changed=${this._valueChanged}
></ha-icon-picker>
`}},{kind:"method",key:"_valueChanged",value:function(e){d(this,"value-changed",{value:e.detail.value})}}]}}),a);export{r as HaIconSelector};

View File

@@ -1,176 +0,0 @@
import{P as t,Q as i,S as a}from"./main-c66a9a06.js";t({_template:i`
<style>
:host {
display: block;
position: absolute;
outline: none;
z-index: 1002;
-moz-user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
user-select: none;
cursor: default;
}
#tooltip {
display: block;
outline: none;
@apply --paper-font-common-base;
font-size: 10px;
line-height: 1;
background-color: var(--paper-tooltip-background, #616161);
color: var(--paper-tooltip-text-color, white);
padding: 8px;
border-radius: 2px;
@apply --paper-tooltip;
}
@keyframes keyFrameScaleUp {
0% {
transform: scale(0.0);
}
100% {
transform: scale(1.0);
}
}
@keyframes keyFrameScaleDown {
0% {
transform: scale(1.0);
}
100% {
transform: scale(0.0);
}
}
@keyframes keyFrameFadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: var(--paper-tooltip-opacity, 0.9);
}
}
@keyframes keyFrameFadeOutOpacity {
0% {
opacity: var(--paper-tooltip-opacity, 0.9);
}
100% {
opacity: 0;
}
}
@keyframes keyFrameSlideDownIn {
0% {
transform: translateY(-2000px);
opacity: 0;
}
10% {
opacity: 0.2;
}
100% {
transform: translateY(0);
opacity: var(--paper-tooltip-opacity, 0.9);
}
}
@keyframes keyFrameSlideDownOut {
0% {
transform: translateY(0);
opacity: var(--paper-tooltip-opacity, 0.9);
}
10% {
opacity: 0.2;
}
100% {
transform: translateY(-2000px);
opacity: 0;
}
}
.fade-in-animation {
opacity: 0;
animation-delay: var(--paper-tooltip-delay-in, 500ms);
animation-name: keyFrameFadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: var(--paper-tooltip-duration-in, 500ms);
animation-fill-mode: forwards;
@apply --paper-tooltip-animation;
}
.fade-out-animation {
opacity: var(--paper-tooltip-opacity, 0.9);
animation-delay: var(--paper-tooltip-delay-out, 0ms);
animation-name: keyFrameFadeOutOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: var(--paper-tooltip-duration-out, 500ms);
animation-fill-mode: forwards;
@apply --paper-tooltip-animation;
}
.scale-up-animation {
transform: scale(0);
opacity: var(--paper-tooltip-opacity, 0.9);
animation-delay: var(--paper-tooltip-delay-in, 500ms);
animation-name: keyFrameScaleUp;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: var(--paper-tooltip-duration-in, 500ms);
animation-fill-mode: forwards;
@apply --paper-tooltip-animation;
}
.scale-down-animation {
transform: scale(1);
opacity: var(--paper-tooltip-opacity, 0.9);
animation-delay: var(--paper-tooltip-delay-out, 500ms);
animation-name: keyFrameScaleDown;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: var(--paper-tooltip-duration-out, 500ms);
animation-fill-mode: forwards;
@apply --paper-tooltip-animation;
}
.slide-down-animation {
transform: translateY(-2000px);
opacity: 0;
animation-delay: var(--paper-tooltip-delay-out, 500ms);
animation-name: keyFrameSlideDownIn;
animation-iteration-count: 1;
animation-timing-function: cubic-bezier(0.0, 0.0, 0.2, 1);
animation-duration: var(--paper-tooltip-duration-out, 500ms);
animation-fill-mode: forwards;
@apply --paper-tooltip-animation;
}
.slide-down-animation-out {
transform: translateY(0);
opacity: var(--paper-tooltip-opacity, 0.9);
animation-delay: var(--paper-tooltip-delay-out, 500ms);
animation-name: keyFrameSlideDownOut;
animation-iteration-count: 1;
animation-timing-function: cubic-bezier(0.4, 0.0, 1, 1);
animation-duration: var(--paper-tooltip-duration-out, 500ms);
animation-fill-mode: forwards;
@apply --paper-tooltip-animation;
}
.cancel-animation {
animation-delay: -30s !important;
}
/* Thanks IE 10. */
.hidden {
display: none !important;
}
</style>
<div id="tooltip" class="hidden">
<slot></slot>
</div>
`,is:"paper-tooltip",hostAttributes:{role:"tooltip",tabindex:-1},properties:{for:{type:String,observer:"_findTarget"},manualMode:{type:Boolean,value:!1,observer:"_manualModeChanged"},position:{type:String,value:"bottom"},fitToVisibleBounds:{type:Boolean,value:!1},offset:{type:Number,value:14},marginTop:{type:Number,value:14},animationDelay:{type:Number,value:500,observer:"_delayChange"},animationEntry:{type:String,value:""},animationExit:{type:String,value:""},animationConfig:{type:Object,value:function(){return{entry:[{name:"fade-in-animation",node:this,timing:{delay:0}}],exit:[{name:"fade-out-animation",node:this}]}}},_showing:{type:Boolean,value:!1}},listeners:{webkitAnimationEnd:"_onAnimationEnd"},get target(){var t=a(this).parentNode,i=a(this).getOwnerRoot();return this.for?a(i).querySelector("#"+this.for):t.nodeType==Node.DOCUMENT_FRAGMENT_NODE?i.host:t},attached:function(){this._findTarget()},detached:function(){this.manualMode||this._removeListeners()},playAnimation:function(t){"entry"===t?this.show():"exit"===t&&this.hide()},cancelAnimation:function(){this.$.tooltip.classList.add("cancel-animation")},show:function(){if(!this._showing){if(""===a(this).textContent.trim()){for(var t=!0,i=a(this).getEffectiveChildNodes(),n=0;n<i.length;n++)if(""!==i[n].textContent.trim()){t=!1;break}if(t)return}this._showing=!0,this.$.tooltip.classList.remove("hidden"),this.$.tooltip.classList.remove("cancel-animation"),this.$.tooltip.classList.remove(this._getAnimationType("exit")),this.updatePosition(),this._animationPlaying=!0,this.$.tooltip.classList.add(this._getAnimationType("entry"))}},hide:function(){if(this._showing){if(this._animationPlaying)return this._showing=!1,void this._cancelAnimation();this._onAnimationFinish(),this._showing=!1,this._animationPlaying=!0}},updatePosition:function(){if(this._target&&this.offsetParent){var t=this.offset;14!=this.marginTop&&14==this.offset&&(t=this.marginTop);var i,a,n=this.offsetParent.getBoundingClientRect(),e=this._target.getBoundingClientRect(),o=this.getBoundingClientRect(),s=(e.width-o.width)/2,r=(e.height-o.height)/2,l=e.left-n.left,p=e.top-n.top;switch(this.position){case"top":i=l+s,a=p-o.height-t;break;case"bottom":i=l+s,a=p+e.height+t;break;case"left":i=l-o.width-t,a=p+r;break;case"right":i=l+e.width+t,a=p+r}this.fitToVisibleBounds?(n.left+i+o.width>window.innerWidth?(this.style.right="0px",this.style.left="auto"):(this.style.left=Math.max(0,i)+"px",this.style.right="auto"),n.top+a+o.height>window.innerHeight?(this.style.bottom=n.height-p+t+"px",this.style.top="auto"):(this.style.top=Math.max(-n.top,a)+"px",this.style.bottom="auto")):(this.style.left=i+"px",this.style.top=a+"px")}},_addListeners:function(){this._target&&(this.listen(this._target,"mouseenter","show"),this.listen(this._target,"focus","show"),this.listen(this._target,"mouseleave","hide"),this.listen(this._target,"blur","hide"),this.listen(this._target,"tap","hide")),this.listen(this.$.tooltip,"animationend","_onAnimationEnd"),this.listen(this,"mouseenter","hide")},_findTarget:function(){this.manualMode||this._removeListeners(),this._target=this.target,this.manualMode||this._addListeners()},_delayChange:function(t){500!==t&&this.updateStyles({"--paper-tooltip-delay-in":t+"ms"})},_manualModeChanged:function(){this.manualMode?this._removeListeners():this._addListeners()},_cancelAnimation:function(){this.$.tooltip.classList.remove(this._getAnimationType("entry")),this.$.tooltip.classList.remove(this._getAnimationType("exit")),this.$.tooltip.classList.remove("cancel-animation"),this.$.tooltip.classList.add("hidden")},_onAnimationFinish:function(){this._showing&&(this.$.tooltip.classList.remove(this._getAnimationType("entry")),this.$.tooltip.classList.remove("cancel-animation"),this.$.tooltip.classList.add(this._getAnimationType("exit")))},_onAnimationEnd:function(){this._animationPlaying=!1,this._showing||(this.$.tooltip.classList.remove(this._getAnimationType("exit")),this.$.tooltip.classList.add("hidden"))},_getAnimationType:function(t){if("entry"===t&&""!==this.animationEntry)return this.animationEntry;if("exit"===t&&""!==this.animationExit)return this.animationExit;if(this.animationConfig[t]&&"string"==typeof this.animationConfig[t][0].name){if(this.animationConfig[t][0].timing&&this.animationConfig[t][0].timing.delay&&0!==this.animationConfig[t][0].timing.delay){var i=this.animationConfig[t][0].timing.delay;"entry"===t?this.updateStyles({"--paper-tooltip-delay-in":i+"ms"}):"exit"===t&&this.updateStyles({"--paper-tooltip-delay-out":i+"ms"})}return this.animationConfig[t][0].name}},_removeListeners:function(){this._target&&(this.unlisten(this._target,"mouseenter","show"),this.unlisten(this._target,"focus","show"),this.unlisten(this._target,"mouseleave","hide"),this.unlisten(this._target,"blur","hide"),this.unlisten(this._target,"tap","hide")),this.unlisten(this.$.tooltip,"animationend","_onAnimationEnd"),this.unlisten(this,"mouseenter","hide")}});

View File

@@ -1,56 +0,0 @@
import{_ as e,j as a,e as o,y as t,aF as i,k as s,aE as l,d as n,n as r,a7 as c,aB as d,af as h,aw as p,ag as m,aG as u,aH as f,aI as g,aJ as b,ax as v,aK as y,a4 as _,ai as w,aL as k,aM as $}from"./main-c66a9a06.js";import"./c.41d13611.js";import"./c.24287846.js";import{g as z}from"./c.f2bb3724.js";import{s as x}from"./c.4b0dc107.js";e([r("ha-icon-overflow-menu")],(function(e,a){return{F:class extends a{constructor(...a){super(...a),e(this)}},d:[{kind:"field",decorators:[o({attribute:!1})],key:"hass",value:void 0},{kind:"field",decorators:[o({type:Array})],key:"items",value:()=>[]},{kind:"field",decorators:[o({type:Boolean})],key:"narrow",value:()=>!1},{kind:"method",key:"render",value:function(){return t`
${this.narrow?t` <!-- Collapsed representation for small screens -->
<ha-button-menu
@click=${this._handleIconOverflowMenuOpened}
@closed=${this._handleIconOverflowMenuClosed}
class="ha-icon-overflow-menu-overflow"
corner="BOTTOM_START"
absolute
>
<ha-icon-button
.label=${this.hass.localize("ui.common.overflow_menu")}
.path=${i}
slot="trigger"
></ha-icon-button>
${this.items.map((e=>e.divider?t`<li divider role="separator"></li>`:t`<mwc-list-item
graphic="icon"
?disabled=${e.disabled}
@click=${e.action}
class=${s({warning:Boolean(e.warning)})}
>
<div slot="graphic">
<ha-svg-icon
class=${s({warning:Boolean(e.warning)})}
.path=${e.path}
></ha-svg-icon>
</div>
${e.label}
</mwc-list-item> `))}
</ha-button-menu>`:t`
<!-- Icon representation for big screens -->
${this.items.map((e=>e.narrowOnly?"":e.divider?t`<div role="separator"></div>`:t`<div>
${e.tooltip?t`<paper-tooltip animation-delay="0" position="left">
${e.tooltip}
</paper-tooltip>`:""}
<ha-icon-button
@click=${e.action}
.label=${e.label}
.path=${e.path}
?disabled=${e.disabled}
></ha-icon-button>
</div> `))}
`}
`}},{kind:"method",key:"_handleIconOverflowMenuOpened",value:function(e){e.stopPropagation();const a=this.closest(".mdc-data-table__row");a&&(a.style.zIndex="1")}},{kind:"method",key:"_handleIconOverflowMenuClosed",value:function(){const e=this.closest(".mdc-data-table__row");e&&(e.style.zIndex="")}},{kind:"get",static:!0,key:"styles",value:function(){return[l,n`
:host {
display: flex;
justify-content: flex-end;
}
li[role="separator"] {
border-bottom-color: var(--divider-color);
}
div[role="separator"] {
border-right: 1px solid var(--divider-color);
width: 1px;
}
`]}}]}}),a);const E=c(((e,a)=>[..."HACS-EXPERIMENTAL-PANEL"===e.nodeName?[{path:d,label:e.hacs.localize("common.show"),action:()=>h(`/hacs/repository/${a.id}`)}]:[],{path:p,label:e.hacs.localize("common.repository"),action:()=>m.open(`https://github.com/${a.full_name}`,"_blank","noreferrer=true")},{path:u,label:e.hacs.localize("repository_card.update_information"),action:async()=>{await f(e.hass,String(a.id))}},...a.installed_version?[{path:g,label:e.hacs.localize("repository_card.redownload"),action:()=>O(e,a.id),hideForUninstalled:!0}]:[],..."plugin"===a.category&&a.installed_version?[{path:b,label:e.hacs.localize("repository_card.open_source"),action:()=>m.open(`/hacsfiles/${a.local_path.split("/").pop()}/${a.file_name}`,"_blank","noreferrer=true")}]:[],{divider:!0},{path:v,label:e.hacs.localize("repository_card.open_issue"),action:()=>m.open(`https://github.com/${a.full_name}/issues`,"_blank","noreferrer=true")},..."172733314"!==a.id&&a.installed_version?[{path:y,label:e.hacs.localize("repository_card.report"),action:()=>m.open(`https://github.com/hacs/integration/issues/new?assignees=ludeeus&labels=flag&template=removal.yml&repo=${a.full_name}&title=Request for removal of ${a.full_name}`,"_blank","noreferrer=true"),warning:!0},{path:_,label:e.hacs.localize("common.remove"),action:async()=>{if("integration"===a.category&&a.config_flow){if((await z(e.hass)).some((e=>e.domain===a.domain))){if(await x(e,{title:e.hacs.localize("dialog.configured.title"),text:e.hacs.localize("dialog.configured.message",{name:a.name}),dismissText:e.hacs.localize("common.ignore"),confirmText:e.hacs.localize("common.navigate"),confirm:()=>{h("/config/integrations",{replace:!0})}}))return}}e.dispatchEvent(new CustomEvent("hacs-dialog",{detail:{type:"progress",title:e.hacs.localize("dialog.remove.title"),confirmText:e.hacs.localize("dialog.remove.title"),content:e.hacs.localize("dialog.remove.message",{name:a.name}),confirm:async()=>{await I(e,a)}},bubbles:!0,composed:!0}))},warning:!0}]:[]])),O=(e,a)=>{e.dispatchEvent(new CustomEvent("hacs-dialog",{detail:{type:"download",repository:a},bubbles:!0,composed:!0}))},I=async(e,a)=>{var o;if("plugin"===a.category&&"yaml"!==(null===(o=e.hacs.info)||void 0===o?void 0:o.lovelace_mode)){(await w(e.hass)).filter((e=>e.url.startsWith(`/hacsfiles/${a.full_name.split("/")[1]}/${a.file_name}`))).forEach((async a=>{await k(e.hass,String(a.id))}))}await $(e.hass,String(a.id)),"HACS-REPOSITORY-PANEL"===e.nodeName&&history.back()},S=e=>a=>({kind:"method",placement:"prototype",key:a.key,descriptor:{set(e){this[`__${String(a.key)}`]=e},get(){return this[`__${String(a.key)}`]},enumerable:!0,configurable:!0},finisher(o){const t=o.prototype.connectedCallback;o.prototype.connectedCallback=function(){if(t.call(this),this[a.key]){const o=this.renderRoot.querySelector(e);if(!o)return;o.scrollTop=this[a.key]}}}});export{E as a,S as r};

View File

@@ -1 +0,0 @@
import{I as e,J as s,L as t,N as r}from"./main-c66a9a06.js";import{m as l,u as n,r as o,p as i,a}from"./c.a5550d10.js";const u=(e,s,t)=>{const r=new Map;for(let l=s;l<=t;l++)r.set(e[l],l);return r},f=e(class extends s{constructor(e){if(super(e),e.type!==t.CHILD)throw Error("repeat() can only be used in text expressions")}ht(e,s,t){let r;void 0===t?t=s:void 0!==s&&(r=s);const l=[],n=[];let o=0;for(const s of e)l[o]=r?r(s,o):o,n[o]=t(s,o),o++;return{values:n,keys:l}}render(e,s,t){return this.ht(e,s,t).values}update(e,[s,t,f]){var c;const h=l(e),{values:d,keys:p}=this.ht(s,t,f);if(!Array.isArray(h))return this.ut=p,d;const v=null!==(c=this.ut)&&void 0!==c?c:this.ut=[],y=[];let m,x,g=0,j=h.length-1,k=0,w=d.length-1;for(;g<=j&&k<=w;)if(null===h[g])g++;else if(null===h[j])j--;else if(v[g]===p[k])y[k]=n(h[g],d[k]),g++,k++;else if(v[j]===p[w])y[w]=n(h[j],d[w]),j--,w--;else if(v[g]===p[w])y[w]=n(h[g],d[w]),o(e,y[w+1],h[g]),g++,w--;else if(v[j]===p[k])y[k]=n(h[j],d[k]),o(e,h[g],h[j]),j--,k++;else if(void 0===m&&(m=u(p,k,w),x=u(v,g,j)),m.has(v[g]))if(m.has(v[j])){const s=x.get(p[k]),t=void 0!==s?h[s]:null;if(null===t){const s=o(e,h[g]);n(s,d[k]),y[k]=s}else y[k]=n(t,d[k]),o(e,h[g],t),h[s]=null;k++}else i(h[j]),j--;else i(h[g]),g++;for(;k<=w;){const s=o(e,y[w+1]);n(s,d[k]),y[k++]=s}for(;g<=j;){const e=h[g++];null!==e&&i(e)}return this.ut=p,a(e,y),r}});export{f as c};

View File

@@ -1,24 +0,0 @@
import{_ as e,j as t,e as a,y as i,eE as l,O as d,eF as r,d as s,n as o}from"./main-c66a9a06.js";import"./c.a5550d10.js";import"./c.8e28b461.js";import"./c.41d13611.js";let n=e([o("ha-selector-color_rgb")],(function(e,t){return{F:class extends t{constructor(...t){super(...t),e(this)}},d:[{kind:"field",decorators:[a({attribute:!1})],key:"hass",value:void 0},{kind:"field",decorators:[a({attribute:!1})],key:"selector",value:void 0},{kind:"field",decorators:[a()],key:"value",value:void 0},{kind:"field",decorators:[a()],key:"label",value:void 0},{kind:"field",decorators:[a()],key:"helper",value:void 0},{kind:"field",decorators:[a({type:Boolean,reflect:!0})],key:"disabled",value:()=>!1},{kind:"field",decorators:[a({type:Boolean})],key:"required",value:()=>!0},{kind:"method",key:"render",value:function(){return i`
<ha-textfield
type="color"
helperPersistent
.value=${this.value?l(this.value):""}
.label=${this.label||""}
.required=${this.required}
.helper=${this.helper}
.disalbled=${this.disabled}
@change=${this._valueChanged}
></ha-textfield>
`}},{kind:"method",key:"_valueChanged",value:function(e){const t=e.target.value;d(this,"value-changed",{value:r(t)})}},{kind:"field",static:!0,key:"styles",value:()=>s`
:host {
display: flex;
justify-content: flex-end;
align-items: center;
}
ha-textfield {
--text-field-padding: 8px;
min-width: 75px;
flex-grow: 1;
margin: 0 4px;
}
`}]}}),t);export{n as HaColorRGBSelector};

View File

@@ -1,11 +0,0 @@
import{_ as e,j as d,e as i,y as a,n as r}from"./main-c66a9a06.js";import"./c.1cede1b9.js";import"./c.31caccfc.js";import"./c.3acef177.js";import"./c.743a15a1.js";import"./c.2610e8cd.js";import"./c.a0946910.js";import"./c.d9d8b90e.js";import"./c.a5550d10.js";import"./c.8e28b461.js";import"./c.41d13611.js";let o=e([r("ha-selector-date")],(function(e,d){return{F:class extends d{constructor(...d){super(...d),e(this)}},d:[{kind:"field",decorators:[i()],key:"hass",value:void 0},{kind:"field",decorators:[i()],key:"selector",value:void 0},{kind:"field",decorators:[i()],key:"value",value:void 0},{kind:"field",decorators:[i()],key:"label",value:void 0},{kind:"field",decorators:[i()],key:"helper",value:void 0},{kind:"field",decorators:[i({type:Boolean,reflect:!0})],key:"disabled",value:()=>!1},{kind:"field",decorators:[i({type:Boolean})],key:"required",value:()=>!0},{kind:"method",key:"render",value:function(){return a`
<ha-date-input
.label=${this.label}
.locale=${this.hass.locale}
.disabled=${this.disabled}
.value=${this.value}
.required=${this.required}
.helper=${this.helper}
>
</ha-date-input>
`}}]}}),d);export{o as HaDateSelector};

View File

@@ -1,29 +0,0 @@
import{_ as e,j as t,e as i,y as a,d as s,O as l,n as d}from"./main-c66a9a06.js";import"./c.41d13611.js";import{s as r}from"./c.a5550d10.js";import"./c.8e28b461.js";e([d("ha-theme-picker")],(function(e,t){return{F:class extends t{constructor(...t){super(...t),e(this)}},d:[{kind:"field",decorators:[i()],key:"value",value:void 0},{kind:"field",decorators:[i()],key:"label",value:void 0},{kind:"field",decorators:[i({attribute:!1})],key:"hass",value:void 0},{kind:"field",decorators:[i({type:Boolean,reflect:!0})],key:"disabled",value:()=>!1},{kind:"field",decorators:[i({type:Boolean})],key:"required",value:()=>!1},{kind:"method",key:"render",value:function(){return a`
<ha-select
.label=${this.label||this.hass.localize("ui.components.theme-picker.theme")}
.value=${this.value}
.required=${this.required}
.disabled=${this.disabled}
@selected=${this._changed}
@closed=${r}
fixedMenuPosition
naturalMenuWidth
>
<mwc-list-item value="remove"
>${this.hass.localize("ui.components.theme-picker.no_theme")}</mwc-list-item
>
${Object.keys(this.hass.themes.themes).sort().map((e=>a`<mwc-list-item .value=${e}>${e}</mwc-list-item>`))}
</ha-select>
`}},{kind:"get",static:!0,key:"styles",value:function(){return s`
ha-select {
width: 100%;
}
`}},{kind:"method",key:"_changed",value:function(e){this.hass&&""!==e.target.value&&(this.value="remove"===e.target.value?void 0:e.target.value,l(this,"value-changed",{value:this.value}))}}]}}),t);let o=e([d("ha-selector-theme")],(function(e,t){return{F:class extends t{constructor(...t){super(...t),e(this)}},d:[{kind:"field",decorators:[i({attribute:!1})],key:"hass",value:void 0},{kind:"field",decorators:[i({attribute:!1})],key:"selector",value:void 0},{kind:"field",decorators:[i()],key:"value",value:void 0},{kind:"field",decorators:[i()],key:"label",value:void 0},{kind:"field",decorators:[i({type:Boolean,reflect:!0})],key:"disabled",value:()=>!1},{kind:"field",decorators:[i({type:Boolean})],key:"required",value:()=>!0},{kind:"method",key:"render",value:function(){return a`
<ha-theme-picker
.hass=${this.hass}
.value=${this.value}
.label=${this.label}
.disabled=${this.disabled}
.required=${this.required}
></ha-theme-picker>
`}}]}}),t);export{o as HaThemeSelector};

View File

@@ -1 +0,0 @@
import{a7 as a}from"./main-c66a9a06.js";import{p as e}from"./c.3acef177.js";e&&await e,a((a=>new Intl.DateTimeFormat(a.language,{weekday:"long",month:"long",day:"numeric"})));const n=(a,e)=>m(e).format(a),m=a((a=>new Intl.DateTimeFormat(a.language,{year:"numeric",month:"long",day:"numeric"}))),t=(a,e)=>r(e).format(a),r=a((a=>new Intl.DateTimeFormat(a.language,{year:"numeric",month:"numeric",day:"numeric"})));a((a=>new Intl.DateTimeFormat(a.language,{day:"numeric",month:"short"}))),a((a=>new Intl.DateTimeFormat(a.language,{month:"long",year:"numeric"}))),a((a=>new Intl.DateTimeFormat(a.language,{month:"long"}))),a((a=>new Intl.DateTimeFormat(a.language,{year:"numeric"})));export{t as a,n as f};

View File

@@ -1,11 +0,0 @@
import{_ as e,j as a,e as i,y as d,O as r,n as l}from"./main-c66a9a06.js";import"./c.6829e397.js";import"./c.bbadaeea.js";import"./c.a5550d10.js";import"./c.8e28b461.js";import"./c.41d13611.js";import"./c.930daaba.js";let o=e([l("ha-selector-navigation")],(function(e,a){return{F:class extends a{constructor(...a){super(...a),e(this)}},d:[{kind:"field",decorators:[i()],key:"hass",value:void 0},{kind:"field",decorators:[i()],key:"selector",value:void 0},{kind:"field",decorators:[i()],key:"value",value:void 0},{kind:"field",decorators:[i()],key:"label",value:void 0},{kind:"field",decorators:[i()],key:"helper",value:void 0},{kind:"field",decorators:[i({type:Boolean,reflect:!0})],key:"disabled",value:()=>!1},{kind:"field",decorators:[i({type:Boolean})],key:"required",value:()=>!0},{kind:"method",key:"render",value:function(){return d`
<ha-navigation-picker
.hass=${this.hass}
.label=${this.label}
.value=${this.value}
.required=${this.required}
.disabled=${this.disabled}
.helper=${this.helper}
@value-changed=${this._valueChanged}
></ha-navigation-picker>
`}},{kind:"method",key:"_valueChanged",value:function(e){r(this,"value-changed",{value:e.detail.value})}}]}}),a);export{o as HaNavigationSelector};

View File

@@ -1,29 +0,0 @@
import{_ as e,j as t,e as i,i as a,y as o,n as d,E as s,G as l,O as r}from"./main-c66a9a06.js";import{S as u}from"./c.baaad129.js";import{f as n}from"./c.d0468013.js";import"./c.bbadaeea.js";import"./c.708f0e16.js";import"./c.a5550d10.js";import"./c.8e28b461.js";import"./c.41d13611.js";import"./c.31caccfc.js";import"./c.3acef177.js";import"./c.743a15a1.js";import"./c.2610e8cd.js";import"./c.a0946910.js";import"./c.e95db283.js";import"./c.930daaba.js";e([d("ha-entity-attribute-picker")],(function(e,t){return{F:class extends t{constructor(...t){super(...t),e(this)}},d:[{kind:"field",decorators:[i({attribute:!1})],key:"hass",value:void 0},{kind:"field",decorators:[i()],key:"entityId",value:void 0},{kind:"field",decorators:[i({type:Array,attribute:"hide-attributes"})],key:"hideAttributes",value:void 0},{kind:"field",decorators:[i({type:Boolean})],key:"autofocus",value:()=>!1},{kind:"field",decorators:[i({type:Boolean})],key:"disabled",value:()=>!1},{kind:"field",decorators:[i({type:Boolean})],key:"required",value:()=>!1},{kind:"field",decorators:[i({type:Boolean,attribute:"allow-custom-value"})],key:"allowCustomValue",value:void 0},{kind:"field",decorators:[i()],key:"label",value:void 0},{kind:"field",decorators:[i()],key:"value",value:void 0},{kind:"field",decorators:[i()],key:"helper",value:void 0},{kind:"field",decorators:[i({type:Boolean})],key:"_opened",value:()=>!1},{kind:"field",decorators:[a("ha-combo-box",!0)],key:"_comboBox",value:void 0},{kind:"method",key:"shouldUpdate",value:function(e){return!(!e.has("_opened")&&this._opened)}},{kind:"method",key:"updated",value:function(e){if(e.has("_opened")&&this._opened){const e=this.entityId?this.hass.states[this.entityId]:void 0;this._comboBox.items=e?Object.keys(e.attributes).filter((e=>{var t;return!(null!==(t=this.hideAttributes)&&void 0!==t&&t.includes(e))})).map((e=>({value:e,label:n(e)}))):[]}}},{kind:"method",key:"render",value:function(){var e;return this.hass?o`
<ha-combo-box
.hass=${this.hass}
.value=${this.value?n(this.value):""}
.autofocus=${this.autofocus}
.label=${null!==(e=this.label)&&void 0!==e?e:this.hass.localize("ui.components.entity.entity-attribute-picker.attribute")}
.disabled=${this.disabled||!this.entityId}
.required=${this.required}
.helper=${this.helper}
.allowCustomValue=${this.allowCustomValue}
item-value-path="value"
item-label-path="label"
@opened-changed=${this._openedChanged}
@value-changed=${this._valueChanged}
>
</ha-combo-box>
`:o``}},{kind:"method",key:"_openedChanged",value:function(e){this._opened=e.detail.value}},{kind:"method",key:"_valueChanged",value:function(e){this.value=e.detail.value}}]}}),t);let c=e([d("ha-selector-attribute")],(function(e,t){class a extends t{constructor(...t){super(...t),e(this)}}return{F:a,d:[{kind:"field",decorators:[i({attribute:!1})],key:"hass",value:void 0},{kind:"field",decorators:[i({attribute:!1})],key:"selector",value:void 0},{kind:"field",decorators:[i()],key:"value",value:void 0},{kind:"field",decorators:[i()],key:"label",value:void 0},{kind:"field",decorators:[i()],key:"helper",value:void 0},{kind:"field",decorators:[i({type:Boolean})],key:"disabled",value:()=>!1},{kind:"field",decorators:[i({type:Boolean})],key:"required",value:()=>!0},{kind:"field",decorators:[i({attribute:!1})],key:"context",value:void 0},{kind:"method",key:"render",value:function(){var e,t,i;return o`
<ha-entity-attribute-picker
.hass=${this.hass}
.entityId=${(null===(e=this.selector.attribute)||void 0===e?void 0:e.entity_id)||(null===(t=this.context)||void 0===t?void 0:t.filter_entity)}
.hideAttributes=${null===(i=this.selector.attribute)||void 0===i?void 0:i.hide_attributes}
.value=${this.value}
.label=${this.label}
.helper=${this.helper}
.disabled=${this.disabled}
.required=${this.required}
allow-custom-value
></ha-entity-attribute-picker>
`}},{kind:"method",key:"updated",value:function(e){var t;if(s(l(a.prototype),"updated",this).call(this,e),!this.value||null!==(t=this.selector.attribute)&&void 0!==t&&t.entity_id||!e.has("context"))return;const i=e.get("context");if(!this.context||(null==i?void 0:i.filter_entity)===this.context.filter_entity)return;let o=!1;if(this.context.filter_entity){const e=this.hass.states[this.context.filter_entity];e&&this.value in e.attributes||(o=!0)}else o=void 0!==this.value;o&&r(this,"value-changed",{value:void 0})}}]}}),u(t));export{c as HaSelectorAttribute};

View File

@@ -1,63 +0,0 @@
import{_ as e,j as i,e as t,y as s,O as d,d as a,n as l,t as c,a7 as r,E as o,G as n}from"./main-c66a9a06.js";import{g as v,d as u}from"./c.15496b0b.js";import{f as h,b as k}from"./c.6f18200a.js";import{S as p}from"./c.baaad129.js";import"./c.9381c7ae.js";import"./c.6eb9fcd4.js";import"./c.1024e243.js";import"./c.a5550d10.js";import"./c.8e28b461.js";import"./c.41d13611.js";import"./c.874c8cfd.js";import"./c.fa0ef026.js";import"./c.d2f13ac1.js";import"./c.bbadaeea.js";import"./c.930daaba.js";e([l("ha-devices-picker")],(function(e,i){return{F:class extends i{constructor(...i){super(...i),e(this)}},d:[{kind:"field",decorators:[t({attribute:!1})],key:"hass",value:void 0},{kind:"field",decorators:[t()],key:"value",value:void 0},{kind:"field",decorators:[t()],key:"helper",value:void 0},{kind:"field",decorators:[t({type:Boolean})],key:"disabled",value:void 0},{kind:"field",decorators:[t({type:Boolean})],key:"required",value:void 0},{kind:"field",decorators:[t({type:Array,attribute:"include-domains"})],key:"includeDomains",value:void 0},{kind:"field",decorators:[t({type:Array,attribute:"exclude-domains"})],key:"excludeDomains",value:void 0},{kind:"field",decorators:[t({attribute:"picked-device-label"}),t({type:Array,attribute:"include-device-classes"})],key:"includeDeviceClasses",value:void 0},{kind:"field",key:"pickedDeviceLabel",value:void 0},{kind:"field",decorators:[t({attribute:"pick-device-label"})],key:"pickDeviceLabel",value:void 0},{kind:"field",decorators:[t()],key:"deviceFilter",value:void 0},{kind:"method",key:"render",value:function(){if(!this.hass)return s``;const e=this._currentDevices;return s`
${e.map((e=>s`
<div>
<ha-device-picker
allow-custom-entity
.curValue=${e}
.hass=${this.hass}
.deviceFilter=${this.deviceFilter}
.includeDomains=${this.includeDomains}
.excludeDomains=${this.excludeDomains}
.includeDeviceClasses=${this.includeDeviceClasses}
.value=${e}
.label=${this.pickedDeviceLabel}
.disabled=${this.disabled}
@value-changed=${this._deviceChanged}
></ha-device-picker>
</div>
`))}
<div>
<ha-device-picker
allow-custom-entity
.hass=${this.hass}
.helper=${this.helper}
.deviceFilter=${this.deviceFilter}
.includeDomains=${this.includeDomains}
.excludeDomains=${this.excludeDomains}
.includeDeviceClasses=${this.includeDeviceClasses}
.label=${this.pickDeviceLabel}
.disabled=${this.disabled}
.required=${this.required&&!e.length}
@value-changed=${this._addDevice}
></ha-device-picker>
</div>
`}},{kind:"get",key:"_currentDevices",value:function(){return this.value||[]}},{kind:"method",key:"_updateDevices",value:async function(e){d(this,"value-changed",{value:e}),this.value=e}},{kind:"method",key:"_deviceChanged",value:function(e){e.stopPropagation();const i=e.currentTarget.curValue,t=e.detail.value;t!==i&&""===t&&(""===t?this._updateDevices(this._currentDevices.filter((e=>e!==i))):this._updateDevices(this._currentDevices.map((e=>e===i?t:e))))}},{kind:"method",key:"_addDevice",value:async function(e){e.stopPropagation();const i=e.detail.value;if(e.currentTarget.value="",!i)return;const t=this._currentDevices;t.includes(i)||this._updateDevices([...t,i])}},{kind:"field",static:!0,key:"styles",value:()=>a`
div {
margin-top: 8px;
}
`}]}}),i);let y=e([l("ha-selector-device")],(function(e,i){class d extends i{constructor(...i){super(...i),e(this)}}return{F:d,d:[{kind:"field",decorators:[t()],key:"hass",value:void 0},{kind:"field",decorators:[t()],key:"selector",value:void 0},{kind:"field",decorators:[c()],key:"_entitySources",value:void 0},{kind:"field",decorators:[c()],key:"_entities",value:void 0},{kind:"field",decorators:[t()],key:"value",value:void 0},{kind:"field",decorators:[t()],key:"label",value:void 0},{kind:"field",decorators:[t()],key:"helper",value:void 0},{kind:"field",decorators:[t({type:Boolean})],key:"disabled",value:()=>!1},{kind:"field",decorators:[t({type:Boolean})],key:"required",value:()=>!0},{kind:"field",key:"_deviceIntegrationLookup",value:()=>r(v)},{kind:"method",key:"hassSubscribe",value:function(){return[u(this.hass.connection,(e=>{this._entities=e.filter((e=>null!==e.device_id))}))]}},{kind:"method",key:"updated",value:function(e){var i;o(n(d.prototype),"updated",this).call(this,e),e.has("selector")&&null!==(i=this.selector.device)&&void 0!==i&&i.integration&&!this._entitySources&&h(this.hass).then((e=>{this._entitySources=e}))}},{kind:"method",key:"render",value:function(){var e,i,t,d,a,l,c,r;return null!==(e=this.selector.device)&&void 0!==e&&e.integration&&!this._entitySources?s``:null!==(i=this.selector.device)&&void 0!==i&&i.multiple?s`
${this.label?s`<label>${this.label}</label>`:""}
<ha-devices-picker
.hass=${this.hass}
.value=${this.value}
.helper=${this.helper}
.deviceFilter=${this._filterDevices}
.includeDeviceClasses=${null!==(t=this.selector.device.entity)&&void 0!==t&&t.device_class?[this.selector.device.entity.device_class]:void 0}
.includeDomains=${null!==(d=this.selector.device.entity)&&void 0!==d&&d.domain?[this.selector.device.entity.domain]:void 0}
.disabled=${this.disabled}
.required=${this.required}
></ha-devices-picker>
`:s`
<ha-device-picker
.hass=${this.hass}
.value=${this.value}
.label=${this.label}
.helper=${this.helper}
.deviceFilter=${this._filterDevices}
.includeDeviceClasses=${null!==(a=this.selector.device)&&void 0!==a&&null!==(l=a.entity)&&void 0!==l&&l.device_class?[this.selector.device.entity.device_class]:void 0}
.includeDomains=${null!==(c=this.selector.device)&&void 0!==c&&null!==(r=c.entity)&&void 0!==r&&r.domain?[this.selector.device.entity.domain]:void 0}
.disabled=${this.disabled}
.required=${this.required}
allow-custom-entity
></ha-device-picker>
`}},{kind:"field",key:"_filterDevices",value(){return e=>{const i=this._entitySources&&this._entities?this._deviceIntegrationLookup(this._entitySources,this._entities):void 0;return!this.selector.device||k(this.selector.device,e,i)}}}]}}),p(i));export{y as HaDeviceSelector};

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
function r(r){return void 0===r||Array.isArray(r)?r:[r]}export{r as e};

File diff suppressed because one or more lines are too long

View File

@@ -1,14 +0,0 @@
import{_ as e,H as i,e as t,y as s,n as o}from"./main-c66a9a06.js";import"./c.e8169f76.js";import"./c.b914d43e.js";import"./c.8e28b461.js";let c=e([o("hacs-progress-dialog")],(function(e,i){return{F:class extends i{constructor(...i){super(...i),e(this)}},d:[{kind:"field",decorators:[t()],key:"title",value:void 0},{kind:"field",decorators:[t()],key:"content",value:void 0},{kind:"field",decorators:[t()],key:"confirmText",value:void 0},{kind:"field",decorators:[t()],key:"confirm",value:void 0},{kind:"field",decorators:[t({type:Boolean})],key:"_inProgress",value:()=>!1},{kind:"method",key:"shouldUpdate",value:function(e){return e.has("active")||e.has("title")||e.has("content")||e.has("confirmText")||e.has("confirm")||e.has("_inProgress")}},{kind:"method",key:"render",value:function(){return this.active?s`
<hacs-dialog .active=${this.active} .hass=${this.hass} title=${this.title||""}>
<div class="content">
${this.content||""}
</div>
<mwc-button slot="secondaryaction" ?disabled=${this._inProgress} @click=${this._close}>
${this.hacs.localize("common.cancel")}
</mwc-button>
<mwc-button slot="primaryaction" @click=${this._confirmed}>
${this._inProgress?s`<ha-circular-progress active size="small"></ha-circular-progress>`:this.confirmText||this.hacs.localize("common.yes")}</mwc-button
>
</mwc-button>
</hacs-dialog>
`:s``}},{kind:"method",key:"_confirmed",value:async function(){this._inProgress=!0,await this.confirm(),this._inProgress=!1,this._close()}},{kind:"method",key:"_close",value:function(){this.active=!1,this.dispatchEvent(new Event("hacs-dialog-closed",{bubbles:!0,composed:!0}))}}]}}),i);export{c as HacsProgressDialog};

View File

@@ -1 +0,0 @@
import{O as o}from"./main-c66a9a06.js";const a=()=>import("./c.5faead67.js"),i=(i,l,m)=>new Promise((n=>{const r=l.cancel,s=l.confirm;o(i,"show-dialog",{dialogTag:"dialog-box",dialogImport:a,dialogParams:{...l,...m,cancel:()=>{n(!(null==m||!m.prompt)&&null),r&&r()},confirm:o=>{n(null==m||!m.prompt||o),s&&s(o)}}})})),l=(o,a)=>i(o,a),m=(o,a)=>i(o,a,{confirmation:!0}),n=(o,a)=>i(o,a,{prompt:!0});export{l as a,n as b,m as s};

Some files were not shown because too many files have changed in this diff Show More