Utilities Overview
The pydoover.utils module provides a collection of utility functions and classes that simplify common tasks in pydoover applications. These utilities cover async/sync abstraction, signal processing, state management, and data manipulation.
Module Exports
All utilities are available directly from pydoover.utils:
from pydoover.utils import (
# Async/Sync helpers
call_maybe_async,
maybe_async,
get_is_async,
wrap_try_except,
wrap_try_except_async,
# Signal processing
apply_kalman_filter,
apply_async_kalman_filter,
PID,
# Alarms
create_alarm,
# Diff operations
apply_diff,
generate_diff,
maybe_load_json,
# Data structures
CaseInsensitiveDict,
CaseInsensitiveDictEncoder,
# Object searching
find_object_with_key,
find_path_to_key,
map_reading,
# Logging
setup_logging,
LogFormatter,
# Decorators
deprecated,
on_change,
)
# State management
from pydoover.state import StateMachine
Utility Categories
Async/Sync Helpers
Functions and decorators that help write code that works in both synchronous and asynchronous contexts.
| Function | Description |
|---|---|
call_maybe_async() | Call a function that may be sync or async |
maybe_async() | Decorator for unified sync/async method interfaces |
get_is_async() | Detect if running in async context |
wrap_try_except() | Exception wrapper for sync functions |
wrap_try_except_async() | Exception wrapper for async functions |
See Async Helpers for detailed documentation.
Signal Processing
Utilities for processing sensor data and implementing control loops.
| Class/Function | Description |
|---|---|
PID | PID controller implementation |
apply_kalman_filter() | Decorator for Kalman filtering |
apply_async_kalman_filter() | Async version of Kalman filter decorator |
See PID Controller and Kalman Filter for detailed documentation.
Alarm Utilities
State machine for threshold-based alarms with grace periods.
| Function | Description |
|---|---|
create_alarm() | Create an alarm that monitors function return values |
See Alarms for detailed documentation.
Diff Operations
Functions for generating and applying diffs between dictionaries.
| Function | Description |
|---|---|
apply_diff() | Apply a diff to a dictionary |
generate_diff() | Generate a diff between two dictionaries |
maybe_load_json() | Attempt to parse JSON, return original on failure |
See Diff Utilities for detailed documentation.
Data Structures
Specialized data structures for common patterns.
| Class | Description |
|---|---|
CaseInsensitiveDict | Dictionary with case-insensitive keys |
CaseInsensitiveDictEncoder | JSON encoder for CaseInsensitiveDict |
Object Searching
Functions for searching through nested dictionaries.
| Function | Description |
|---|---|
find_object_with_key() | Find a value by key in nested dict |
find_path_to_key() | Find the path to a key in nested dict |
map_reading() | Map sensor readings to output ranges |
Logging
Utilities for configuring application logging.
| Function/Class | Description |
|---|---|
setup_logging() | Configure logging with optional formatters |
LogFormatter | Color-coded log formatter |
Decorators
General-purpose decorators.
| Decorator | Description |
|---|---|
deprecated() | Mark functions/classes as deprecated |
on_change() | Trigger callback when return value changes |
State Management
The StateMachine class from pydoover.state provides a wrapper around the transitions library for managing application state with timeouts.
| Class | Description |
|---|---|
StateMachine | State machine with timeout support and async callbacks |
See State Machine for detailed documentation.
Quick Examples
Setting Up Logging
from pydoover.utils import setup_logging # Enable debug logging setup_logging(debug=True) # Standard info logging setup_logging(debug=False)
Case-Insensitive Dictionary
from pydoover.utils import CaseInsensitiveDict config = CaseInsensitiveDict() config["API_KEY"] = "secret123" # All of these access the same value print(config["api_key"]) # "secret123" print(config["Api_Key"]) # "secret123" print(config["API_KEY"]) # "secret123"
Finding Values in Nested Structures
from pydoover.utils import find_object_with_key, find_path_to_key
data = {
"sensors": {
"temperature": {
"value": 23.5,
"unit": "celsius"
}
}
}
# Find the value
value = find_object_with_key(data, "value")
print(value) # 23.5
# Find the path to the key
path = find_path_to_key(data, "value")
print(path) # "sensors.temperature.value"
Mapping Sensor Readings
from pydoover.utils import map_reading # Map a 4-20mA reading to a 0-100 range raw_value = 12 # mA output_values = [0, 100] raw_readings = [4, 20] mapped = map_reading(raw_value, output_values, raw_readings) print(mapped) # 50.0
Deprecation Decorator
from pydoover.utils import deprecated
@deprecated("Use new_function() instead")
def old_function():
pass
@deprecated
def another_old_function():
pass
On Change Callback
from pydoover.utils import on_change
class SensorMonitor:
def handle_change(self, new_val, old_val, is_first, name):
if not is_first:
print(f"{name} changed from {old_val} to {new_val}")
@on_change("handle_change", name="temperature")
def read_temperature(self):
# Return current temperature
return self.sensor.read()
Related Pages
- Async Helpers - Sync/async abstraction utilities
- PID Controller - PID control implementation
- Kalman Filter - Signal filtering for sensor data
- Alarms - Threshold-based alarm system
- Diff Utilities - Dictionary diff operations
- State Machine - State management with timeouts