linode server steuern, zirkulationspumpe steuern
This commit is contained in:
parent
8e61c164c8
commit
71b44d6a09
|
|
@ -1 +1 @@
|
|||
2023.12.3
|
||||
2024.1.3
|
||||
|
|
@ -1,21 +1,21 @@
|
|||
# https://www.home-assistant.io/docs/automation/trigger/#event-trigger
|
||||
description: Änderung Türsensor Kellertür zu geschlossen
|
||||
alias: Änderung Türsensor Kellertür zu geschlossen
|
||||
id: 95dd0b0b-0deb-470c-a2d7-e6b6dac08891
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: binary_sensor.door_sensor_kellertur_window_door_is_open
|
||||
to: "off"
|
||||
action:
|
||||
- service: notify.dev_telegram
|
||||
data:
|
||||
message: >
|
||||
{% if is_state('binary_sensor.door_sensor_kellertur_window_door_is_open', 'on') %}
|
||||
Kellertür wurde geöffnet
|
||||
{% else %}
|
||||
Kellertür wurde geschlossen
|
||||
{% endif %}
|
||||
|
||||
- service: switch.turn_off
|
||||
target:
|
||||
# https://www.home-assistant.io/docs/automation/trigger/#event-trigger
|
||||
description: Änderung Türsensor Kellertür zu geschlossen
|
||||
alias: Änderung Türsensor Kellertür zu geschlossen
|
||||
id: 95dd0b0b-0deb-470c-a2d7-e6b6dac08891
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: binary_sensor.door_sensor_kellertur_window_door_is_open
|
||||
to: "off"
|
||||
action:
|
||||
- service: notify.dev_telegram
|
||||
data:
|
||||
message: >
|
||||
{% if is_state('binary_sensor.door_sensor_kellertur_window_door_is_open', 'on') %}
|
||||
Kellertür wurde geöffnet
|
||||
{% else %}
|
||||
Kellertür wurde geschlossen
|
||||
{% endif %}
|
||||
|
||||
- service: switch.turn_off
|
||||
target:
|
||||
entity_id: switch.double_switch_node12_4
|
||||
|
|
@ -1,21 +1,21 @@
|
|||
# https://www.home-assistant.io/docs/automation/trigger/#event-trigger
|
||||
description: Änderung Türsensor Kellertür zu offen
|
||||
alias: Änderung Türsensor Kellertür zu offen
|
||||
id: a22bec55-1ad8-438b-97c8-73ee60cf07d0
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: binary_sensor.door_sensor_kellertur_window_door_is_open
|
||||
to: "on"
|
||||
action:
|
||||
- service: notify.dev_telegram
|
||||
data:
|
||||
message: >
|
||||
{% if is_state('binary_sensor.door_sensor_kellertur_window_door_is_open', 'on') %}
|
||||
Kellertür wurde geöffnet
|
||||
{% else %}
|
||||
Kellertür wurde geschlossen
|
||||
{% endif %}
|
||||
|
||||
- service: switch.turn_on
|
||||
target:
|
||||
entity_id: switch.double_switch_node12_4
|
||||
# https://www.home-assistant.io/docs/automation/trigger/#event-trigger
|
||||
description: Änderung Türsensor Kellertür zu offen
|
||||
alias: Änderung Türsensor Kellertür zu offen
|
||||
id: a22bec55-1ad8-438b-97c8-73ee60cf07d0
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: binary_sensor.door_sensor_kellertur_window_door_is_open
|
||||
to: "on"
|
||||
action:
|
||||
- service: notify.dev_telegram
|
||||
data:
|
||||
message: >
|
||||
{% if is_state('binary_sensor.door_sensor_kellertur_window_door_is_open', 'on') %}
|
||||
Kellertür wurde geöffnet
|
||||
{% else %}
|
||||
Kellertür wurde geschlossen
|
||||
{% endif %}
|
||||
|
||||
- service: switch.turn_on
|
||||
target:
|
||||
entity_id: switch.double_switch_node12_4
|
||||
|
|
|
|||
|
|
@ -1,37 +1,37 @@
|
|||
description: Rauchmelder-Alarm
|
||||
alias: Rauchmelder-Alarm
|
||||
id: 8ce59ed4-f7dd-47a5-a1ab-ada15310fc2d
|
||||
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id:
|
||||
- binary_sensor.rauchmelder_buro_christian_smoke_detected
|
||||
- binary_sensor.rauchmelder_buro_christian_smoke_alarm_test
|
||||
- binary_sensor.feueralarm_dummy
|
||||
- binary_sensor.rauchmelder_heizungskeller_smoke_detected
|
||||
- binary_sensor.rauchmelder_heizungskeller_smoke_alarm_test
|
||||
to:
|
||||
- "on"
|
||||
|
||||
action:
|
||||
- variables:
|
||||
param_entity: "{{trigger.to_state.entity_id}}"
|
||||
param_test_alert: "{{states('binary_sensor.group_smoke_sensors_test_alert')}}"
|
||||
- service: system_log.write
|
||||
data:
|
||||
level: info
|
||||
message: "Automation Feuer erkannt!! | Entity: {{param_entity}} | Test-Alert: {{param_test_alert}} Starte Skript für Feueralarm..."
|
||||
# - service: notify.dev_telegram
|
||||
# data:
|
||||
# message: >
|
||||
# rauchmelder_buro_christian_smoke_detected changed
|
||||
# {{ trigger.entity_id }}
|
||||
# from {{ trigger.from_state.state }} to {{ trigger.to_state.state }}
|
||||
# starting "smoke_sensor_script"...
|
||||
- service: script.smoke_sensor_script
|
||||
data:
|
||||
param_state: "{{trigger.to_state.state}}"
|
||||
param_entity_id: "{{param_entity}}"
|
||||
param_test_alert: "{{param_test_alert}}"
|
||||
|
||||
mode: single
|
||||
description: Rauchmelder-Alarm
|
||||
alias: Rauchmelder-Alarm
|
||||
id: 8ce59ed4-f7dd-47a5-a1ab-ada15310fc2d
|
||||
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id:
|
||||
- binary_sensor.rauchmelder_buro_christian_smoke_detected
|
||||
- binary_sensor.rauchmelder_buro_christian_smoke_alarm_test
|
||||
- binary_sensor.feueralarm_dummy
|
||||
- binary_sensor.rauchmelder_heizungskeller_smoke_detected
|
||||
- binary_sensor.rauchmelder_heizungskeller_smoke_alarm_test
|
||||
to:
|
||||
- "on"
|
||||
|
||||
action:
|
||||
- variables:
|
||||
param_entity: "{{trigger.to_state.entity_id}}"
|
||||
param_test_alert: "{{states('binary_sensor.group_smoke_sensors_test_alert')}}"
|
||||
- service: system_log.write
|
||||
data:
|
||||
level: info
|
||||
message: "Automation Feuer erkannt!! | Entity: {{param_entity}} | Test-Alert: {{param_test_alert}} Starte Skript für Feueralarm..."
|
||||
# - service: notify.dev_telegram
|
||||
# data:
|
||||
# message: >
|
||||
# rauchmelder_buro_christian_smoke_detected changed
|
||||
# {{ trigger.entity_id }}
|
||||
# from {{ trigger.from_state.state }} to {{ trigger.to_state.state }}
|
||||
# starting "smoke_sensor_script"...
|
||||
- service: script.smoke_sensor_script
|
||||
data:
|
||||
param_state: "{{trigger.to_state.state}}"
|
||||
param_entity_id: "{{param_entity}}"
|
||||
param_test_alert: "{{param_test_alert}}"
|
||||
|
||||
mode: single
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
mode: single
|
||||
id: 28152be7-98e7-4041-b3f1-d775c381f5b4
|
||||
desciption: Zeitsteuerung Poolpumpe
|
||||
alias: Event Poolpumpe schalten
|
||||
trigger:
|
||||
- platform: time
|
||||
at: "21:15:00"
|
||||
id: weekday
|
||||
- platform: time
|
||||
at: "22:30:00"
|
||||
id: weekend
|
||||
condition: []
|
||||
action:
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: trigger
|
||||
id: weekday
|
||||
- condition: time
|
||||
weekday:
|
||||
- mon
|
||||
- tue
|
||||
- wed
|
||||
- thu
|
||||
sequence:
|
||||
# - service: switch.turn_on
|
||||
# data: {}
|
||||
# target:
|
||||
# entity_id: switch.your_switch
|
||||
- conditions:
|
||||
- condition: trigger
|
||||
id: weekend
|
||||
- condition: time
|
||||
weekday:
|
||||
- fri
|
||||
- sat
|
||||
- sun
|
||||
sequence:
|
||||
# - service: switch.turn_on
|
||||
# data: {}
|
||||
# target:
|
||||
# entity_id: switch.your_switch
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
mode: single
|
||||
id: 61dfcad1-b4e2-4b03-afe5-37e08a11466c
|
||||
desciption: Zeitsteuerung Zirkulationspumpe
|
||||
alias: Event Zirkulationspumpe schalten
|
||||
trigger:
|
||||
- platform: time
|
||||
at: "11:00:00"
|
||||
id: stop
|
||||
- platform: time
|
||||
at: "15:00:00"
|
||||
id: start
|
||||
- platform: time
|
||||
at: "22:00:00"
|
||||
id: stop
|
||||
- platform: time
|
||||
at: "05:00:00"
|
||||
id: start
|
||||
condition: []
|
||||
action:
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: trigger
|
||||
id: start
|
||||
sequence:
|
||||
- service: notify.dev_telegram
|
||||
data:
|
||||
message: Zirkulation wird gestartet
|
||||
- conditions:
|
||||
- condition: trigger
|
||||
id: stop
|
||||
sequence:
|
||||
- service: notify.dev_telegram
|
||||
data:
|
||||
message: Zirkulation wird gestoppe
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
blueprint:
|
||||
name: Group Sonos on Motion
|
||||
description: "# Group Sonos on Motion\n**Version: 1.0**\nGroup a Sonos device to
|
||||
a main device when presence (e.g. motion) is detected and the main device is playing
|
||||
music. Can be extended with custom conditions, for example, only group the Sonos
|
||||
when you're not asleep.\nLet us know what you think of this blueprint and for
|
||||
community support including updates: [Click Here](https://community.home-assistant.io/t/sonos-grouping-and-ungrouping-using-motion-detection/575452)\n**The
|
||||
Automation Process:**\n - In this example we will use a motion sensor as the trigger
|
||||
but you can use one or multiple [Binary Sensors](https://www.home-assistant.io/integrations/binary_sensor/)
|
||||
as the trigger/s.\n - Triggers on a motion sensor and adds the Sonos speaker (target)
|
||||
in the room to a group (source).\n - When no motion is detected, a time delay
|
||||
is activated and removes the Sonos player from the group Automatically.\n - The
|
||||
Sonos speaker will remain GROUPED if the motion sensor detects motion before the
|
||||
time delay removes the Sonos speaker from the group. It will then reset the time
|
||||
delay after last motion is detected.\n - You have the option to add \"Custom conditions\".
|
||||
This allows you to extend this blueprint with more advanced YAML syntax.\n - You
|
||||
have the option to set the \"Allow TV\" option. When selected, the target Sonos
|
||||
Speaker will join the group even if the group is playing audio from the TV.\n
|
||||
- You have the option to adjust the \"Time Delay\". This will increase or decrease
|
||||
the amount of time it will take before the target Sonos Speaker will leave the
|
||||
group again.\n"
|
||||
domain: automation
|
||||
input:
|
||||
motion_trigger:
|
||||
name: Trigger Sensor - Binary Sensors *
|
||||
description: The Sensor/s that will make a Sonos speaker join a group. The trigger
|
||||
can be any [Binary Sensors](https://www.home-assistant.io/integrations/binary_sensor/)
|
||||
you like.
|
||||
selector:
|
||||
entity:
|
||||
domain:
|
||||
- binary_sensor
|
||||
multiple: true
|
||||
sonos_source:
|
||||
name: Sonos source
|
||||
description: The sonos player which this player will join. Probably located
|
||||
in a different room.
|
||||
selector:
|
||||
entity:
|
||||
integration: sonos
|
||||
domain:
|
||||
- media_player
|
||||
multiple: false
|
||||
sonos_target:
|
||||
name: Sonos target
|
||||
description: The Sonos player that will be joining the existing group. Probably
|
||||
the player which is located in the room where the motion has been triggered.
|
||||
selector:
|
||||
entity:
|
||||
integration: sonos
|
||||
domain:
|
||||
- media_player
|
||||
multiple: false
|
||||
time_delay:
|
||||
name: Time Delay
|
||||
description: The delay time to leave the sonos player in the group after the
|
||||
last trigger is detected.
|
||||
default: 5
|
||||
selector:
|
||||
number:
|
||||
min: 0.0
|
||||
max: 30.0
|
||||
step: 0.5
|
||||
unit_of_measurement: minutes
|
||||
mode: slider
|
||||
custom_conditions:
|
||||
name: Custom conditions
|
||||
default: []
|
||||
description: A list of custom condititions that also have to be met before grouping
|
||||
the sonos. Only available via YAML mode.
|
||||
allow_tv:
|
||||
name: Allow TV grouping
|
||||
description: Whether to also group the Sonos when the source is playing TV audio.
|
||||
default: false
|
||||
selector:
|
||||
boolean: {}
|
||||
source_url: https://gist.github.com/legovaer/b0211044a36411d8089220687ffda1d8
|
||||
mode: restart
|
||||
max_exceeded: silent
|
||||
variables:
|
||||
motion_trigger: !input motion_trigger
|
||||
sonos_source: !input sonos_source
|
||||
sonos_target: !input sonos_target
|
||||
allow_tv: !input allow_tv
|
||||
time_delay: !input time_delay
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: !input motion_trigger
|
||||
from: 'off'
|
||||
to: 'on'
|
||||
id: t1
|
||||
- platform: state
|
||||
entity_id: !input motion_trigger
|
||||
from: 'on'
|
||||
to: 'off'
|
||||
id: t2
|
||||
- platform: state
|
||||
entity_id: !input sonos_source
|
||||
to: playing
|
||||
id: t3
|
||||
- platform: homeassistant
|
||||
event: start
|
||||
id: t4
|
||||
- platform: event
|
||||
event_type: automation_reloaded
|
||||
id: t5
|
||||
condition:
|
||||
- condition: and
|
||||
conditions:
|
||||
- condition: state
|
||||
entity_id: !input sonos_source
|
||||
state: playing
|
||||
- condition: or
|
||||
conditions:
|
||||
- condition: state
|
||||
entity_id: !input sonos_target
|
||||
state: paused
|
||||
- condition: state
|
||||
entity_id: !input sonos_target
|
||||
state: idle
|
||||
- '{{ sonos_target in state_attr(sonos_source, "group_members") }}'
|
||||
- '{{ allow_tv or state_attr(sonos_source, "source") != "TV" }}'
|
||||
- condition: and
|
||||
conditions: !input custom_conditions
|
||||
action:
|
||||
- choose:
|
||||
- alias: Motion has been detected - group speakers
|
||||
conditions:
|
||||
- condition: trigger
|
||||
id: t1
|
||||
sequence:
|
||||
- alias: Add the speaker to the group
|
||||
service: media_player.join
|
||||
data:
|
||||
group_members:
|
||||
- !input sonos_target
|
||||
target:
|
||||
entity_id: !input sonos_source
|
||||
- alias: Motion has no longer been detected - unjoin after delay
|
||||
conditions:
|
||||
- condition: trigger
|
||||
id: t2
|
||||
sequence:
|
||||
- alias: Wait the number of minutes set in the time delay
|
||||
delay:
|
||||
minutes: !input time_delay
|
||||
- alias: Unjoin the speaker from the group
|
||||
service: media_player.unjoin
|
||||
target:
|
||||
entity_id: !input sonos_target
|
||||
|
|
@ -11,7 +11,6 @@ default_config:
|
|||
tts:
|
||||
- platform: google_translate
|
||||
|
||||
|
||||
ios: # https://www.justiot.de/smart-home/anleitung-push-nachrichten-mit-home-assistant-unter-ios/
|
||||
|
||||
logger: # https://www.home-assistant.io/integrations/logger/
|
||||
|
|
@ -20,4 +19,4 @@ logger: # https://www.home-assistant.io/integrations/logger/
|
|||
waste_collection_schedule: debug
|
||||
homeassistant.components.script: debug
|
||||
homeassistant.components.automation: debug
|
||||
pyfritzhome.fritzhome: warning
|
||||
pyfritzhome.fritzhome: warning
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
"""HACS Frontend"""
|
||||
from .version import VERSION
|
||||
|
||||
def locate_dir():
|
||||
"""HACS Frontend"""
|
||||
from .version import VERSION
|
||||
|
||||
def locate_dir():
|
||||
return __path__[0]
|
||||
|
|
@ -1,82 +1,82 @@
|
|||
import datetime
|
||||
|
||||
import requests
|
||||
from lxml import etree
|
||||
from waste_collection_schedule import Collection # type: ignore[attr-defined]
|
||||
|
||||
TITLE = "BIR (Bergensområdets Interkommunale Renovasjonsselskap)"
|
||||
DESCRIPTION = "Askøy, Bergen, Bjørnafjorden, Eidfjord, Kvam, Osterøy, Samnanger, Ulvik, Vaksdal, Øygarden og Voss Kommune (Norway)."
|
||||
URL = "https://bir.no"
|
||||
|
||||
TEST_CASES = {
|
||||
"Villa Paradiso": {
|
||||
"street_name": "Nordåsgrenda",
|
||||
"house_number": 7,
|
||||
"house_letter": "",
|
||||
},
|
||||
"Mardalsrenen 12 B": {
|
||||
"street_name": "Mardalsrenen",
|
||||
"house_number": "11",
|
||||
},
|
||||
"Alf Bondes Veg 13 B": {
|
||||
"street_name": "Alf Bondes Veg",
|
||||
"house_number": "13",
|
||||
"house_letter": "B",
|
||||
},
|
||||
}
|
||||
|
||||
API_URL = "https://bir.no/api/search/AddressSearch"
|
||||
ICON_MAP = {"restavfall": "mdi:trash-can", "papir": "mdi:newspaper-variant-multiple"}
|
||||
|
||||
|
||||
def map_icon(text):
|
||||
for key, value in ICON_MAP.items():
|
||||
if key in text:
|
||||
return value
|
||||
return "mdi:trash-can"
|
||||
|
||||
|
||||
class Source:
|
||||
def __init__(self, street_name, house_number, house_letter=""):
|
||||
self._street_name = street_name
|
||||
self._house_number = house_number
|
||||
self._house_letter = house_letter
|
||||
|
||||
def fetch(self):
|
||||
headers = {"user-agent": "Home-Assitant-waste-col-sched/0.1"}
|
||||
|
||||
args = {
|
||||
"q": f"{self._street_name} {self._house_number}{self._house_letter} ", # The space at the end is serving as a termination character for the query
|
||||
"s": False,
|
||||
}
|
||||
|
||||
r = requests.get(API_URL, params=args, headers=headers)
|
||||
r = requests.get(
|
||||
f"{URL}/adressesoek/toemmekalender",
|
||||
params={"rId": {r.json()[0]["Id"]}},
|
||||
headers=headers,
|
||||
)
|
||||
doc = etree.HTML(r.content)
|
||||
month_containers = doc.cssselect(
|
||||
".main-content .address-page-box .month-container"
|
||||
)
|
||||
|
||||
return [
|
||||
Collection(
|
||||
date=datetime.datetime.strptime(
|
||||
f"{date.text.replace('des','dec').replace('mai','may').replace('okt','oct')} {container.cssselect('.month-title')[0].text.strip().split(' ')[1]}",
|
||||
"%d. %b %Y",
|
||||
).date(),
|
||||
t=doc.cssselect(
|
||||
f'.trash-categories > .trash-row > img[src="{category_row.cssselect(".icon > img")[0].get("src")}"] + .trash-text'
|
||||
)[0].text,
|
||||
icon=map_icon(
|
||||
doc.cssselect(
|
||||
f'.trash-categories > .trash-row > img[src="{category_row.cssselect(".icon > img")[0].get("src")}"] + .trash-text'
|
||||
)[0].text.lower()
|
||||
),
|
||||
)
|
||||
for container in month_containers
|
||||
for category_row in container.cssselect(".category-row")
|
||||
for date in category_row.cssselect(".date-item > .date-item-date")
|
||||
]
|
||||
import datetime
|
||||
|
||||
import requests
|
||||
from lxml import etree
|
||||
from waste_collection_schedule import Collection # type: ignore[attr-defined]
|
||||
|
||||
TITLE = "BIR (Bergensområdets Interkommunale Renovasjonsselskap)"
|
||||
DESCRIPTION = "Askøy, Bergen, Bjørnafjorden, Eidfjord, Kvam, Osterøy, Samnanger, Ulvik, Vaksdal, Øygarden og Voss Kommune (Norway)."
|
||||
URL = "https://bir.no"
|
||||
|
||||
TEST_CASES = {
|
||||
"Villa Paradiso": {
|
||||
"street_name": "Nordåsgrenda",
|
||||
"house_number": 7,
|
||||
"house_letter": "",
|
||||
},
|
||||
"Mardalsrenen 12 B": {
|
||||
"street_name": "Mardalsrenen",
|
||||
"house_number": "11",
|
||||
},
|
||||
"Alf Bondes Veg 13 B": {
|
||||
"street_name": "Alf Bondes Veg",
|
||||
"house_number": "13",
|
||||
"house_letter": "B",
|
||||
},
|
||||
}
|
||||
|
||||
API_URL = "https://bir.no/api/search/AddressSearch"
|
||||
ICON_MAP = {"restavfall": "mdi:trash-can", "papir": "mdi:newspaper-variant-multiple"}
|
||||
|
||||
|
||||
def map_icon(text):
|
||||
for key, value in ICON_MAP.items():
|
||||
if key in text:
|
||||
return value
|
||||
return "mdi:trash-can"
|
||||
|
||||
|
||||
class Source:
|
||||
def __init__(self, street_name, house_number, house_letter=""):
|
||||
self._street_name = street_name
|
||||
self._house_number = house_number
|
||||
self._house_letter = house_letter
|
||||
|
||||
def fetch(self):
|
||||
headers = {"user-agent": "Home-Assitant-waste-col-sched/0.1"}
|
||||
|
||||
args = {
|
||||
"q": f"{self._street_name} {self._house_number}{self._house_letter} ", # The space at the end is serving as a termination character for the query
|
||||
"s": False,
|
||||
}
|
||||
|
||||
r = requests.get(API_URL, params=args, headers=headers)
|
||||
r = requests.get(
|
||||
f"{URL}/adressesoek/toemmekalender",
|
||||
params={"rId": {r.json()[0]["Id"]}},
|
||||
headers=headers,
|
||||
)
|
||||
doc = etree.HTML(r.content)
|
||||
month_containers = doc.cssselect(
|
||||
".main-content .address-page-box .month-container"
|
||||
)
|
||||
|
||||
return [
|
||||
Collection(
|
||||
date=datetime.datetime.strptime(
|
||||
f"{date.text.replace('des','dec').replace('mai','may').replace('okt','oct')} {container.cssselect('.month-title')[0].text.strip().split(' ')[1]}",
|
||||
"%d. %b %Y",
|
||||
).date(),
|
||||
t=doc.cssselect(
|
||||
f'.trash-categories > .trash-row > img[src="{category_row.cssselect(".icon > img")[0].get("src")}"] + .trash-text'
|
||||
)[0].text,
|
||||
icon=map_icon(
|
||||
doc.cssselect(
|
||||
f'.trash-categories > .trash-row > img[src="{category_row.cssselect(".icon > img")[0].get("src")}"] + .trash-text'
|
||||
)[0].text.lower()
|
||||
),
|
||||
)
|
||||
for container in month_containers
|
||||
for category_row in container.cssselect(".category-row")
|
||||
for date in category_row.cssselect(".date-item > .date-item-date")
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,92 +1,92 @@
|
|||
import datetime
|
||||
import json
|
||||
import re
|
||||
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
from waste_collection_schedule import Collection # type: ignore[attr-defined]
|
||||
|
||||
TITLE = "Cederbaum Braunschweig"
|
||||
DESCRIPTION = "Cederbaum Braunschweig Paperimüll"
|
||||
URL = "https://www.cederbaum.de"
|
||||
TEST_CASES = {
|
||||
"Hans-Sommer-Str": {"street": "Hans-Sommer-Str."},
|
||||
"Adolfstr 31-42": {"street": "Adolfstr. 31-42"},
|
||||
"Am Schwarzen Berge": {"street": "am Schwarzen Berge "},
|
||||
}
|
||||
|
||||
API_URL = "https://www.cederbaum.de/blaue-tonne/abfuhrkalender"
|
||||
ICON_MAP = {
|
||||
"PAPER": "mdi:newspaper",
|
||||
}
|
||||
|
||||
|
||||
class Source:
|
||||
def __init__(self, street):
|
||||
self._street = street
|
||||
|
||||
self.page_source = None
|
||||
self.street_id = None
|
||||
self.collection_data = None
|
||||
|
||||
def fetch_page_source(self):
|
||||
resp = requests.get(API_URL)
|
||||
soup = BeautifulSoup(resp.text, "html.parser")
|
||||
self.page_source = soup
|
||||
|
||||
def get_street_id(self):
|
||||
if not self.page_source:
|
||||
raise ValueError("No page source found")
|
||||
|
||||
select = self.page_source.find("select")
|
||||
|
||||
if not select:
|
||||
raise ValueError("No <select> tag found")
|
||||
|
||||
options = select.find_all("option")
|
||||
for option in options:
|
||||
value = option.get("value")
|
||||
text = option.get_text()
|
||||
if text.lower().strip() == self._street.lower().strip():
|
||||
self.street_id = value
|
||||
break
|
||||
|
||||
def get_collection_data(self):
|
||||
if not self.page_source:
|
||||
raise ValueError("No page source found")
|
||||
|
||||
script_tags = self.page_source.find_all("script")
|
||||
script_with_text = [tag for tag in script_tags if tag.string]
|
||||
pattern = re.compile(r"var rate = (\{.*?\});")
|
||||
|
||||
for script_tag in script_with_text:
|
||||
match = pattern.search(script_tag.string)
|
||||
if match:
|
||||
var_content = match.group(1)
|
||||
self.collection_data = json.loads(var_content)
|
||||
break
|
||||
|
||||
def fetch(self):
|
||||
self.fetch_page_source()
|
||||
self.get_street_id()
|
||||
self.get_collection_data()
|
||||
|
||||
if not self.collection_data:
|
||||
raise ValueError("No collection data found")
|
||||
|
||||
entries = []
|
||||
waste_dates = self.collection_data[self.street_id]["Termine"]
|
||||
for waste_date in waste_dates:
|
||||
date = datetime.datetime.strptime(
|
||||
waste_dates[waste_date]["Termin"], "%d.%m.%Y"
|
||||
)
|
||||
|
||||
entries.append(
|
||||
Collection(
|
||||
date=date.date(),
|
||||
t="Paper",
|
||||
icon=ICON_MAP.get("PAPER"),
|
||||
)
|
||||
)
|
||||
|
||||
return entries
|
||||
import datetime
|
||||
import json
|
||||
import re
|
||||
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
from waste_collection_schedule import Collection # type: ignore[attr-defined]
|
||||
|
||||
TITLE = "Cederbaum Braunschweig"
|
||||
DESCRIPTION = "Cederbaum Braunschweig Paperimüll"
|
||||
URL = "https://www.cederbaum.de"
|
||||
TEST_CASES = {
|
||||
"Hans-Sommer-Str": {"street": "Hans-Sommer-Str."},
|
||||
"Adolfstr 31-42": {"street": "Adolfstr. 31-42"},
|
||||
"Am Schwarzen Berge": {"street": "am Schwarzen Berge "},
|
||||
}
|
||||
|
||||
API_URL = "https://www.cederbaum.de/blaue-tonne/abfuhrkalender"
|
||||
ICON_MAP = {
|
||||
"PAPER": "mdi:newspaper",
|
||||
}
|
||||
|
||||
|
||||
class Source:
|
||||
def __init__(self, street):
|
||||
self._street = street
|
||||
|
||||
self.page_source = None
|
||||
self.street_id = None
|
||||
self.collection_data = None
|
||||
|
||||
def fetch_page_source(self):
|
||||
resp = requests.get(API_URL)
|
||||
soup = BeautifulSoup(resp.text, "html.parser")
|
||||
self.page_source = soup
|
||||
|
||||
def get_street_id(self):
|
||||
if not self.page_source:
|
||||
raise ValueError("No page source found")
|
||||
|
||||
select = self.page_source.find("select")
|
||||
|
||||
if not select:
|
||||
raise ValueError("No <select> tag found")
|
||||
|
||||
options = select.find_all("option")
|
||||
for option in options:
|
||||
value = option.get("value")
|
||||
text = option.get_text()
|
||||
if text.lower().strip() == self._street.lower().strip():
|
||||
self.street_id = value
|
||||
break
|
||||
|
||||
def get_collection_data(self):
|
||||
if not self.page_source:
|
||||
raise ValueError("No page source found")
|
||||
|
||||
script_tags = self.page_source.find_all("script")
|
||||
script_with_text = [tag for tag in script_tags if tag.string]
|
||||
pattern = re.compile(r"var rate = (\{.*?\});")
|
||||
|
||||
for script_tag in script_with_text:
|
||||
match = pattern.search(script_tag.string)
|
||||
if match:
|
||||
var_content = match.group(1)
|
||||
self.collection_data = json.loads(var_content)
|
||||
break
|
||||
|
||||
def fetch(self):
|
||||
self.fetch_page_source()
|
||||
self.get_street_id()
|
||||
self.get_collection_data()
|
||||
|
||||
if not self.collection_data:
|
||||
raise ValueError("No collection data found")
|
||||
|
||||
entries = []
|
||||
waste_dates = self.collection_data[self.street_id]["Termine"]
|
||||
for waste_date in waste_dates:
|
||||
date = datetime.datetime.strptime(
|
||||
waste_dates[waste_date]["Termin"], "%d.%m.%Y"
|
||||
)
|
||||
|
||||
entries.append(
|
||||
Collection(
|
||||
date=date.date(),
|
||||
t="Paper",
|
||||
icon=ICON_MAP.get("PAPER"),
|
||||
)
|
||||
)
|
||||
|
||||
return entries
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# https://companion.home-assistant.io/docs/notifications/notifications-basic/
|
||||
name: iPhones
|
||||
platform: group
|
||||
services:
|
||||
# https://companion.home-assistant.io/docs/notifications/notifications-basic/
|
||||
name: iPhones
|
||||
platform: group
|
||||
services:
|
||||
- service: mobile_app_christians_iphone_14
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# https://www.linode.com/docs/api/linode-instances/#linode-view
|
||||
- platform: rest
|
||||
method: GET
|
||||
name: linode_server1_status
|
||||
resource: https://api.linode.com/v4/linode/instances/53770635/
|
||||
headers:
|
||||
User-Agent: Home Assistant
|
||||
Content-Type: application/json
|
||||
Authorization: !secret rest_headers_secret_linode
|
||||
value_template: "{{ value_json.status }}"
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
# https://www.home-assistant.io/integrations/http/
|
||||
#
|
||||
#
|
||||
http:
|
||||
ssl_certificate: /ssl/cert.pem
|
||||
ssl_key: /ssl/privkey.pem
|
||||
# ssl_certificate: /ssl/cert.pem
|
||||
# ssl_key: /ssl/privkey.pem
|
||||
use_x_forwarded_for: true
|
||||
trusted_proxies:
|
||||
- 192.168.178.35
|
||||
- 192.168.178.2
|
||||
- 192.168.178.70
|
||||
- 192.168.178.0/24
|
||||
- 127.0.0.1
|
||||
- ::1
|
||||
ip_ban_enabled: false
|
||||
login_attempts_threshold: 100
|
||||
login_attempts_threshold: 5
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
# https://www.home-assistant.io/docs/mqtt/broker
|
||||
# 2022-12-23: rausgenommen, da nicht mehr kompatibel
|
||||
# mqtt:
|
||||
# broker: 192.168.178.44
|
||||
# username: !secret mqtt_user
|
||||
# password: !secret mqtt_pw
|
||||
|
||||
mqtt:
|
||||
switch:
|
||||
- unique_id: sonoff1_switch
|
||||
command_topic: "cmnd/sonoff-1/POWER"
|
||||
name: "Tannenbaum"
|
||||
payload_on: "ON"
|
||||
payload_off: "OFF"
|
||||
payload_available: "Online"
|
||||
payload_not_available: "Offline"
|
||||
retain: true
|
||||
qos: 0
|
||||
state_topic: "tele/sonoff-1/STATE"
|
||||
availability_topic: "tele/sonoff-1/LWT"
|
||||
state_on: "ON"
|
||||
# https://www.home-assistant.io/docs/mqtt/broker
|
||||
# 2022-12-23: rausgenommen, da nicht mehr kompatibel
|
||||
# mqtt:
|
||||
# broker: 192.168.178.44
|
||||
# username: !secret mqtt_user
|
||||
# password: !secret mqtt_pw
|
||||
|
||||
mqtt:
|
||||
switch:
|
||||
- unique_id: sonoff1_switch
|
||||
command_topic: "cmnd/sonoff-1/POWER"
|
||||
name: "Tannenbaum"
|
||||
payload_on: "ON"
|
||||
payload_off: "OFF"
|
||||
payload_available: "Online"
|
||||
payload_not_available: "Offline"
|
||||
retain: true
|
||||
qos: 0
|
||||
state_topic: "tele/sonoff-1/STATE"
|
||||
availability_topic: "tele/sonoff-1/LWT"
|
||||
state_on: "ON"
|
||||
state_off: "OFF"
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# https://www.home-assistant.io/integrations/rest_command/
|
||||
|
||||
#rest_command: !include ../rest_command.yaml
|
||||
# rest_command split: !include_dir_named ../rest_commands
|
||||
rest_command: !include_dir_merge_named ../rest_commands/
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
---
|
||||
# The script integration allows users to specify a sequence of actions to be
|
||||
# executed by Home Assistant when turned on.
|
||||
#
|
||||
# This loads up my custom tempates.
|
||||
#
|
||||
# https://www.home-assistant.io/integrations/template/
|
||||
#
|
||||
|
||||
template: !include ../templates.yaml
|
||||
template split: !include_dir_named ../templates
|
||||
---
|
||||
# The script integration allows users to specify a sequence of actions to be
|
||||
# executed by Home Assistant when turned on.
|
||||
#
|
||||
# This loads up my custom tempates.
|
||||
#
|
||||
# https://www.home-assistant.io/integrations/template/
|
||||
#
|
||||
|
||||
template: !include ../templates.yaml
|
||||
template split: !include_dir_named ../templates
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
# https://www.linode.com/docs/api/linode-instances/#linode-shut-down
|
||||
trigger_linode_server1_shutdown:
|
||||
url: "https://api.linode.com/v4/linode/instances/53770635/shutdown"
|
||||
method: POST
|
||||
payload: "{}"
|
||||
content_type: "application/json"
|
||||
verify_ssl: true
|
||||
headers:
|
||||
authorization: !secret rest_headers_secret_linode
|
||||
accept: "application/json, text/html"
|
||||
user-agent: "Home Assistant"
|
||||
|
||||
# https://www.linode.com/docs/api/linode-instances/#linode-boot
|
||||
trigger_linode_server1_boot:
|
||||
url: "https://api.linode.com/v4/linode/instances/53770635/boot"
|
||||
method: POST
|
||||
payload: "{}"
|
||||
content_type: "application/json"
|
||||
verify_ssl: true
|
||||
headers:
|
||||
authorization: !secret rest_headers_secret_linode
|
||||
accept: "application/json, text/html"
|
||||
user-agent: "Home Assistant"
|
||||
|
|
@ -1,38 +1,38 @@
|
|||
description: "Racumelder Ereignisse bearbeiten"
|
||||
fields: # https://www.home-assistant.io/integrations/script/#passing-variables-to-scripts
|
||||
param_entity_id: # https://www.home-assistant.io/integrations/script/#fields
|
||||
description: "entity_id des meldenden Gerätes"
|
||||
example: "binary_sensor.rauchmelder_buro_christian_smoke_detected"
|
||||
required: "true"
|
||||
param_test_alert:
|
||||
description: "probealarm ja/nein"
|
||||
required: "true"
|
||||
param_state:
|
||||
description: "Status des Ereignisses"
|
||||
example: "on"
|
||||
required: "true"
|
||||
default: "off"
|
||||
sequence:
|
||||
- service: system_log.write
|
||||
data:
|
||||
level: info
|
||||
message: "Skript Feueralarm für Entity '{{param_entity_id}}' gestartet. (State: {{param_state}}) | Probealarm: {{param_test_alert}} Starte Aktionen..."
|
||||
|
||||
# send critical notifications https://companion.home-assistant.io/docs/notifications/critical-notifications
|
||||
- service: notify.iPHONES
|
||||
data:
|
||||
title: "FEUERALARM"
|
||||
message: "Feueralarm für '{{param_entity_id}}'"
|
||||
data:
|
||||
push:
|
||||
sound:
|
||||
name: "default"
|
||||
critical: 1
|
||||
volume: 1.0
|
||||
|
||||
- service: notify.dev_telegram
|
||||
data:
|
||||
message: >
|
||||
Feueralarm für Entity '{{param_entity_id}}'!!! (State: {{param_state}}) | Probealarm: {{param_test_alert}}
|
||||
|
||||
|
||||
description: "Racumelder Ereignisse bearbeiten"
|
||||
fields: # https://www.home-assistant.io/integrations/script/#passing-variables-to-scripts
|
||||
param_entity_id: # https://www.home-assistant.io/integrations/script/#fields
|
||||
description: "entity_id des meldenden Gerätes"
|
||||
example: "binary_sensor.rauchmelder_buro_christian_smoke_detected"
|
||||
required: "true"
|
||||
param_test_alert:
|
||||
description: "probealarm ja/nein"
|
||||
required: "true"
|
||||
param_state:
|
||||
description: "Status des Ereignisses"
|
||||
example: "on"
|
||||
required: "true"
|
||||
default: "off"
|
||||
sequence:
|
||||
- service: system_log.write
|
||||
data:
|
||||
level: info
|
||||
message: "Skript Feueralarm für Entity '{{param_entity_id}}' gestartet. (State: {{param_state}}) | Probealarm: {{param_test_alert}} Starte Aktionen..."
|
||||
|
||||
# send critical notifications https://companion.home-assistant.io/docs/notifications/critical-notifications
|
||||
- service: notify.iPHONES
|
||||
data:
|
||||
title: "FEUERALARM"
|
||||
message: "Feueralarm für '{{param_entity_id}}'"
|
||||
data:
|
||||
push:
|
||||
sound:
|
||||
name: "default"
|
||||
critical: 1
|
||||
volume: 1.0
|
||||
|
||||
- service: notify.dev_telegram
|
||||
data:
|
||||
message: >
|
||||
Feueralarm für Entity '{{param_entity_id}}'!!! (State: {{param_state}}) | Probealarm: {{param_test_alert}}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
|
||||
# Use this file to store secrets like usernames and passwords.
|
||||
# Learn more at https://www.home-assistant.io/docs/configuration/secrets/
|
||||
some_password: welcome
|
||||
|
||||
|
||||
telegram_api_key: 448772521:AAHIIrXBVEUF7_1zYRCmGo5YHipRJyBlp7o
|
||||
telegram_dev: -391668323
|
||||
telegram_chk: 14652347
|
||||
telegram_homegroup: -192460863
|
||||
|
||||
mqtt_user: mqtt_user
|
||||
mqtt_pw: IH88EZW4mIm9LI8oJWIK
|
||||
mqtt_pw: IH88EZW4mIm9LI8oJWIK
|
||||
|
||||
rest_headers_secret_linode: Bearer db59c00118966bdfaf97aa5661d934d822a5fc94656e1d5be4a8a12bf6f34780
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
- sensor:
|
||||
|
||||
- binary_sensor:
|
||||
# simuliert einen nicht Hardware-Rouchmelder, der einfach über dem Dummy-Schalter aktiviert werden kann
|
||||
- name: Feueralarm_Dummy
|
||||
state: >
|
||||
{% if states("input_boolean.switch_fire_alert_dummy")|lower == "on" %}
|
||||
On
|
||||
{% else %}
|
||||
Off
|
||||
- sensor:
|
||||
|
||||
- binary_sensor:
|
||||
# simuliert einen nicht Hardware-Rouchmelder, der einfach über dem Dummy-Schalter aktiviert werden kann
|
||||
- name: Feueralarm_Dummy
|
||||
state: >
|
||||
{% if states("input_boolean.switch_fire_alert_dummy")|lower == "on" %}
|
||||
On
|
||||
{% else %}
|
||||
Off
|
||||
{% endif %}
|
||||
Loading…
Reference in New Issue