diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml new file mode 100644 index 000000000..44f9d2761 --- /dev/null +++ b/.github/workflows/codespell.yml @@ -0,0 +1,25 @@ +# Codespell configuration is within pyproject.toml +--- +name: Codespell + +on: + push: + branches: [dev] + pull_request: + branches: [dev] + +permissions: + contents: read + +jobs: + codespell: + name: Check for spelling errors + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Annotate locations with typos + uses: codespell-project/codespell-problem-matcher@v1 + - name: Codespell + uses: codespell-project/actions-codespell@v2 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5f5fd5de8..afdd1a616 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,3 +14,10 @@ repos: # hooks: # - id: black # language_version: python3 +- repo: https://github.com/codespell-project/codespell + # Configuration for codespell is in pyproject.toml + rev: v2.3.0 + hooks: + - id: codespell + additional_dependencies: + - tomli diff --git a/appdaemon/adapi.py b/appdaemon/adapi.py index a587900f9..aa0da05e7 100644 --- a/appdaemon/adapi.py +++ b/appdaemon/adapi.py @@ -1617,7 +1617,7 @@ def register_service(self, service: str, cb: Callable, **kwargs: Optional[Any]) This will automatically make it available to other apps using the `call_service()` API call, as well as publish it as a service in the REST API and make it available to the `call_service` command in the event stream. It should be noted that registering services within a plugin's namespace is a bad idea. It could work, but not always reliable - It is recommended to make use of this api, within a user definded namespace, or one not tied to a plugin. + It is recommended to make use of this api, within a user defined namespace, or one not tied to a plugin. Args: service: Name of the service, in the format `domain/service`. If the domain does not exist it will be created @@ -1754,7 +1754,7 @@ async def call_service(self, service: str, **kwargs: Optional[Any]) -> Any: return_result(str, option): If `return_result` is provided and set to `True` AD will attempt to wait for the result, and return it after execution. In the case of Home Assistant calls that do not return values this may seem pointless, but it does force the call to be synchronous with respect to Home Assistant - whcih can in turn highlight slow performing services if they timeout or trigger thread warnings. + which can in turn highlight slow performing services if they timeout or trigger thread warnings. callback: The non-async callback to be executed when complete. hass_result (False, Home Assistant Specific): Mark the service call to Home Assistant as returnng a value. If set to ``True``, the call to Home Assistant will specifically request a return result. @@ -1765,7 +1765,7 @@ async def call_service(self, service: str, **kwargs: Optional[Any]) -> Any: hass_timeout (Home Assistant Specific): time in seconds to wait for Home Assistant's response for this specific service call. If not specified defaults to the value of the ``q_timeout`` parameter in the HASS plugin configuration, which itself defaults to 30 seconds. See `Some Notes on Service Calls `__ suppress_log_messages (Home Assistant Specific, False): if set to ``True`` Appdaemon will suppress logging of warnings for service calls to Home Assistant, specifically timeouts and non OK statuses. Use this flag and set it to ``True`` - to supress these log messages if you are performing your own error checking as described `here `__ + to suppress these log messages if you are performing your own error checking as described `here `__ @@ -2406,7 +2406,7 @@ async def reset_timer(self, handle: str) -> bool: Args: handle: A valid handle value returned from the original call to create the timer. - The timer must be actively running, and not a Sun related one like sunrise/sunset for it to be resetted. + The timer must be actively running, and not a Sun related one like sunrise/sunset for it to be reset. Returns: Boolean, true if the reset succeeded. diff --git a/appdaemon/app_management.py b/appdaemon/app_management.py index 96bbc8c34..7bf825ac7 100644 --- a/appdaemon/app_management.py +++ b/appdaemon/app_management.py @@ -1039,7 +1039,7 @@ async def check_app_updates(self, plugin: str = None, mode: UpdateMode = UpdateM - Marks the apps for reloading or removal as necessary - Restarts the plugin, if specified - Terminates apps as necessary - - Loads or reloads modules/pacakges as necessary + - Loads or reloads modules/packages as necessary - Loads apps from the modules/packages """ async with self.check_updates_lock: @@ -1111,7 +1111,7 @@ async def _init_update_mode(self): module_file: dir.stem for dir in top_packages_dirs for module_file in dir.rglob("*.py") } - # Add any aditional import paths + # Add any additional import paths for path in self.AD.import_paths: if os.path.isdir(path): self.add_to_import_path(path) @@ -1282,7 +1282,7 @@ async def _terminate_apps(self, mode: UpdateMode, apps: AppActions, modules: Lis if apps is not None and apps.term: prio_apps = self.get_app_deps_and_prios(apps.term, mode) - # Mark dependant global modules for reload + # Mark dependent global modules for reload for app_name in sorted(prio_apps, key=prio_apps.get): app_path = self.get_path_from_app(app_name) diff --git a/appdaemon/entity.py b/appdaemon/entity.py index 4aad22c68..5f35501dc 100644 --- a/appdaemon/entity.py +++ b/appdaemon/entity.py @@ -375,7 +375,7 @@ async def wait_state( ) -> None: """Used to wait for the state of an entity's attribute - This API call is only functional within an async function. It should be noted that when instanciated, + This API call is only functional within an async function. It should be noted that when instantiated, the api checks immediately if its already on the required state, and if it is, it will continue. Args: diff --git a/appdaemon/http.py b/appdaemon/http.py index 8f198210e..f369142fd 100644 --- a/appdaemon/http.py +++ b/appdaemon/http.py @@ -384,7 +384,7 @@ async def start_server(self): await site.start() except gaierror: self.logger.error("Invalid host specified in URL for HTTP component") - self.logger.error("As of AppDaemon 4.5 the host name specificed in the URL must resolve to a known host") + self.logger.error("As of AppDaemon 4.5 the host name specified in the URL must resolve to a known host") self.logger.error("You can restore previous behavior by using `0.0.0.0` as the host portion of the URL") self.logger.error("For instance: `http://0.0.0.0:5050`") raise StartupAbortedException("Invalid host specified in URL for HTTP component") @@ -899,7 +899,7 @@ async def call_app_endpoint(self, request): return self.get_response(request, code, "App Not Found") elif code == 500: - return self.get_response(request, code, "An Error occured while processing request") + return self.get_response(request, code, "An Error occurred while processing request") response = "OK" self.access.info("API Call to %s: status: %s %s", endpoint, code, response) diff --git a/appdaemon/plugin_management.py b/appdaemon/plugin_management.py index 8c9e3378f..eb1993eb3 100644 --- a/appdaemon/plugin_management.py +++ b/appdaemon/plugin_management.py @@ -288,7 +288,7 @@ async def notify_plugin_started(self, name, ns, meta, state, first_time=False): if not self.stopping: self.plugin_meta[namespace] = meta - if namespaces != []: # there are multiple namesapces + if namespaces != []: # there are multiple namespaces for namesp in namespaces: if state[namesp] is not None: await utils.run_in_executor( diff --git a/appdaemon/plugins/hass/hassplugin.py b/appdaemon/plugins/hass/hassplugin.py index 6d0416a8e..f164ebdc4 100644 --- a/appdaemon/plugins/hass/hassplugin.py +++ b/appdaemon/plugins/hass/hassplugin.py @@ -1,5 +1,5 @@ """ -Interface with Home Assistant, send and recieve evets, state etc. +Interface with Home Assistant, send and receive evets, state etc. """ import asyncio @@ -102,7 +102,7 @@ def init_q(self): self.queues = {} async def process_response(self, response): - # We recieved a response from the WS, match it up with the caller + # We received a response from the WS, match it up with the caller if "id" in response and response["id"] in self.queues: q = self.queues[response["id"]] await q.put(response) @@ -158,7 +158,7 @@ async def process_command(self, command, return_result, hass_timeout=0, suppress # self.logger.info(f"Response: {response}") # We got a valid response - # Set the AD response code and timeing + # Set the AD response code and timing response["ad_status"] = "OK" now = await self.AD.sched.get_now_ts() diff --git a/appdaemon/plugins/mqtt/mqttapi.py b/appdaemon/plugins/mqtt/mqttapi.py index 955c91a8b..72f04a3e2 100644 --- a/appdaemon/plugins/mqtt/mqttapi.py +++ b/appdaemon/plugins/mqtt/mqttapi.py @@ -116,7 +116,7 @@ async def listen_event(self, callback: Callable, event: str = None, **kwargs: Op binary (bool, optional): If wanting the payload to be returned as binary, this should be specified. If not given, AD will return the payload as decoded data. It should - be noted that it is not possible to have different apps receieve both binary and non-binary + be noted that it is not possible to have different apps receive both binary and non-binary data on the same topic Returns: diff --git a/appdaemon/scheduler.py b/appdaemon/scheduler.py index 5539e050a..e53473e6e 100644 --- a/appdaemon/scheduler.py +++ b/appdaemon/scheduler.py @@ -596,7 +596,7 @@ async def loop(self): # noqa: C901 next_entries = self.get_next_entries() elif self.timer_resetted is True: - # a timer was resetted, so need to recalculate next entries + # a timer was reset, so need to recalculate next entries next_entries = self.get_next_entries() self.timer_resetted = False diff --git a/appdaemon/threading.py b/appdaemon/threading.py index 2d9d7309a..2374a8d4f 100644 --- a/appdaemon/threading.py +++ b/appdaemon/threading.py @@ -1027,7 +1027,7 @@ async def async_worker(self, args): # noqa: C901 error_logger.warning("-" * 60) error_logger.warning( "Unexpected error in worker for App %s:", name) - error_logger.warning("Worker Ags: %s", args) + error_logger.warning("Worker Args: %s", args) error_logger.warning("-" * 60) error_logger.warning(traceback.format_exc()) error_logger.warning("-" * 60) @@ -1176,7 +1176,7 @@ def worker(self): # noqa: C901 error_logger.warning("-" * 60) error_logger.warning( "Unexpected error in worker for App %s:", name) - error_logger.warning("Worker Ags: %s", args) + error_logger.warning("Worker Args: %s", args) error_logger.warning("-" * 60) error_logger.warning(traceback.format_exc()) error_logger.warning("-" * 60) @@ -1250,7 +1250,7 @@ def report_callback_sig(self, name, type, funcref, args): error_logger.warning("-" * 60) error_logger.warning( "Unexpected error in worker for App %s:", name) - error_logger.warning("Worker Ags: %s", args) + error_logger.warning("Worker Args: %s", args) error_logger.warning("-" * 60) error_logger.warning(traceback.format_exc()) error_logger.warning("-" * 60) diff --git a/appdaemon/utils.py b/appdaemon/utils.py index 3496b3164..2e9454a21 100644 --- a/appdaemon/utils.py +++ b/appdaemon/utils.py @@ -54,8 +54,8 @@ def set_formater(self, obj, callback): def __call__(self, value, **args): for key in args: setattr(self, key, args[key]) - formater = self.types[type(value) if type(value) in self.types else object] - return formater(self, value, self.indent) + formatter = self.types[type(value) if type(value) in self.types else object] + return formatter(self, value, self.indent) @staticmethod def format_object(value, indent): @@ -709,7 +709,7 @@ def _secret_yaml(loader, node): def _env_var_yaml(loader, node): env_var = node.value if env_var not in os.environ: - raise ValueError("{} not found in as environment varibale".format(env_var)) + raise ValueError("{} not found in as environment variable".format(env_var)) return os.environ[env_var] diff --git a/appdaemon/widgets/basefan/basefan.js b/appdaemon/widgets/basefan/basefan.js index e612492f2..6d315906a 100755 --- a/appdaemon/widgets/basefan/basefan.js +++ b/appdaemon/widgets/basefan/basefan.js @@ -107,7 +107,7 @@ function basefan(widget_id, url, skin, parameters) else //Fan is on { - //turn main icon on & dispay speed selector + //turn main icon on & display speed selector self.set_icon(self, "icon", self.icons.icon_active) self.set_field(self, "icon_style", self.css.icon_style_active) diff --git a/conf/example_apps/ObjectTracker/general_app_functions.py b/conf/example_apps/ObjectTracker/general_app_functions.py index 8a37c66fb..5349be10e 100644 --- a/conf/example_apps/ObjectTracker/general_app_functions.py +++ b/conf/example_apps/ObjectTracker/general_app_functions.py @@ -6,7 +6,7 @@ # state can be last time updated or time gone by since last update # # check_last_update_time: checks when the last time was that a sensor was updated # # save_last_update_time: saves the time that an object is updated to a file in a dir # -# you can define. the file wil have the name: lut_entity_id.py # +# you can define. the file will have the name: lut_entity_id.py # # reformat_time: changed a timeformat from H:M:S to %H:%M:%S # # # # Rene Tode ( hass@reot.org ) # diff --git a/conf/example_dashboards/Modular/Test.dash b/conf/example_dashboards/Modular/Test.dash index 286fb9406..aca0a3a31 100755 --- a/conf/example_dashboards/Modular/Test.dash +++ b/conf/example_dashboards/Modular/Test.dash @@ -87,7 +87,7 @@ side_humidity: #precision: 0 entity: sensor.side_humidity_corrected #state_map: - # "49.0": Realy Cold + # "49.0": Really Cold garage: widget_type: cover diff --git a/conf/examples.yaml b/conf/examples.yaml index 4cfae217c..5243836d1 100644 --- a/conf/examples.yaml +++ b/conf/examples.yaml @@ -262,7 +262,7 @@ Security: insecure_message: "The following items are insecure :" securing_message: "I have secured the following items: " failed_message: "The following items failed to secure: " - alarm_cancel_message: ["Alarm has been cancelled", "uh oh, canceling alarm", "oh noes!"] + alarm_cancel_message: ["Alarm has been cancelled", "uh oh, canceling alarm", "oh no!"] alarm_arm_message: "Alarm is armed" alarm_disarm_message: "Alarm is disarmed" alarm_entity: alarm_control_panel.ha_alarm @@ -304,7 +304,7 @@ Security: service: cover/close_cover timeout: 20 #state_map: - # locked: "bannana" + # locked: "banana" # unlocked: "fruitbat" Garage Motion: binary_sensor.garage_sensor: diff --git a/dockerStart.sh b/dockerStart.sh index a1b1eebd7..3da2c40a8 100755 --- a/dockerStart.sh +++ b/dockerStart.sh @@ -82,7 +82,7 @@ if [ -n "$ELEVATION" ]; then fi # Install packages specified by the end-user. -# - Recusively traverse $CONF directory, searching for non-empty system_packages.txt files +# - Recursively traverse $CONF directory, searching for non-empty system_packages.txt files # - Use cat to read all the file contents, use echo to append whtespace " " char to the file content (to guard against the corner case where the user does not put a newline after the package name) # - Use tr to substitute all newlines with " " char, to concatenate the name of all packages in a single line # - Pipe to xargs, printing the executed command (-t), invoking `apk add` with the list of required packages. Do nothing if no system_packages.txt files is present (--no-run-if-empty) diff --git a/docs/APPGUIDE.rst b/docs/APPGUIDE.rst index 2750cad0d..8424faa5c 100644 --- a/docs/APPGUIDE.rst +++ b/docs/APPGUIDE.rst @@ -168,7 +168,7 @@ To configure a new App you need a minimum of two directives: - ``class`` - the name of the class as defined within the module for the App's code -Although the section/App name must be unique, it is possible to re-use a +Although the section/App name must be unique, it is possible to reuse a class as many times as you want, and conversely to put as many classes in a module as you want. A sample definition for a new App might look as follows in YAML: @@ -179,7 +179,7 @@ follows in YAML: module: new class: NewApp -The TOML equivqlent would look like this: +The TOML equivalent would look like this: .. code:: toml @@ -455,7 +455,7 @@ In the App, the app_users can be accessed like every other argument the App can App Dependencies ---------------- -It is possible for apps to be dependant upon other apps. Some +It is possible for apps to be dependent upon other apps. Some examples where this might be the case are: - A global App that defines constants for use in other apps @@ -593,7 +593,7 @@ as global can be achieved creating an entry for each module: module: other_globals global: true -Once we have marked the global modules, the next step is to configure any apps that are dependant upon them. This is done by adding them to the standard ``dependencies`` field to the App description, e.g.: +Once we have marked the global modules, the next step is to configure any apps that are dependent upon them. This is done by adding them to the standard ``dependencies`` field to the App description, e.g.: .. code:: yaml @@ -615,7 +615,7 @@ Or for multiple dependencies: With this in place, whenever a global module changes that apps depend upon, all dependent apps will be reloaded. This also works well with the App level dependencies. If a change to a global module forces an App to reload -that other apps are dependant upon, the dependant apps will also be reloaded in sequence. +that other apps are dependent upon, the dependent apps will also be reloaded in sequence. Using this mechanism, it is also possible to mark global modules as being dependent on other global modules. Note: the old ``global_modules`` directive used to be used for this function but has been deprecated. @@ -626,7 +626,7 @@ Plugin Reloads -------------- When a plugin reloads e.g., due to the underlying system restarting, or a network issue, -AppDaemon's default assumption is that all apps could potentially be dependant on that system, +AppDaemon's default assumption is that all apps could potentially be dependent on that system, and it will force a restart of every App. It is possible to modify this behavior at the individual App level, using the ``plugin`` parameter in apps.yaml. Specifying a specific plugin or list of plugins will force the App to reload after the named plugin restarts. @@ -1461,7 +1461,7 @@ callbacks vis the ``**`` operator rather than passing a dictionary containing th def motion(self, entity, attribute, old, new, **kwargs): self.log("Arg1 is {}".format(kwargs["arg1"])) -It now makes more sense to rewite the callback's method signature to the following if desired: +It now makes more sense to rewrite the callback's method signature to the following if desired: .. code:: python @@ -1898,7 +1898,7 @@ AppDaemon uses 2 separate logs - the general log and the error log. An App can write to either of these using the supplied convenience methods ``log()`` and ``error()``, which are provided as part of parent ``AppDaemon`` class, and the call will automatically -pre-pend the name of the App making the call. +prepend the name of the App making the call. The functions are based on the Python ``logging`` module and are able to pass through parameters for interpolation, and additional parameters such as ``exc_info`` just as with the usual style of invocation. Use of loggers interpolation method over the use of ``format()`` is recommended for performance reasons, as logger will only interpolate of the line is actually written whereas ``format()`` will always do the substitution. @@ -2777,7 +2777,7 @@ You can use this with 2 separate constraints like so: Sequences --------- -AppDaemon supports `sequences` as a simple way of re-using predefined steps of commands. The initial usecase for sequences +AppDaemon supports `sequences` as a simple way of reusing predefined steps of commands. The initial usecase for sequences is to allow users to create scenes within AppDaemon, however they are useful for many other things. Sequences are fairly simple and allow the user to define 3 types of activities: @@ -2897,7 +2897,7 @@ Defining a Sequence Call Namespace ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ By default, a sequence will run on entities in the current namespace, however , the namespace can be specified on a per call -basis if required. Also it can be specifed at the top tier level, allowing for all service calls in the sequence to use the same namespace +basis if required. Also it can be specified at the top tier level, allowing for all service calls in the sequence to use the same namespace .. code:: yaml @@ -2992,7 +2992,7 @@ Keeping Your IDE Happy Although it is possible to develop AppDaemon apps using a straight forward text editor, most users prefer to use some flavor of IDE. In order to simplify App development however, AppDaemon hides some of the complexity of import paths which makes for simpler coding but does have the side effect of confusing modern IDEs that are much stricter with import paths, and will show errors for modules -that don't conform to these rules, and will not unserstand enough about the import paths to supply helpful information about AppDaemon's +that don't conform to these rules, and will not understand enough about the import paths to supply helpful information about AppDaemon's API. Fortunately however, with a few simple steps, the IDE can be persuaded to work as desired. In addition, AppDaemon's APIs now have full type hints to make use of a modern IDE a lot easier and more helpful. This capability has been tested in Microsoft's VS Code but these steps should apply equally to other IDEs such as PyCharm. @@ -3047,7 +3047,7 @@ With these preparations in place your IDE should give you correct error reportin Some Notes on Service Calls --------------------------- -Service calls within AppDaemon are used to make something happen. For instance, instructing Home Assitant to turn a light on, or instructing AppDaemon itself +Service calls within AppDaemon are used to make something happen. For instance, instructing Home Assistant to turn a light on, or instructing AppDaemon itself to reload an App. The Home Assistant plugin provides AppDaemon apps with a number of services that can be called, dependent upon what devices are configured, and what integrations have been added. While entities and state tell you what the current situation is, service calls will usually make some sort of change to the current situation, and the results will often be propagated back to the app via a state change callback, for instance, a light's state changing from @@ -3055,7 +3055,7 @@ to the current situation, and the results will often be propagated back to the a Most service calls to date have been "fire and forget" - the service call is made and control is returned to the App immediately. This has the benefit of keeping things moving along which AppDaemon likes, but the downside of this is that you have to hope that the service call went through OK, and your app won't -be given information on any errors that may have occured. Also, sometimes we may want to get specific information back from a service call, as the use +be given information on any errors that may have occurred. Also, sometimes we may want to get specific information back from a service call, as the use of AppDaemon internal service calls is a powerful way of modularizing and communicating between apps. With the above in mind, service calls have recently had a few enhancements to improve this aspect of operation. @@ -3128,18 +3128,18 @@ called when the service call returns with data: The return value of the service will be in the ``result`` entry of the kwargs dictionary. -Note that you may use the ``return_result`` or the ``calback`` option in a single call, but not both. +Note that you may use the ``return_result`` or the ``callback`` option in a single call, but not both. Returning Results from Home Assistant ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Home Assistant recently added the ability to return data from specific service calls. Not very many calls support this yet, but as of release 4.5 AppDaemon is now able -to propagate return values from Home Assitant service calls to the App. As a result of this support, it is also now possible to wait for return statuses for Home Assistant +to propagate return values from Home Assistant service calls to the App. As a result of this support, it is also now possible to wait for return statuses for Home Assistant service calls even if no return data is requested, this is beneficial as it is now possible to detect errors that were previously unreported. In addition, waiting for the response also allows the app and AppDaemon to identify poorly performing Home Assistant services (such as ZWave communication slowdowns) that previously would have gone unnoticed. To tell AppDaemon that you are expecting Home Assistant to return a value, set the ``hass_result`` parameter to True. In addition, you should also set either the ``callback`` or ``return_result`` -flags depending on how you want to recieve the result - both methods are supported. In order to force the call to be synchronous for a Home Assistant service that does not return a value, simply set ``return_result`` +flags depending on how you want to receive the result - both methods are supported. In order to force the call to be synchronous for a Home Assistant service that does not return a value, simply set ``return_result`` to ``True`` but don't set ``hass_result`` to anything. Note that Home Assistant requires that you tell it explicitly whether or not you want a result. If you ask for a result from a service that doesn't return one, you will get an error. @@ -3152,7 +3152,7 @@ app with an error. There are a couple of other timers already in AppDaemon that * The callback tracking timer will issue warnings if a callback takes longer than 10 seconds to return * The internal function timer will cancel any task that takes longer than 60 seconds. -With the above in mind, the default timeout for the Home Assitant service call has been set to 30 seconds to fall in between these 2 values so that in most cases for a slow service call +With the above in mind, the default timeout for the Home Assistant service call has been set to 30 seconds to fall in between these 2 values so that in most cases for a slow service call you will get warnings from the callback tracking, but the call will cleanly timeout before AppDaemon is forced to cancel it for it's own internal housekeeping. If you set the timeout value higher, the internal function timer is the upper limit (this can be changed as part of the appdamon config if required). @@ -3195,16 +3195,16 @@ It is also possible to force all calls to be synchronous by setting the ``return Home Assistant Return Data Format ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Return Data from internal AppDaemon service calls is arbitary and returned as is from the return statement of the called service. and can be of any time just as you would expect with a regular Python ```return`` statement. +Return Data from internal AppDaemon service calls is arbitrary and returned as is from the return statement of the called service. and can be of any time just as you would expect with a regular Python ```return`` statement. The return format from Home Assistant service calls is more complex and includes additional data as well as the requested data. -The return data wil be a dictionary, and AppDaemon starts with the data returned directly +The return data will be a dictionary, and AppDaemon starts with the data returned directly from HomeAssistant and adds a couple of additional fields that can be used to check status and gather information. The AppDaemon specific fields are guaranteed to exist and are: * ``ad_status`` - the status of the call from AppDaemon's perspective. Possible values are: - * ``OK`` - everything went as planned from AppDaemon's perspective, a call was made to Home Assistant and a Response was obtained, and the response from Home Assistant is also contained within the results dictionary. This does not mean Home Assistant didn't produce an error, just that AppDaemon succesfully obtained a response from Home Assistant - * ``TIMEOUT`` - the call to Home Assistant did not return a value before a timeout occured (either the default 30 second timeout, or a per call timeout specified by the user) + * ``OK`` - everything went as planned from AppDaemon's perspective, a call was made to Home Assistant and a Response was obtained, and the response from Home Assistant is also contained within the results dictionary. This does not mean Home Assistant didn't produce an error, just that AppDaemon successfully obtained a response from Home Assistant + * ``TIMEOUT`` - the call to Home Assistant did not return a value before a timeout occurred (either the default 30 second timeout, or a per call timeout specified by the user) * ``TERMINATING`` - the service call was terminated as AppDaemon is shutting down * ``ad_duration`` - the amount of time in seconds the round trip took from AppDaemon to Home Assistant and back, useful for timing service calls. diff --git a/docs/CONFIGURE.rst b/docs/CONFIGURE.rst index 1cf1603f3..db139e37f 100644 --- a/docs/CONFIGURE.rst +++ b/docs/CONFIGURE.rst @@ -177,7 +177,7 @@ The following options are available under the ``appdaemon`` section: - No * - thread_duration_warning_threshold - - AppDaemon monitors the time that each tread spends in an App. + - AppDaemon monitors the time that each thread spends in an App. If a thread is taking too long to finish a callback, it may impact other apps. AppDaemon will log a warning if any thread is over the duration specified in seconds. The default is ``10`` seconds, setting this value to ``00`` will disable this check. - No @@ -188,11 +188,11 @@ The following options are available under the ``appdaemon`` section: - No * - import_method - - By default, AppDaemon will add all subdirectories of appdir to the python interpreters path. This is intended to simplfy imports for simple applications. There is also an expert mode that will add just the top level appdir dircetory to the path allowing the user to use a more traditional hierarchical approach to imports. The default value for this directive is `normal`, set it to `expert` to enable the expert mode. + - By default, AppDaemon will add all subdirectories of appdir to the python interpreters path. This is intended to simplify imports for simple applications. There is also an expert mode that will add just the top level appdir directory to the path allowing the user to use a more traditional hierarchical approach to imports. The default value for this directive is `normal`, set it to `expert` to enable the expert mode. - No * - import_paths - - Use this directive to add additional arbitary directories to the python interpreter's search path. Directories must be fully qualified. + - Use this directive to add additional arbitrary directories to the python interpreter's search path. Directories must be fully qualified. - No @@ -499,7 +499,7 @@ Plugins also support some optional parameters: - ``refresh_delay`` - How often the complete state of the plugin is refreshed, in seconds. Default is 600 seconds. - ``refresh_timeout`` - How long to wait for the state refresh before cancelling it, in seconds. Default is 30 seconds. -- ``persist_entities`` - If `True` all entities created within the plugin's namespace will be persitent within AD. So in the event of a restart, the entities will be recreated in the same namespace +- ``persist_entities`` - If `True` all entities created within the plugin's namespace will be persistent within AD. So in the event of a restart, the entities will be recreated in the same namespace The rest will vary depending upon which plugin type is in use. diff --git a/docs/DASHBOARD_CREATION.rst b/docs/DASHBOARD_CREATION.rst index c96aa95cf..d22de4334 100644 --- a/docs/DASHBOARD_CREATION.rst +++ b/docs/DASHBOARD_CREATION.rst @@ -432,7 +432,7 @@ For example: - label(2x2),clock(2x2) In this example of a header, we reference a clock and a label in the -layout. We can re-use this header, but in order to make the label change +layout. We can reuse this header, but in order to make the label change for every page we use it on we actually define it in the dashboard file itself, and include the header in the layout: @@ -625,8 +625,8 @@ the dashboard url, for instance: ``http://192.168.1.20:5050/mypanel?deviceid=kitchentablet`` HADashboard will try to store the deviceid on the device so you don't need -to use this parameter everytime. You may use it again if you want to set -a new deviceid or if you cleaned device's cookies or the device doesnt +to use this parameter every time. You may use it again if you want to set +a new deviceid or if you cleaned device's cookies or the device doesn't support it. @@ -2036,7 +2036,7 @@ Mandatory Arguments: - ``entity`` - the entity\_id of the alarm to be monitored - ``settings`` - a list if values describing the gauge with the following entries: -- title - title of the guage +- title - title of the gauge - minValue - minimum value to display - maxValue - maximum value to display - majorTicks - Where to mark major values, a list @@ -2204,7 +2204,7 @@ Optional Arguments: - ``title2`` - a second line of title text - ``state_text`` - ``state_map`` -- ``enabled`` - if set to 0 the switch cant be pressed but only shows status +- ``enabled`` - if set to 0 the switch can't be pressed but only shows status - ``momentary`` - after the set amount of milliseconds the old state returns (momentary button) Style Arguments: @@ -2328,7 +2328,7 @@ Optional Arguments: - ``title2`` - a second line of title text - ``state_text`` - ``state_map`` -- ``enabled`` - if set to 0 the switch cant be pressed but only shows status +- ``enabled`` - if set to 0 the switch can't be pressed but only shows status - ``momentary`` - after the set amount of milliseconds the old state returns (momentary button) Style Arguments: @@ -2659,11 +2659,11 @@ to the head includes or body includes. Custom widgets require their own special .js files, but to trigger a function from the javascript widget or from the body includes you can create a ``custom_javascript`` directory in the configuration directory. -All files that are placed in that directory will automaticly included in +All files that are placed in that directory will automatically included in Dashboard. All functions you place in a .js file inside that directory will be available everywhere in dashboard. -Remember that you do this on your own responsibility. javscript code in +Remember that you do this on your own responsibility. javascript code in those files can break Dashboards, and create vulnerabilities. Example Dashboards diff --git a/docs/DEV.rst b/docs/DEV.rst index 7f47120af..76617c0f3 100644 --- a/docs/DEV.rst +++ b/docs/DEV.rst @@ -134,7 +134,7 @@ It uses the ``pyproject.toml`` as the source from which to read the project depe Each file has the ``pip-compile`` command used to generated them as a reference. The runtime ``requirements.txt`` file is fundamental for efficiently building the ``Docker`` images: thanks to the Docker build cache, -the dependencies are only installed the first time in the build process, and are re-used from the Docker cache in subsequent builds. +the dependencies are only installed the first time in the build process, and are reused from the Docker cache in subsequent builds. This improves dramatically the build times, especially when there is the need to compile native dependencies. See :ref:`Docker build` for more information. diff --git a/docs/HASS_TUTORIAL.rst b/docs/HASS_TUTORIAL.rst index b2cc72243..1f89160a3 100644 --- a/docs/HASS_TUTORIAL.rst +++ b/docs/HASS_TUTORIAL.rst @@ -84,7 +84,7 @@ the table: keep track of things like the number of times a motion sensor has been activated, or how long it has been since a door opened - All the power of Python - use any of Python's libraries, create your - own modules, share variables, refactor and re-use code, create a + own modules, share variables, refactor and reuse code, create a single app to do everything, or multiple apps for individual tasks - nothing is off-limits! diff --git a/docs/HISTORY.md b/docs/HISTORY.md index 73cc7b4f5..ffcfe31df 100644 --- a/docs/HISTORY.md +++ b/docs/HISTORY.md @@ -7,7 +7,7 @@ - Added Pirateweather widget - contributed by [Dave Dixon](https://github.com/DaveDixon) - Added ability to know the topic associated with an MQTT message decode error - Added `expert` mode for python imports via the `import_method` directive -- Added `import_path` directive to enable python imports from arbitary paths +- Added `import_path` directive to enable python imports from arbitrary paths - Added access to the request object for both async and non-async http callbacks - contributed by [Eric Severance](https://github.com/esev) - Added option for N deg rising|setting to Scheduler._parse_time - Added `silent` parameter to `cancel_listen_state()` - contributed by [Daniel Rocha](https://github.com/danroc) @@ -127,12 +127,12 @@ None Moreno](https://github.com/xaviml) - Added the ability to reset a running timer via api - Removed a warning from info_timer() for stale handles -- Added the ability to supress invalid timer handle warnings in +- Added the ability to suppress invalid timer handle warnings in cancel_timer() - All scheduler calls and helper functions now support fractional timestamps. including parse_time() and now_is_between() - sunrise(), sunset(), parse_time() and parse_datetime() now allow you - to select today\'s sunrise/sunset, rather than the next occuring, + to select today\'s sunrise/sunset, rather than the next occurring, and specify a number of offset days - now_is_between() now supports specification of a timethat can be used for testing rather than using the current time @@ -153,7 +153,7 @@ None - Fixed issue with the inability to know which app\'s callback failed [constrain_state]{.title-ref} check - Fixed issue with AD giving messed up error messages -- Fixed an issue with scheduler.now_is_between() where it wasn\'t +- Fixed an issue with scheduler.now_is_between() where it wasn't\'t zeroing out microseconds leading to race conditions - Fixed another issue with now_is_between() relating to sunrise & sunset periods spanning midnight @@ -445,7 +445,7 @@ None example if wanting to persist entities within MQTT namespace - Moved the `appdaemon` reladed services to the `admin` namespace. So no more `appdaemon` namespace -- Added services for creating, editting, removing, enabling, disabling +- Added services for creating, editing, removing, enabling, disabling apps - Added ability to receive binary payload from MQTT broker - Added [cchardet](https://pypi.org/project/cchardet) and @@ -477,7 +477,7 @@ None [event/state/log/timer]{.title-ref}, it gives no warning its invalid - Fixed an issue with stream api using [get_state]{.title-ref} api call -- Fixed Azure packages by droping deprecated packages - contributed by +- Fixed Azure packages by dropping deprecated packages - contributed by [freezeboy](https://github.com/freezeboy) - Prevent the ability for apps to register services in non-existent namespaces @@ -560,7 +560,7 @@ None - If using user defined namespace, there is need to delete the present ones in the `namespaces` directory. - Due to the removal of the [appdaemon]{.title-ref} namespace, if - anyone was manaully making a service call using it, will need to be + anyone was manually making a service call using it, will need to be updated - `binary` is now a reserved keyword argument used when listening to MQTT events @@ -814,7 +814,7 @@ None - Added callback locking decorators - Rearchitected the work Q to allow App pinning and avoid re-entrant and concurrent code if desired -- Implemented multiple worker Ques to avoid Head of Line blocking +- Implemented multiple worker Queues to avoid Head of Line blocking - API Calls to control app pinning - Added the `run_in_thread()` api call - with assistance from [Odianosen Ejale](https://github.com/Odianosen25) diff --git a/docs/WIDGETDEV.rst b/docs/WIDGETDEV.rst index 20e2e9322..979ea090a 100644 --- a/docs/WIDGETDEV.rst +++ b/docs/WIDGETDEV.rst @@ -183,7 +183,7 @@ These could be different in another skin. In the base widget, there is code to change the icon from the on icon to the off icon in response to a touch or a state change triggered elsewhere. -The Base Widget has access to theses icon names when executing that code. +The Base Widget has access to these icon names when executing that code. Static Icons ~~~~~~~~~~~~ @@ -297,7 +297,7 @@ Widget HTML Files The HTML files exist to provide a basic layout for the widget and insert the styles. They are usually fairly simple. -By convention, the various tag types have styling suitable for some common elements although that can be overidden in +By convention, the various tag types have styling suitable for some common elements although that can be overridden in the css file or the skin: -

is styled for small text such as titles or state text @@ -539,7 +539,7 @@ The next step is to set up the widget to respond to various events such as butto There could be occasions when it is desirable to register for an event, and get the whole event data. -This is possible by registering and passing "DOMEventData" and boolen `true`, so that dashboard is aware of the fact the entire +This is possible by registering and passing "DOMEventData" and boolean `true`, so that dashboard is aware of the fact the entire event data is required. Below is an example .. code:: javascript diff --git a/pyproject.toml b/pyproject.toml index 862fc9b75..f908e63d1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ readme = "README.md" authors = [ {name = "Andrew I Cockburn", email = "appdaemon@acockburn.com"}, ] -dynamic = ["version"] # The verison is computed dynamically. See `tool.setuptools.dynamic` section below. +dynamic = ["version"] # The version is computed dynamically. See `tool.setuptools.dynamic` section below. license= { file = "LICENSE.md" } requires-python = ">=3.10" keywords=[ "appdaemon", "home", "automation" ] @@ -147,3 +147,10 @@ target-version = "py310" [tool.ruff.mccabe] # Unlike Flake8, default to a complexity level of 10. max-complexity = 10 + +[tool.codespell] +# Ref: https://github.com/codespell-project/codespell#using-a-config-file +skip = '.git*,*.svg,*.css,*.min.*,*.map,assets' +check-hidden = true +# ignore-regex = '' +ignore-words-list = 'hass,noone,dependee,dependees,whet,controle'