Compare commits
11 Commits
5fca821637
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ba1abec84 | ||
|
|
475bdb9dd9 | ||
|
|
ba043554dc | ||
|
|
bd5c7ee339 | ||
|
|
ce4ede51b1 | ||
|
|
edee038a9f | ||
|
|
7025bcde99 | ||
|
|
ad34a6e919 | ||
|
|
99936f2c85 | ||
|
|
4655b93b64 | ||
|
|
cbd91c8873 |
8
.gitignore
vendored
8
.gitignore
vendored
@@ -4,7 +4,15 @@ __pycache__
|
||||
.python-version
|
||||
.venv
|
||||
|
||||
conf/compiled
|
||||
conf/dashboards
|
||||
conf/namespaces
|
||||
conf/www
|
||||
conf/appdaemon.yaml
|
||||
conf/secrets.yaml
|
||||
|
||||
log
|
||||
*.log
|
||||
*.db
|
||||
*.js
|
||||
*cache*
|
||||
@@ -4,5 +4,4 @@ logger = logging.getLogger('AppDaemon.Perimeter')
|
||||
logger.info('Imported statemachine')
|
||||
|
||||
|
||||
class StateMachine:
|
||||
...
|
||||
class StateMachine: ...
|
||||
|
||||
@@ -5,8 +5,8 @@ from dataclasses import dataclass
|
||||
class Rule1:
|
||||
state: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Rule2:
|
||||
value: int
|
||||
other: str = "default" # test changing this
|
||||
|
||||
other: str = 'default' # test changing this
|
||||
|
||||
@@ -2,5 +2,5 @@ from appdaemon.adapi import ADAPI
|
||||
|
||||
|
||||
class GrandParent(ADAPI):
|
||||
def initialize(self):
|
||||
def initialize(self) -> None:
|
||||
self.log(f'{self.__class__.__name__} Initialized')
|
||||
|
||||
@@ -2,5 +2,5 @@ from appdaemon.adapi import ADAPI
|
||||
|
||||
|
||||
class Parent(ADAPI):
|
||||
def initialize(self):
|
||||
def initialize(self) -> None:
|
||||
self.log(f'{self.__class__.__name__} Initialized')
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
|
||||
from child import Child
|
||||
|
||||
|
||||
class Sibling(Child):
|
||||
def initialize(self):
|
||||
def initialize(self) -> None:
|
||||
self.log(f'{self.__class__.__name__} Initialized')
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from dataclasses import dataclass, field
|
||||
from typing import List
|
||||
|
||||
from .base import FoodItem
|
||||
from .eggs import Eggs
|
||||
@@ -12,7 +11,7 @@ class GreenEggs(Eggs):
|
||||
|
||||
@dataclass
|
||||
class Menu:
|
||||
dishes: List[type[FoodItem]] = field(init=False)
|
||||
dishes: list[type[FoodItem]] = field(init=False)
|
||||
|
||||
def __post_init__(self):
|
||||
self.dishes = [GreenEggs, Ham]
|
||||
|
||||
@@ -13,4 +13,5 @@ class Utensil(Enum):
|
||||
POT = auto()
|
||||
PAN = auto()
|
||||
|
||||
|
||||
GLOBAL_VAR = Utensil.FORK
|
||||
|
||||
0
conf/apps/food-repo/src/restaurant/__init__.py
Normal file
0
conf/apps/food-repo/src/restaurant/__init__.py
Normal file
@@ -5,7 +5,7 @@ from food.menu import Menu
|
||||
class Restaurant(ADAPI):
|
||||
menu: Menu
|
||||
|
||||
def initialize(self):
|
||||
def initialize(self) -> None:
|
||||
self.log(f'{self.__class__.__name__} initialized')
|
||||
|
||||
self.menu = Menu()
|
||||
|
||||
28
conf/apps/globals.py
Normal file
28
conf/apps/globals.py
Normal file
@@ -0,0 +1,28 @@
|
||||
import logging
|
||||
from enum import Enum
|
||||
|
||||
LOGGER = logging.getLogger('AppDaemon._globals')
|
||||
|
||||
|
||||
GLOBAL_VAR = 'Hello, World!'
|
||||
|
||||
|
||||
def global_function() -> None:
|
||||
LOGGER.info('This is a global function.')
|
||||
|
||||
|
||||
class GlobalClass:
|
||||
def __init__(self) -> None:
|
||||
self.value = 'This is a global class instance.'
|
||||
|
||||
def display(self) -> None:
|
||||
LOGGER.info(self.value)
|
||||
|
||||
|
||||
class ModeSelect(Enum):
|
||||
MODE_A = 'mode_a'
|
||||
MODE_B = 'mode_b'
|
||||
MODE_C = 'mode_c'
|
||||
|
||||
|
||||
GLOBAL_MODE = ModeSelect.MODE_C
|
||||
@@ -3,8 +3,9 @@ from typing import Any
|
||||
|
||||
logger = logging.getLogger('AppDaemon.Perimeter')
|
||||
|
||||
|
||||
class HAL:
|
||||
def __init__(self, *args: Any, **kwargs: Any):
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
logger.info('Logging from HAL')
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
CONSTANTS = {
|
||||
'A': 1,
|
||||
'B': 2,
|
||||
'C': 3
|
||||
'C': 3,
|
||||
}
|
||||
|
||||
|
||||
def utility_function():
|
||||
return 123, 456
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
# scratch1:
|
||||
# module: "scratch"
|
||||
# class: "Scratch"
|
||||
# priority: 1
|
||||
# dependencies:
|
||||
# - scratch2
|
||||
|
||||
dummy:
|
||||
module: dummy
|
||||
class: Dummy
|
||||
dependencies:
|
||||
- dev
|
||||
|
||||
eboon:
|
||||
module: eboon
|
||||
class: Eboon
|
||||
|
||||
dev:
|
||||
module: notifications
|
||||
class: NotifyDev
|
||||
|
||||
# scratch3:
|
||||
# module: "scratch"
|
||||
# class: "Scratch"
|
||||
# scratch4:
|
||||
# module: "scratch"
|
||||
# class: "Scratch"
|
||||
# scratch5:
|
||||
# module: "scratch"
|
||||
# class: "Scratch"
|
||||
# scratch6:
|
||||
# module: "scratch"
|
||||
# class: "Scratch"
|
||||
# scratch7:
|
||||
# module: "scratch"
|
||||
# class: "Scratch"
|
||||
12
conf/apps/simple_app/app_a.py
Normal file
12
conf/apps/simple_app/app_a.py
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
from appdaemon.adapi import ADAPI
|
||||
from globals import GLOBAL_MODE, GLOBAL_VAR
|
||||
|
||||
|
||||
class AppA(ADAPI):
|
||||
def initialize(self) -> None:
|
||||
self.log(f'{self.__class__.__name__} Initialized')
|
||||
self.log(GLOBAL_VAR)
|
||||
self.log(f'Global mode is set to: {GLOBAL_MODE.value}')
|
||||
|
||||
def terminate(self) -> None: ...
|
||||
11
conf/apps/simple_app/app_b.py
Normal file
11
conf/apps/simple_app/app_b.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from appdaemon.adapi import ADAPI
|
||||
from globals import GLOBAL_MODE, GLOBAL_VAR
|
||||
|
||||
|
||||
class AppB(ADAPI):
|
||||
def initialize(self) -> None:
|
||||
self.log(f'{self.__class__.__name__} Initialized')
|
||||
self.log(GLOBAL_VAR)
|
||||
self.log(f'Global mode is set to: {GLOBAL_MODE.value}')
|
||||
|
||||
def terminate(self) -> None: ...
|
||||
@@ -1,10 +1,27 @@
|
||||
hello_world:
|
||||
module: hello
|
||||
class: HelloWorld
|
||||
extra: abc123
|
||||
# disable: true
|
||||
|
||||
simple_app:
|
||||
module: simple
|
||||
class: SimpleApp
|
||||
extra: 1234
|
||||
dependencies:
|
||||
- hello_world
|
||||
priority: 10
|
||||
# dependencies:
|
||||
# - hello_world
|
||||
|
||||
base_app:
|
||||
module: simple
|
||||
class: BaseApp
|
||||
|
||||
# AppA:
|
||||
# module: app_a
|
||||
# class: AppA
|
||||
# dependencies:
|
||||
# - AppB # This is only set to demonstrate forcing it to load after AppB
|
||||
|
||||
# AppB:
|
||||
# module: app_b
|
||||
# class: AppB
|
||||
|
||||
@@ -2,13 +2,23 @@ from typing import Any
|
||||
|
||||
from appdaemon.adapi import ADAPI
|
||||
|
||||
# fake_name.get()
|
||||
|
||||
# if:
|
||||
# OUtisde&sdf'asdfasdf'<txF> asdfasdfom some html</.dstd>
|
||||
|
||||
# fake/
|
||||
# SimpleApp
|
||||
|
||||
|
||||
class HelloWorld(ADAPI):
|
||||
def initialize(self):
|
||||
def initialize(self) -> None:
|
||||
self.log(f'{self.__class__.__name__} Initialized')
|
||||
self.register_service("my_domain/my_exciting_service", self.my_exciting_cb)
|
||||
self.log('+' * 50)
|
||||
# fake
|
||||
self.register_service('my_domain/my_exciting_service', self.my_exciting_cb)
|
||||
|
||||
def my_exciting_cb(self, *args: str, my_arg: int = 0, **kwargs: Any) -> Any:
|
||||
namespace, domain, service = args
|
||||
self.log(f"Service {domain}/{service} in the {namespace} namepsace called with {kwargs}")
|
||||
self.log(f'Service {domain}/{service} in the {namespace} namepsace called with {kwargs}')
|
||||
return 999 + my_arg
|
||||
|
||||
9
conf/apps/simple_app/malformed.py
Normal file
9
conf/apps/simple_app/malformed.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from appdaemon.adapi import ADAPI
|
||||
|
||||
|
||||
class SimpleApp(ADAPI):
|
||||
def initialize(self):
|
||||
self.log(f'{self.__class__.__name__} Initialized')
|
||||
|
||||
if:
|
||||
OUtisde&sdf'asdfasdf'<txF> asdfasdfom some html</.dstd>
|
||||
@@ -1,6 +1,21 @@
|
||||
from appdaemon.adapi import ADAPI
|
||||
from appdaemon import utils
|
||||
from appdaemon.adbase import ADBase
|
||||
from appdaemon.plugins.hass import Hass
|
||||
|
||||
|
||||
class SimpleApp(ADAPI):
|
||||
def initialize(self):
|
||||
self.log(f'{self.__class__.__name__} Initialized')
|
||||
class SimpleApp(Hass):
|
||||
def initialize(self) -> None:
|
||||
match self.ping():
|
||||
case float() as ping:
|
||||
ping = utils.format_timedelta(ping)
|
||||
self.log(f'{self.__class__.__name__} Initialized: {ping}')
|
||||
case _:
|
||||
pass
|
||||
|
||||
|
||||
class BaseApp(ADBase):
|
||||
def initialize(self) -> None:
|
||||
self.adapi = self.get_ad_api()
|
||||
self.log = self.adapi.log
|
||||
self.hassapi = self.get_plugin_api('HASS')
|
||||
assert isinstance(self.hassapi, Hass), 'HASS API not available'
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#
|
||||
# Main arguments, all optional
|
||||
#
|
||||
title: Hello Panel
|
||||
widget_dimensions: [120, 120]
|
||||
widget_margins: [5, 5]
|
||||
columns: 8
|
||||
|
||||
label:
|
||||
widget_type: label
|
||||
text: Hello World
|
||||
|
||||
layout:
|
||||
- label(2x2)
|
||||
29
conf/pyrightconfig.json
Normal file
29
conf/pyrightconfig.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
// Specify which paths to check
|
||||
"include": [
|
||||
"./ad-test/conf/apps/**"
|
||||
],
|
||||
// "typeCheckingMode": "standard",
|
||||
"typeCheckingMode": "basic",
|
||||
// Be somewhat tolerant with regards to imperfect dependencies or types
|
||||
"reportUnknownMemberType": "none",
|
||||
"reportUnusedImport": "warning",
|
||||
"reportMissingTypeStubs": "none",
|
||||
"reportIncompleteStub": "none",
|
||||
"reportUnknownVariableType": "none",
|
||||
"reportUnknownParameterType": "warning",
|
||||
"reportMissingTypeArgument": "warning",
|
||||
"useLibraryCodeForTypes": true, // Homogeneous with pylance's default
|
||||
// Add warnings for probable programming errors
|
||||
"reportUnnecessaryTypeIgnoreComment": "warning",
|
||||
"reportMissingParameterType": "warning",
|
||||
"reportUnnecessaryComparison": "warning",
|
||||
"reportUnnecessaryIsInstance": "warning",
|
||||
"reportUnnecessaryCast": "warning",
|
||||
"reportUnnecessaryContains": "warning",
|
||||
"reportMatchNotExhaustive": "error",
|
||||
"reportUnusedVariable": "warning",
|
||||
"reportUnusedCoroutine": "warning",
|
||||
"reportUnusedExpression": "warning",
|
||||
"reportUnusedFunction": "warning"
|
||||
}
|
||||
@@ -8,18 +8,15 @@ authors = [
|
||||
dependencies = [
|
||||
"pytest>=8.3.2",
|
||||
"gitpython>=3.1.43",
|
||||
"appdaemon",
|
||||
]
|
||||
readme = "README.md"
|
||||
requires-python = ">= 3.8"
|
||||
requires-python = ">= 3.10"
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[tool.rye]
|
||||
managed = true
|
||||
dev-dependencies = []
|
||||
|
||||
[tool.ruff.format]
|
||||
quote-style = "single"
|
||||
|
||||
@@ -28,3 +25,11 @@ allow-direct-references = true
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["src/ad_test"]
|
||||
|
||||
[tool.uv.sources]
|
||||
appdaemon = {path = "/home/john/Documents/appdaemon" }
|
||||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"ruff>=0.11.13",
|
||||
]
|
||||
|
||||
29
ruff.toml
Normal file
29
ruff.toml
Normal file
@@ -0,0 +1,29 @@
|
||||
line-length = 100
|
||||
target-version = "py312"
|
||||
|
||||
[format]
|
||||
quote-style = "single"
|
||||
indent-style = "space"
|
||||
|
||||
[lint]
|
||||
exclude = [
|
||||
"conf/apps/simple_app/malformed.py"
|
||||
]
|
||||
|
||||
select = ["ALL"]
|
||||
extend-ignore = [
|
||||
"ANN",
|
||||
"BLE001",
|
||||
"COM812",
|
||||
"D",
|
||||
"E501",
|
||||
"ERA001",
|
||||
"INP001",
|
||||
"S101",
|
||||
]
|
||||
|
||||
|
||||
[lint.flake8-quotes]
|
||||
inline-quotes = "single"
|
||||
docstring-quotes = "double"
|
||||
multiline-quotes = "double"
|
||||
@@ -1,2 +0,0 @@
|
||||
def hello() -> str:
|
||||
return 'Hello from ad-test!'
|
||||
|
||||
Reference in New Issue
Block a user