appdaemon 4.4.2__tar.gz → 4.5.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {appdaemon-4.4.2/appdaemon.egg-info → appdaemon-4.5.1}/PKG-INFO +39 -7
- {appdaemon-4.4.2 → appdaemon-4.5.1}/README.md +1 -1
- {appdaemon-4.4.2 → appdaemon-4.5.1}/README.rst +1 -1
- appdaemon-4.5.1/appdaemon/__init__.py +7 -0
- appdaemon-4.5.1/appdaemon/__main__.py +405 -0
- appdaemon-4.5.1/appdaemon/adapi.py +3884 -0
- appdaemon-4.5.1/appdaemon/adbase.py +182 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/admin.py +6 -3
- appdaemon-4.5.1/appdaemon/admin_loop.py +36 -0
- appdaemon-4.5.1/appdaemon/app_management.py +1333 -0
- appdaemon-4.5.1/appdaemon/appdaemon.py +377 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/default/variables.yaml +1 -1
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/glassic/variables.yaml +1 -1
- appdaemon-4.5.1/appdaemon/assets/css/materialdesignicons.min.css +3 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/obsidian/variables.yaml +1 -1
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/simplyred/variables.yaml +1 -1
- appdaemon-4.4.2/appdaemon/assets/fonts/materialdesignicons-webfont.ttf → appdaemon-4.5.1/appdaemon/assets/fonts/materialdesignicons-webfont.eot +0 -0
- appdaemon-4.4.2/appdaemon/assets/fonts/materialdesignicons-webfont.eot → appdaemon-4.5.1/appdaemon/assets/fonts/materialdesignicons-webfont.ttf +0 -0
- appdaemon-4.5.1/appdaemon/assets/fonts/materialdesignicons-webfont.woff +0 -0
- appdaemon-4.5.1/appdaemon/assets/fonts/materialdesignicons-webfont.woff2 +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/callbacks.py +21 -3
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/dashboard.py +10 -9
- appdaemon-4.5.1/appdaemon/dependency.py +248 -0
- appdaemon-4.5.1/appdaemon/dependency_manager.py +211 -0
- appdaemon-4.5.1/appdaemon/entity.py +623 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/events.py +119 -97
- appdaemon-4.5.1/appdaemon/exceptions.py +503 -0
- appdaemon-4.5.1/appdaemon/futures.py +47 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/http.py +75 -66
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/logging.py +156 -137
- {appdaemon-4.4.2/appdaemon → appdaemon-4.5.1/appdaemon/models}/__init__.py +0 -0
- appdaemon-4.5.1/appdaemon/models/config/__init__.py +18 -0
- appdaemon-4.5.1/appdaemon/models/config/app.py +219 -0
- appdaemon-4.5.1/appdaemon/models/config/appdaemon.py +178 -0
- appdaemon-4.5.1/appdaemon/models/config/common.py +35 -0
- appdaemon-4.5.1/appdaemon/models/config/dashboard.py +14 -0
- appdaemon-4.5.1/appdaemon/models/config/http.py +15 -0
- appdaemon-4.5.1/appdaemon/models/config/log.py +36 -0
- appdaemon-4.5.1/appdaemon/models/config/misc.py +49 -0
- appdaemon-4.5.1/appdaemon/models/config/plugin.py +226 -0
- appdaemon-4.5.1/appdaemon/models/config/sequence.py +103 -0
- appdaemon-4.5.1/appdaemon/models/config/yaml.py +50 -0
- appdaemon-4.5.1/appdaemon/models/internal/__init__.py +2 -0
- appdaemon-4.5.1/appdaemon/models/internal/app_management.py +140 -0
- appdaemon-4.5.1/appdaemon/models/internal/file_check.py +103 -0
- appdaemon-4.5.1/appdaemon/models/internal/plugin.py +21 -0
- appdaemon-4.5.1/appdaemon/models/internal/state.py +27 -0
- appdaemon-4.5.1/appdaemon/models/internal/threading.py +32 -0
- appdaemon-4.5.1/appdaemon/models/notification/__init__.py +4 -0
- appdaemon-4.5.1/appdaemon/models/notification/android.py +94 -0
- appdaemon-4.5.1/appdaemon/models/notification/base.py +37 -0
- appdaemon-4.5.1/appdaemon/models/notification/iOS.py +48 -0
- appdaemon-4.5.1/appdaemon/plugin_management.py +493 -0
- appdaemon-4.5.1/appdaemon/plugins/dummy/dummyapi.py +37 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/plugins/dummy/dummyplugin.py +4 -16
- appdaemon-4.5.1/appdaemon/plugins/hass/__init__.py +4 -0
- appdaemon-4.5.1/appdaemon/plugins/hass/exceptions.py +30 -0
- appdaemon-4.5.1/appdaemon/plugins/hass/hassapi.py +1531 -0
- appdaemon-4.5.1/appdaemon/plugins/hass/hassplugin.py +900 -0
- appdaemon-4.5.1/appdaemon/plugins/hass/models.py +71 -0
- appdaemon-4.5.1/appdaemon/plugins/hass/notifications.py +164 -0
- appdaemon-4.5.1/appdaemon/plugins/hass/utils.py +46 -0
- appdaemon-4.5.1/appdaemon/plugins/mqtt/__init__.py +4 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/plugins/mqtt/mqttapi.py +68 -50
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/plugins/mqtt/mqttplugin.py +143 -211
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/scheduler.py +310 -327
- appdaemon-4.5.1/appdaemon/sequences.py +199 -0
- appdaemon-4.5.1/appdaemon/services.py +270 -0
- appdaemon-4.5.1/appdaemon/state.py +845 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/stream/adstream.py +6 -1
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/thread_async.py +10 -7
- appdaemon-4.4.2/appdaemon/threading.py → appdaemon-4.5.1/appdaemon/threads.py +361 -386
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/utility_loop.py +69 -54
- appdaemon-4.5.1/appdaemon/utils.py +1115 -0
- appdaemon-4.5.1/appdaemon/version.py +2 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basefan/basefan.js +1 -1
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseicon/baseicon.js +1 -1
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseweather/baseweather.js +2 -2
- appdaemon-4.5.1/appdaemon/widgets/pirateweather.yaml +64 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1/appdaemon.egg-info}/PKG-INFO +39 -7
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon.egg-info/SOURCES.txt +31 -1
- appdaemon-4.5.1/appdaemon.egg-info/requires.txt +42 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon.egg-info/top_level.txt +1 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/ObjectTracker/general_app_functions.py +4 -8
- {appdaemon-4.4.2 → appdaemon-4.5.1}/pyproject.toml +74 -45
- appdaemon-4.4.2/appdaemon/__main__.py +0 -421
- appdaemon-4.4.2/appdaemon/adapi.py +0 -3273
- appdaemon-4.4.2/appdaemon/adbase.py +0 -136
- appdaemon-4.4.2/appdaemon/admin_loop.py +0 -21
- appdaemon-4.4.2/appdaemon/app_management.py +0 -1510
- appdaemon-4.4.2/appdaemon/appdaemon.py +0 -298
- appdaemon-4.4.2/appdaemon/assets/css/materialdesignicons.min.css +0 -3
- appdaemon-4.4.2/appdaemon/assets/fonts/materialdesignicons-webfont.woff +0 -0
- appdaemon-4.4.2/appdaemon/assets/fonts/materialdesignicons-webfont.woff2 +0 -0
- appdaemon-4.4.2/appdaemon/entity.py +0 -596
- appdaemon-4.4.2/appdaemon/exceptions.py +0 -32
- appdaemon-4.4.2/appdaemon/futures.py +0 -38
- appdaemon-4.4.2/appdaemon/plugin_management.py +0 -415
- appdaemon-4.4.2/appdaemon/plugins/dummy/dummyapi.py +0 -30
- appdaemon-4.4.2/appdaemon/plugins/hass/hassapi.py +0 -743
- appdaemon-4.4.2/appdaemon/plugins/hass/hassplugin.py +0 -896
- appdaemon-4.4.2/appdaemon/sequences.py +0 -246
- appdaemon-4.4.2/appdaemon/services.py +0 -249
- appdaemon-4.4.2/appdaemon/state.py +0 -723
- appdaemon-4.4.2/appdaemon/stream/__init__.py +0 -0
- appdaemon-4.4.2/appdaemon/utils.py +0 -758
- appdaemon-4.4.2/appdaemon/version.py +0 -1
- appdaemon-4.4.2/appdaemon.egg-info/requires.txt +0 -41
- {appdaemon-4.4.2 → appdaemon-4.5.1}/LICENSE.md +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/MANIFEST.in +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/aui/appdaemon.png +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/aui/css/app.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/aui/css/chunk-vendors.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/aui/favicon.ico +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/aui/index.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/aui/js/app.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/aui/js/app.js.map +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/aui/js/chunk-vendors.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/aui/js/chunk-vendors.js.map +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/all.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/climacons-font.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/default/dashboard.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/fontawesome.min.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/fonts.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/glassic/dashboard.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/glassic/img/carbon1.jpg +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/glassic/img/carbon2.jpg +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/glassic/img/carbon3.jpg +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/glassic/img/carbon4.jpg +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/glassic/img/glassic_bg.jpg +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/images/ui-icons_444444_256x240.png +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/images/ui-icons_555555_256x240.png +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/images/ui-icons_777620_256x240.png +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/images/ui-icons_777777_256x240.png +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/images/ui-icons_cc0000_256x240.png +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/images/ui-icons_ffffff_256x240.png +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/jquery-ui.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/jquery.gridster.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/main.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/non_dashboard.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/obsidian/dashboard.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/obsidian/img/obsidian_bg.jpg +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/obsidian/img/obsidian_w_bg.jpg +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/obsidian/img/obsidianbg.jpg +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/obsidian/img/widgetbg.jpg +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/rickshaw.min.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/simplyred/dashboard.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/simplyred/img/goldgradient.png +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/simplyred/img/goldtexture.jpg +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/simplyred/js/timer.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/v4-shims.min.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/zen/dashboard.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/zen/img/zen_bg.jpg +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/zen/img/zen_bg2.jpg +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/zen/img/zen_weatherbg.jpg +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/css/zen/variables.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/fonts/TickingTimebombBB.ttf +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/fonts/climacons-webfont.eot +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/fonts/climacons-webfont.svg +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/fonts/climacons-webfont.ttf +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/fonts/climacons-webfont.woff +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/fonts/digital-7-mono.eot +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/fonts/digital-7-mono.ttf +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/fonts/repetition.ttf +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/images/Blank.gif +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/images/android-chrome-192x192.png +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/images/android-chrome-512x512.png +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/images/apple-touch-icon.png +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/images/browserconfig.xml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/images/favicon-16x16.png +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/images/favicon-32x32.png +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/images/favicon.ico +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/images/manifest.json +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/images/mstile-144x144.png +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/images/mstile-150x150.png +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/images/mstile-310x150.png +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/images/mstile-310x310.png +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/images/mstile-70x70.png +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/javascript/admin.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/javascript/d3.layout.min.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/javascript/d3.min.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/javascript/dashboard.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/javascript/gauge.min.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/javascript/jquery-3.1.1.min.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/javascript/jquery-ui.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/javascript/jquery.gridster.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/javascript/justgage.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/javascript/knockout-3.4.1.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/javascript/list.min.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/javascript/plotly.min.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/javascript/raphael-2.1.4.min.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/javascript/reconnecting-websocket.min.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/javascript/rickshaw.min.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/javascript/socket.io.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/javascript/sockjs.min.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/javascript/stream.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/templates/admin.jinja2 +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/templates/body_include.jinja2 +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/templates/dashboard.jinja2 +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/templates/dashinit.jinja2 +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/templates/error.jinja2 +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/templates/head_include.jinja2 +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/templates/list.jinja2 +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/templates/logon.jinja2 +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/webfonts/fa-brands-400.eot +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/webfonts/fa-brands-400.svg +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/webfonts/fa-brands-400.ttf +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/webfonts/fa-brands-400.woff +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/webfonts/fa-brands-400.woff2 +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/webfonts/fa-regular-400.eot +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/webfonts/fa-regular-400.svg +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/webfonts/fa-regular-400.ttf +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/webfonts/fa-regular-400.woff +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/webfonts/fa-regular-400.woff2 +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/webfonts/fa-solid-900.eot +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/webfonts/fa-solid-900.svg +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/webfonts/fa-solid-900.ttf +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/webfonts/fa-solid-900.woff +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/assets/webfonts/fa-solid-900.woff2 +0 -0
- /appdaemon-4.4.2/appdaemon/plugins/__init__.py → /appdaemon-4.5.1/appdaemon/models/config/api.py +0 -0
- {appdaemon-4.4.2/appdaemon/plugins/hass → appdaemon-4.5.1/appdaemon/plugins}/__init__.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/pyversions.py +0 -0
- {appdaemon-4.4.2/appdaemon/plugins/mqtt → appdaemon-4.5.1/appdaemon/stream}/__init__.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/stream/socketio_handler.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/stream/sockjs_handler.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/stream/ws_handler.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/AdminLog.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/AdminSummary.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/AdminTable.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/alarm.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basealarm/basealarm.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basealarm/basealarm.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basealarm/basealarm.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basecamera/basecamera.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basecamera/basecamera.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basecamera/basecamera.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseclimate/baseclimate.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseclimate/baseclimate.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseclimate/baseclimate.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseclock/baseclock.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseclock/baseclock.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseclock/baseclock.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basedatetime/basedatetime.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basedatetime/basedatetime.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basedatetime/basedatetime.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basedisplay/basedisplay.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basedisplay/basedisplay.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basedisplay/basedisplay.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseentitypicture/baseentitypicture.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseentitypicture/baseentitypicture.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseentitypicture/baseentitypicture.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseerror/baseerror.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseerror/baseerror.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseerror/baseerror.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basefan/basefan.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basefan/basefan.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basegauge/basegauge.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basegauge/basegauge.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basegauge/basegauge.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseheater/baseheater.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseheater/baseheater.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseheater/baseheater.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseicon/baseicon.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseicon/baseicon.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseiframe/baseiframe.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseiframe/baseiframe.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseiframe/baseiframe.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseinputnumber/baseinputnumber.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseinputnumber/baseinputnumber.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseinputnumber/baseinputnumber.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basejavascript/basejavascript.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basejavascript/basejavascript.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basejavascript/basejavascript.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baselight/baselight.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baselight/baselight.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baselight/baselight.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basemedia/basemedia.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basemedia/basemedia.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basemedia/basemedia.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseradial/baseradial.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseradial/baseradial.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseradial/baseradial.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baserss/baserss.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baserss/baserss.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baserss/baserss.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseselect/baseselect.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseselect/baseselect.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseselect/baseselect.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseslider/baseslider.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseslider/baseslider.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseslider/baseslider.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseswitch/baseswitch.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseswitch/baseswitch.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseswitch/baseswitch.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basetemperature/basetemperature.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basetemperature/basetemperature.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basetemperature/basetemperature.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basetext/basetext.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basetext/basetext.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/basetext/basetext.js +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseweather/baseweather.css +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/baseweather/baseweather.html +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/binary_sensor.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/camera.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/climate.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/clock.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/cover.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/device_tracker.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/entitypicture.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/fan.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/gauge.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/group.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/heater.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/icon.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/iframe.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/input_boolean.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/input_datetime.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/input_number.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/input_select.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/input_slider.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/input_text.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/javascript.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/label.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/light.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/lock.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/london_underground.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/media_player.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/mode.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/navigate.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/person.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/radial.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/reload.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/rss.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/scene.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/script.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/sensor.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/sequence.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/switch.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/temperature.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/text_sensor.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/weather.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon/widgets/weather_summary.yaml +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon.egg-info/dependency_links.txt +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/appdaemon.egg-info/entry_points.txt +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/apps/hello.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/ObjectTracker/objectcontrole.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/alexa.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/battery.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/bysykkel.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/commute.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/dark_day.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/door_notification.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/eventCache.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/eventMonitor.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/globals.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/grandfather.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/hwcheck.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/ical.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/minimote.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/modes.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/momentary_switch.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/motion_lights.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/motion_notification.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/occusim.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/outside_lights.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/presence.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/ruter.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/secure.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/sensor_notification.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/sensor_notify.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/sequence.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/smart_heat.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/sound.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/switch_reset.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/conf/example_apps/yr.py +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/setup.cfg +0 -0
- {appdaemon-4.4.2 → appdaemon-4.5.1}/tests/test_main.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: appdaemon
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.5.1
|
|
4
4
|
Summary: Apps for the Home Assistant home automation package.
|
|
5
5
|
Author-email: Andrew I Cockburn <appdaemon@acockburn.com>
|
|
6
6
|
License: Apache License
|
|
@@ -206,16 +206,48 @@ Classifier: Development Status :: 5 - Production/Stable
|
|
|
206
206
|
Classifier: Intended Audience :: Developers
|
|
207
207
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
208
208
|
Classifier: Natural Language :: English
|
|
209
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
210
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
211
209
|
Classifier: Programming Language :: Python :: 3.10
|
|
212
210
|
Classifier: Programming Language :: Python :: 3.11
|
|
211
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
213
212
|
Classifier: Topic :: Home Automation
|
|
214
|
-
Requires-Python:
|
|
213
|
+
Requires-Python: <3.13,>=3.10
|
|
215
214
|
Description-Content-Type: text/markdown
|
|
215
|
+
License-File: LICENSE.md
|
|
216
|
+
Requires-Dist: importlib-metadata; python_version < "3.8"
|
|
217
|
+
Requires-Dist: aiohttp<3.12.0,>=3.9.0
|
|
218
|
+
Requires-Dist: aiohttp_jinja2<1.7.0,>=1.5.1
|
|
219
|
+
Requires-Dist: astral~=3.2
|
|
220
|
+
Requires-Dist: bcrypt<4.3.0,>=4.0.1
|
|
221
|
+
Requires-Dist: deepdiff==8.2.0
|
|
222
|
+
Requires-Dist: feedparser~=6.0.10
|
|
223
|
+
Requires-Dist: iso8601<2.2,>=1.1
|
|
224
|
+
Requires-Dist: paho-mqtt<2.2.0,>=1.6.1
|
|
225
|
+
Requires-Dist: pid~=3.0.4
|
|
226
|
+
Requires-Dist: python-dateutil<2.10.0,>=2.8.2
|
|
227
|
+
Requires-Dist: python-socketio<5.12,>=5.5
|
|
228
|
+
Requires-Dist: pytz<2025.2.0,>=2022.7.1
|
|
229
|
+
Requires-Dist: pyyaml~=6.0.1
|
|
230
|
+
Requires-Dist: requests<2.33.0,>=2.28.2
|
|
231
|
+
Requires-Dist: sockjs<0.14,>=0.11
|
|
232
|
+
Requires-Dist: uvloop==0.21.0; sys_platform != "win32"
|
|
233
|
+
Requires-Dist: tomli==2.2.1
|
|
234
|
+
Requires-Dist: tomli_w<1.3,>=1.0
|
|
235
|
+
Requires-Dist: pydantic~=2.10.6
|
|
216
236
|
Provides-Extra: dev
|
|
237
|
+
Requires-Dist: pip-tools<7.5.0,>=6.12.3; extra == "dev"
|
|
238
|
+
Requires-Dist: build<1.3,>=0.10; extra == "dev"
|
|
239
|
+
Requires-Dist: flake8~=7.1.1; extra == "dev"
|
|
240
|
+
Requires-Dist: black<25.2,>=23.1; extra == "dev"
|
|
241
|
+
Requires-Dist: pre-commit<3.9.0,>=3.1.1; python_version > "3.7" and extra == "dev"
|
|
242
|
+
Requires-Dist: pytest<8.4.0,>=7.2.1; extra == "dev"
|
|
243
|
+
Requires-Dist: ruff<0.7.0,>=0.0.261; extra == "dev"
|
|
244
|
+
Requires-Dist: codespell>=2.4.1; extra == "dev"
|
|
217
245
|
Provides-Extra: doc
|
|
218
|
-
|
|
246
|
+
Requires-Dist: sphinx-autobuild<2024.10.0,>=2021.3.14; extra == "doc"
|
|
247
|
+
Requires-Dist: sphinx-rtd-theme==3.0.2; extra == "doc"
|
|
248
|
+
Requires-Dist: pygments<2.20,>=2.14; extra == "doc"
|
|
249
|
+
Requires-Dist: myst-parser==4.0.0; extra == "doc"
|
|
250
|
+
Dynamic: license-file
|
|
219
251
|
|
|
220
252
|
# Description
|
|
221
253
|
|
|
@@ -235,7 +267,7 @@ For full instructions on installation and usage check out the [AppDaemon Project
|
|
|
235
267
|
|
|
236
268
|
AppDaemon has reached a very stable point, works reliably and is fairly feature rich at this point
|
|
237
269
|
in its development. For that reason, releases have been slow in recent months. This does not mean that AppDaemon has been abandoned -
|
|
238
|
-
it is used every day by the core developers and has an active discord server [here](https://discord.gg/
|
|
270
|
+
it is used every day by the core developers and has an active discord server [here](https://discord.gg/sgSr79jW5x) - please join us for tips
|
|
239
271
|
and tricks, AppDaemon discussions and general home automation.
|
|
240
272
|
|
|
241
273
|
## Contributing
|
|
@@ -16,7 +16,7 @@ For full instructions on installation and usage check out the [AppDaemon Project
|
|
|
16
16
|
|
|
17
17
|
AppDaemon has reached a very stable point, works reliably and is fairly feature rich at this point
|
|
18
18
|
in its development. For that reason, releases have been slow in recent months. This does not mean that AppDaemon has been abandoned -
|
|
19
|
-
it is used every day by the core developers and has an active discord server [here](https://discord.gg/
|
|
19
|
+
it is used every day by the core developers and has an active discord server [here](https://discord.gg/sgSr79jW5x) - please join us for tips
|
|
20
20
|
and tricks, AppDaemon discussions and general home automation.
|
|
21
21
|
|
|
22
22
|
## Contributing
|
|
@@ -11,7 +11,7 @@ suitable for wall mounted tablets.
|
|
|
11
11
|
|
|
12
12
|
AppDaemon has reached a very stable point, works reliably and is fairly feature rich at this point
|
|
13
13
|
in its development. For that reason, releases have been slow in recent months. This does not mean that AppDaemon has been abandoned -
|
|
14
|
-
it is used every day by the core developers and has an active discord server `here <https://discord.gg/
|
|
14
|
+
it is used every day by the core developers and has an active discord server `here <https://discord.gg/sgSr79jW5x>`__ - please join us for tips
|
|
15
15
|
and tricks, AppDaemon discussions and general home automation.
|
|
16
16
|
|
|
17
17
|
For full instructions on installation and use check out the `AppDaemon
|
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
|
|
3
|
+
"""AppDaemon main() module.
|
|
4
|
+
|
|
5
|
+
AppDaemon module that contains main() along with argument parsing, instantiation of the AppDaemon and HTTP Objects,
|
|
6
|
+
also creates the loop and kicks everything off
|
|
7
|
+
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
import asyncio
|
|
12
|
+
import functools
|
|
13
|
+
import itertools
|
|
14
|
+
import json
|
|
15
|
+
import logging
|
|
16
|
+
import os
|
|
17
|
+
import signal
|
|
18
|
+
import sys
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
import pytz
|
|
22
|
+
from pydantic import ValidationError
|
|
23
|
+
|
|
24
|
+
import appdaemon.appdaemon as ad
|
|
25
|
+
import appdaemon.utils as utils
|
|
26
|
+
from appdaemon import exceptions as ade
|
|
27
|
+
from appdaemon.app_management import UpdateMode
|
|
28
|
+
from appdaemon.appdaemon import AppDaemon
|
|
29
|
+
from appdaemon.exceptions import StartupAbortedException
|
|
30
|
+
from appdaemon.http import HTTP
|
|
31
|
+
from appdaemon.logging import Logging
|
|
32
|
+
from appdaemon.models.config import AppDaemonConfig
|
|
33
|
+
|
|
34
|
+
from .models.config.yaml import MainConfig
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
import pid
|
|
38
|
+
except ImportError:
|
|
39
|
+
pid = None
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
import uvloop
|
|
43
|
+
except ImportError:
|
|
44
|
+
uvloop = None
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class NoADConfig(Exception):
|
|
48
|
+
pass
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ADMain:
|
|
52
|
+
"""
|
|
53
|
+
Class to encapsulate all main() functionality.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
AD: AppDaemon
|
|
57
|
+
|
|
58
|
+
logging: Logging
|
|
59
|
+
|
|
60
|
+
def __init__(self):
|
|
61
|
+
"""Constructor."""
|
|
62
|
+
|
|
63
|
+
self.logging = None
|
|
64
|
+
self.error = None
|
|
65
|
+
self.diag = None
|
|
66
|
+
self.AD = None
|
|
67
|
+
self.http_object = None
|
|
68
|
+
self.logger = None
|
|
69
|
+
|
|
70
|
+
# noinspection PyUnusedLocal
|
|
71
|
+
def handle_sig(self, signum: int):
|
|
72
|
+
"""Function to handle signals.
|
|
73
|
+
|
|
74
|
+
Signals:
|
|
75
|
+
SIGUSR1 will result in internal info being dumped to the DIAG log
|
|
76
|
+
SIGHUP will force a reload of all apps
|
|
77
|
+
SIGINT and SIGTEM both result in AD shutting down
|
|
78
|
+
"""
|
|
79
|
+
match signum:
|
|
80
|
+
case signal.SIGUSR1:
|
|
81
|
+
self.AD.thread_async.call_async_no_wait(self.AD.sched.dump_schedule)
|
|
82
|
+
self.AD.thread_async.call_async_no_wait(self.AD.callbacks.dump_callbacks)
|
|
83
|
+
self.AD.thread_async.call_async_no_wait(self.AD.threading.dump_threads)
|
|
84
|
+
self.AD.thread_async.call_async_no_wait(self.AD.app_management.dump_objects)
|
|
85
|
+
self.AD.thread_async.call_async_no_wait(self.AD.sched.dump_sun)
|
|
86
|
+
case signal.SIGHUP:
|
|
87
|
+
self.AD.thread_async.call_async_no_wait(self.AD.app_management.check_app_updates, mode=UpdateMode.TERMINATE)
|
|
88
|
+
case signal.SIGINT:
|
|
89
|
+
self.logger.info("Keyboard interrupt")
|
|
90
|
+
self.stop()
|
|
91
|
+
case signal.SIGTERM:
|
|
92
|
+
self.logger.info("SIGTERM Received")
|
|
93
|
+
self.stop()
|
|
94
|
+
# case signal.SIGWINCH:
|
|
95
|
+
# ... # disregard window changes
|
|
96
|
+
# case _:
|
|
97
|
+
# self.logger.error(f'Unhandled signal: {signal.Signals(signum).name}')
|
|
98
|
+
|
|
99
|
+
def stop(self):
|
|
100
|
+
"""Called by the signal handler to shut AD down.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
None.
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
self.logger.info("AppDaemon is shutting down")
|
|
107
|
+
self.AD.stop()
|
|
108
|
+
if self.http_object is not None:
|
|
109
|
+
self.http_object.stop()
|
|
110
|
+
|
|
111
|
+
# noinspection PyBroadException,PyBroadException
|
|
112
|
+
def run(self, ad_config_model: AppDaemonConfig, *args, http):
|
|
113
|
+
"""Start AppDaemon up after initial argument parsing.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
ad_config_model: Config for AppDaemon Object.
|
|
117
|
+
*args: Gets used to create the HTTP object.
|
|
118
|
+
http: Main HTTP config
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
try:
|
|
122
|
+
# if to use uvloop
|
|
123
|
+
if ad_config_model.uvloop and uvloop:
|
|
124
|
+
self.logger.info("Running AD using uvloop")
|
|
125
|
+
uvloop.install()
|
|
126
|
+
|
|
127
|
+
loop: asyncio.BaseEventLoop = asyncio.new_event_loop()
|
|
128
|
+
|
|
129
|
+
# Initialize AppDaemon
|
|
130
|
+
|
|
131
|
+
self.AD = ad.AppDaemon(self.logging, loop, ad_config_model)
|
|
132
|
+
loop.set_exception_handler(functools.partial(ade.exception_handler, self.AD))
|
|
133
|
+
|
|
134
|
+
for sig in signal.Signals:
|
|
135
|
+
callback = functools.partial(self.handle_sig, sig)
|
|
136
|
+
try:
|
|
137
|
+
loop.add_signal_handler(sig.value, callback)
|
|
138
|
+
except RuntimeError:
|
|
139
|
+
# This happens for some signals on some operating systems, no problem
|
|
140
|
+
continue
|
|
141
|
+
|
|
142
|
+
# Initialize Dashboard/API/admin
|
|
143
|
+
|
|
144
|
+
if http is not None and any(arg is not None for arg in args):
|
|
145
|
+
self.logger.info("Initializing HTTP")
|
|
146
|
+
self.http_object = HTTP(self.AD, *args, http)
|
|
147
|
+
self.AD.register_http(self.http_object)
|
|
148
|
+
else:
|
|
149
|
+
if http is not None:
|
|
150
|
+
self.logger.info("HTTP configured but no consumers are configured - disabling")
|
|
151
|
+
else:
|
|
152
|
+
self.logger.info("HTTP is disabled")
|
|
153
|
+
|
|
154
|
+
self.logger.debug("Start Main Loop")
|
|
155
|
+
|
|
156
|
+
pending = asyncio.all_tasks(loop)
|
|
157
|
+
loop.run_until_complete(asyncio.gather(*pending))
|
|
158
|
+
|
|
159
|
+
#
|
|
160
|
+
# Now we are shutting down - perform any necessary cleanup
|
|
161
|
+
#
|
|
162
|
+
|
|
163
|
+
self.AD.terminate()
|
|
164
|
+
|
|
165
|
+
self.logger.info("AppDaemon is stopped.")
|
|
166
|
+
except ValidationError as e:
|
|
167
|
+
logging.getLogger().exception(e)
|
|
168
|
+
except StartupAbortedException as e:
|
|
169
|
+
# We got an unrecoverable error during startup so print it out and quit
|
|
170
|
+
self.logger.error(f"AppDaemon terminated with errors: {e}")
|
|
171
|
+
except ade.AppDaemonException as e:
|
|
172
|
+
ade.user_exception_block(self.logger, e, self.AD.app_dir)
|
|
173
|
+
except Exception:
|
|
174
|
+
self.logger.warning("-" * 60)
|
|
175
|
+
self.logger.warning("Unexpected error during run()")
|
|
176
|
+
self.logger.warning("-" * 60, exc_info=True)
|
|
177
|
+
self.logger.warning("-" * 60)
|
|
178
|
+
|
|
179
|
+
self.logger.debug("End Loop")
|
|
180
|
+
|
|
181
|
+
self.logger.info("AppDaemon Exited")
|
|
182
|
+
|
|
183
|
+
# noinspection PyBroadException
|
|
184
|
+
def main(self): # noqa: C901
|
|
185
|
+
"""Initial AppDaemon entry point.
|
|
186
|
+
|
|
187
|
+
Parse command line arguments, load configuration, set up logging.
|
|
188
|
+
|
|
189
|
+
"""
|
|
190
|
+
|
|
191
|
+
# Get command line args
|
|
192
|
+
|
|
193
|
+
parser = argparse.ArgumentParser()
|
|
194
|
+
|
|
195
|
+
parser.add_argument(
|
|
196
|
+
"-c",
|
|
197
|
+
"--config",
|
|
198
|
+
help="full path to config directory",
|
|
199
|
+
type=str,
|
|
200
|
+
)
|
|
201
|
+
parser.add_argument("-p", "--pidfile", help="full path to PID File", default=None)
|
|
202
|
+
parser.add_argument(
|
|
203
|
+
"-t",
|
|
204
|
+
"--timewarp",
|
|
205
|
+
help="speed that the scheduler will work at for time travel",
|
|
206
|
+
type=float,
|
|
207
|
+
)
|
|
208
|
+
parser.add_argument(
|
|
209
|
+
"-s",
|
|
210
|
+
"--starttime",
|
|
211
|
+
help="start time for scheduler <YYYY-MM-DD HH:MM:SS|YYYY-MM-DD#HH:MM:SS>",
|
|
212
|
+
type=str,
|
|
213
|
+
)
|
|
214
|
+
parser.add_argument(
|
|
215
|
+
"-e",
|
|
216
|
+
"--endtime",
|
|
217
|
+
help="end time for scheduler <YYYY-MM-DD HH:MM:SS|YYYY-MM-DD#HH:MM:SS>",
|
|
218
|
+
type=str,
|
|
219
|
+
)
|
|
220
|
+
parser.add_argument(
|
|
221
|
+
"-C",
|
|
222
|
+
"--configfile",
|
|
223
|
+
help="name for config file",
|
|
224
|
+
type=str,
|
|
225
|
+
)
|
|
226
|
+
parser.add_argument(
|
|
227
|
+
"-D",
|
|
228
|
+
"--debug",
|
|
229
|
+
help="global debug level",
|
|
230
|
+
default="INFO",
|
|
231
|
+
choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
|
|
232
|
+
)
|
|
233
|
+
parser.add_argument("-m", "--moduledebug", nargs=2, action="append")
|
|
234
|
+
parser.add_argument("-v", "--version", action="version", version="%(prog)s " + utils.__version__)
|
|
235
|
+
parser.add_argument("--profiledash", help=argparse.SUPPRESS, action="store_true")
|
|
236
|
+
parser.add_argument("--write_toml", help="use TOML for creating new app configuration files", action="store_true")
|
|
237
|
+
# TODO Implement --write_toml
|
|
238
|
+
parser.add_argument("--toml", help="Deprecated", action="store_true")
|
|
239
|
+
|
|
240
|
+
args = parser.parse_args()
|
|
241
|
+
|
|
242
|
+
pidfile = args.pidfile
|
|
243
|
+
|
|
244
|
+
default_config_files = [
|
|
245
|
+
"appdaemon.toml",
|
|
246
|
+
"appdaemon.yaml",
|
|
247
|
+
]
|
|
248
|
+
default_config_paths = [Path("~/.homeassistant").expanduser(), Path("/etc/appdaemon"), Path("/conf")]
|
|
249
|
+
|
|
250
|
+
try:
|
|
251
|
+
if args.configfile is not None:
|
|
252
|
+
config_file = Path(args.configfile).resolve()
|
|
253
|
+
if args.config is not None:
|
|
254
|
+
config_dir = Path(args.config).resolve()
|
|
255
|
+
else:
|
|
256
|
+
config_dir = config_file.parent
|
|
257
|
+
else:
|
|
258
|
+
if args.config is not None:
|
|
259
|
+
config_dir = Path(args.config).resolve()
|
|
260
|
+
for file in default_config_files:
|
|
261
|
+
if (config_file := (config_dir / file)).exists():
|
|
262
|
+
break
|
|
263
|
+
else:
|
|
264
|
+
raise NoADConfig(f"{config_file} not found")
|
|
265
|
+
else:
|
|
266
|
+
all_default_config_paths = itertools.product(default_config_files, default_config_paths)
|
|
267
|
+
for file in all_default_config_paths:
|
|
268
|
+
dir = file[1]
|
|
269
|
+
final_path = dir / file[0]
|
|
270
|
+
if (config_file := final_path).exists():
|
|
271
|
+
break
|
|
272
|
+
else:
|
|
273
|
+
raise NoADConfig(f"No valid configuration file found in default locations: {[str(d) for d in default_config_paths]}")
|
|
274
|
+
|
|
275
|
+
assert config_file.exists(), f"{config_file} does not exist"
|
|
276
|
+
assert os.access(config_file, os.R_OK), f"{config_file} is not readable"
|
|
277
|
+
except (AssertionError, NoADConfig) as e:
|
|
278
|
+
print(f"FATAL: Error accessing configuration: {e}")
|
|
279
|
+
sys.exit(1)
|
|
280
|
+
|
|
281
|
+
try:
|
|
282
|
+
config = utils.read_config_file(config_file)
|
|
283
|
+
config = {
|
|
284
|
+
k: v if v is not None else {}
|
|
285
|
+
for k, v in config.items()
|
|
286
|
+
} # fmt: skip
|
|
287
|
+
|
|
288
|
+
ad_kwargs = config["appdaemon"]
|
|
289
|
+
|
|
290
|
+
ad_kwargs["config_dir"] = config_dir
|
|
291
|
+
ad_kwargs["config_file"] = config_file
|
|
292
|
+
ad_kwargs["write_toml"] = args.write_toml
|
|
293
|
+
|
|
294
|
+
if args.timewarp:
|
|
295
|
+
ad_kwargs["timewarp"] = args.timewarp
|
|
296
|
+
if args.starttime:
|
|
297
|
+
ad_kwargs["starttime"] = args.starttime
|
|
298
|
+
if args.endtime:
|
|
299
|
+
ad_kwargs["endtime"] = args.endtime
|
|
300
|
+
|
|
301
|
+
ad_kwargs["stop_function"] = self.stop
|
|
302
|
+
ad_kwargs["loglevel"] = args.debug
|
|
303
|
+
|
|
304
|
+
if args.moduledebug is not None:
|
|
305
|
+
module_debug_cli = {arg[0]: arg[1] for arg in args.moduledebug}
|
|
306
|
+
else:
|
|
307
|
+
module_debug_cli = {}
|
|
308
|
+
|
|
309
|
+
if isinstance(ad_kwargs.get("module_debug"), dict):
|
|
310
|
+
ad_kwargs["module_debug"] |= module_debug_cli
|
|
311
|
+
else:
|
|
312
|
+
ad_kwargs["module_debug"] = module_debug_cli
|
|
313
|
+
|
|
314
|
+
if isinstance((hadashboard := config.get("hadashboard")), dict):
|
|
315
|
+
hadashboard["config_dir"] = config_dir
|
|
316
|
+
hadashboard["config_file"] = config_file
|
|
317
|
+
hadashboard["dashboard"] = True
|
|
318
|
+
hadashboard["profile_dashboard"] = args.profiledash
|
|
319
|
+
|
|
320
|
+
model = MainConfig.model_validate(config)
|
|
321
|
+
|
|
322
|
+
if args.debug.upper() == "DEBUG":
|
|
323
|
+
# need to dump as python types or serializing the timezone object will fail
|
|
324
|
+
model_json = model.model_dump(mode='python', by_alias=True)
|
|
325
|
+
print(json.dumps(model_json, indent=4, default=str, sort_keys=True))
|
|
326
|
+
except ValidationError as e:
|
|
327
|
+
print(f"Configuration error in: {config_file}")
|
|
328
|
+
print(e)
|
|
329
|
+
sys.exit(1)
|
|
330
|
+
except ade.ConfigReadFailure as e:
|
|
331
|
+
ade.user_exception_block(logging.getLogger(), e, config_dir, "Reading AppDaemon configuration")
|
|
332
|
+
sys.exit(1)
|
|
333
|
+
except Exception as e:
|
|
334
|
+
print(f"Unexpected error loading config file: {config_file}")
|
|
335
|
+
print(e)
|
|
336
|
+
sys.exit(1)
|
|
337
|
+
|
|
338
|
+
self.logging = Logging(model.model_dump(mode='python')['logs'], args.debug)
|
|
339
|
+
self.logger = self.logging.get_logger()
|
|
340
|
+
|
|
341
|
+
if "time_zone" in config["appdaemon"]:
|
|
342
|
+
self.logging.set_tz(pytz.timezone(config["appdaemon"]["time_zone"]))
|
|
343
|
+
|
|
344
|
+
# Startup message
|
|
345
|
+
|
|
346
|
+
self.logger.info("-" * 60)
|
|
347
|
+
self.logger.info("AppDaemon Version %s starting", utils.__version__)
|
|
348
|
+
|
|
349
|
+
if utils.__version_comments__ is not None and utils.__version_comments__ != "":
|
|
350
|
+
self.logger.info("Additional version info: %s", utils.__version_comments__)
|
|
351
|
+
|
|
352
|
+
self.logger.info("-" * 60)
|
|
353
|
+
self.logger.info(
|
|
354
|
+
"Python version is %s.%s.%s",
|
|
355
|
+
sys.version_info[0],
|
|
356
|
+
sys.version_info[1],
|
|
357
|
+
sys.version_info[2],
|
|
358
|
+
)
|
|
359
|
+
self.logger.info("Configuration read from: %s", config_file)
|
|
360
|
+
|
|
361
|
+
utils.deprecation_warnings(model.appdaemon, self.logger)
|
|
362
|
+
|
|
363
|
+
self.logging.dump_log_config()
|
|
364
|
+
self.logger.debug("AppDaemon Section: %s", config.get("appdaemon"))
|
|
365
|
+
self.logger.debug("HADashboard Section: %s", config.get("hadashboard"))
|
|
366
|
+
|
|
367
|
+
dump_kwargs = dict(mode='json', by_alias=True, exclude_unset=True)
|
|
368
|
+
|
|
369
|
+
if (hadashboard := model.hadashboard) is not None:
|
|
370
|
+
hadashboard = hadashboard.model_dump(**dump_kwargs)
|
|
371
|
+
|
|
372
|
+
if (http := model.http) is not None:
|
|
373
|
+
http = http.model_dump(**dump_kwargs)
|
|
374
|
+
|
|
375
|
+
run = functools.partial(
|
|
376
|
+
self.run,
|
|
377
|
+
model.appdaemon,
|
|
378
|
+
hadashboard,
|
|
379
|
+
model.old_admin,
|
|
380
|
+
model.admin,
|
|
381
|
+
model.api,
|
|
382
|
+
http=http,
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
if pidfile is not None:
|
|
386
|
+
self.logger.info("Using pidfile: %s", pidfile)
|
|
387
|
+
dir = os.path.dirname(pidfile)
|
|
388
|
+
name = os.path.basename(pidfile)
|
|
389
|
+
try:
|
|
390
|
+
with pid.PidFile(name, dir):
|
|
391
|
+
run()
|
|
392
|
+
except pid.PidFileError:
|
|
393
|
+
self.logger.error("Unable to acquire pidfile - terminating")
|
|
394
|
+
else:
|
|
395
|
+
run()
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
def main():
|
|
399
|
+
"""Called when run from the command line."""
|
|
400
|
+
admain = ADMain()
|
|
401
|
+
admain.main()
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
if __name__ == "__main__":
|
|
405
|
+
main()
|