Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
109 changes: 109 additions & 0 deletions .github/workflows/scripts/docs/gen-docs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/usr/bin/env python
import logging
from pathlib import Path
from datetime import datetime
from jinja2 import Environment, FileSystemLoader, select_autoescape
import subprocess

from luxtronik.cfi import (
CALCULATIONS_DEFINITIONS,
PARAMETERS_DEFINITIONS,
VISIBILITIES_DEFINITIONS,
)
from luxtronik.shi import (
INPUTS_DEFINITIONS,
HOLDINGS_DEFINITIONS,
)

from luxtronik.datatypes import (
SelectionBase,
)

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("docs generator")


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


def get_git_version():
try:
return subprocess.check_output(
["git", "describe", "--tags"],
stderr=subprocess.STDOUT
).decode().strip()
except Exception:
return None

def get_string(string):
return f'"{str(string)}"'

def get_writeable(writeable):
return get_string("y" if writeable else "")

def get_unit(unit):
return get_string(unit if unit else "")

def get_version(version):
return get_string("" if version is None else ".".join(map(str, version[:3])))

def get_desc(desc):
return get_string(desc.replace('\n', '\\n'))

def get_items(definitions):
items = []
for d in definitions:
desc = d.description
if issubclass(d.field_type, SelectionBase) and d.writeable:
desc += ("\n" if desc else "") + "\nUser-Options:\n" + "\n".join(d.field_type.options())
for n in d.names:
items.append({
"category": get_string(definitions.name),
"index": d.index,
"name": get_string(n),
"lsb": 0 if d.bit_offset is None else d.bit_offset,
"width": d.num_bits,
"class": get_string(d.field_type.datatype_class),
"writeable": get_writeable(d.writeable),
"unit": get_unit(d.field_type.unit),
"since": get_version(d.since),
"until": get_version(d.until),
"description": get_desc(desc),
})
return items

def gather_data():
logger.info("gather docs data")
defs = [
PARAMETERS_DEFINITIONS,
CALCULATIONS_DEFINITIONS,
VISIBILITIES_DEFINITIONS,
HOLDINGS_DEFINITIONS,
INPUTS_DEFINITIONS
]
data = {}
for d in defs:
data[d.name] = get_items(d)
return data

def render_docs():
logger.info("render docs")
env = Environment(loader=FileSystemLoader(str(BASEPATH / "templates")), autoescape=select_autoescape())

data = gather_data()
(BASEPATH.parents[3] / "docs").mkdir(exist_ok=True)

# create data files
template = env.get_template("definitions.js")
for name, items in data.items():
with open(BASEPATH.parents[3] / f"docs/{name}.js", "w", encoding="UTF-8") as f:
f.write(template.render(group=name.upper(), data=items))

# create meta file
template = env.get_template("meta.js")
with open(BASEPATH.parents[3] / "docs/meta.js", "w", encoding="UTF-8") as f:
f.write(template.render(version=get_git_version(), now=datetime.now().replace(microsecond=0)))


if __name__ == "__main__":
render_docs()
5 changes: 5 additions & 0 deletions .github/workflows/scripts/docs/templates/definitions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
window.{{ group }} = [
{% for items in data %}{{"{"}}{% for key, value in items.items() %}
{{key}}: {{value}}{% if not loop.last %},{% endif %}{% endfor %}
{{"}"}}{% if not loop.last %},{% endif %}{% endfor %}
];
4 changes: 4 additions & 0 deletions .github/workflows/scripts/docs/templates/meta.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
window.META = {
createdOn: "{{ now }}",
version: "{{ version }}"
};
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ This changelog follows the "Keep a Changelog" format and Semantic Versioning.
is required for this. See README for further information. [#190]
- Add a command-line-interface (CLI) with the following commands:
`dump`, `dump-cfi`, `dump.shi`, `changes`, `watch-cfi`, `watch-shi`, `discover`
- Provide an automatically generated documentation for the data fields. [#189]

### Changed

Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ There is no automatically rendered documentation of this library available yet,
so you'll have to fall back to using the source code itself as documentation.
It can be found in the [luxtronik](luxtronik/) directory.

Discovered data fields:
At least for the data fields, there is such a
[documentation](https://bouni.github.io/python-luxtronik/). Alternatively,
you can take a look at the definitions for all discovered data fields:

- Calculations holds measurement values (config interface): \
[luxtronik/definitions/calculations.py](luxtronik/definitions/calculations.py)
Expand Down
Loading
Loading