@@ -10,14 +10,15 @@ This guide explains how to maintain and extend the Pydantic-based configuration
1010
1111## Table of Contents
12121 . [ 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% f or 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