Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
9e2f01e
Add new parameters/visibilities/calculations names (#204)
Guzz-T Dec 22, 2025
930b09b
Support Smart-Home-Interface Part 5: Main interface (#203)
Guzz-T Dec 22, 2025
25c7f70
Remove socket.MSG_DONTWAIT to be able to use the source code under Wi…
Guzz-T Dec 23, 2025
d24f8c8
Call main() in case the module is called via "python -m luxtronik"
Guzz-T Dec 23, 2025
17d03a4
Move time.sleep(WAIT_TIME_AFTER_PARAMETER_WRITE) into _write()
Guzz-T Dec 23, 2025
c6b1c0e
Add properties for accessing the data field definitions
Guzz-T Dec 23, 2025
a71a292
Emulate the ID_WEB_SoftStand field from version 0.3.14
Guzz-T Dec 23, 2025
46b743e
Ensure that only integer values are written to the parameter queue.
Guzz-T Dec 23, 2025
60f6a2d
Compare data field names case-insensitive
Guzz-T Dec 23, 2025
70a8d41
Return "Unknown_{value}" for not supported selections
Guzz-T Dec 23, 2025
cc76dfe
Merge pull request #212 from Guzz-T/issue/197/selection
kbabioch Dec 25, 2025
e4ae6fd
Merge pull request #211 from Guzz-T/issue/198/lower-case
kbabioch Dec 25, 2025
9284067
Merge pull request #210 from Guzz-T/issue/198/compatibility
kbabioch Dec 25, 2025
c9b6f17
Merge pull request #209 from Guzz-T/try/wait
kbabioch Dec 25, 2025
0f36718
Merge pull request #208 from Guzz-T/try/windows
kbabioch Dec 25, 2025
ac34f26
Integrate the smart-home-interface into the luxtronik object
Guzz-T Dec 23, 2025
20f9956
Add scripts for the smart-home-interface
Guzz-T Dec 23, 2025
ad55b87
Add unit tests for the smart-home-interface integration
Guzz-T Dec 23, 2025
ddf0d07
Use the spelling "smart home interface" consistently
Guzz-T Dec 27, 2025
c3d5f95
Merge pull request #207 from Guzz-T/issue/190/integration
kbabioch Dec 30, 2025
3440df6
Update smart home interface definitions according to (in)official doc…
Guzz-T Dec 25, 2025
f031c67
Refine lpc_mode description
Guzz-T Dec 25, 2025
6745492
Add some thermal energy definitions
Guzz-T Dec 26, 2025
00603fd
Report an error in case to_heatpump() returns None
Guzz-T Dec 27, 2025
a3050ba
Return None instead of Unknown_None from SelectionBase.from_heatpump()
Guzz-T Dec 27, 2025
8f23057
Only attempt to resolve "unknown" for string-based values
Guzz-T Dec 27, 2025
30a2b03
Allow the value of SelectionBase to be set using an integer or intege…
Guzz-T Dec 27, 2025
b505e30
Remove redundant datatype_class = "selection" assignment
Guzz-T Dec 27, 2025
9c9dc1a
Correct MixedCircuitMode description
Guzz-T Dec 27, 2025
156bad7
Handle contiguous values that are distributed across multiple registe…
Guzz-T Dec 27, 2025
4d43428
Enhance ScalingBase so that it can also handle non-4-byte values.
Guzz-T Dec 27, 2025
333c385
Add 16-bit temperature data types
Guzz-T Dec 27, 2025
956eeea
Add a buffer-type data-type
Guzz-T Dec 27, 2025
48b5e8d
Add "0" to data-type Errorcode to indicate "no error"
Guzz-T Dec 27, 2025
3d31e05
Add a BitMaskBase data-type
Guzz-T Dec 27, 2025
64d3af7
Use BitMaskBase as base class for the HeatPumpState data-type
Guzz-T Dec 27, 2025
9a48710
Further updates of the smart home interface definitions according to …
Guzz-T Dec 27, 2025
90576cb
Refactored "state" to "status" for shi data-types
Guzz-T Dec 27, 2025
24ca59b
Fix power data-type for shi register
Guzz-T Dec 28, 2025
50e9500
Add a testcase with obsolete entry names
gerw Oct 31, 2024
732e6e3
Add an adapted version of test_compatibility.py from gerw's #171
Guzz-T Jan 1, 2026
f9eeb54
Increase pytest coverage for data vectors
Guzz-T Jan 1, 2026
6fd1bb7
Establish the socket connection only when necessary
Guzz-T Dec 28, 2025
296be2e
Add information about the shi to the README.md
Guzz-T Jan 1, 2026
c214c23
Re-add the `datatype_unit` information as base.unit class property
Guzz-T Jan 1, 2026
0693025
Add the shi scripts to the CLI
Guzz-T Jan 1, 2026
82f4c0f
Add a note about the necessary activation of the shi
Guzz-T Jan 1, 2026
12f7b95
Add definitions for the config interface f.k.a socket interface simil…
Guzz-T Jan 2, 2026
05fe498
Remove unused includes
Guzz-T Jan 2, 2026
3110a68
Merge pull request #216 from Guzz-T/issue/196/connection
kbabioch Jan 3, 2026
d0ea85b
Merge pull request #213 from Guzz-T/try/shi-fields
kbabioch Jan 3, 2026
9922a4f
Merge pull request #218 from Guzz-T/try/cfi-definitions
kbabioch Jan 3, 2026
dfb25c6
Merge pull request #187 from Guzz-T/issue/168/compatibility
kbabioch Jan 3, 2026
63c406c
Use a case-insensitive compare to set the options of SelectionBase
Guzz-T Jan 2, 2026
39313d4
Use relative links instead of absolute links
Guzz-T Jan 5, 2026
d55118e
Merge pull request #217 from Guzz-T/issue/214/readme
kbabioch Jan 5, 2026
7b94645
Fix write_all() and write_and_read() description and supported data-t…
Guzz-T Jan 5, 2026
3a48e5e
Merge pull request #220 from Guzz-T/try/fix-write
kbabioch Jan 5, 2026
add35cf
Prepare the SHI definition classes so that they can also be used for …
Guzz-T Jan 5, 2026
34c18cc
Return an Unknown() field with a lowercase name for undefined configu…
Guzz-T Jan 5, 2026
7a03c12
Use the information from the definition list to initialize the data v…
Guzz-T Jan 5, 2026
1762308
Update README.md
Guzz-T Jan 5, 2026
ea8aa80
Merge pull request #222 from Guzz-T/issue/221/definitions
kbabioch Jan 6, 2026
aa7667b
Merge pull request #219 from Guzz-T/try/case-insensitive-options
kbabioch Jan 6, 2026
dcf3454
Restructure source code and imports. No effective code change.
Guzz-T Jan 6, 2026
639fe84
First attempt to auto generate docs
Bouni Dec 12, 2024
3362c36
Comment branch constraint for testing purposes
Bouni Dec 12, 2024
471cc65
Trigger CI
Bouni Dec 12, 2024
d068f79
Add uv venv
Bouni Dec 12, 2024
a061d60
Import instead of regex
Bouni Dec 16, 2024
3379c94
Cleanup 🧹
Bouni Dec 16, 2024
1c91c27
Update bulma css to 1.0.4
Bouni Dec 22, 2025
9bdcd54
Improved style of docs
Bouni Dec 22, 2025
ad3851d
Improved the docs
Bouni Dec 22, 2025
0e6c69e
Update actions
Bouni Dec 22, 2025
1f8fd36
Minor improvements
Bouni Dec 22, 2025
e7a8dd8
Add more polish
Bouni Dec 22, 2025
7ee342f
Only trigger when a push to main is done
Bouni Dec 22, 2025
7f225ea
Add link to the docs to the README
Bouni Dec 22, 2025
219849c
Use the definitions to create the documentation
Guzz-T Jan 6, 2026
548050a
Merge pull request #223 from Guzz-T/issue/221/common
kbabioch Jan 6, 2026
0eff359
Use the definitions list to query the field data
Guzz-T Jan 6, 2026
fd12f96
Merge branch 'Bouni:main' into docs-new
Guzz-T Jan 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Generate and deploy docs to GH pages

on:
push:
branches: ["main"]
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: "pages"
cancel-in-progress: false

jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Set up Python
run: uv python install
- name: Install dependencies
run: |
uv venv
uv pip install jinja2
uv pip install -e .
- name: Generate docs
run: uv run python .github/workflows/scripts/docs/gen-docs.py
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Upload artifact
uses: actions/upload-pages-artifact@v4
with:
path: docs
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
64 changes: 64 additions & 0 deletions .github/workflows/scripts/docs/gen-docs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/env python
import logging
from pathlib import Path
from datetime import datetime
from jinja2 import Environment, FileSystemLoader, select_autoescape

from luxtronik import (
Calculations,
Parameters,
Visibilities,
Holdings,
Inputs,
)
from luxtronik.datatypes import (
SelectionBase,
)

logging.basicConfig(level=logging.INFO)

logger = logging.getLogger("docs generator")


BASEPATH = Path(__file__).resolve().parent


def get_items(definitions):
items = []
for d in definitions:
desc = d.description
if issubclass(d.data_type, SelectionBase):
desc += "\nUser-Options: " + ", ".join(d.data_type.options())
items.append({
"number": d.index,
"type": definitions.name,
"name": d.name,
"unit": d.data_type.unit,
"description": desc,
})
return items


def gather_data() -> dict:
logger.info("gather docs data")
data = {}
data["parameters"] = get_items(Parameters.definitions)
data["calculations"] = get_items(Calculations.definitions)
data["visibilities"] = get_items(Visibilities.definitions)
data["holdings"] = get_items(Holdings.definitions)
data["inputs"] = get_items(Inputs.definitions)
return data


def render_docs():
logger.info("render docs")
env = Environment(loader=FileSystemLoader(str(BASEPATH / "templates")), autoescape=select_autoescape())
template = env.get_template("docs.html")
group_data = gather_data()
(BASEPATH.parents[3] / "docs").mkdir(exist_ok=True)
with open(BASEPATH.parents[3] / "docs/index.html", "w", encoding="UTF-8") as f:
f.write(template.render(data=group_data, now=datetime.now()))


if __name__ == "__main__":
render_docs()
249 changes: 249 additions & 0 deletions .github/workflows/scripts/docs/templates/docs.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
<!doctype html>
<html lang="en">
<head>
<title>python-luxtronik docs</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css"
/>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css"
/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<!-- and it's easy to individually load additional languages -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/yaml.min.js"></script>
</head>
<body>
<style>
pre {
all: unset;
display: block !important;
font-family: monospace !important;
overflow-x: auto !important;
font-size: 0 !important;
}

pre code {
display: block !important;
font-size: 0.875rem !important;
line-height: 1.5 !important;
padding: 1em !important;
white-space: pre !important;
}
.card {
--bulma-card-shadow: none;
border-color: rgb(53, 58, 70);
border-width: 1px;
border-style: solid;
}
</style>
<div class="container">
<section class="hero">
<div class="hero-body">
<p class="title has-text-centered">python-luxtronik docs</p>
<p class="subtitle has-text-centered mt-2">
Latest info about calculations, parameters and visibilities of
python-luxtronik
</p>
<p class="has-text-centered mb-2" >Generated: {{ now.strftime('%Y-%m-%d %H:%M:%S') }}</p>
<div class="has-text-centered">
<a
href="https://github.com/bouni/python-luxtronik"
aria-label="GitHub repo"
class="footer-octicon"
title="GitHub repo"
>
<svg
aria-hidden="true"
class="octicon octicon-mark-github"
height="24"
version="1.1"
viewBox="0 0 16 16"
width="24"
>
<path
fill-rule="evenodd"
fill="#FFF"
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"
></path>
</svg>
</a>
</div>
</div>
</section>
<section class="section py-0">
<input class="input search" type="text" placeholder="Search" />
</section>
{% for group, items in data.items() %}
<section class="section">
<h1 class="title" id="{{ group }}">
<a href="#{{group}}">{{ group.capitalize() }}</a><span class="ml-4 tag is-medium">{{items|length}}</span>
</h1>
<div class="my-2">
{% for _group in data.keys() %}
<a href="#{{ _group }}"><button class="button is-small is-dark">Jump to {{ _group.capitalize() }}</button></a>
{% endfor %}
</div>
<div class="columns is-multiline">
{% for item in items %}
<div
class="column is-full item"
data-name="{{ item.name }}"
data-number="{{ item.number }}"
data-type="{{ item.type }}"
data-unit="{{ item.unit }}"
data-desc="{{ item.description }}"
>
<div class="card" id="{{ group }}-{{ item.name }}">
<div class="card-content">
<p class="title is-4">
<a href="#{{ group }}-{{ item.name }}">{{ item.name }}</a>
</p>
<div class="content">
<div class="fixed-grid has-5-cols">
<div class="grid">
<div class="cell has-text-centered">
<div class="is-size-5 mb-2">Group</div>
<span
class="tag is-medium"
style="background-color: oklch(37.2% 0.044 257.287)"
><strong>{{ group }}</strong></span
>
</div>
<div class="cell has-text-centered">
<div class="is-size-5 mb-2">Name</div>
<span
class="tag is-medium"
style="background-color: oklch(37.2% 0.044 257.287)"
><strong>{{ item.name }}</strong></span
>
</div>
<div class="cell has-text-centered">
<div class="is-size-5 mb-2">Number</div>
<span
class="tag is-medium"
style="background-color: oklch(37.2% 0.044 257.287)"
><strong>{{ item.number }}</strong></span
>
</div>
<div class="cell has-text-centered">
<div class="is-size-5 mb-2">Type</div>
<span
class="tag is-medium"
style="background-color: oklch(37.2% 0.044 257.287)"
><strong>{{ item.type }}</strong></span
>
</div>
<div class="cell has-text-centered">
<div class="is-size-5 mb-2">Unit</div>
<span
class="tag is-medium"
style="background-color: oklch(37.2% 0.044 257.287)"
><strong>{{ item.unit }}</strong></span
>
</div>
</div>
<div class="grid">
<div class="cell has-text-centered">
<div class="is-size-5 mb-2">Description</div>
</div>
</div>
</div>
<div class="fixed-grid has-1-cols">
<div class="grid">
<div
style="
background-color: oklch(37.2% 0.044 257.287);
padding: 0.25em 0.75em;
border-radius: 4px;
display: block;
width: 100%;
white-space: pre-line;
text-align: left;
min-height: 2em;
"
>{{ item.description }}</div>
</div>
</div>
<div>
<p class="title is-6">
Usage example in Home-Assitant config:
</p>
<div class="fixed-grid has-12-cols">
<div class="grid">
<div class="cell is-col-span-5">
<pre class="theme-atom-one-dark">
<code class="language-yaml">
sensor:
- platform: luxtronik
sensors:
- group: {{ group }}
id: {{ item.name }}
friendly_name: my_parameter_name # Optional
</code>
</pre>
</div>
<div
class="cell is-col-span-2 has-text-centered is-size-3"
>
<p>or</p>
</div>
<div class="cell is-col-span-5">
<pre class="theme-atom-one-dark">
<code class="language-yaml">
sensor:
- platform: luxtronik
sensors:
- group: {{ group }}
id: {{ item.number }}
friendly_name: my_parameter_name # Optional
</code>
</pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</section>
{% endfor %}
</div>
<script lang="javascript">
const searchbar = document.querySelector(".search");

searchbar.addEventListener("keyup", () => {
let searchword = searchbar.value.toString().toLowerCase();
if (searchword.length < 1) {
let items = document.querySelectorAll(".item");
Array.from(items, (el) => {
el.style.display = "block";
});
} else {
let items = document.querySelectorAll(".item");
Array.from(items, (el) => {
if (
!el.dataset.type.toLowerCase().includes(searchword) &&
!el.dataset.number
.toString()
.toLowerCase()
.includes(searchword) &&
!el.dataset.name.toLowerCase().includes(searchword)
) {
el.style.display = "none";
} else {
el.style.display = "block";
}
});
}
});
</script>
<script>
hljs.highlightAll();
</script>
</body>
</html>
Loading