pyg90alarm.dataclass.load_save

Base class for loading/saving dataclasses to a device.

Functions

field_readonly_if_not_provided(*args[, default])

Helper function to create a dataclass field with ReadOnlyIfNotProvided descriptor.

Classes

DataclassLoadPolicy()

Defines strategy for loading dataclass-backed panel entity.

DataclassLoadSave()

Base class for loading/saving dataclasses to a device.

LoadOnceDataclassLoadPolicy()

Loads entity from the device once per G90Alarm instance.

Metadata()

Metadata keys for DataclassLoadSave fields.

NoCacheDataclassLoadPolicy()

Always loads entity from the panel.

ReadOnlyIfNotProvided([default, ...])

Descriptor for dataclass fields to be read-only if not provided during initialization.

TtlDataclassLoadPolicy(ttl_seconds)

Reuses loaded entity for a given parent within a TTL.

Exceptions

ReadOnlyIfNotProvidedError

Raised when assigning to a ReadOnlyIfNotProvided field that was omitted during instance construction.

class pyg90alarm.dataclass.load_save.DataclassLoadPolicy

Bases: object

Defines strategy for loading dataclass-backed panel entity.

async load(cls, parent, force=False)

Load entity according to the policy.

Return type:

TypeVar(DataclassLoadSaveT, bound= DataclassLoadSave)

class pyg90alarm.dataclass.load_save.NoCacheDataclassLoadPolicy

Bases: DataclassLoadPolicy

Always loads entity from the panel.

async load(cls, parent, force=False)

Always load from the device, ignoring force.

Return type:

TypeVar(DataclassLoadSaveT, bound= DataclassLoadSave)

class pyg90alarm.dataclass.load_save.TtlDataclassLoadPolicy(ttl_seconds)

Bases: DataclassLoadPolicy

Reuses loaded entity for a given parent within a TTL.

async load(cls, parent, force=False)

Load from cache when fresh, otherwise read from the device.

Return type:

TypeVar(DataclassLoadSaveT, bound= DataclassLoadSave)

class pyg90alarm.dataclass.load_save.LoadOnceDataclassLoadPolicy

Bases: DataclassLoadPolicy

Loads entity from the device once per G90Alarm instance.

Subsequent load calls return the same in-memory object until force=True (or the parent alarm instance is garbage-collected).

async load(cls, parent, force=False)

Load from cache when present, otherwise read from the device.

Return type:

TypeVar(DataclassLoadSaveT, bound= DataclassLoadSave)

class pyg90alarm.dataclass.load_save.Metadata

Bases: object

Metadata keys for DataclassLoadSave fields.

exception pyg90alarm.dataclass.load_save.ReadOnlyIfNotProvidedError

Bases: ValueError

Raised when assigning to a ReadOnlyIfNotProvided field that was omitted during instance construction.

add_note(note, /)

Add a note to the exception

with_traceback(tb, /)

Set self.__traceback__ to tb and return self.

class pyg90alarm.dataclass.load_save.ReadOnlyIfNotProvided(default=<pyg90alarm.dataclass.validation._DefaultNotSet object>, trust_initial_value=False)

Bases: ValidatorBase[T]

Descriptor for dataclass fields to be read-only if not provided during initialization.

The field can be read, but attempts to modify it will raise ReadOnlyIfNotProvidedError (a ValueError subclass) if the field was not provided during initialization. In other words, the only way to set the value is during object creation.

Example usage:

@dataclass class Example:

read_only_field: Optional[int] = field_readonly_if_not_provided(

default=None

)

# Works ok ex = Example(read_only_field=42) print(ex.read_only_field) # Outputs: 42 ex.read_only_field = 100 # Works ok

# Raises ReadOnlyIfNotProvidedError ex2 = Example() print(ex2.read_only_field) # Outputs: None ex2.read_only_field = 100 # Raises ReadOnlyIfNotProvidedError

Parameters:

default (TypeVar(T) | _DefaultNotSet) – Default value to return upon read if not provided during initialization.

pyg90alarm.dataclass.load_save.field_readonly_if_not_provided(*args, default=None, **kwargs)

Helper function to create a dataclass field with ReadOnlyIfNotProvided descriptor.

Parameters:
  • args (Any) – Positional arguments to pass to dataclasses.field().

  • default (TypeVar(T) | None) – Default value to return upon read if not provided during initialization.

  • kwargs (Any) – Keyword arguments to pass to dataclasses.field().

Return type:

TypeVar(T)

Returns:

A dataclass field with ReadOnlyIfNotProvided descriptor attached.

class pyg90alarm.dataclass.load_save.DataclassLoadSave

Bases: object

Base class for loading/saving dataclasses to a device.

There are multiple ways to implement the functionality:
  • Encapsulate the dataclass inside another class that handles loading/saving and exposes dataclass fields as properties. The latter part gets complex as properties need to be asynchronous, as well as added dynamically at runtime to improve maintainability.

  • Inherit from this class, which provides load and save methods on top of standard dataclasses. This is believed to be more concise and easier to understand.

Implementing classes must define LOAD_COMMAND and SAVE_COMMAND class variables to specify which commands to use for loading and saving data.

Example usage:

@dataclass class G90ExampleConfig(DataclassLoadSave):

LOAD_COMMAND = G90Commands.GETEXAMPLECONFIG SAVE_COMMAND = G90Commands.SETEXAMPLECONFIG field1: int field2: str

# Loading data config = await G90ExampleConfig.load(G90_alarm_instance) print(config.field1, config.field2)

# Modifying and saving data config.field1 = 42 await config.save()

serialize()

Returns the dataclass fields as a list.

Handles specific metadata for the fields. :seealso:`Metadata`.

Return type:

List[Any]

Returns:

Dataclass serialized as list.

async save()

Save the current data to the device.

Refreshes the load policy cache (if any): the initial load(..., force=True) repopulates the policy’s entry for this parent with the newly loaded instance used for read-modify-write.

Return type:

None

async classmethod load(parent, force=False)

Create an instance with values loaded from the device.

Parameters:

force (bool) – If True, bypass policy cache (if any).

Return type:

TypeVar(DataclassLoadSaveT, bound= DataclassLoadSave)

Returns:

An instance of the dataclass loaded from the device.

async classmethod load_uncached(parent)

Create an instance with values loaded from the device bypassing cache.

Return type:

TypeVar(DataclassLoadSaveT, bound= DataclassLoadSave)