Skip to content

Commit ebffd98

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 ebffd98

21 files changed

+2490
-696
lines changed

SETTINGS.md

Lines changed: 1585 additions & 298 deletions
Large diffs are not rendered by default.

config_schema.json

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

47350
---
48351

0 commit comments

Comments
 (0)