1# events.json
2
3This file defines the events that dictate how fan control operates.  Each event
4can contain groups, triggers, and actions.
5
6Actions are where fan targets are calculated and set, among other things.
7Triggers specify when an action should run. Groups specify which D-Bus objects
8the triggers and actions should operate on.
9
10Some actions have modifiers, which help calculate a value.
11
12- [Groups](#groups)
13- [Triggers](#triggers)
14- [Actions](#actions)
15- [Modifiers](#modifiers)
16
17## Example
18
19```
20[
21   {
22     "name": "fan(s) missing",
23     "groups": [
24       {
25         "name": "fan inventory",
26         "interface": "xyz.openbmc_project.Inventory.Item",
27         "property": { "name": "Present" }
28       }
29     ],
30     "triggers": [
31       {
32         "class": "init",
33         "method": "get_properties"
34       },
35       {
36         "class": "signal",
37         "signal": "properties_changed"
38       }
39     ],
40     "actions": [
41       {
42         "name": "count_state_before_target",
43         "count": 1,
44         "state": false,
45         "target": 15000
46       }
47     ]
48   }
49]
50```
51
52The above event is an example of a method to set the fan target to 15000 when
53one or more fans is missing. The basic behavior with this config is:
54
55The trigger `init.get_properties` will, on fan control startup, read the
56Present property on the `xyz.openbmc_project.Inventory.Item` interface from
57every D-Bus object in the 'fan inventory' group, update those values in the
58object cache, and then call the `count_state_before_target` action.
59
60The trigger `signal.properties_changed` will watch for changes on the Present
61property on each D-Bus object in the group, update the new value in the object
62cache, and call the `count_state_before_target` action when the value changes.
63
64The `count_state_before_target` action will look at the object cache value of
65the Present property on each member of the group and set the fan target hold to
6615000 when one or more of them is false.  Otherwise, it will clear its fan
67target hold.
68
69## Groups
70
71```
72"groups": [
73    {
74        "name": "<name>",
75        "interface": "<interface>",
76        "property": { "name": "<name>" }
77    }
78    ...
79]
80```
81
82### name
83The name of a group that must be also be defined in
84[groups.json](groups.md).
85
86### interface
87The actions and triggers defined with this group will look at this D-Bus
88interface on the members of this group.
89
90### property: name
91The actions and triggers defined with this group will look at this D-Bus
92property on the members of this group.
93
94## Triggers
95
96There are several classes of triggers, and the JSON configuration is different
97for each.
98
99### init
100Init triggers run when fan control events are enabled on fan control startup.
101After invoking the configured method, any actions configured for this trigger
102will run.
103
104```
105{
106    "class": "init",
107    "method": "<method>"
108}
109```
110
111#### methods
112
1131. `get_properties` - Read the property configured for the group from every
114   member of the group, and store it in fan control's object cache.
115
1162. `name_has_owner` - Populates the service owned state from D-Bus for each
117   group member in fan control's D-Bus service cache map.
118
119### signal
120Signal triggers subscribe to certain D-Bus signals for each member of its
121configured group.  After handling the signal, any configured actions are run.
122
123```
124{
125    "class": "signal",
126    "signal": "<signal>"
127}
128```
129
130#### signal types
1311. `properties_changed` - Subscribes to the PropertiesChanged signal for the
132   D-Bus interface and property specified in the group definition for each
133   group member.  When the signal occurs, the new property value will be added
134   to or updated in the object cache.
135
1362. `interfaces_added` - Subscribes to the InterfacesAdded signal for the D-Bus
137   interface specified in the group definition for each group member.  When the
138   signal occurs, the interface and its properties will be added to the object
139   cache.
140
1413. `interfaces_removed` - Subscribes to the InterfacesRemoved signal for the
142   D-Bus interface specified in the group definition for each group member.
143   When the signal occurs, the interface and properties will be removed from
144   the object cache.
145
1464. `name_owner_changed` - Subscribes to the NameOwnerChanged signal for the
147   services that host the D-bus interface specified in the group definition for
148   each group member.  When the signal occurs, the service owned state will be
149   updated in the service cache map.
150
1515. `member` - Subscribes to the signal listed on each group member.  No caches
152   are updated when the signal occurs.
153
154### timer
155Timer triggers run actions after the configured type of timer expires.
156
157```
158{
159    "class": "timer",
160    "type": "<type>",
161    "interval": "<interval>",
162    "preload_groups": "<true/false>"
163}
164```
165
166#### type
1671. `oneshot` - Starts a timer that runs once.
168
1692. `repeating` - Starts a repeating timer.
170
171#### interval
172The timer length in microseconds
173
174#### preload_groups
175Optional, if set to true, will update the D-Bus properties from the configured
176groups in the object cache after the timer expires but before any actions run.
177
178### parameter
179Parameter triggers run actions after a parameter changes.
180
181```
182{
183    "class": "parameter",
184    "parameter": "<parameter>"
185}
186```
187#### parameter
188The parameter value to watch.
189
190### poweron
191PowerOn triggers run when the power turns on.  Functionally, they behave like
192an init trigger.
193
194```
195{
196    "class": "poweron",
197    "method": "<method>"
198}
199```
200
201#### method
202The methods are the same as with the init trigger.
203
204### poweroff
205
206PowerOff triggers run when the power turns off.  Functionally, they behave like
207an init trigger.
208
209```
210{
211    "class": "poweroff",
212    "method": "<method>"
213}
214```
215
216#### method
217The methods are the same as with the init trigger.
218
219## Actions
220Actions can either operate on the groups listed with the event, or on the
221groups listed within the action's JSON config.
222
223Most actions set fan targets or floors.  This can be done by requesting a
224target value explicitly, or by requesting an increase or decrease delta.
225Targets and floors can also be set with a hold, meaning another action can't
226set a floor/target below the one that is held.
227
228Some actions set or read a key/value pair called a parameter.  These can be
229created, updated, and deleted as necessary.  For example, one action may
230calculate and set a `floor_index` parameter, and another action may then read
231that parameter to help choose a fan floor.
232
233The available actions are:
234
235- [set_net_increase_target](#set_net_increase_target)
236- [set_net_decrease_target](#set_net_decrease_target)
237- [count_state_floor](#count_state_floor)
238- [count_state_before_target](#count_state_before_target)
239- [default_floor_on_missing_owner](#default_floor_on_missing_owner)
240- [mapped_floor](#mapped_floor)
241- [set_target_on_missing_owner](#set_target_on_missing_owner)
242- [override_fan_target](#override_fan_target)
243- [pcie_card_floors](#pcie_card_floors)
244- [set_request_target_base_with_max](#set_request_target_base_with_max)
245- [set_parameter_from_group_max](#set_parameter_from_group_max)
246- [call_actions_based_on_timer](#call_actions_based_on_timer)
247- [get_managed_objects](#get_managed_objects)
248
249### set_net_increase_target
250
251Calculates the net target increase to be requested based on the value of each
252property given within a group. The net target increase is based on the maximum
253difference between the `delta` JSON value and all of the properties of the group.
254The final result is the increase change that's requested to the current target
255of a zone.
256
257The group values can be compared to either a value hardcoded in the JSON, or a
258parameter value.
259
260```
261{
262    "name": "set_net_increase_target",
263    "groups": [{
264        "name": "pcie temps",
265        "interface": "xyz.openbmc_project.Sensor.Value",
266        "property": { "name": "Value" }
267      }],
268    "state": 70.0,
269    "delta": 255
270}
271```
272
273The above config uses a hardcoded state value:
2741. For each member of the 'pcie temps' group:
275  - Read its 'Value' D-Bus property.
276  - If that property value is greater than the 'state' value of 70.0:
277   - Subtracts 70.0 from the property value.
278   - Multiplies that difference by the 'delta' value of 255.
2792. Requests an increase of the largest calculated delta value, if there is
280   one.
281
282```
283{
284    "name": "set_net_increase_target",
285    "groups": [{
286        "name": "proc0 core temps",
287        "interface": "xyz.openbmc_project.Sensor.Value",
288        "property": { "name": "Value" }
289      }],
290    "state_parameter_name": "proc_0_core_dvfs_increase_temp",
291    "delta": 300
292}
293```
294
295The above config uses a parameter as the state value:
2961. For each member of the 'proc 0 core temps' group:
297  - Read its 'Value' D-Bus property.
298  - If that property value is greater than the value of the parameter listed in
299    the 'state_parameter_name' field, in this case
300    'proc_0_core_dvfs_increase_temp':
301   - Subtracts that parameter value from the property value.
302   - Multiplies that difference by the 'delta' value of 300.
3032. Requests an increase of the largest calculated delta value, if there is one.
304
305### set_net_decrease_target
306Calculates the net target decrease to be requested based on the value of each
307property given within a group. The net target decrease is based on the minimum
308difference between the `delta` JSON value and all properties in the group. The
309final result is the decrease change that's requested to the current target of a
310zone.
311
312The group values can be compared to either a value hardcoded in the JSON, or a
313parameter value.
314
315```
316{
317    "name": "set_net_decrease_target",
318    "groups": [{
319        "name": "pcie temps",
320        "interface": "xyz.openbmc_project.Sensor.Value",
321        "property": { "name": "Value" }
322      }],
323    "state": 65.0,
324    "delta": 80
325}
326
327```
328
329The above config uses a hardcoded state value:
3301. For each member of the 'pcie temps' group:
331  - Read its 'Value' D-Bus property.
332  - If that property value is less than the 'state' value of 65.0:
333   - Subtracts the property value from 65.0.
334   - Multiplies that difference by the 'delta' value of 80.
3352. Requests a decrease of the smallest calculated delta value, if there is
336   one.
337
338```
339{
340    "name": "set_net_decrease_target",
341    "groups": [{
342        "name": "proc 0 core temps",
343        "interface": "xyz.openbmc_project.Sensor.Value",
344        "property": { "name": "Value" }
345      }],
346    "state_parameter_name": "proc_0_core_dvfs_decrease_temp",
347    "delta": 50
348}
349```
350
351The above config uses a parameter as the state value:
3521. For each member of the 'proc 0 core temps' group:
353  - Read its 'Value' D-Bus property.
354  - If that property value is less than the value of the parameter listed
355    the 'state_parameter_name' field, in this case
356    'proc_0_core_dvfs_decrease_temp':
357   - Subtracts the property value from the parameter value.
358   - Multiplies that difference by the 'delta' value of 50.
3592. Requests a decrease of the smallest calculated delta value, if there is
360   one.
361