Skip to content

Commit 53a37ab

Browse files
[Common] Docs: Dynamic Documentation Generation, Natures (incl. ESS & IO) (OpenEMS#3488)
* extends docu on Dynamic Documentation Generation, Natures in general and 2 specific natures: ESS & IO * improved ALT-texts of images to improve accessability
1 parent e1186f2 commit 53a37ab

5 files changed

Lines changed: 270 additions & 22 deletions

File tree

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ If you plan to use OpenEMS for your own projects, please consider joining the [O
1414

1515
### OpenEMS in »Local Energy Management«
1616

17-
![alt text](./doc/modules/ROOT/assets/images/local-energy-management.png "Local Energy Management")
17+
![Local Energy Management](./doc/modules/ROOT/assets/images/local-energy-management.png "Local Energy Management")
1818

1919
### OpenEMS in »Areal Energy Management«
2020

21-
![alt text](./doc/modules/ROOT/assets/images/areal-energy-management.png "Areal Energy Management")
21+
![Areal Energy Management](./doc/modules/ROOT/assets/images/areal-energy-management.png "Areal Energy Management")
2222

2323
## OpenEMS IoT stack
2424

@@ -39,14 +39,14 @@ The OpenEMS software architecture was designed to leverage some features that ar
3939

4040
## OpenEMS UI Screenshots
4141

42-
![alt text](./doc/modules/ROOT/assets/images/ui-live.png "OpenEMS UI Live View")
43-
![alt text](./doc/modules/ROOT/assets/images/ui-history.png "OpenEMS UI History View")
42+
![OpenEMS UI Live View](./doc/modules/ROOT/assets/images/ui-live.png "OpenEMS UI Live View")
43+
![OpenEMS UI History View](./doc/modules/ROOT/assets/images/ui-history.png "OpenEMS UI History View")
4444

4545
## System architecture
4646

4747
OpenEMS is generally used in combination with external hardware and software components
4848
(the exception is a simulated development environment - see [Getting Started](https://openems.github.io/openems.io/openems/latest/gettingstarted.html)). As a brief overview, this is how OpenEMS is used in production setups:
49-
![alt text](./doc/modules/ROOT/assets/images/system-architecture.png "OpenEMS System Architecture")
49+
![OpenEMS System Architecture](./doc/modules/ROOT/assets/images/system-architecture.png "OpenEMS System Architecture")
5050

5151
## Getting Started
5252

doc/modules/ROOT/pages/development/documentation.adoc

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,65 @@ Docs should be building.. the finished HTML Folder can be found in your local 'b
5858
NOTE: If you want to build your own docs with Antora see https://fabianfnc.github.io/bocs/[this guide icon:external-link[]]
5959

6060

61+
== Dynamic Documentation Generation
62+
63+
Some parts of the OpenEMS documentation are generated dynamically during the build process.
64+
65+
In the repository you can find pages like `nature.adoc` with some text and then
66+
[source,adoc]
67+
----
68+
include::nature.adoc.d/_include.adoc[leveloffset=+0]
69+
----
70+
where the corresponding folder `nature.adoc.d` is basically empty. (It only contains a `.gitignore` file to keep it that way in version control.) This is, where the dynamic generation happens.
71+
72+
=== The Process
73+
(shown at the example of link:https://openems.github.io/openems.io/openems/latest/edge/nature.html[Natures] documentation)
74+
75+
1. Build-Time Generation (in `doc/build.gradle` lines 320-405)
76+
77+
The copyBundleReadmes Gradle task runs during the documentation build process and:
78+
79+
1. Creates an empty `_include.adoc` file in `doc/modules/ROOT/pages/edge/nature.adoc.d/`
80+
2. Scans all bundles in the project looking for `readme.adoc` files
81+
3. Identifies .api bundles - When it finds a bundle ending with .api, it:
82+
- Copies that bundle's `readme.adoc` to `nature.adoc.d/{bundle-name}.adoc`
83+
- Appends an include statement to `_include.adoc`:
84+
[source,adoc]
85+
----
86+
include::{bundle-name}.adoc[leveloffset=+1]
87+
----
88+
89+
2. The Result
90+
91+
The generated `nature.adoc.d/_include.adoc` file contains something like:
92+
93+
[source,adoc]
94+
----
95+
include::io.openems.edge.battery.api.adoc[leveloffset=+1]
96+
include::io.openems.edge.batteryinverter.api.adoc[leveloffset=+1]
97+
include::io.openems.edge.ess.api.adoc[leveloffset=+1]
98+
include::io.openems.edge.meter.api.adoc[leveloffset=+1]
99+
...
100+
----
101+
102+
3. AsciiDoc Processing
103+
104+
When Antora builds the documentation, it processes `nature.adoc` which includes the line:
105+
include::nature.adoc.d/_include.adoc[leveloffset=+0]
106+
107+
This cascades to include all the individual bundle readme files, creating the complete list of natures.
108+
109+
=== Why This Pattern?
110+
111+
- Automatic: New .api bundles with `readme.adoc` files automatically appear in the documentation
112+
- Maintainable: Each bundle documents itself in its own `readme.adoc`
113+
- DRY: No need to manually maintain a central list
114+
- Build artifact: The `_include.adoc` is git-ignored (hence the `.gitignore` in the directory) and regenerated on each build
115+
116+
You can see this in action by running:
117+
[source,bash]
118+
----
119+
./gradlew copyBundleReadmes
120+
----
121+
122+
This will not only populate `doc/modules/ROOT/pages/edge/nature.adoc.d/` with all the individual nature documentation files! It will do it for all dynamically generated documentation parts in the OpenEMS docs that follow this pattern.

doc/modules/ROOT/pages/edge/nature.adoc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,36 @@ Physical hardware is abstracted in OpenEMS Edge using _Natures_. A Nature define
1212

1313
Technically Natures are implemented as OSGi API Bundles.
1414

15+
Each .api bundle contains the nature interfaces that device implementations must implement. For example, io.openems.edge.ess.api defines interfaces like SymmetricEss, AsymmetricEss, ManagedSymmetricEss, etc. These are sub-natures of the Ess nature.
16+
17+
OpenEMS Edge provides the following types of Natures:
18+
19+
== Device Natures
20+
e.g.:
21+
- io.openems.edge.battery.api - Battery interfaces
22+
- io.openems.edge.batteryinverter.api - Battery inverter interfaces
23+
- io.openems.edge.ess.api - Energy Storage System interfaces
24+
- io.openems.edge.evcs.api - EV Charging Station interfaces
25+
- io.openems.edge.evse.api - EV Supply Equipment interfaces
26+
- io.openems.edge.meter.api - Power meter interfaces
27+
- io.openems.edge.pvinverter.api - PV inverter interfaces
28+
- io.openems.edge.io.api - IO device interfaces
29+
- io.openems.edge.heat.api - Heat pump interfaces
30+
- io.openems.edge.thermometer.api - Thermometer interfaces
31+
32+
== Service/Support Natures
33+
e.g.:
34+
- io.openems.edge.controller.api - Controller interfaces
35+
- io.openems.edge.scheduler.api - Scheduler interfaces
36+
- io.openems.edge.timedata.api - Time-series data interfaces
37+
- io.openems.edge.timeofusetariff.api - Dynamic pricing interfaces
38+
- io.openems.edge.predictor.api - Forecasting interfaces
39+
- io.openems.edge.weather.api - Weather service interfaces
40+
- io.openems.edge.energy.api - Energy management interfaces
41+
42+
43+
Following you find all natures currently defined in OpenEMS Edge:
44+
1545
include::nature.adoc.d/_include.adoc[leveloffset=+0]
1646

1747
// TODO
Lines changed: 162 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,170 @@
11
= ESS (Energy Storage System)
22

3-
An Energy Storage System is an integrated system with battery and battery inverter.
3+
An Energy Storage System is an integrated system with battery and battery inverter. This API bundle defines the core natures (interfaces) that ESS components implement.
44

5-
link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.ess.api/src/io/openems/edge/ess/api/SymmetricEss.java[Ess icon:code[]]::
6-
A generic Energy Storage System
7-
// +
8-
// |===
9-
// include::https://raw.githubusercontent.com/OpenEMS/openems/develop/doc/_old/devices/_include/EssNature.adoc[tag=channels]
10-
// |===
5+
== Core ESS Natures
116

12-
link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.ess.api/src/io/openems/edge/ess/api/SymmetricEss.java[SymmetricEssReadonly icon:code[]]::
13-
A symmetric Energy Storage System in readonly-mode.
14-
// TODO add channels
7+
link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.ess.api/src/io/openems/edge/ess/api/SymmetricEss.java[SymmetricEss icon:code[]]::
8+
A symmetric Energy Storage System that provides balanced power across all phases. This is the base nature for most ESS implementations.
9+
+
10+
*Key Channels:*
11+
+
12+
* `SOC` - State of Charge (%)
13+
* `CAPACITY` - Battery capacity (Wh)
14+
* `GRID_MODE` - Current grid mode (On-Grid/Off-Grid)
15+
* `ACTIVE_POWER` - Active power (W, negative=charge, positive=discharge)
16+
* `REACTIVE_POWER` - Reactive power (var)
1517

16-
//link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.ess.api/src/io/openems/edge/ess/api/ManagedSymmetricEss.java[SymmetricEss icon:code[]]::
17-
A symmetric, controllable Energy Storage System.
18-
// TODO add channels
18+
link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.ess.api/src/io/openems/edge/ess/api/ManagedSymmetricEss.java[ManagedSymmetricEss icon:code[]]::
19+
A controllable symmetric Energy Storage System that extends `SymmetricEss`. Supports active and reactive power control commands.
20+
This is the most commonly used nature for controllable ESS implementations.
21+
+
22+
*Key Channels:*
23+
+
24+
* `ALLOWED_CHARGE_POWER` - Maximum allowed charge power (W, negative value)
25+
* `ALLOWED_DISCHARGE_POWER` - Maximum allowed discharge power (W, positive value)
26+
* `SET_ACTIVE_POWER_EQUALS` - Write command to set active power
27+
* `SET_ACTIVE_POWER_LESS_OR_EQUALS` - Write command to limit maximum discharge power
28+
* `SET_ACTIVE_POWER_GREATER_OR_EQUALS` - Write command to limit maximum charge power
29+
* `SET_REACTIVE_POWER_EQUALS` - Write command to set reactive power
30+
+
1931

20-
// TODO: describe SymmetricPower 'Active/Reactive Power circle' + callback
32+
link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.ess.api/src/io/openems/edge/ess/api/AsymmetricEss.java[AsymmetricEss icon:code[]]::
33+
A three-phase Asymmetric Energy Storage System that extends `SymmetricEss`. Provides separate power measurements for each phase (L1, L2, L3).
34+
+
35+
*Key Channels:*
36+
+
37+
* `ACTIVE_POWER_L1`, `ACTIVE_POWER_L2`, `ACTIVE_POWER_L3` - Active power per phase (W)
38+
* `REACTIVE_POWER_L1`, `REACTIVE_POWER_L2`, `REACTIVE_POWER_L3` - Reactive power per phase (var)
39+
40+
link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.ess.api/src/io/openems/edge/ess/api/ManagedAsymmetricEss.java[ManagedAsymmetricEss icon:code[]]::
41+
A controllable asymmetric Energy Storage System that extends both `ManagedSymmetricEss` and `AsymmetricEss`. Allows independent control of each phase.
42+
+
43+
*Key Channels:*
44+
+
45+
* `SET_ACTIVE_POWER_L1_EQUALS`, `SET_ACTIVE_POWER_L2_EQUALS`, `SET_ACTIVE_POWER_L3_EQUALS` - Write commands for active power per phase
46+
* `SET_REACTIVE_POWER_L1_EQUALS`, `SET_REACTIVE_POWER_L2_EQUALS`, `SET_REACTIVE_POWER_L3_EQUALS` - Write commands for reactive power per phase
47+
48+
link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.ess.api/src/io/openems/edge/ess/api/SinglePhaseEss.java[SinglePhaseEss icon:code[]]::
49+
A single-phase Energy Storage System that extends `AsymmetricEss`. Connected to only one phase (L1, L2, or L3).
50+
+
51+
*Key Methods:*
52+
+
53+
* `getPhase()` - Returns which phase (L1/L2/L3) the ESS is connected to
54+
55+
link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.ess.api/src/io/openems/edge/ess/api/ManagedSinglePhaseEss.java[ManagedSinglePhaseEss icon:code[]]::
56+
A controllable single-phase Energy Storage System that extends both `ManagedSymmetricEss` and `SinglePhaseEss`.
57+
58+
== Specialized ESS Natures
59+
60+
link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.ess.api/src/io/openems/edge/ess/api/HybridEss.java[HybridEss icon:code[]]::
61+
An ESS with one or more DC-coupled PV chargers. Extends `SymmetricEss`.
62+
+
63+
*Key Channels:*
64+
+
65+
* `DC_DISCHARGE_POWER` - Actual battery discharge power (W), i.e., `ACTIVE_POWER` minus DC charger production
66+
* `DC_CHARGE_ENERGY` - Cumulative battery charge energy (Wh)
67+
* `DC_DISCHARGE_ENERGY` - Cumulative battery discharge energy (Wh)
68+
+
69+
*Note:* For hybrid inverters, `ACTIVE_POWER` includes excess DC-PV production, while `DC_DISCHARGE_POWER` represents the actual battery power flow.
70+
71+
link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.ess.api/src/io/openems/edge/ess/api/MetaEss.java[MetaEss icon:code[]]::
72+
A virtual ESS that wraps one or more physical energy storage systems. Extends `SymmetricEss`. Used for ESS clusters or combined systems.
73+
+
74+
*Key Methods:*
75+
+
76+
* `getEssIds()` - Returns array of Component-IDs of the physical ESS components
77+
+
78+
*Usage:* Implements aggregation logic to combine multiple ESS into a single logical unit.
79+
80+
link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.ess.api/src/io/openems/edge/ess/offgrid/api/OffGridEss.java[OffGridEss icon:code[]]::
81+
An ESS with off-grid (island mode) capabilities. Extends `ManagedSymmetricEss`.
82+
+
83+
*Key Methods:*
84+
+
85+
* `isOffGridPossible()` - Returns true if the ESS can build a micro-grid in off-grid mode
86+
+
87+
*Usage:* Typically used with systems that can form and maintain an AC grid when disconnected from the utility grid.
88+
89+
link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.ess.api/src/io/openems/edge/ess/api/EssErrorAcknowledge.java[EssErrorAcknowledge icon:code[]]::
90+
Defines error acknowledgement capabilities for ESS components. Extends `OpenemsComponent`.
91+
+
92+
*Key Channels:*
93+
+
94+
* `TIMEOUT_START_BATTERY` - Fault state when battery start timeout is exceeded
95+
* `TIMEOUT_START_BATTERY_INVERTER` - Fault state when battery inverter start timeout is exceeded
96+
* `TIMEOUT_STOP_BATTERY` - Fault state when battery stop timeout is exceeded
97+
* `TIMEOUT_STOP_BATTERY_INVERTER` - Fault state when battery inverter stop timeout is exceeded
98+
+
99+
*Key Methods:*
100+
+
101+
* `executeErrorAcknowledge()` - Attempts to clear error channels
102+
+
103+
*Usage:* Implemented by ESS components that require explicit error acknowledgement and timeout handling.
104+
105+
== Auxiliary Components
106+
107+
=== DC Charger
21108

22109
link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.ess.api/src/io/openems/edge/ess/dccharger/api/EssDcCharger.java[EssDcCharger icon:code[]]::
23-
A solar charger that is connected to DC side of an energy storage system.
24-
// TODO add channels
110+
A DC-coupled solar charger connected to the DC side of an energy storage system. Extends `OpenemsComponent`.
111+
+
112+
*Key Channels:*
113+
+
114+
* `ACTUAL_POWER` - Current DC power production (W, positive value)
115+
* `ACTUAL_ENERGY` - Cumulative energy production (Wh)
116+
* `MAX_ACTUAL_POWER` - Maximum ever recorded power (W)
117+
* `VOLTAGE` - DC voltage (V)
118+
+
119+
*Usage:* Used in hybrid ESS systems where PV production feeds directly into the battery DC bus.
120+
121+
=== Off-Grid Switch
122+
123+
link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.ess.api/src/io/openems/edge/ess/offgrid/api/OffGridSwitch.java[OffGridSwitch icon:code[]]::
124+
A device that determines grid status and actively switches between on-grid and off-grid modes. Extends `OpenemsComponent`.
125+
+
126+
*Key Channels:*
127+
+
128+
* `MAIN_CONTACTOR` - Main contactor state connecting inverter to public grid (Boolean)
129+
* `GROUNDING_CONTACTOR` - Grounding contactor state for off-grid neutral connection (Boolean)
130+
* `GRID_MODE` - Current grid mode (On-Grid/Off-Grid)
131+
+
132+
*Usage:* Used in systems with active grid separation capabilities.
133+
134+
== Nature Hierarchy
135+
136+
The following diagram shows the inheritance relationships:
137+
138+
[source]
139+
----
140+
OpenemsComponent (base interface)
141+
├── SymmetricEss
142+
│ ├── ManagedSymmetricEss
143+
│ │ ├── ManagedAsymmetricEss (also extends AsymmetricEss)
144+
│ │ ├── ManagedSinglePhaseEss (also extends SinglePhaseEss)
145+
│ │ └── OffGridEss
146+
│ ├── AsymmetricEss
147+
│ │ ├── ManagedAsymmetricEss (also extends ManagedSymmetricEss)
148+
│ │ └── SinglePhaseEss
149+
│ │ └── ManagedSinglePhaseEss (also extends ManagedSymmetricEss)
150+
│ ├── MetaEss
151+
│ └── HybridEss
152+
├── EssDcCharger
153+
├── OffGridSwitch
154+
└── EssErrorAcknowledge
155+
----
156+
157+
== Implementation Guidelines
158+
159+
When implementing an ESS component, choose the appropriate nature(s):
160+
161+
* *Read-only ESS*: Implement `SymmetricEss` only
162+
* *Controllable ESS*: Implement `ManagedSymmetricEss`
163+
* *Three-phase with independent control*: Implement `ManagedAsymmetricEss`
164+
* *Single-phase system*: Implement `ManagedSinglePhaseEss`
165+
* *Hybrid inverter with DC-PV*: Implement `HybridEss` and provide `EssDcCharger` component(s)
166+
* *Off-grid capable*: Implement `OffGridEss` and optionally `OffGridSwitch`
167+
* *ESS cluster/aggregation*: Implement `MetaEss`
168+
169+
Multiple natures can be combined. For example, a hybrid off-grid ESS would implement both `HybridEss` and `OffGridEss`.
170+

io.openems.edge.io.api/readme.adoc

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
1-
= I/O (Digital Input/Output)
1+
= I/O (Digital or Analog Input/Output)
22

33
link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.io.api/src/io/openems/edge/io/api/DigitalOutput.java[DigitalOutput icon:code[]]::
44
One or more digital outputs or relays.
5+
6+
link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.io.api/src/io/openems/edge/io/api/DigitalInput.java[DigitalInput icon:code[]]::
7+
One or more digital inputs.
8+
9+
link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.io.api/src/io/openems/edge/io/api/AnalogVoltageOutput.java[AnalogVoltageOutput icon:code[]]::
10+
One or more Analog Voltage outputs.
11+
12+
link:https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.io.api/src/io/openems/edge/io/api/AnalogInput.java[AnalogInput icon:code[]]::
13+
One or more analog inputs.
14+
515
// TODO add channels

0 commit comments

Comments
 (0)