AppDaemon Q&A

Why are there only constraints for input_boolean and input_select but no constraints for switch, light, sensor, etc? What if I want to have an app callback only if the living room light is off, or the front door is closed? Do I have to create an input_boolean in home assistant for every one of my contacts sensors, switches and lights that match the state of the actual device in order to have constraints? I have 37 z-wave door/window sensors, 18 z-wave light switches as well as a slew of other z-wave devices, but it doesn’t look like I can use their current state as a constraint. This would make it impossible for me to use appdaemon for any of my automations.

Or am I misunderstanding constraints? Aren’t they equivalent to conditions in home assistant? Home Assistant conditions can be based on the state of any item as well as AND and OR, but it appears that appdaemon constraints are only based on AND

yeah, i have it splitt out.
but i still count the lines together as 1 config :wink:

as i see it, with the little bit i have done you can listen to everything and set everything.

its py, so off course there is also OR.

somthing like:

if (self.sun_down or self.sun_rise):
       self.toggle("light.living_room")

in a case like this:

  def initialize(self):
    self.listen_state(self.motion, "switch.livingroom")
    self.listen_state(self.motion, "switch.diningroom")
    self.listen_state(self.motion, "switch.hallway")
  
  def motion(self, entity, attribute, old, new, kwargs):
    if (entity=="switch.hallway"):
      self.turn_on("switch_bathroom")
    else:
      self.turn_off("switchbathroom")

so in this case if livingroom OR diningroom OR hallway is toggled an action is taken
if someone is in the hallway the bathroomlights go on
if someone is in the diningroom or livingroom the bathroomlights go out.

@justyns - that is how I would have done it too. I will put some thought into a more concise way but however it looks it will end up doing the same as you did under the covers - it’s a good idea though. It is also an example of something I mentioned in the blog - you can pretty much do anything with AppDaemon already, but there is scope for making things easier for sure.

@jbardi - Constraints are just a convenience. As @ReneTode explained above, you can check for state on any entity and use it for conditions using the get_state() call. For instance, to check if a light is on:

if self.get_state("light.bedroom") == "on":
  do something ...

To use this in an automation you would simply perform this and other checks in the first lines of the callback to determine if you wanted to do anything. You have all the power of Python here to set the conditions and you can use AND/OR in any combination, nested to any degree using Python If/Else which I think is a lot easier to understand and more powerful than nested YAML.

What I found was that some tests like this were so common - time of day, use of an input_boolean to activate or deactivate, whether or not anyone was home etc. that I added constraints to save on lines of code to check them explicitly but you don’t have to use them if you need more complex logic.

You can think of the callback as the trigger, and the python checks on state as the conditions, and constraints as a built-in simplified type of condition that will save you coding if it matches what you want to do.

Also, this piece is wrong (it was a typo in the blog post so my bad) - the signature for state callbacks should be:

garage_closed(self, **kwargs):

I think I fixed it in the docs but I’ll check when I get home. In this case it doesn’t probably doesn’t matter because AppDaemon will never supply additional positional args but just wanted to let you know.

Andrew, 1 question:

when i was looking at the device_tracker parts, i saw that IP adress is used in the code.
do you know if there is an easy way to get the IP adress out off HA with apps?

Hi -

Not sure what you mean by “IP address is used in the code” ? Are you talking about IP addresses used by the trackers or something else?

in the known devices, devices are only listed by name and MAC.
but if i look at the pycode from nmap i see that devices are searched by IP.

and this part tells me that the IP from a device must be known to HA:

out off nmap_tracker.py

            last_results.append(Device(mac.upper(), name, ipv4, now))

i cant find the part where things are written to the knowndevices yaml, but then i find it Always hard to understand code from other people when it is splitt up in lotts off small part.

so i thought that maybe there would be an easy way to get the IP out off HA with apps.

Awesome, thanks for the explanation… I have to divorce my mind from the standard trigger/condition/action layout of HA YAML and realize I have all of Python at my disposal… do’h :smiley:

2 Likes

This is specific to the NMAP device tracker and not part of the state machine of HA, you can prove this by grepping through the logfile and looking for a specific IP address within a state change message. (Caveat - I don’t use NMAP so I might be wrong, in which case you can prove me wrong with the same technique!)

The basic principle here is that no matter what is happening under the covers, device trackers have a state of “home”, “not_home” or a specific location, it doesn’t matter how that works under the covers it doesn’t make it to Home Assistant’s internal state.

What use did you have in mind for the IP address?

I already searched at different places for IP adress, without luck, so youre probably right.
with a registered ip adress it would be easy to check with which router a device is connected.
i dont want an exact pinpoint in the house but it would be nice to know in which part off the house our devices are at a specific time.
i know that it is possible to work around it, but i was hoping on a easy way around, without rewriting parts or making changes to devices :wink:

Hi,

First I would like to say THANK YOU! Like you my HA restarts take way too long to settle out. Having the ability to create and modify automations and scripts on the fly is awesome!

Now for the issue I am having. When I set HA up to run without SSL AppDaemon runs fine. After adding my SSL back into HA AppDaemon will not start. I am assuming that HA_Key is my HA password and not the path to my SSL_Key that is set in the config.yaml file. Is there an environment variable or something that I need to set in order to use a self signed certificate? I had to do some hoop jumping with HomeBridge in order to get it running with SSL and thought maybe I might have to do something similar with AppDaemon. Suggestions?

@Keith
I ran into a similar issue, and noticed the errors about not accepting the SSL cert were being swallowed up. I’m using let’s encrypt for a real certificate, so I just added t he hostname to my /etc/hosts file and used it instead of the hass ip.

Unfortunately I am visually impaired and am not able to get LetsEncrypt working with my text to speech software. Wish they had a GUI interface that worked on the Mac instead of the horrible CLI interface. Anyway, thats why I chose to generate one using open-ssl. Well that and the open-ssl cert is good for a year instead of 90 days.

I am not clear on what you did with your hosts file in regard to SSL. Do I need to add my internal IP address and associate it with my domain name?

Thanks.

Yes, the problem is that the HTTP Library won;t let you make an SSL connection if the URL you are connecting to doesn’t match the one in the cert. So, if you add the full host name in your hosts file and map it to the IP it should work OK.

This is an unfortunate side effect of me not wanting to SPAM the log with errors when HASS restarts - I’ll take another look and see if I can give better error info for other conditions.

1 Like

i get an unexpected error when i’m trying thigs.

    testtijd = parse_time("sunrise - 01:00:00")
NameError: name 'parse_time' is not defined

is that something which hangs together with the parts i blended out or is there a failure somewhere?

edit:
this one also:

 if now_is_between("sunset - 01:00:00", "sunrise"):
NameError: name 'now_is_between' is not defined

They both need ‘self.’ In front of them.

1 Like

i could have thought about that myself :wink:

but in the API there is no self :wink:

It’s part of the way Python objects work so I was in 2 minds if I should put t in or not …

i think it is best to choose 1 way.

you have used self. on a lot off places in the API
if you then dont put it there at some place it is expected that it isnt needed there (or at least i think in that way :wink: )

i now tried out to use datetime just like you have it in the API.
i guess i have to import it? because just using the code you have in the API gives an error.

Yes, you need to import any additional modules you need to use, just as in a regular Python program. Let me know if/when you find examples that don’t work and I will correct them.

1 Like