Also interested in this with the latest AppDaemon (3?). My Hass often seems to hang and I have a script to restart it, but I lose alarm state when that happens.
I’m getting the same error
OK got past that
I’ve now got this working. I’ll happily share if people are still interested
Please do!
So instead of trying to extend the set switch app, I just created a new one just for resetting the alarm. Mainly to reduce the complexity while I was learning and in case I ran into issues. Here’s what I ended up with:
import appdaemon.plugins.hass.hassapi as hass
import shelve
import time
#
# App to reset alarm_control_panel to previous state after HA restart
#
# Args:
#
# delay - amount of time after restart to set the state
# file - file in which to save state
#
# Release Notes
#
# Version 1.0:
# Initial Version
class AlarmReset(hass.Hass):
def initialize(self):
self.device_db = shelve.open(self.args["file"])
self.listen_event(self.ha_event, "plugin_started")
self.listen_event(self.appd_event, "appd_started")
self.listen_state(self.state_change, "alarm_control_panel")
def ha_event(self, event_name, data, kwargs):
self.log_notify("Home Assistant restart detected")
self.run_in(self.set_alarm, self.args["delay"])
def appd_event(self, event_name, data, kwargs):
self.log_notify("AppDaemon restart detected")
self.run_in(self.set_alarm, self.args["delay"])
def state_change(self, entity, attribute, old, new, kwargs):
self.log_notify("State change: {} to {}".format(entity, new))
self.device_db[entity] = new
def set_alarm(self, kwargs):
self.log_notify("Checking for alarm_control_panel")
# Find out what devices are avaiable.
# If we don't know about it initialize, if we do set the switch appropriately
state = self.get_state()
for entity in state:
type, id = entity.split(".")
if type == "alarm_control_panel":
if entity in self.device_db:
if self.device_db[entity] != state[entity]["state"]:
self.log_notify("Setting {} to {} (was {})".format(entity, self.device_db[entity], state[entity]["state"]))
new_state = self.set_state(entity, state = self.device_db[entity])
else:
self.log_notify("Adding {}, setting value to current state ({})".format(entity, state[entity]["state"]))
self.device_db[entity] = state[entity]["state"]
def log_notify(self, message, level = "INFO"):
#if "verbose_log" in self.args:
self.log(message)
The bit that fixed the error above was changing
self.listen_event(self.ha_event, "ha_started")
to
self.listen_event(self.ha_event, "plugin_started")
as that changed in recent versions of appdaemon.
I also learnt that you shouldn’t create an empty file for it to save into - you need to just supply it with the name you want and let it create the file.
Have tested it a few times and seems to work fine
Hmmm, not quite working for me. I see this when I change the alarm:
INFO Alarm_Reset: State change: alarm_control_panel.home_alarm to armed_home
But on reboot, i get:
INFO Alarm_Reset: Adding alarm_control_panel.home_alarm, setting value to current state (disarmed)
Doesn’t seem to be writing to my DB file, tried changing ownership/permissions and no luck.
My apps.yaml config is this:
Alarm_Reset:
class: AlarmReset
module: alarmreset
# Choose where to store the states across restarts
file: "/home/homeassistant/.homeassistant/preserved_states"
delay: 10
Strange. If you cat the DB file after a state change you should see the latest state at the end of the cat output.
Interesting, working now.
One important thing I found out is that you should close and open the database after each “save” operation. If it’s not saved and there’s a power outage you’ll lose the saved state.
Shelve doesn’t save to the file after every operation? It must do, as my file changes whenever the state does.
Hmmm…yeah it’s not picking up all the changes, only some.
Hmm that’s odd?
Yeah not picking up at all. File isn’t modifying either.
Must be a permissions thing then?
File is owned by homeassistant user and i just tried it as 777, still no luck.
Tried deleting the file and restarting. Stumped. It writes some gibberish to the file but no alarm state.
Yeah I think the gibberish is just the shelve db meta data or something. Normally the state stuff is in plaintext at the end of the gibberish. I’ll have a look at mine when I get home to see if there’s anything about how I’ve set it up.
Not under all circumstances. I found out when killing appdaemon in testing that it doesn’t flush the saved data to the file immediately.
Ok will have to look at how to close, and move the open into the set_alarm routine.
Mine’s gibberish but with this at the end:
alarm_control_panel.ha_alarm▒Xpendingq.alarm_control_panel.ha_alarm▒disarmedq.alarm_control_panel.ha_alarm▒X
I run appdaemon in a docker container and my db file is owned by root with 644 perms.