LAB02-Research / HASS.Agent

Windows-based client for Home Assistant. Provides notifications, quick actions, commands, sensors and more.
https://hassagent.lab02-research.org
MIT License
1.61k stars 74 forks source link

Misc: Detecting that the PC is on or off #132

Closed Draghmar closed 2 years ago

Draghmar commented 2 years ago

Hi I've made an automation that uses light sensor to update brightness of my screens. It works by monitoring changes to the sensor and sending MQTT to HASS.Agent. The question here is: how to add condition that will prevent sending if the PC is turned off. I mean, it works right now without it but it simply bothers me. :D Also, having that I could trigger initial brightness after the PC turns on. Below is the automation itself (I'm still tweaking the values there and will have to move some thing to template variables, so consider this as a work in progress ;)):

alias: Change LCDs brightness based on lux
id: c45b151a-87a8-4356-a26e-0e997891bf33
mode: queued
trigger:
  - platform: state
    entity_id: sensor.xiaomi_lumi_sen_ill_mgl01_illuminance
    to: ~
condition:
  - condition: template
    value_template: "{{ state_attr('automation.lcd_change_brightness', 'last_triggered') != 'None' or ((as_timestamp(utcnow()) - as_timestamp(state_attr('automation.lcd_change_brightness', 'last_triggered')) |int(0) ) > 10) }}"
  - condition: template
    value_template: '{{ states("input_number.lux_value_for_automation") | int(0) != (25 + (( (states("sensor.xiaomi_lumi_sen_ill_mgl01_illuminance") | int(0)) / 220) * 30) | int(0)) }}'
action:
  - service: mqtt.publish
    data:
      topic: 'homeassistant/light/EARTH/set_lcd01_brightness/action'
      payload_template: '%LOCALAPPDATA%\\Microsoft\\WindowsApps\\Monitorian.exe /set "DISPLAY\AOC2713\5&3f30a18&0&UID4357" {{ 25 + (( (states("sensor.xiaomi_lumi_sen_ill_mgl01_illuminance") | int(0)) / 220) * 30) | int(0) }}'
  - service: mqtt.publish
    data:
      topic: 'homeassistant/light/EARTH/set_lcd01_brightness/action'
      payload_template: '%LOCALAPPDATA%\\Microsoft\\WindowsApps\\Monitorian.exe /set "DISPLAY\PHL08E9\5&3f30a18&0&UID4355" {{ (( (states("sensor.xiaomi_lumi_sen_ill_mgl01_illuminance") | int(0)) / 220) * 7) | int(0) }}'
  - service: input_number.set_value
    target:
      entity_id: input_number.lux_value_for_automation
    data:
      value: '{{ 25 + (( (states("sensor.xiaomi_lumi_sen_ill_mgl01_illuminance") | int(0)) / 220) * 30) | int(0) }}'
LAB02-Admin commented 2 years ago

Hey @Draghmar,

Looks cool! You can use a wol or a simple ping sensor to determine the pc's state. The first has an example here:

https://hassagent.readthedocs.io/en/latest/sensor-command-automation-and-script-examples/#switch-wake-on-lan

Take note of the tips beneath it regarding windows firewall, to make sure you can ping the device :)

Draghmar commented 2 years ago

Hm...but both of those are things that HA would have to query for. Isn't there some Local Sensor that could be used this way? Like setting something when HASS.Agent starts and that would sent update to the HA and then when PC is shutting down, which would mean app is closing down, set it to something - don't know if that's even possible for Win app to know...

LAB02-Admin commented 2 years ago

Oh, yea, you can use a LastSystemStateChangeSensor to do exactly that :)

Draghmar commented 2 years ago

Oh, that one looks promising. :) Do you have some doc explaining when all the states can happen? Some of them looks obvious but some not.

ApplicationStarted, Logoff, SystemShutdown, Resume, Suspend, ConsoleConnect, ConsoleDisconnect, RemoteConnect, RemoteDisconnect, SessionLock, SessionLogoff, SessionLogon, SessionRemoteControl and SessionUnlock.

LAB02-Admin commented 2 years ago

Not really besides MS's developer docs. Basically the ConsoleConnect, ConsoleDisconnect, RemoteConnect, RemoteDisconnect, SessionRemoteControl ones aren't relevant unless you're using remote desktop. ApplicationStarted is triggered when hass.agent (or the satellite service, depending on where you added the sensor) starts.

Logoff, SystemShutdown, Resume, Suspend, SessionLock, SessionLogoff, SessionLogon and SessionUnlock are straight-forward.

Draghmar commented 2 years ago

Ok, thanks. For the moment it looks like this thing did the trick! :) For the record this is the (almost) final automation:

alias: Change LCDs brightness based on lux
mode: queued
id: c45b151a-87a8-4356-a26e-0e997891bf33
variables:
  lux_lcd01: '{{ 25 + (( (states("sensor.xiaomi_lumi_sen_ill_mgl01_illuminance") | int(0)) / 220) * 30) | int(0) }}'
trigger:
  - platform: state
    entity_id: sensor.xiaomi_lumi_sen_ill_mgl01_illuminance
    to: ~ 
condition:
  - condition: template
    value_template: "{{ states('sensor.earth_lastsystemstatechange') in ['ApplicationStarted', 'Resume', 'SessionLogon', 'SessionUnlock'] }}"
  - condition: template
    value_template: "{{ state_attr('automation.lcd_change_brightness', 'last_triggered') != 'None' or ((as_timestamp(utcnow()) - as_timestamp(state_attr('automation.lcd_change_brightness', 'last_triggered')) |int(0) ) > 10) }}"
  - condition: template
    value_template: '{{ states("input_number.lux_value_for_automation") | int(0) != lux_lcd01 }}'
action:
  - service: mqtt.publish
    data:
      topic: "homeassistant/light/EARTH/set_lcd01_brightness/action"
      payload_template: '%LOCALAPPDATA%\\Microsoft\\WindowsApps\\Monitorian.exe /set "DISPLAY\AOC2713\5&3f30a18&0&UID4357" {{ lux_lcd01 }}'
  - service: mqtt.publish
    data:
      topic: "homeassistant/light/EARTH/set_lcd01_brightness/action"
      payload_template: '%LOCALAPPDATA%\\Microsoft\\WindowsApps\\Monitorian.exe /set "DISPLAY\PHL08E9\5&3f30a18&0&UID4355" {{ (( (states("sensor.xiaomi_lumi_sen_ill_mgl01_illuminance") | int(0)) / 220) * 7) | int(0) }}'
  - service: input_number.set_value
    target:
      entity_id: input_number.lux_value_for_automation
    data:
      value: '{{ lux_lcd01 }}'
LAB02-Admin commented 2 years ago

Very nice :)

Thanks for sharing, added to the docs: https://hassagent.readthedocs.io/en/latest/sensor-command-automation-and-script-examples/#automation-change-lcd-brightness-based-on-lux-and-session-state

Draghmar commented 2 years ago

I didn't know you'll gonna do this. I'd prepare a commented version :P

alias: Change LCDs brightness based on lux
mode: queued
id: c45b151a-87a8-4356-a26e-0e997891bf33
variables:
  # 25 - min value to set on first LCD (my LCD is hard to view below this value)
  # 30 - the difference between max value and min value that should be set, which gives us number of steps LCD can be set on (above 55 my LCD is already to bright for normal viewing)
  # 220 - the max lux value I've observed where the LCDs are standing throughout normal day of work
  # states("sensor.xiaomi_lumi_sen_ill_mgl01_illuminance") | int(0) - make sure to get int value, not text
  lux_lcd01: '{{ 25 + (( (states("sensor.xiaomi_lumi_sen_ill_mgl01_illuminance") | int(0)) / 220) * 30) | int(0) }}'
trigger:
  - platform: state
    entity_id: sensor.xiaomi_lumi_sen_ill_mgl01_illuminance
    to: ~ 
condition:
  # set brightness only if the PC is up by looking for specific values from sensor set in HASS.Agent
  - condition: template
    value_template: "{{ states('sensor.earth_lastsystemstatechange') in ['ApplicationStarted', 'Resume', 'SessionLogon', 'SessionUnlock'] }}"
  # don't update brightness if the last trigger was less the 10s ago but do if there was no trigger at all (like after restarting HA)
  - condition: template
    value_template: "{{ state_attr('automation.lcd_change_brightness', 'last_triggered') != 'None' or ((as_timestamp(utcnow()) - as_timestamp(state_attr('automation.lcd_change_brightness', 'last_triggered')) |int(0) ) > 10) }}"
  - condition: template
    value_template: '{{ states("input_number.lux_value_for_automation") | int(0) != lux_lcd01 }}'
action:
  - service: mqtt.publish
    data:
      topic: "homeassistant/light/EARTH/set_lcd01_brightness/action"
      payload_template: '%LOCALAPPDATA%\\Microsoft\\WindowsApps\\Monitorian.exe /set "DISPLAY\AOC2713\5&3f30a18&0&UID4357" {{ lux_lcd01 }}'
  - service: mqtt.publish
    data:
      topic: "homeassistant/light/EARTH/set_lcd01_brightness/action"
      # this is the same as for lux_lcd01 but second LCD has different min and max (zero and 7 - yeah, that's how bright it is...)
      payload_template: '%LOCALAPPDATA%\\Microsoft\\WindowsApps\\Monitorian.exe /set "DISPLAY\PHL08E9\5&3f30a18&0&UID4355" {{ (( (states("sensor.xiaomi_lumi_sen_ill_mgl01_illuminance") | int(0)) / 220) * 7) | int(0) }}'
  # I'm saving this to use later on when checking if the brightness changes even if the lux changed (automation was triggered)
  - service: input_number.set_value
    target:
      entity_id: input_number.lux_value_for_automation
    data:
      value: '{{ lux_lcd01 }}'
LAB02-Admin commented 2 years ago

Hah, wow, that's awesome! Thanks for taking the time to do that ❤️

It's updated :)