Announcement - AppDaemon 3.0 beta 1!

TL;DR - AppDaemon 3.0 is here - it’s a beta and it brings a few breaking changes - in particular, python 3.4 is no longer supported. Please read on for more detail.

NOTE: The link to the beta docs is here:

http://appdaemon.readthedocs.io/en/latest/

If you want the old version 2 docs, they can be found here:

http://appdaemon.readthedocs.io/en/stable/

Hi all - it’s been a little while but I am hoping the wait will be worth it - introducing AppDaemon 3.0 beta1!

In addition to some new functionality (listed below), I have completely rewritten and re-architected sections of AppDaemon, and as such I wanted to release this initially as a beta to see if any of you brave souls out there would kick the tires for me and let me know about any issues. As far as I know it is stable and I have been using it myself for many weeks with no issues, but you never know!

The main reasons for the rewrite was twofold:

  1. I want to integrate AppDaemon very closely with Home Assistant, and in order to do that the best possible way, I needed to make some changes to the way the code was structured
  2. I wanted to introduce the concept of pluggable support. In AD 3.0, the HASS support is a plugin, one of potentially many - for instance it is now possible to write an OpenHab plugin for instance and have AD work with both at the same time. (I have no plans to do that , but others might). A more practical outcome of the way the plugin support is implementes is that it is now possible to run AppDaemon connected to multiple HASS instances if you desire.

I have also taken this opportunity to make some changes and some of them are breaking changes. I haven;t done this lightly and I’ll explain below what the changes are, and why I made them - in most cases I have good reason :slight_smile:

Note that not all changes will apply to everyone, some of them are in fairly obscure parts of AppDaemon that few if any people use, however, everyone will have to mnake some changes, so read carefully.

  • AppDaemon no longer supports python 3.4

This is a fairly significant step, and the decision to do this was influenced by HASS’ pending end of support for Python 3.4. There are many technical reasons why this is a good thing, but the bottom line is that you will need to upgrade your pyton version to run HASS anyway, so I took this opportunity to follow suit. AppDaemon 3.0 will remain in beta until HASS drops python 3.4 support entirely.

  • Apps need to change the import and super class

The naming and placement of the imports needed to change to support the plugin architecture, and to make more sense of the naming in a multiple plugin environment. You will need to edit each of your apps and change the top couple of lines from:

import appdaemon.appapi as appapi

class MyClass(appapi.AppDaemon):
...

to:

import appdaemon.plugins.hass.hassapi as hass

class MyClass(hass.Hass):
...

Note, we are changing both the import name, and the superclass.

  • info_listen_state() now returns the namespace in addition to the previous parameters

I introduced namespaces as a way of handling multiple plugins at the same time - the docs have more details, but if you are just using a single HASS instance, as everyone has been doing until now, you can safely ignore namespaces.

  • The “ha_started” event has been renamed to “plugin_started”

If you use this event, the name has been changed. The plugin started event has a parameter called name which gives the name of the plugin that was restarted.

  • RSS Feed parameters have been moved to the hadashboard section

When HADashboard is integrated with HASS, the config for HADashboard needs to be all in one place.

e.g.:

hadashboard:
  dash_url: http://192.168.1.20:5050
  rss_feeds:
    - feed: http://rss.cnn.com/rss/cnn_topstories.rss
      target: news
  rss_update: 300
  • Log directives now have their own section

Logging is a function of the underlying execution code, not specifically AppDaemon (for instance, when integrated with HASS, AppDaemon will use HASS logging. For that Reason, the log directives were pulled out into their own section. The section is optional, and if not specified all the previous defaults will apply.

For example:

log:
  accessfile: /export/hass/appdaemon_test/logs/access.log
  errorfile: /export/hass/appdaemon_test/logs/error.log
  logfile: /export/hass/appdaemon_test/logs/appdaemon.log
  log_generations: 5
  log_size: 1024
appdaemon:
...
  • AppDaemon section renamed to appdaemon, HADashboard section renamed to hadashboard

This was done mainly for consistency, and because the capitals bugged me :wink:

  • Plugins (such as the HASS plugin now have their own parameters under the plugin section of the config file

This comes down to a reorganization of the apps.yaml file to reflect the fact that there are now plugins and there may be more than one of them. Rather than having it’s own section, the HASS plugin is now listed under the appdaemon section, although the arguments remain the same. Here is an example:

appdaemon:
  api_port: 5001
  api_key: !secret appdaemon_key
  threads: 10
  time_zone: GMT+0BST-1,M3.5.0
  plugins:
    HASS:
      type: hass
      ha_key: !secret home_assistant_key
      ha_url: http://192.168.1.20:8123
      #commtype: SSE
  • –commtype command line argument has been moved to the appdaemon.cfg file

This parameter applies specifically to HASS, so it made no sense to have it as a commandline argument. See above for an example.

  • Accessing other Apps arguments is now via the app_config attribute, config retains just the AppDaemon configuration parameters

Required due to the restructuring of the config files.

  • the self.ha_config attribute has been replaced by the self.get_hass_config() api call and now supports namespaces.

This reflects the fact that the yaml files have been reconfigured, and that the config info is now owned by the individual plugins.

  • The !secret directive has been moved to the top level of appdaemon.yaml

The same argument as the logs - not strictly relevant to AppDaemon, more a concern of the execution environment.

  • apps.yaml in the config directory has now been deprecated

One of the new features in 3.0 is that it is now possible to split the apps.yaml into multiple files. You are free to do this in any way you want and place the yaml files with any name, anywhere in the directoty hierarchy under the appdir. Apart from flexibility, another reason for this was to prepare the way for later features around configuration tools and automatic app installs. For now, the only necessary step is to move your apps.yaml file from the config dircetory into the apps directory. If you do not, you will get a warning but everything should still work for now. If you do stick with apps.yaml at in the config directory for now, any other yaml files in the apps directory will be ignored.

  • select_value() has been renamed to set_value() to harmonize with HASS

A minor change just to reflect the recent changes to HASS in this area, e.g input_slider being renamed to input_number and the sevice name changing.

  • It is no longer possible to automatically migrate from the legacy cfg style of config, and support for cfg files has been dropped.

This has been on the cards for a while - if yo uare still using cfg files, use the latest 2.0 version of appdaemon to migrate to yaml style configuration before you upgrade to 3.0.

That’s it for the breaking changes. I intend to keep AppDaemon at beta for a while, and there will be additional functionality added in future beta versions, I have a targeted list and will add new stuff as I go along before I release the GA version.

To install 3.0b1 using pip, you will need to specify the -pre flag to pick up the beta. Docker users I believe should pick up the beta automatically if they are specifying the latest image.

That’s it for now - please report any issues and/or ask questions on this thread so we can keep all of the accumulated wisdom in one place.

Enjoy!

3.0.0b1 (2018-01-12)

Features

  • Refactored pluggable architecture
  • Support for multiple HASS instances
  • Custom constraints
  • Namespaces
  • Path of Secret file can now be specified
  • apps.yaml can now be split across multiple files and directories
  • Apps can now establish loading priorities to influence their loading order
  • IFRAME Refreshes should now be more reliable
  • Added calls to access the underlying logger objects for the main and error logs
  • Add the ability to ignore specific subdirectories under appdir
  • Added error handling for apps that can’t be read or have broken links
  • Added london Underground Widget - contributed by mmmmmmtasty <https://github.com/mmmmmtasty>__
  • Added ability to display sensor attributes - contributed by mmmmmmtasty <https://github.com/mmmmmtasty>__
  • Added Weather Summary Widget - contributed by mmmmmmtasty <https://github.com/mmmmmtasty>__
  • Added Sticky navigation - contributed by Lars Englund <https://github.com/larsenglund>__
  • Added Input Select widget - contributed by Rene Tode <https://github.com/ReneTode>__
  • Redesigned Input Number widget (old is still available as input_slider) - contributed by Rene Tode <https://github.com/ReneTode>__
  • Added Radial widget - contributed by Rene Tode <https://github.com/ReneTode>__
  • Added Temperature widget - contributed by Rene Tode <https://github.com/ReneTode>__
  • Added container style to sensor widget - contributed by Rene Tode <https://github.com/ReneTode>__

Fixes

  • Fixed an issue with the compiled directory not being created early enough

Breaking Changes

  • Apps need to change the import and super class
  • info_listen_state() now returns the namespace in addition to the previous parameters
  • AppDaemon no longer supports python 3.4
  • –commtype command line argument has been moved to the appdaemon.cfg file
  • The “ha_started” event has been renamed to “plugin_started”
  • RSS Feed parameters have been moved to the hadashboard section
  • Log directives now have their own section
  • AppDaemon section renamed to appdaemon, HADashboard section renamed to hadashboard
  • Accessing other Apps arguments is now via the app_config attribute, config retains just the AppDaemon configuration parameters
  • Plugins (such as the HASS plugin now have their own parameters under the plugin section of the config file
  • The !secret directive has been moved to the top level of appdaemon.yaml
  • the self.ha_config attribute has been replaced by the self.get_hass_config() api call and now supports namespaces.
  • apps.yaml in the config directory has now been deprecated
  • select_value() has been renamed to set_value() to harmonize with HASS
  • It is no longer possible to automatically migrate from the legacy cfg style of config, and support for cfg files has been dropped.
16 Likes

o boy this is gonna take me a while.
will pip install it besides the existing AD or will it overwrite the existing AD?

It will overwrite. If you want to run them side by side you need to clone the repo and run it form the command line with:

python3 -m appdaemon.admain -c <config dir>

just cloning/downloading is enough?

It’s how you ran the HADashboard beta if you recall - eventually you should use PIP, but if you want to run both you can do the clone and run it locally

Hi
Looking forward to testing, I get this error right now:

pytz.exceptions.UnknownTimeZoneError: ‘GMT+0BST-1,M3.5.0’

Did you get that in 2.x?

No, this is the first time i see it, But I didnt set that in the config file previous, I copied it from this page
Its working now, but with that line in the config commented out

If you leave it out, it should get the timezone from HASS.

Great, then I just do that, all my automations is now portet and running fine in 3.0. Lookng forward to testing on

1 Like

I put this in the chat, but wanted to put it here in case it got lost.

Given this code: https://hastebin.com/avadoledel.py
print(attribute) prints state to the console. Shouldn’t it be a dict with all of the attributes of the entity, like friendly_name etc?

No, from the docs:

attribute

Name of the attribute the callback was requested for or None.

It’s intended to tell you which attribute changing caused the callback to fire. If you want access to the attributes from within the callback, you can use the get_state() function.

I have Appdaemon starting fine with no errors and my apps loads and are working fine, but when loading a dashboard, I get this error in the log:

http://192.168.1.124:5050/state/Error handling request
Traceback (most recent call last):
File “/home/pi/.local/lib/python3.5/site-packages/aiohttp/web_protocol.py”, line 416, in start
resp = yield from self._request_handler(request)
File “/home/pi/.local/lib/python3.5/site-packages/aiohttp/web.py”, line 323, in _handle
resp = yield from handler(request)
File “/home/pi/.local/lib/python3.5/site-packages/aiohttp/web_urldispatcher.py”, line 141, in handler_wrapper
result = yield from result
File “/usr/local/lib/python3.5/dist-packages/appdaemon/rundash.py”, line 297, in call_service
namespace = data[“namespace”]
File “multidict/_multidict.pyx”, line 140, in multidict._multidict._Base.getitem (multidict/_multidict.c:3313)
File “multidict/_multidict.pyx”, line 135, in multidict._multidict._Base._getone (multidict/_multidict.c:3248)
KeyError: “Key not found: ‘namespace’”

and the frontend cannot retrieve data from appdeamon. Navigating to for instance “http://192.168.1.124:5050/state/sun.sun” returns a 404; not found.

This piece is a red herring, the correct URL now includes a namespace, e.g.:

http://192.168.1.20:5151/state/default/sun.sun

Regarding the rest, can you post the dashboard config and a complete log of the session please?

Solved: Just needed to clear the browser cache on all devices accessing the dashboards.

1 Like

Getting some errors in the docker container:

File "/usr/local/lib/python3.6/site-packages/appdaemon/appdaemon.py", line 221, in __init__
for i in range(self.threads):
TypeError: 'str' object cannot be interpreted as an integer
Traceback (most recent call last):
File "/usr/local/bin/appdaemon", line 11, in <module>
load_entry_point('appdaemon==3.0.0b1', 'console_scripts', 'appdaemon')()
File "/usr/local/lib/python3.6/site-packages/appdaemon/admain.py", line 335, in main
admain.main()
File "/usr/local/lib/python3.6/site-packages/appdaemon/admain.py", line 331, in main
self.run(appdaemon, hadashboard)
File "/usr/local/lib/python3.6/site-packages/appdaemon/admain.py", line 58, in run
self.AD = ad.AppDaemon(self.logger, self.error, loop, **appdaemon)

Try removing any quotes around your threads argument - I’ll make this more robust in the next version.

awesome, that did it. Thanks for the quick reply.

1 Like

Ok, now I’m getting:

2018-01-14 06:14:03.958010 INFO AppDaemon: Loading Plugin HASS using class HassPlugin from module hassplugin
2018-01-14 06:14:04.027626 INFO AppDaemon: HASS: HASS Plugin Initializing
2018-01-14 06:14:04.028041 INFO AppDaemon: HASS: HASS Plugin initialization complete
2018-01-14 06:14:04.028377 INFO Starting Dashboards
2018-01-14 06:14:04.032632 INFO Starting API
2018-01-14 06:14:04.039137 INFO AppDaemon: HASS: Connected to Home Assistant 0.60.1
2018-01-14 06:14:04.082309 INFO AppDaemon: Got initial state from namespace default
2018-01-14 06:14:06.098155 ERROR AppDaemon: Unable to resolve dependencies due to incorrect references
2018-01-14 06:14:06.098645 ERROR AppDaemon: The following modules have unresolved dependencies:
2018-01-14 06:14:20.712719 INFO AppDaemon Version 3.0.0b1 starting
2018-01-14 06:14:20.713041 INFO Configuration read from: /conf/appdaemon.yaml
2018-01-14 06:14:20.713698 INFO AppDaemon: Starting Apps

But I’m not seeing the stack trace for unresolved dependencies or any additional errors.

EDIT: Looks like the stacktrace isn’t outputting to the same log file (or any log file) but I ran it down:

Traceback (most recent call last):
File "/usr/local/bin/appdaemon", line 11, in <module>
load_entry_point('appdaemon==3.0.0b1', 'console_scripts', 'appdaemon')()
File "/usr/local/lib/python3.6/site-packages/appdaemon/admain.py", line 335, in main
admain.main()
File "/usr/local/lib/python3.6/site-packages/appdaemon/admain.py", line 331, in main
self.run(appdaemon, hadashboard)
File "/usr/local/lib/python3.6/site-packages/appdaemon/admain.py", line 78, in run
loop.run_until_complete(asyncio.gather(*pending))
File "/usr/local/lib/python3.6/asyncio/base_events.py", line 467, in run_until_complete
return future.result()
File "/usr/local/lib/python3.6/site-packages/appdaemon/appdaemon.py", line 1157, in utility
await utils.run_in_executor(self.loop, self.executor,self.read_apps, True)
File "/usr/local/lib/python3.6/site-packages/appdaemon/utils.py", line 121, in run_in_executor
response = list(completed)[0].result()
File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/local/lib/python3.6/site-packages/appdaemon/appdaemon.py", line 1628, in read_apps
self.log("ERROR", self.get_module_from_path(mod["file"]))

KeyError: 'file'

I’m thinking this might be an app_dir problem. From the documentation I’m unsure whether it should be in the appdaemon section or the plugins/HASS section… But neither seem to fix it.

Also note, this is enough to kill the docker container.

Looks like you have abn app for which you haven’t specified a file directive