Switch_Reset

I keep getting an error when trying to use AppDaemon and Switch_Reset

Here is the error I get:

2017-10-28 07:09:37.003627 WARNING ------------------------------------------------------------
2017-10-28 07:09:37.003715 WARNING Scheduler entry has been deleted
2017-10-28 07:09:37.003753 WARNING ------------------------------------------------------------
2017-10-28 09:14:36.235356 WARNING ------------------------------------------------------------
2017-10-28 09:14:36.235404 WARNING Unexpected error during loading of Switch Reset:
2017-10-28 09:14:36.235437 WARNING ------------------------------------------------------------
2017-10-28 09:14:36.235825 WARNING Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/appdaemon/appdaemon.py", line 911, in read_app
    init_object(name, class_name, module_name, conf.app_config[name])
  File "/usr/local/lib/python3.5/dist-packages/appdaemon/appdaemon.py", line 582, in init_object
    conf.objects[name]["object"].initialize()
  File "home/mgranger/.homeassistant/conf/apps/switch_reset.py", line 22, in initialize
    self.device_db = shelve.open(self.args["file"])
  File "/usr/lib/python3.5/shelve.py", line 243, in open
    return DbfilenameShelf(filename, flag, protocol, writeback)
  File "/usr/lib/python3.5/shelve.py", line 227, in __init__
    Shelf.__init__(self, dbm.open(filename, flag), protocol, writeback)
  File "/usr/lib/python3.5/dbm/__init__.py", line 94, in open
    return mod.open(file, flag, mode)
_gdbm.error: [Errno 13] Permission denied

2017-10-28 09:14:36.235879 WARNING ------------------------------------------------------------

Here is my apps.yaml file:

Switch Reset:
  module: switch_reset
  class: SwitchReset
  file: /home/mgranger/.homeassistant/switches.db
  delay: '5'
  log: '1'

seems that the filerights from the file /home/mgranger/.homeassistant/switches.db are not enough for the appdaemon user.
the appdaemon user has probably no writing acces in the dir where you want the db created.

Same problem. I am sure appdaemon has proper rights @grangemd did you ever solved (2017)

appdaemon from 2017 was a complete different program then appdaemon now.
so most likely its not the same problem.

and if you use an app from 5 years old, it can be all kind of things.

Thanks for replying @ReneTode I solved by introducing a terminate function closing the db
Here is the updated code

import hassapi as hass
import shelve

#
# App to reset input_boolean, input_select, input_number, input_text to previous values after HA restart
#
# Args:
#
# delay - amount of time after restart to set the switches
#
#
# Release Notes
#
# Version 1.0:
#   Initial Version
#

class SwitchReset(hass.Hass):
    def initialize(self):
        self.log_notify("SwitchReset Started")
        try:
            self.device_db = shelve.open(self.args["file"])
        except:
            self.log_notify("Could not open db")
            self.log_notify(self.device_db)
            return
        self.listen_event(self.ha_event, "plugin_started")
        self.listen_event(self.appd_event, "appd_started")
        self.listen_state(self.state_change, "input_boolean")
        self.listen_state(self.state_change, "input_select")
        self.listen_state(self.state_change, "input_number")
        self.listen_state(self.state_change, "input_text")
    
    def terminate(self):
        try:
            self.device_db.close()
        except:
            self.log_notify("Could not close db")
            return           

    def ha_event(self, event_name, data, kwargs):
        self.log_notify("Home Assistant restart detected")
        self.run_in(self.set_switches, self.args["delay"])

    def appd_event(self, event_name, data, kwargs):
        self.log_notify("AppDaemon restart detected")
        self.run_in(self.set_switches, 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_switches(self, kwargs):
        self.log_notify("Setting switches")
        # Find out what devices are available.
        # 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 == "input_boolean" or type == "input_select" or type == "input_number" or type == "input_text":
                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"])
                        )
                        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)
        if "notify" in self.args:
            self.notify(message, globals.notify, name=globals.notify)
1 Like