AppDaemon Q&A

Very glad you like AppDaemon :slight_smile:

Thanks for spotting the get_app() example - will be fixed in the next release.

Regarding multiple callback constraints - what would you want to do?

Callback constraints are meant to be a simple way of saving programming logic but you can easily perform more complex logic in the App itself. I am hesitant about adding multiples of the same type because the next question is “should they be ANDed or ORed” - then the obvious answer is “both, and by the way can we have complex nested expressions as well” - at that point I am trying to duplicate a Python interpreter in parameters - which is what we already have in HA Automations with YAML.

I am always happy to discuss and review on the basis of other people’s experiences but for now I want to keep constraints simple - they are there to make the Apps Simpler, not move the programming into the config file.

Good Points and that totally make sense.:+1:

1 Like

OK, I have it coded but it will take a few days to test on account of the fact that we are limited to one sunrise and sunset per day :wink: Look out for a release in the next few days.

1 Like

This is great! I can finally start moving off OpenHAB! Quick question - in the motion light example, what would be the cleanest way of dealing with repeat motion triggers - would the function triggered check timestamp of the latest motion event or is there a good way to cancel previous timers when new one is set?

Yes - when you set the timer it returns a handle that you can use in the cancel_timer() call. All the details are in the API docs.

Great! … how is concurrency handled on this? I cannot see anything being returned from the cancel_timer function, therefore one always has to assume that the cancellation timer ran anyway.

Answering my own question a bit, I think that locks needs to be used to ensure proper functionality even for the smallest examples (unless there is something already provided?)

Imagine the following scenario:

light_off - triggered by a timer after the light is off
light_on - triggered by a motion sensor

In the past, I had issue when the light_on was triggered exactly when the light_off started running meaning that it sent command to switch the light off and finished but right after that the light_off finished as well, immediately switching the light off. I had put in a proper lock to ensure that ligt_off and light_on cannot be ran at the same time.

Would the above be a correct assumption?

The cancellation is a simple key deletion in a Python dictionary - not necessarily atomic but pretty fast.

I think this is correct but in reality not something I have come across. In my setup the sensors can only activate every 4 minutes - if I keep the light on for less than that there will never be an issue.

I have mulled over the whole subject of locking and decided to shelve it unless it started to cause issues - the fact of the matter is that even though AppDaemon is a highly concurrent architecture, processing speeds relative to real world events are quick enough that it will probably be OK 99.99% of the time - scheduler ticks happen once a second, HA state updates are asynchronous to that.

If you can convince me other wise, my plan would be to make each App single threaded to the worker threads which would probably fix most issues, and then for extra credit I would lock the scheduler and state callback tables for inserts and deletes, all of which would be trandparent to the Apps themselves.

In the meantime you can use instance variables as a less threadsafe way of achieving the same thing, or if you prefer, nothing is stopping you from rolling your own using Python libraries.

Thank you, roger that - makes sense. I will most likely use a lock in my code to be on a safe side - I think that for many (if not most) use cases the locking may not be necessary, so I am fine using a per-app solution. Curious to see if I will be proven wrong over time :slight_smile:

Yep - I will be watching too - I have thought about this during design but you are the first person to actually mention it :slight_smile:

@aimc i cant seem to get the get_app() working.

i’m trying to make some general functions and call 1 from the other, but i get stuck somehow.

in de API you have a wrong example and you mention the header section but for me thats not enough.
i’m trying and trying, dont seem to get it working.
i also tried to make a file and then import that, but somehow i get stuck with self and missing arguments.

so can you please make it clear for me how to use get_app?

I fixed up the example in the latest version so the entry now reads:

get_app()

get_app() will return the instantiated object of another app running within the system. This is useful for calling functions or accessing variables that reside in different apps without requiring duplication of code.

Synopsis

get_app(self, name)

Parameters

name

Name of the app required. This is the name specified in header section of the config file, not the module or class.

Returns

An object reference to the class.

Example

MyApp = self.get_app("MotionLights")
MyApp.turn_light_on()

Is that enough to get you going?

only the name part gets me puzzled.
how must i specify the name in the header section?

edit: i suddenly get a flash :wink:
i get what is mentioned with it.

It’s the name in the square brackets [] in the config file for each App - but I think you just figured that out :wink:

yeah, i figured it out :wink:
doesnt bring me anything though.

today im running from error to error.

now i tried:

    fnc = self.get_app("generalvars")
    fnc.update_sensor_time(self.args["control_time_name"], self.args["dir_name"], self.args["time_gone_by"], self.args["time_format"])

and get

AttributeError: 'dict' object has no attribute 'update_sensor_time'

today nothing is going like i want.

i tried installing the latest version.
i copied and did pip3, edited my apps, copied the config. so far so good.

the i tried to start appdaemon.
but i get an importerror.
no module appdaemon.conf appdaemon is not a package.

How are you starting appdaemon? You need to run it as an executable in your path, e.g. appdaemon instead of trying to run the python directly from the git repository - this is as a resulkt of the pip install.

i tried

py C:\Python34\Lib\site-packages\appdaemon\appdaemon.py -c C:\Users\rene\appdaemon-master\conf\appdaemon.cfg
and

C:\Python34\Lib\site-packages\appdaemon\appdaemon.py -c C:\Users\rene\appdaemon-master\conf\appdaemon.cfg

no run it from your path:

appdaemon -c C:\Users\rene\appdaemon-master\conf\appdaemon.cfg

It’s in the docs:

PIP3

You can then run AppDaemon from the command line as follows:

$ appdaemon -c conf/appdaemon.cfg

If all is well, you should see something like the following:

$ appdaemon -c conf/appdaemon.cfg
2016-08-22 10:08:16,575 INFO Got initial state
2016-08-22 10:08:16,576 INFO Loading Module: /export/hass/appdaemon_test/conf/apps/hello.py
2016-08-22 10:08:16,578 INFO Loading Object hello_world using class HelloWorld from module hello
2016-08-22 10:08:16,580 INFO Hello from AppDaemon
2016-08-22 10:08:16,584 INFO You are now ready to run Apps!

Regarding this - you found a bug :frowning:

What you wrote should work, but it is broken.

As a workaround you can use

fnc = self.get_app("generalvars")["object"]

That will work for now but it will break in the next version when I fix it.

lol, i today i think i am a bug :wink:

yeah, i have it started up again.

the only thing is that it doesnt show anything in my shell anymore.

all error and ifo go to the error and info log files, but nothing to the shell anymore.

1 Like