Compare commits

...
4 Commits
Author SHA1 Message Date
Pierre 842cfe6c6a commut_rain sensor simplification 2026-10-04 11:51:35 +02:00
Pierre 5061e4395b new commut_rain sensor 2026-10-04 10:26:39 +02:00
Pierre 3562e14c4c Added a workday sensor 2026-10-04 10:25:18 +02:00
Pierre aafc932818 replace a bunch of log by log_info 2026-10-02 22:18:16 +02:00
5 changed files with 111 additions and 34 deletions

No files matched your search

+12 -3
View File
@@ -38,6 +38,7 @@ class AlarmClock(SmartObject):
self.inputdate_alarmclock_main = self.args['inputdate_alarmclock_main']
self.inputdate_alarmclock_secondary = self.args['inputdate_alarmclock_secondary']
self.input_text_wakeup_time = self.args['input_text_wakeup_time']
self.output_workday_sensor = self.args['output_workday_sensor']
#self.sensor_wakeup_datetime = self.args['sensor_wakeup_datetime']
self.sleeping_condition = SmartCondition.Evaluator(self, self.args['sleeping_condition'], condition_name="sleeping_condition", constants=self.constants, templates_library=self.templates_library)
@@ -54,12 +55,14 @@ class AlarmClock(SmartObject):
self.run_hourly(self.on_refresh_cal,datetime.time(0, 0, 0))
self.sensor_wakeup_datetime_entity = self.create_entity("sensor.wakeup_datetime", icon="mdi:alarm")
self.workday_entity = self.create_entity(self.output_workday_sensor, icon="mdi:briefcase-check")
#sensor_wakeup_datetime_entity = self.get_entity(self.sensor_wakeup_datetime)
#if not sensor_wakeup_datetime_entity.exists():
# sensor_wakeup_datetime_entity.add()
self.calendar = list()
self.refresh_cal()
self.update_workday_status()
self.update_wakeup_time()
@@ -151,9 +154,17 @@ class AlarmClock(SmartObject):
self.update_wakeup_time()
def on_refresh_cal(self, kwargs):
if self.refresh_cal():
calendar_changed = self.refresh_cal()
self.update_workday_status()
if calendar_changed:
self.update_wakeup_time()
def update_workday_status(self):
is_workday = self.is_wakeup_time_on_a_working_day(datetime.datetime.now())
new_state = "on" if is_workday else "off"
if self.workday_entity.get_state() != new_state:
self.workday_entity.set_state(state=new_state)
def on_program_next_wakeup(self, kwargs):
self.handle_program_next_wakueup_cb = None
@@ -329,5 +340,3 @@ class AlarmClock(SmartObject):
def update_wakeup_time(self):
self.register_callbacks(self.calculate_wakeup_time())
+65
View File
@@ -9,6 +9,71 @@ virtual_sensors:
sensors:
binary_sensor.someone_home: person.maeva == 'home' or person.pierre == 'home' or (input_boolean.use_red_shelly_presence and binary_sensor.red_shelly_home)
binary_sensor.is_dark_outside: sun.sun == 'below_horizon'
value_selector.commut_rain_minutes_until_rain:
values:
le_cres_first:
conditions:
local_expressions:
cres_minutes: sensor.next_rain_le_cres.minutes_until_rain
castelnau_minutes: sensor.next_rain_castelnau_le_lez.minutes_until_rain
cres_minutes_available: cres_minutes != None and cres_minutes != 'unknown' and cres_minutes != 'unavailable'
castelnau_minutes_available: castelnau_minutes != None and castelnau_minutes != 'unknown' and castelnau_minutes != 'unavailable'
trigger_conditions: cres_minutes_available and (not castelnau_minutes_available or cres_minutes <= castelnau_minutes)
value: sensor.next_rain_le_cres.minutes_until_rain
castelnau_only:
conditions:
local_expressions:
cres_minutes: sensor.next_rain_le_cres.minutes_until_rain
castelnau_minutes: sensor.next_rain_castelnau_le_lez.minutes_until_rain
cres_minutes_available: cres_minutes != None and cres_minutes != 'unknown' and cres_minutes != 'unavailable'
castelnau_minutes_available: castelnau_minutes != None and castelnau_minutes != 'unknown' and castelnau_minutes != 'unavailable'
trigger_conditions: castelnau_minutes_available and (not cres_minutes_available or castelnau_minutes < cres_minutes)
value: sensor.next_rain_castelnau_le_lez.minutes_until_rain
unknown: true
value_selector.commut_rain_intensity:
values:
Pluie forte:
conditions:
local_expressions:
cres_intensity: sensor.next_rain_le_cres.intensity
castelnau_intensity: sensor.next_rain_castelnau_le_lez.intensity
trigger_conditions: cres_intensity == 'Pluie forte' or castelnau_intensity == 'Pluie forte'
Pluie modérée:
conditions:
local_expressions:
cres_intensity: sensor.next_rain_le_cres.intensity
castelnau_intensity: sensor.next_rain_castelnau_le_lez.intensity
trigger_conditions: cres_intensity == 'Pluie modérée' or castelnau_intensity == 'Pluie modérée'
Pluie faible:
conditions:
local_expressions:
cres_intensity: sensor.next_rain_le_cres.intensity
castelnau_intensity: sensor.next_rain_castelnau_le_lez.intensity
trigger_conditions: cres_intensity == 'Pluie faible' or castelnau_intensity == 'Pluie faible'
Temps sec:
conditions:
local_expressions:
cres_intensity: sensor.next_rain_le_cres.intensity
castelnau_intensity: sensor.next_rain_castelnau_le_lez.intensity
trigger_conditions: cres_intensity == 'Temps sec' and castelnau_intensity == 'Temps sec'
unknown: true
binary_sensor.commut_rain:
conditions:
trigger_conditions:
- sensor.next_rain_le_cres != 'unknown' and sensor.next_rain_le_cres != 'unavailable'
- sensor.next_rain_castelnau_le_lez != 'unknown' and sensor.next_rain_castelnau_le_lez != 'unavailable'
blocking_conditions:
- not person.pierre
- person.pierre == 'home' and not binary_sensor.morning_commut_time
- person.pierre != 'home' and not binary_sensor.evening_commut_time
- not binary_sensor.pierre_workday
sensor_attributes:
minutes_until_rain_le_cres: sensor.next_rain_le_cres.minutes_until_rain
minutes_until_rain_castelnau: sensor.next_rain_castelnau_le_lez.minutes_until_rain
minutes_until_rain: sensor.commut_rain_minutes_until_rain
intensity: sensor.commut_rain_intensity
event_sensor.red_shelly_home:
retain_time: 120
activation_events:
+3
View File
@@ -175,10 +175,13 @@ alarm_clock:
module: alarmclock
class: AlarmClock
priority: 5
switch_alarmclock_main: input_boolean.main_alarmclock
switch_alarmclock_secondary: input_boolean.secondary_alarmclock
inputdate_alarmclock_main: input_datetime.main_alarmclock
inputdate_alarmclock_secondary: input_datetime.secondary_alarmclock
input_text_wakeup_time: input_text.wakeup_time
output_workday_sensor: binary_sensor.pierre_workday
sleeping_condition: binary_sensor.is_bedroom_sleeping
+30 -30
View File
@@ -15,7 +15,7 @@ class SamsungTheFrame(SmartObject):
def on_initialize_smart_object(self):
super().on_initialize_smart_object()
self.log(f"Initializing TheFrame with ip {self.args['ip_address']}")
self.log_info(f"Initializing TheFrame with ip {self.args['ip_address']}")
#self.need_to_turn_off_when_hdmi_gone = False
self.volume_connection = None
self.requested_state = None
@@ -98,7 +98,7 @@ class SamsungTheFrame(SmartObject):
key_press_delay=0)
except (OSError, tv_exceptions.ConnectionFailure, tv_exceptions.ResponseError,
websocket.WebSocketException) as error:
self.log(f"Volume {direction} failed: {error}", level="WARNING")
self.log_info(f"Volume {direction} failed: {error}", level="WARNING")
# Reconnect on the next press, without replaying a failed command.
self.close_volume_connection()
@@ -108,10 +108,10 @@ class SamsungTheFrame(SmartObject):
def wake_up(self):
if 'wake_up_service' in self.args:
service = self.args['wake_up_service']
self.log(f"Calling service {service}")
self.log_info(f"Calling service {service}")
self.call_service(service)
elif 'wol_switch' in self.args:
self.log(f"Switching on {self.args['wol_switch']}")
self.log_info(f"Switching on {self.args['wol_switch']}")
self.turn_on(self.args['wol_switch'])
if 'mac_address' in self.args:
wakeonlan.send_magic_packet(self.args['mac_address'])
@@ -128,23 +128,23 @@ class SamsungTheFrame(SmartObject):
selected_art = random.choice(available_art)
tv.art().select_image(selected_art['content_id'], show=True)
except tv_exceptions.ResponseError as e:
self.log(f"select_random_art with exception ResponseError {e}")
self.log_info(f"select_random_art with exception ResponseError {e}")
except TimeoutError:
self.log(f"select_random_art with exception TimeoutError")
self.log_info(f"select_random_art with exception TimeoutError")
def request_tv_state(self,requested_state):
valid_states = ['art_mode','tv_off','hdmi','power_off','manual']
assert requested_state in valid_states, f"{requested_state} is not a valid states. Valid states are {valid_states}"
self.log(f"Requesting TV to switch to {requested_state}")
self.log_info(f"Requesting TV to switch to {requested_state}")
if requested_state == 'hdmi' and self.get_state(self.is_on_sensor) == 'off':
self.log(f"setting {self.tv_auto_shutdown} to 'on'")
self.log_info(f"setting {self.tv_auto_shutdown} to 'on'")
self.set_state(self.tv_auto_shutdown,state = 'on')
#if we already have a confirm callback, let's cancel it
if self.requested_state_confirm_cb_handle:
self.log("Canceling previous confirm CB")
self.log_info("Canceling previous confirm CB")
self.cancel_timer(self.requested_state_confirm_cb_handle)
self.requested_state_confirm_cb_handle = None
@@ -153,7 +153,7 @@ class SamsungTheFrame(SmartObject):
else:
self.requested_state = requested_state
if self._process_state_request():
self.log(f"The TV was already in the right state")
self.log_info(f"The TV was already in the right state")
def _process_state_request(self):
try:
@@ -167,26 +167,26 @@ class SamsungTheFrame(SmartObject):
if self.requested_state == 'tv_off':
if not is_plugged:
self.log("Powering on TV")
self.log_info("Powering on TV")
self.turn_on(self.power_plug)
self.requested_state_confirm_cb_handle = self.run_in(self.confirm_change_state_cb, 60)
return False
elif is_on:
tv = self.connect()
self.log("Switching to art mode")
self.log_info("Switching to art mode")
tv.shortcuts().power()
self.requested_state_confirm_cb_handle = self.run_in(self.confirm_change_state_cb, 10)
return False
elif is_art_mode:
tv = self.connect()
self.log("Turning off TV")
self.log_info("Turning off TV")
tv.hold_key('KEY_POWER',4)
self.requested_state_confirm_cb_handle = self.run_in(self.confirm_change_state_cb, 10)
return False
elif self.requested_state == 'art_mode':
if not is_art_mode:
if not is_plugged:
self.log("Powering on TV")
self.log_info("Powering on TV")
self.turn_on(self.power_plug)
self.requested_state_confirm_cb_handle = self.run_in(self.confirm_change_state_cb, 60)
return False
@@ -204,18 +204,18 @@ class SamsungTheFrame(SmartObject):
elif self.requested_state == "hdmi":
if not is_plugged:
self.log("Powering on TV")
self.log_info("Powering on TV")
self.turn_on(self.power_plug)
self.requested_state_confirm_cb_handle = self.run_in(self.confirm_change_state_cb, 60)
return False
elif not self.has_power():
self.log("Waking up TV")
self.log_info("Waking up TV")
self.wake_up()
self.requested_state_confirm_cb_handle = self.run_in(self.confirm_change_state_cb, 60)
return False
elif not is_on:
tv = self.connect()
self.log("Turning on TV")
self.log_info("Turning on TV")
tv.shortcuts().power()
self.requested_state_confirm_cb_handle = self.run_in(self.confirm_change_state_cb, 5)
return False
@@ -225,8 +225,8 @@ class SamsungTheFrame(SmartObject):
# {'id': '3201907018807', 'name': 'Netflix', 'running': True, 'version': '5.2.59020', 'visible': True}
app_status = tv.rest_app_status(str(app))
if app_status['visible']:
self.log(f"{app_status['name']} is active")
self.log("Switching to Hdmi")
self.log_info(f"{app_status['name']} is active")
self.log_info("Switching to Hdmi")
tv.send_key('KEY_HDMI')
self.requested_state_confirm_cb_handle = self.run_in(self.confirm_change_state_cb, 5)
return False
@@ -240,14 +240,14 @@ class SamsungTheFrame(SmartObject):
self.requested_state_confirm_cb_handle = self.run_in(self.confirm_change_state_cb, 10)
return False
elif not self.has_power():
self.log("Waking up TV")
self.log_info("Waking up TV")
self.wake_up()
self.requested_state_confirm_cb_handle = self.run_in(self.confirm_change_state_cb, 60)
return False
elif is_art_mode: #it's better to turn off while it's art mode to ensure the TV will wake up in art mode and support properly wake on lan
self.select_random_art()
time.sleep(5)
self.log("Powering off TV")
self.log_info("Powering off TV")
self.turn_off(self.power_plug)
self.requested_state_confirm_cb_handle = self.run_in(self.confirm_change_state_cb, 5)
return False
@@ -290,23 +290,23 @@ class SamsungTheFrame(SmartObject):
else:
is_on = "on"
except KeyError as e: #sometimes the lib throw an exception in File "/samsungtvws/art.py", line 318, in get_artmode
self.log(f"get_artmode() throw a KeyError Exception {e}")
self.log_info(f"get_artmode() throw a KeyError Exception {e}")
return False , 10
except websocket.WebSocketConnectionClosedException:
self.log(f"update sensors failed with exception WebSocketConnectionClosedException")
self.log_info(f"update sensors failed with exception WebSocketConnectionClosedException")
return False , 30
except ConnectionRefusedError:
self.log(f"update sensors failed with exception ConnectionRefusedError")
self.log_info(f"update sensors failed with exception ConnectionRefusedError")
return False , 30
except tv_exceptions.ConnectionFailure:
self.log(f"update sensors failed with exception ConnectionFailure")
self.log_info(f"update sensors failed with exception ConnectionFailure")
return False , 30
except OSError as error:
self.log(f"update sensors failed with exception OsError {error}")
self.log_info(f"update sensors failed with exception OsError {error}")
return False , 30
except tv_exceptions.ResponseError as e:
self.log(f"update sensors failed with exception ResponseError {e}")
self.log_info(f"update sensors failed with exception ResponseError {e}")
return False , 30
# except:
# import traceback
@@ -316,17 +316,17 @@ class SamsungTheFrame(SmartObject):
# return False , 5
if self.get_state(self.is_art_mode_sensor) != is_art_mode:
self.log(f"Updating sensor: {self.is_art_mode_sensor} = '{is_art_mode}'")
self.log_info(f"Updating sensor: {self.is_art_mode_sensor} = '{is_art_mode}'")
self.set_state(self.is_art_mode_sensor,state = is_art_mode)
if is_on == 'off':
self.close_volume_connection()
if self.get_state(self.is_on_sensor) != is_on:
self.log(f"Updating sensor: {self.is_on_sensor} = '{is_on}'")
self.log_info(f"Updating sensor: {self.is_on_sensor} = '{is_on}'")
self.set_state(self.is_on_sensor,state = is_on)
if is_on == 'off' and self.get_state(self.tv_auto_shutdown) != 'off':
self.log(f"setting {self.tv_auto_shutdown} to 'off'")
self.log_info(f"setting {self.tv_auto_shutdown} to 'off'")
self.set_state(self.tv_auto_shutdown,state = 'off')