/patch

Home Assistant Integration for patching HA's files

Primary LanguagePythonMIT LicenseMIT

Patch

HACS Badge

GitHub Release

Download Analytics

Project Maintenance

Patch Home Assistant Core files

Note: This is an advanced integration. If you are not a programmer, you probably don’t want to play with it.

There are cases when a code change is slow to happen. For example, integrations have often dependency libraries which are maintained by a single person or a very small set of people. The pace of a change (e.g. code review, releasing a new version, etc') can take weeks. This integration mitigates such situations by allowing a short-term patch of the system. In addition, the patch will get re-applied after a Home Assistant update which brings a fresh container (overriding all patches).

Note: When the change is inside an integration code, it's possible to override the entire integration using the instructions here. This is a better way for such situation. However, when the change is inside a dependency library, it's not straightforward to use the method above. This is a scenario where this integration can come handy.

Configuration

configuration.yaml should be used (there is no UI on purpose). Here is an example:

patch:
  delay: 60
  restart: true
  files:
    - name: adm_mapping.json
      base: /share/fileserver/pysiaalarm/base/data
      destination: "{site-packages}/pysiaalarm/data"
      patch: /share/fileserver/pysiaalarm/patch/data

delay is an optional integer parameter, with a default of 300 (seconds, which is 5 minutes). This is the delay between the startup time of the integration and when it applies the patches.

restart is an optional boolean parameter, with a default of true. If a patch was applied (to one file or more) and this parameter is true the integration initiates a restart of Home Assistant (Core). This should happen only once since the next time (after the restart) there should be no further patches.

files is a list of patches to apply. Each item on the list has the following properties (all are mandatory):

  • name: the file name
  • base: the directory containing an original copy of the file (before the patch). The patch happens only if the content of the file to be patched (destination/name) is identical to the content of the base file (base/name). Otherwise, a repair issue is raised. In such a case, a rebase of the patch is required along with updating the content of the files base/name and patch/name.
  • destination: the local directory with the file to be patched.
  • patch: the directory containing the file with the change.

All files must exist (e.g. base/name, etc') inside the Home Assistant Core environment. It’s convenient to mount base and patch directories as network shares.

The destination directory can use the following variables as a prefix:

  1. site-packages: path to the location of Python libraries (e.g. /usr/local/lib/python3.12/site-packages).
  2. homeassistant: path to the homeassistant directory, i.e. /usr/src/homeassistant/homeassistant (the 2nd /homeassistant is not a mistake. There is homeassistant directory under the root.)

Install

HACS is the preferred and easier way to install the component, and can be done by using this My button:

Open your Home Assistant instance and open a repository inside the Home Assistant Community Store.

Otherwise, download patch.zip from the latest release, extract and copy the content under custom_components directory.

Home Assistant restart is required once the integration files are copied (either by HACS or manually). After the restart, the configuration.yaml should be edited and the patch section should be created. An additional restart is required after that for the integration to be loaded.

File System structure

Home Assistant can run in different configurations. A common one is Home Assistant Operating System, which will be used in the explanation below. In this configuration Home Assistant Core runs as a container. The 2 most relevant directories are:

  1. /usr/src/homeassistant: this is the place with Home Assistant files built from the Core repository. The variable homeassistant can be used as a prefix in the destination parameter and it will be resolved to /usr/src/homeassistant/homeassistant (the 2nd /homeassistant is not a mistake. There is homeassistant directory under the root.)
  2. /usr/local/lib/python3.12/site-packages: this is the place where Python libraries are installed. (Note: python3.12 will be changed when Home Assistant upgrades its Python version.) The variable site-packages can be used as a prefix in the destination parameter and it will be resolved automatically.

It’s possible to explore the environment along with the file system structure and content by:

  1. SSH-ing into the host. Instructions are here.
  2. In the SSH session switch into Home Assistant Core’s container via the command: docker exec -it homeassistant /bin/bash

Reload

The integration also exposes a reload action. The delay parameter is ignored in this case and the logic is executed immediately, including Home Assistant restart, when needed.

Re-patching

It's not possible to re-patch a file by simply updating the content of patch/name. The problem is that destination/name was already patched, so it's different than base/name and therefore will not be patched again. The solution is to change base to be the same as destination. This will cause the comparison to succeed as both will be pointing the same file. Once the patch is applied, base should get reverted to it's original value, so the patch can be safely re-applied on Home Assistant update (only if the file is still identical to base.)