juham.app¶
Module: Juham Applications
Description:
This module implements applications built on top of the Juham framework. It provides a set of base classes and utilities that serve as the foundation for developing home automation applications. These classes enable seamless integration and interaction with various components of a home automation system, facilitating the creation of robust and customizable automation solutions.
Features:
Modular Plugin Architecture: Design and implement home automation applications with a modular approach.
Extensible Base Classes: Extendable classes that can be customized to meet specific automation requirements.
Seamless Integration: Smooth integration with the Juham framework and its components.
Event Handling: Efficient event handling and response mechanisms for real-time automation.
Logging and Error Handling: Comprehensive logging and error handling for reliable application performance.
Serialization: Robust serialization system for configuring applications with file formats e.g. JSON.
Usage:
To create a home automation application, extend the provided base classes with your custom logic and configurations. Instantiate and configure your application, then run it to start automating your home.
Example:
from juham.app import JApp
class MyHomeAutomationApp(JApp):
def __init__(self, name):
super().__init__(name)
# Custom initialization code here
def handle_event(self, event):
# Custom event handling code here
app = MyHome("cottage")
app.run()
- class juham.app.JApp(name)[source]¶
Bases:
Group
Default application class.
Configures Base class with JPaho2 MQTT and JInflux time series database. It is up to the sub classes to initialize appropriate JInflux toke, org, host and database attributes to match the Influx account in question.
- add(h)¶
Add new automation object as children. The object to be inserted must be derived from Object base class.
- Parameters:
h (Object) – object to be inserted.
- Return type:
None
- app_name = 'juham'¶
- classmethod classattrs_from_dict(attributes)¶
Set class attributes from a dictionary.
- classmethod classattrs_to_dict()¶
Convert class attributes to a dictionary.
- config_folder = 'config'¶
- configure()[source]¶
Application instance specific configuration tasks.
Up to the sub classes to implement.
- Return type:
None
- copy()¶
Create and return a copy of the current object.
This method serializes the current object to a dictionary using the to_dict method, creates a new instance of the object’s class, and populates it with the serialized data using the from_dict method.
This method uses class identifier based instantiation (see factory method pattern) to create a new instance of the object, and ‘to_dict’ and ‘from_dict’ methods to initialize object’s state.
- Returns:
A new instance of the object’s class with the same state as the original object.
Example:
john = Human("john") john.height = 1.8 john.age = 62 clone_of_john = john.copy()
- database_class_id: str = 0¶
- debug(msg, details='')¶
Logs the given debug message to the database after logging it using the BaseClass’s info() method.
- Parameters:
msg (str) – The information message to be logged.
details (str) – Additional detailed information for the message to be logged
- deserialize_from_json(f)¶
Load attributes from a JSON file.
- epoc2utc(epoch)¶
Converts the given epoch time to UTC time string. All time coordinates are represented in UTC time. This allows the time coordinate to be mapped to any local time representation without ambiguity.
- Parameters:
epoch (float) – timestamp in UTC time
rc (str) – time string describing date, time and time zone e.g 2024-07-08T12:10:22Z
- Returns:
UTC time
- error(msg, details='')¶
Logs the given error message to the database after logging it using the BaseClass’s info() method.
- Parameters:
msg (str) – The information message to be logged.
details (str) – Additional detailed information for the message to be logged
- classmethod find_class(class_id)¶
Given class identifier find the registered class. If no class with the give identifier exists return None.
- Parameters:
class_id (int) – class identifier
- Returns:
class or null if not registered
- Return type:
obj (obj)
- find_plugin(name, cls)[source]¶
Check if the application contains the given plugin, as defined by its name and class, and return the plugin.
- Returns:
plugin object if found, None if the application does not contain a plugin of that name and type
- from_dict(data)¶
Recursively deserialize the group from a dictionary, including it children.
- Parameters:
data (dict) – data to deserialize from.
Example:
from juham.base import Group, Base # create a group with a child group = Group("foo") base = Base("bar") group.add(base) # group to dictionary data = group.to_dict() copy_of_group = Group() copy_of_group.from_dict(data)
- classmethod get_class_id()¶
Return the class id of the class. Each class has an unique identifier that can be used for instantiating the class via
Object.instantiate()
method.- Parameters:
cls (class) – class
- Return type:
str
- Returns:
id (int) unique class identifier through which the class can be instantiated by factory method pattern.
- classmethod get_json_file()¶
Generate the JSON file name based on the class name.
The file is created into users home folder.
- info(msg, details='')¶
Logs the given information message to the database after logging it using the BaseClass’s info() method.
- Parameters:
msg (
str
) – The information message to be logged.details (
str
) – Additional detailed information for the message to be logged
Example:
obj = new Base('test') obj.info('Message arrived', str(msg))
- init_database(name)¶
Instantiates the configured time series database object.
Issues a warning if the
database_class_id
has not been configured, in which case the object will not have the time series recording feature.This method is called internally and typically there is no need to call it from the application code.
- Return type:
None
- init_mqtt(name)¶
Instantiates the configured MQTT object for networking.
This method is called internally and typically there is no need to call it from the application code.
Issues a warning if the
pubsub_class_id
has not been configured, even though objects without a capability to communicate are rather crippled.- Return type:
None
- classmethod initialize_class(load_class_attrs=True)¶
Initialize the class for instantiation, if not initialized already. This method initializes the class identifier and deserializes the public attributes from the specified configuration folder.
- Parameters:
load_class_attrs (bool, optional) – If true then attempts to initialize class attributes
True. (from the class specific configuration files. Defaults to)
- Returns:
returns true if the class was initialized, false implies the class is already initialized in which case the method call has no effect.
- Return type:
bool
- classmethod instantiate(class_id)¶
Create an instance of the class corresponding to the given class identifier. This method implements the factory method pattern, which is essential for a plugin architecture.
- Parameters:
class_id (int) – Identifier of the class to instantiate.
- Returns:
An instance of the class corresponding to the given class identifier.
- Return type:
obj
- classmethod instantiate_plugins(plugin_classes)[source]¶
Instantiates all installed plugin classes with their default names. This method is provided for testing purposes only, or for small home automation applications that needs only one instance per class.
- Parameters:
plugins (list) – list of plugin classes
- Return type:
list
- Returns:
list of plugin objects
- classmethod instantiate_with_param(class_id, param)¶
Given class identifier and one constructor argument create the corresponding object.
- Parameters:
class_id (
str
) – class identifierparam (
Any
) – class specific constructor parameter
- Returns:
instance of the given class.
- Return type:
obj
- classmethod is_abstract()¶
Check whether the class is abstract or real. Override in the derived sub-classes. The default is False.
- Return type:
bool
- Returns:
True (bool) if abstract
- is_time_between(begin_time, end_time, check_time=None)¶
Check if the given time is within the given time line. All timestamps must be in UTC time.
- Parameters:
begin_time (timestamp) – beginning of the timeline
end_time (timestamp) – end of the timeline
check_time (timestamp) – time to be checked
- Returns:
True if within the timeline
- Return type:
rc (bool)
- classmethod load_from_json()¶
Load class attributes from a JSON file.
- log_message(type, msg, details='')¶
Publish the given log message to the MQTT ‘log’ topic.
This method constructs a log message with a timestamp, class type, source name, message, and optional details. It then publishes this message to the ‘log’ topic using the MQTT protocol.
- Parameters:
type – str The classification or type of the log message (e.g., ‘Error’, ‘Info’).
msg – str The main log message to be published.
details – str, optional Additional details about the log message (default is an empty string).
- Returns:
None
- Raises:
Exception – If there is an issue with the MQTT client while publishing the message.
Example:
# publish info message to the Juham's 'log' topic self.log_message("Info", f"Some cool message {some_stuff}", str(dict))
- mqtt_class_id: str = ''¶
- mqtt_host: str = 'localhost'¶
- mqtt_port: int = 1883¶
- mqtt_root_topic: str = 'juham'¶
- on_connect(client, userdata, flags, rc)¶
Notification on connect.
This method is called whenever the MQTT broker is connected. For more information on this method consult MQTT documentation available in many public sources.
- Parameters:
client (obj) – MQTT client
userdata (Any) – application specific data
flags (int) – Consult MQTT
rc (int) – See MQTT docs
- on_disconnect(client, userdata, rc=0)¶
Notification on disconnect.
This method is called whenever the MQTT broker is disconnected. For more information on this method consult MQTT documentation available in many public sources.
- Parameters:
client (obj) – MQTT client
userdata (Any) – application specific data
rc (int) – See MQTT docs
- on_message(client, userdata, msg)¶
MQTT message notification on arrived message.
Called whenever a new message is posted on one of the topics the object has subscribed to via subscribe() method. This method is the heart of automation: here, derived subclasses should automate whatever they were designed to automate. For example, they could switch a relay when a boiler temperature sensor signals that the temperature is too low for a comforting shower for say one’s lovely wife.
For more information on this method consult MQTT documentation available in many public sources.
- Parameters:
client (obj) – MQTT client
userdata (Any) – application specific data
msg (object) – The MQTT message
- classmethod parse_args()¶
Parse the startup arguments defined by this class.
- Return type:
None
-
plugins:
List
= []¶
- publish(topic, msg, qos=1, retain=True)¶
Publish the given message to the given MQTT topic. For more information consult MQTT.
- Parameters:
topic (str) – topic
msg (str) – message to be published
qos (int, optional) – quality of service. Defaults to 1.
retain (bool, optional) – retain. Defaults to True.
- pubsub_class_id = 0¶
- read(point)¶
Reads the given measurement from the database.
- Parameters:
point – point with initialized time stamp.
… note: NOT IMPLEMENTED YET
- classmethod register()[source]¶
Register the class to the class database.
Once registered the class can be instantiated by its class identifier. Note that this method is called automatically by the system when the python loads the class. In this method sub classes should prepare themselves for instantiation by initializing their class attributes, for example.
- classmethod register_class(class_id, ctor)¶
Register the given class identifier for identifier based instantiation . This, factory method pattern, as it is called, decouples the actual implementation from the interface. For more information see
instantiate()
method.- Parameters:
class_id (str) – class identifier
ctor (function) – constructor
- classmethod register_topic(topic)¶
Register the given topic as known valid topic. Publishing and subscriptions are allowed only to registered topics. Each topic must have an owner, who is responsible for registering the topic.
- Parameters:
topic (str) – valid topic
- run()¶
Start up all automation objects in the group and enter the network event loop to process MQTT messages.
The method returns only when the process is terminated by some means e.g. Ctrl+C or kill, or by sending ‘quit’ event to MQTT message broker.
- Return type:
None
- run_forever()¶
Starts the network loop and blocks the main thread, continuously running the loop to process MQTT messages.
The loop will run indefinitely unless the connection is lost or the program is terminated.
- classmethod save_to_json()¶
Create class configuration file, if the file does not exist yet.
- serialize_to_json(f)¶
Serialize.
- classmethod set_log(l)¶
Set logger.
- Parameters:
l (logger) – logger object
- Return type:
None
- shutdown()¶
Shut down all services, free resources, stop threads, disconnect from mqtt, in general, prepare for shutdown.
- subscribe(topic)¶
Subscribe to the given MQTT topic.
This method sets up the subscription to the specified MQTT topic and registers the
on_message()
method as the callback for incoming messages.- Parameters:
topic (str) – The MQTT topic to subscribe to.
- Return type:
None
Example:
# configure obj.subscribe('foo/bar')
- timestamp()¶
Returns the current date-time in UTC.
- Returns:
datetime in UTC.
- Return type:
rc (datetime)
- timestampstr(ts)¶
Converts the given timestamp to human readable string of form ‘Y-m-d H:M:S’.
- Parameters:
ts (timestamp) – time stamp to be converted
- Returns:
human readable date-time string
- Return type:
rc (string)
- to_dict()¶
Convert instance attributes to a dictionary.
- valid_topic(topic)¶
Check if the given topic has been registered as valid topic.
- Parameters:
topic (str) – topic to be validated
- Returns:
true if known topic.
- Return type:
bool
- warning(msg, details='')¶
Logs the given warning message to the database after logging it using the BaseClass’s info() method.
- Parameters:
msg (str) – The information message to be logged.
details (str) – Additional detailed information for the message to be logged
- write(point)¶
Writes the given measurement to the database. In case of an error, it tries again until the maximum number of attempts is reached. If it is still unsuccessful, it gives up and passes the first encountered exception to the caller.
- Parameters:
point – a measurement describing a time stamp and related attributes for one measurement.
- write_attempts = 3¶