Creating your first Thymis module
This guide walks you through creating your first custom Thymis module — a temperature logger that simulates sensor readings and writes them to a log file.
Step 1: Create the Module File
Create a Python file named temperature_logger.py in a directory with the structure:
my-thymis-project/
├── README.md (must contain "contains thymis modules")
├── flake.nix
└── my_project_name/
├── __init__.py
└── temperature_logger.pyFile content:
README.md:
# Temperature Logger
This projects contains thymis modulesflake.nix:
{
description = "";
inputs = {
};
outputs = { self }: {
};
}temperature_logger.py:
from thymis_controller.modules.modules import Module, Setting, LocalizedString
from thymis_controller.project import Project
from thymis_controller import models
import pathlib
class TemperatureLoggerModule(Module):
display_name: LocalizedString = "Temperature Logger"
# Module settings
log_file = Setting(
display_name="Log File Path",
type="string",
default="/var/log/temp.log",
description="Where to store temperature logs"
)
interval = Setting(
display_name="Logger Interval (seconds)",
type="int",
default=60,
description="Time between readings"
)
unit = Setting(
display_name="Temperature Unit",
type="string",
default="°C",
description="Display unit for temperature"
)
def write_nix_settings(self, f, path, module_settings, priority, project: Project):
# Extract configured settings with fallback to defaults
log_file = module_settings.settings.get("log_file", self.log_file.default)
interval = module_settings.settings.get("interval", self.interval.default)
unit = module_settings.settings.get("unit", self.unit.default)
# Create Python script using Nix's writePython3 helper
script = (
"import time\n"
"from datetime import datetime\n"
"from random import uniform\n\n"
"while True:\n"
" temp = uniform(20.0, 30.0)\n"
" timestamp = datetime.now().isoformat()\n"
f" with open('{log_file}', 'a') as f:\n"
f" f.write(f"{{timestamp}} Temperature: {{temp:.2f}}{unit}\n")\n"
f" time.sleep({interval})\n"
)
# Generate NixOS configuration
f.write(
"systemd.services.temperature-logger = {\n"
" description = "Temperature Logger";\n"
" wantedBy = ["multi-user.target"];\n"
" serviceConfig = {\n"
f" ExecStart = pkgs.writers.writePython3 "temp_logger" {{}} ''{script}'';\n"
" Restart = "always";\n"
" };\n"
"};\n"
)Thymis Python Package
To add the thymis_controller package to your local project, install it directly from the Thymis GitHub repository.
This is not required but makes development much easier. Here we use uv to add the package:
uv add git+ssh://git@github.com/Thymis-io/thymis#subdirectory=controllerPart Breakdown
Module Structure
- Imports — required base classes and helper functions.
- Settings — exposed configurations in the Thymis UI.
write_nix_settings— generates:- Python logger script.
systemdservice configuration.
Setting Types
| Setting | Type | Purpose |
|---|---|---|
log_file | string | Output file path |
interval | integer | Seconds between measurements |
unit | string | Temperature unit symbol |
Generated Infrastructure
- Persistent systemd service using
writePython3 - Random temperature simulation (20‑30 °C range)
- ISO‑timestamped log entries
Step 2: Add the Repository to Thymis
- Upload your module repository to GitHub/GitLab.
- In Thymis UI: External Repositories → Add Repository.
- Enter your repository URL.
Step 3: Add the Module to Devices
- Create a new configuration or edit an existing one.
- + Add Module → Select “Temperature Logger”.
- Configure settings:
- Set log file path (
/var/log/temps.log) - Adjust interval (e.g., 120 seconds)
- Set log file path (
- Commit → Deploy
Step 4: Verify Operation
Access the device via terminal:
# Check service status
systemctl status temperature-logger
# View logs
tail -f /var/log/temp.log
# Sample output:
# 2025-03-15T14:32:18.12345 Temperature: 24.71°CNext Steps
- Make parameters configurable via tags.
- Add secret authentication for remote APIs.
- Create dashboard integrations.
- Review the Full Module Class API Reference for advanced capabilities like
register_secret_settings, custom setting types, and icon embedding.
Tip: For physical sensors, replace the random number generator with hardware interface libraries like
gpiozeroorAdafruit_DHTin your Python script. Just add required packages to your NixOS configuration!