AppDaemon Q&A

You may have seen the latest BLOG entry We Have Apps Now - I figured I’d start this thread for any questions to avoid cluttering up the BLOG Post.

Ask Away!

Note: For detailed usage instructions after you have installed AppDaemon, check out thew API Reference Doc

EDIT: Also forgot to thanks @rpitera for being my Beta Tester!

11 Likes

This sounds great, I was just struggling with the following:

  1. I would like my fountain to go for 25 minutes
  2. The fountain should only start when I enter my garden (ibeacon)
  3. It should only start between 10:00 and 22:00
  4. It should only start if the temperature is above 15 C
  5. It should only run max two times a day.

Instead of adding a lot of logic_states, it seems I now can make an app that subscribes on the first four external conditions above, and letting the app combine them and keeping track of the last condition.

So, is this best implemented as an app or did I miss something.

Absolutely - should be very easy with AppDaemon:

  1. Register a callback for presence on the beacon
  2. Whenever it triggers chekc if it is between 10:00 and 22:00 (there is an API call just for that)
  3. Check the temperature either with the weather addon or using a sensor if you have one
  4. If all pass start the fountain
  5. Register a callback for 25 minutes
  6. Callback stops the fountain
  7. Add logic to count the number of activations, and only start if less than 2, and register a callback once a day to reset the counter

Should be able to do it in 10-15 lines of code :slight_smile:

@aimc This is absolutely wonderful. My main frustration with configuring automations in Home Assistant is how abstracted everything is from actual programming. Don’t get me wrong, something like the yaml configurations over the top of things makes this stuff way more accessible to those without as much coding background - but I like to get my hands dirty. I kept finding myself frustrated at having to re-write the same script 15+ times (once for each bulb or sensor) when a simple case statement or nested if/than would have been much more elegant. Templating helps a bit, but doesn’t quite go far enough.

From your blogpost:
"(...)I am hopeful that for some users this will seem a more natural, powerful and nimble way of building potentially very complex automations."
Mission accomplished. You found at least one of those users right here. This system looks to be exactly what I was looking for. Thanks!

Great! Let me know how you get on - happy to help with any questions or issues - I feel much the same as you, this is much closer to how I think :slight_smile:

This looks awesome, I’m going to try to integrate this into my Docker.

I have been working on docker support but haven’t quite finished it yet - let me know if you get it working first!

@brusc, We are going to need a new Video. :slight_smile:

Do you think something like (https://github.com/maddox/dasher) could be turned into an APPDaemon app?

//CC: @maddox

Great Work BTW!

2 Likes

i get the feeling this is great by first reading it.
i guess it would take me to study this for a short time to understand how to use it.

i think i can use this to reduce my config for quite a bit.

could you give me directions how to go on in this situation:

i have about xxx (a lot and getting more) times this in my config:

automation:
- alias: 'pchoek aan'
  trigger:
    platform: state
    entity_id: input_boolean.eetpchoek
    to: 'on'
  action:
    service: switch.mysensors_send_ir_code
    entity_id: switch.afstandbediening_2_5
    data:
      V_IR_SEND: 'P02t'
- alias: 'pchoek uit'
  trigger:
    platform: state
    entity_id: input_boolean.eetpchoek
    to: 'off'
  action:
    service: switch.mysensors_send_ir_code
    entity_id: switch.afstandbediening_2_5
    data:
      V_IR_SEND: 'P02f'

input_boolean:
  eetpchoek:
    name: PC hoek
    initial: off
    icon: mdi:lightbulb-outline

and every time i add a new switch this code get copied and only name and ircode is changed.

im sure when i read about appdeamon this would exactly why it would be helpfull.
but right now i am not sure what would be the best way to put what where.

It would be very easy to write an app that waits for state changes on the input boolean and then sends the IR codes to the appropriate entity. You have a couple of choices - you could write an app that takes an input boolean and the entity id as parameters and re-use it multiple times, or if you prefer you could write one app that takes all of the input booleans and switches as comma separated arguments.

A standalone app might look a little like this (if I have understood what you are doing):

import appapi

class IRSwitch(appapi.AppDaemon):

  def initialize(self):
    self.listen_state(self.switch, args["boolean"])
  
  def switch(self, entity, attribute, old, new, kwargs):
    if new == "on":
      self.call_service("switch.mysensors_send_ir_code", entity_id = args["switch"], V_IR_SEND="P02t")
    else:
      self.call_service("switch.mysensors_send_ir_code", entity_id = args["switch"], V_IR_SEND="P02f")

Then put this in a file called irswitch.py in the apps dir.

Then every time you wanted to add one, you would create the input boolean as before, then instantiate a version of the app in the config file like this:

[IRSwitch1]
module = irswitch
class = IRSwitch
boolean = input_boolean.eetpchoek
switch = switch.afstandbediening_2_5

Then add another:

[IRSwitch2]
module = irswitch
class = IRSwitch
boolean = input_boolean.eetpchoek_2
switch = switch.afstandbediening_2_5_2

etc. - the class and module stay the same but you are giving it different input booleans and switches each time.

2 Likes

yeah i knew it would be perfect.

my code in the config will become something like:

[IRSwitch1]
module = RFswitch
class = RFSwitch
boolean = eetpchoek
switchtype = kaku
switchcode = P01

would the config file have the same name and place as the app?

and would it be possible to listen to more then 1 boolean in the app and decide action based on which bollean is used?

Checkout the install instructions ad the API doc for info on how to configure the apps - there is a centralised config file, and a specific directory that you place the app files in but it is all configurable.

And yes, you can register as many callbacks as you like in an App - I once did a unit test where I registered roughly a million schedule callbacks all to run at the same time and it actually worked :).

So yes, you can add as many input booleans as you like and decide what to do by sending them to different callbacks, or you could listen out for ALL input booleans in a single callback and decide what to do based on the actual one changed when the callback is activated.

1 Like

see i knew it would be perfect :wink:

then i can listen out all booleans, and if there is something like rf in the name (probaly a bit longer) then action would be taken.

the config the could be something like:

[IRSwitch1]
module = RFswitch
class = RFSwitch
code1 = rfaakakuP01
code2 = rfabkakuP02
code3 - rfacelroB31
...

and everytime i add a switch i just add a boolean with name rf… and a new line in the config.
everything would be a lot better readable and i would reduce my automation.yaml with 21 lines pro switch (so about 300 line right now and growing)

i guess i know what i’m doing tommorow :wink:

many many many thanks from my side!!

Sounds like you are thinking along the right lines - let me know if you need any help :slight_smile:

1 Like

less is more :wink:

you already gave me about everything i need.

i really should read up about this, but if you tell me how to listen to more then 1 state then all i have to do is install and rewrite the code you have given.

is it as easy as:

self.listen_state(self.switch, args["boolean1"])
self.listen_state(self.switch, args["boolean2"])
self.listen_state(self.switch, args["boolean3"])

in the init?

and now that i write this i think: “hmm and how to listen to all booleans at once? and how to find out which boolean is used?”

see i must read first before you do all the work for me :wink:

That would certainly work, but as you are just about to find out by reading the docs, if you do:

self.listen_state(self.switch, "input_boolean")

It will listen to ALL input_booleans.

Then in switch() the entity argument is set to which boolean changed when the callback is called.

1 Like

@CCOSTAN For sure! I definitely want to explore this and we certainly make a video on it. I’m terribly behind this summer since I’m moving. But, I should have a lot more coming in September.

As for this app method, it’s awesome! Thanks much @aimc or your tremendous effort on this. It’ll definitely give power users an awesome way to cut back on the number of scripts and such they have laying around. With the big updates coming in 0.27, I’m super confident HA will continue to grow like crazy.

Cheers!

3 Likes

This looks pretty awesome @aimc, thanks!

Is there any reason you didn’t (or couldn’t) write this as a component instead of a separate app? It’d be pretty nice if something like this could be loaded from hass. I’ll probably get a lot of use out of it either way :smiley:

i am crying right now.

it wont work in with windows :frowning:

i know i want to go to my PI but developing on my PC is so nice.
but i guess now i need to install everything on the PI before i can start using this :frowning:

@brusc - glad you like it! I would love to see one of your excellent videos about this - I would probably learn something too :slight_smile: Let me know if I can help in any way.

@justyns - Several reasons, but none of them would prevent this from being migrated to HA in the future:

  • An important design goal was to remove the need to restart HA for every tweak and change - my HA instance takes about 2-3 mins to be up and stable owing to the number of devices I have and developing automations was a little cumbersome. For that reason I decided on a loosely coupled model using APIs. Having said that, other features that came along later such as auto reload and compilation of the modules, auto addition and removal etc. have largely obviated the need to restart AppDaemon at all, so this reason no longer holds water

  • I also wanted to be respectful to Paulus - this is a huge departure for the way automations are coded and it may not have suited his vision. Building this as a component and hoping he was OK with it didn’t seem right to me - I wanted to prove that it was useful as a first step, not just for me but also for other users. This thread is certainly showing a gratifying level of engagement but at the end, if it is only useful for 2-3 users it probably isn’t worth the effort of integrating and maintaining it in HA.

  • For a long time I was unconvinced if what I was building was substantially different from the Component API. If someone can write an App, they could also write a component. It took me a while to find out the answer to this and be comfortable with it: Apps are a way to code automations, Components are a way to add to base HA functionality. Either could do both, but they are each optimized to their specific task. When I figured this out the priority became making Apps as easy to use and quick to develop as possible - which kind of fed into the first reason - keep this environment as nimble as possible.

  • No real advantages - as I said in the blog post, AppDaemon is in every way a first class citizen operationally, there would be no real advantages to making it a part of HA - it is possible that we might manage to shave a few milliseconds off reactions to events and perhaps make the odd service call a little quicker but the performance is already extremely good as it is, and HA events generally only need to react in the second range to be extremely effective. Having said that however, there are also no disadvantages to including it in HA either.

When taken together these reasons are more of a journey than a design decision - I had to build this thing and see how it turned out. Now that we are here and gathering input, I would absolutely be happy to migrate this to be a core piece of HA if enough folks use it, and the other Devs are OK with it - time will tell :slight_smile:

@ReneTode - Bummer :frowning: What is the problem with it? I havent tried it but if you have windows 10 maybe the new Linux subsytem will work for this?

2 Likes