Skip to content

Commit 01b735e

Browse files
committed
Create better settings.md based on additional fields
We use the newly provided json extensions to generate better documentation. Signed-off-by: Jeroen Simonetti <jeroen@simonetti.nl>
1 parent 5170e48 commit 01b735e

22 files changed

+2699
-829
lines changed

SETTINGS.md

Lines changed: 1830 additions & 294 deletions
Large diffs are not rendered by default.

config_schema.json

Lines changed: 198 additions & 264 deletions
Large diffs are not rendered by default.
Lines changed: 300 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ This guide explains how to maintain and extend the Pydantic-based configuration
1010

1111
## Table of Contents
1212
1. [Overview](#overview)
13-
2. [Making a Key Required/Optional](#making-a-key-requiredoptional)
14-
3. [Modifying Default Values](#modifying-default-values)
15-
4. [Extending an Existing Model](#extending-an-existing-model)
16-
5. [Creating a New Model](#creating-a-new-model)
17-
6. [Using Direct Config Access](#using-direct-config-access)
18-
7. [Migration Workflows](#migration-workflows)
19-
8. [Testing Requirements](#testing-requirements)
20-
9. [Common Pitfalls](#common-pitfalls)
13+
2. [JSON Schema Extensions](#json-schema-extensions)
14+
3. [Making a Key Required/Optional](#making-a-key-requiredoptional)
15+
4. [Modifying Default Values](#modifying-default-values)
16+
5. [Extending an Existing Model](#extending-an-existing-model)
17+
6. [Creating a New Model](#creating-a-new-model)
18+
7. [Using Direct Config Access](#using-direct-config-access)
19+
8. [Migration Workflows](#migration-workflows)
20+
9. [Testing Requirements](#testing-requirements)
21+
10. [Common Pitfalls](#common-pitfalls)
2122

2223
---
2324

@@ -42,7 +43,297 @@ The configuration system consists of:
4243
-**All fields MUST have descriptions** - build fails otherwise
4344
- ⚠️ Never edit generated docs manually - they regenerate from code!
4445

45-
**📚 See [DOCUMENTATION_VALIDATION.md](DOCUMENTATION_VALIDATION.md) for validation details**
46+
---
47+
48+
## JSON Schema Extensions
49+
50+
The configuration system uses **JSON Schema extensions** (custom `x-*` fields) to provide rich metadata for documentation generation, UI hints, and better developer experience. All extensions follow the JSON Schema specification for custom properties.
51+
52+
### Why Use Extensions?
53+
54+
- **📄 Better Documentation**: Generate comprehensive SETTINGS.md with examples, tips, and detailed help
55+
- **🎨 UI Hints**: Guide UI developers on widget types and entity filters
56+
- **🔍 Validation Help**: Provide clear validation messages and hints
57+
- **📊 Organization**: Categorize and order fields logically
58+
- **🔗 External Links**: Link to detailed wiki documentation
59+
60+
### Available Extensions
61+
62+
#### Field-Level Extensions
63+
64+
These go in `json_schema_extra` dict within `Field()`:
65+
66+
| Extension | Type | Purpose | Example |
67+
|-----------|------|---------|---------|
68+
| `x-help` | `str` | Detailed help text with markdown, examples, and tips | See example below |
69+
| `x-unit` | `str` | Physical unit of measurement | `"kWh"`, `"W"`, `"%"`, `"degrees"` |
70+
| `x-ui-section` | `str` | UI form section/grouping hint | `"Battery Specifications"`, `"SOC Limits"`, `"Power Configuration"` |
71+
| `x-validation-hint` | `str` | Explain validation constraints | `"Must be > 0, typically 40-100 kWh"` |
72+
| `x-ui-widget` | `str` | Suggested UI widget type | `"entity-picker"`, `"slider"`, `"time-picker"` |
73+
| `x-entity-filter` | `str` | Filter for HA entity picker | `"sensor"`, `"switch"`, `"binary_sensor"` |
74+
| `x-docs-url` | `str` | External documentation URL | `"https://github.com/.../wiki/Battery"` |
75+
76+
**Note:** `x-ui-section` is a **hint** for UI builders on how to group related fields. Documentation generators may ignore it.
77+
78+
#### Model-Level Extensions
79+
80+
These go in `ConfigDict` `json_schema_extra`:
81+
82+
| Extension | Type | Purpose | Example |
83+
|-----------|------|---------|---------|
84+
| `x-ui-group` | `str` | TOC section grouping | `"Energy Storage"`, `"Devices"`, `"Infrastructure"` |
85+
| `x-icon` | `str` | Icon identifier (mapped to emoji) | `"battery-charging"`, `"solar-panel"`, `"ev-plug"` |
86+
| `x-order` | `int` | Sort order within group | `1`, `2`, `3`, ... |
87+
| `x-help` | `str` | Detailed model help (markdown) | Multi-line markdown with examples |
88+
| `x-docs-url` | `str` | External documentation URL | `"https://github.com/.../wiki/Battery-Configuration"` |
89+
90+
### Complete Example: Field with Extensions
91+
92+
```python
93+
from pydantic import BaseModel, Field
94+
95+
class BatteryConfig(BaseModel):
96+
capacity: float = Field(
97+
gt=0,
98+
description="Battery capacity in kWh", # ✅ REQUIRED - shown in tables
99+
json_schema_extra={
100+
# Detailed help with examples and tips
101+
"x-help": """Total usable battery capacity in kilowatt-hours.
102+
103+
**Finding Your Capacity:**
104+
- Check battery specifications (often less than advertised)
105+
- Look for "usable capacity" or "effective capacity"
106+
- Example: Tesla Powerwall 2 = 13.5 kWh usable
107+
108+
**Tips:**
109+
- Use usable capacity, not total capacity
110+
- Account for manufacturer SOC limits
111+
- Multiple batteries: sum their capacities
112+
113+
**Common Values:**
114+
- Home batteries: 5-15 kWh
115+
- Large systems: 20-50 kWh
116+
- Tesla Powerwall 2: 13.5 kWh
117+
- LG RESU 10H: 9.8 kWh""",
118+
119+
# Physical unit
120+
"x-unit": "kWh",
121+
122+
# UI section grouping hint
123+
"x-ui-section": "Battery Specifications",
124+
125+
# Validation explanation
126+
"x-validation-hint": "Must be > 0, typically 5-50 kWh for home systems",
127+
128+
# UI widget suggestion
129+
"x-ui-widget": "number-input",
130+
131+
# External documentation
132+
"x-docs-url": "https://github.com/corneel27/day-ahead/wiki/Battery-Capacity"
133+
}
134+
)
135+
```
136+
137+
### Complete Example: Model with Extensions
138+
139+
```python
140+
from pydantic import BaseModel, Field, ConfigDict
141+
142+
class BatteryConfig(BaseModel):
143+
"""Battery configuration for optimization."""
144+
145+
name: str = Field(description="Battery identifier")
146+
capacity: float = Field(gt=0, description="Battery capacity in kWh")
147+
# ... more fields ...
148+
149+
model_config = ConfigDict(
150+
extra='allow',
151+
populate_by_name=True,
152+
json_schema_extra={
153+
# TOC section grouping
154+
'x-ui-group': 'Energy Storage',
155+
156+
# Icon identifier (mapped to 🔋 emoji)
157+
'x-icon': 'battery-charging',
158+
159+
# Sort order (1 = first in group)
160+
'x-order': 1,
161+
162+
# Detailed model-level help
163+
'x-help': '''# Battery Configuration
164+
165+
Configure your home battery storage system for optimal energy management.
166+
167+
## Key Settings
168+
- **Capacity**: Total storage capacity in kWh
169+
- **SOC Limits**: Upper and lower charge limits
170+
- **Power Stages**: Charging/discharging efficiency curves
171+
- **Control Entities**: Home Assistant entities
172+
173+
## Optimization Strategy
174+
The optimizer decides when to charge/discharge based on:
175+
- Electricity prices (charge when cheap, discharge when expensive)
176+
- Solar production forecasts
177+
- Battery efficiency and degradation costs
178+
- SOC limits and constraints
179+
180+
## Tips
181+
- Set upper_limit to 80-90% for longer battery life
182+
- Configure charge/discharge stages for accurate optimization
183+
- Monitor battery degradation with cycle_cost setting
184+
- Use optimal_lower_level for cost optimization''',
185+
186+
# External documentation
187+
'x-docs-url': 'https://github.com/corneel27/day-ahead/wiki/Battery-Configuration'
188+
}
189+
)
190+
```
191+
192+
### UI Sections
193+
194+
Use `x-ui-section` to hint at logical grouping of related fields within a form:
195+
196+
**Purpose:** Helps UI builders organize fields into logical sections/groups. Documentation generators may ignore this.
197+
198+
**Common Sections:**
199+
- **"Battery Specifications"**: Core capacity and identification
200+
- **"SOC Limits"**: State of charge boundaries
201+
- **"Power Configuration"**: Power levels and stages
202+
- **"Efficiency Parameters"**: Conversion efficiencies
203+
- **"Cost & Degradation"**: Economic parameters
204+
- **"Control Entities"**: Home Assistant entity controls
205+
- **"Panel Orientation"**: Solar panel positioning
206+
- **"Temperature Parameters"**: Heating/cooling settings
207+
- **"Connection Settings"**: Database/API connections
208+
- **"Authentication"**: Credentials and tokens
209+
210+
**Note:** This is a **hint**, not a requirement. UI builders can group fields differently based on their UX needs.
211+
212+
### UI Groups
213+
214+
Use `x-ui-group` to organize models into logical documentation sections:
215+
216+
| Group | Purpose | Examples |
217+
|-------|---------|----------|
218+
| `"Energy Storage"` | Battery systems | BatteryConfig |
219+
| `"Energy Production"` | Solar panels | SolarConfig |
220+
| `"Devices"` | Controllable devices | EVConfig, MachineConfig |
221+
| `"Heating & Climate"` | Heating systems | HeatingConfig, BoilerConfig |
222+
| `"Infrastructure"` | Core system config | DatabaseConfig, GridConfig |
223+
| `"Integration"` | External integrations | TibberConfig, HomeAssistantConfig |
224+
| `"Pricing & Markets"` | Price data sources | PricingConfig |
225+
| `"Automation"` | Scheduling & tasks | SchedulerConfig |
226+
| `"Visualization"` | Graphics & reporting | GraphicsConfig, ReportConfig |
227+
228+
### Icon Identifiers
229+
230+
Use `x-icon` with these identifiers (mapped to emojis in documentation):
231+
232+
| Identifier | Emoji | Used For |
233+
|------------|-------|----------|
234+
| `"battery-charging"` | 🔋 | Battery systems |
235+
| `"solar-panel"` | ☀️ | Solar panels |
236+
| `"ev-plug"` | 🚗 | Electric vehicles |
237+
| `"thermometer"` | 🌡️ | Heating systems |
238+
| `"water-boiler"` | 💧 | Boiler/DHW |
239+
| `"washing-machine"` | 🧺 | Appliances/machines |
240+
| `"database"` | 💾 | Databases |
241+
| `"chart-line"` | 📈 | Graphics/charts |
242+
| `"report"` | 📉 | Reports |
243+
| `"bell"` | 🔔 | Notifications |
244+
| `"clock"` | 🕐 | Scheduler/time |
245+
| `"home"` | 🏠 | Home Assistant |
246+
| `"lightning"` || Grid/power/Tibber |
247+
| `"history"` || History tracking |
248+
| `"dashboard"` | 📊 | Dashboard UI |
249+
| `"currency"` | 💰 | Pricing |
250+
251+
### Writing Good Help Text
252+
253+
The `x-help` field supports full Markdown and should include:
254+
255+
1. **Clear Explanation**: What the field does
256+
2. **Examples**: Concrete values or configurations
257+
3. **Tips**: Best practices and gotchas
258+
4. **Common Values**: Typical ranges
259+
5. **Troubleshooting**: Common issues
260+
261+
**Example Template:**
262+
```python
263+
"x-help": """Brief one-line summary.
264+
265+
**What It Does:**
266+
Clear explanation of the field's purpose and behavior.
267+
268+
**Examples:**
269+
- Example 1: Description
270+
- Example 2: Description
271+
272+
**Common Values:**
273+
- Typical case 1: 10-20
274+
- Typical case 2: 50-100
275+
276+
**Tips:**
277+
- Tip 1 for best results
278+
- Tip 2 to avoid issues
279+
280+
**Related:**
281+
See also: field1, field2"""
282+
```
283+
284+
### Validation Hints
285+
286+
Use `x-validation-hint` to explain constraints in human terms:
287+
288+
```python
289+
# Instead of just: ge=0, le=100
290+
"x-validation-hint": "0-100%, protects battery from deep discharge"
291+
292+
# Instead of just: gt=0
293+
"x-validation-hint": "Must be > 0, typically 5-15 kWh for home systems"
294+
295+
# For enums:
296+
"x-validation-hint": "Options: 'mysql', 'postgresql', 'sqlite'"
297+
298+
# For patterns:
299+
"x-validation-hint": "Format: HHMM (e.g., '0430', 'xx00' for every hour)"
300+
```
301+
302+
### Best Practices
303+
304+
1. **Always add extensions to new fields**:
305+
- Minimum: `x-category`, `x-unit` (if applicable)
306+
- Recommended: Add `x-help` for complex fields
307+
- Optional: `x-ui-widget`, `x-entity-filter` for UI hints
308+
309+
2. **Be consistent**:
310+
- Use same category names across similar fields
311+
- Use standard unit abbreviations (kWh, W, %, °C, etc.)
312+
- Follow existing patterns for help text structure
313+
314+
3. **Keep help text focused**:
315+
- Don't duplicate what's in the description
316+
- Add value with examples and tips
317+
- Link to external docs for deep dives
318+
319+
4. **Test generated documentation**:
320+
```bash
321+
python3 -m dao.prog.config.generate_docs
322+
# Check SETTINGS.md for formatting
323+
```
324+
325+
5. **Update ICON_MAP** if adding new icons:
326+
- Edit `dao/prog/config/generate_docs.py`
327+
- Add mapping: `"your-icon-id": "🔥"`
328+
329+
### Migration Considerations
330+
331+
Extensions are **metadata only** and do **not** affect:
332+
- Configuration validation
333+
- Runtime behavior
334+
- Backward compatibility
335+
336+
You can add/modify extensions without creating migrations!
46337

47338
---
48339

0 commit comments

Comments
 (0)