p The .Nm framework consists of two parts:
p l -enum -offset indent -compact t the userland part, to receive the current sensor data and to set some properties on sensors: .Nm . t the kernel part that is able to talk to the drivers providing sensor data: .Xr sysmon_envsys 9 . .El
p The .Nm framework uses .Xr proplib 3 for communication between kernel and user space. The following .Xr ioctl 2 types are available:
p l -tag -width XX -compact t Dv ENVSYS_GETDICTIONARY (prop_dictionary_t)
p This .Xr ioctl 2 is used to receive the global dictionary that is being used in the kernel by the .Xr sysmon_envsys 9 framework. It will contain an array of dictionaries per device and one dictionary per sensor, each of them with its own characteristics and values.
p The following XML property list represents a virtual device .Dq device0 with one sensor .Dq sensor0 and all available properties set on it:
p d -literal \*[Lt]key\*[Gt]device0\*[Lt]/key\*[Gt] \*[Lt]array\*[Gt] \*[Lt]dict\*[Gt] \*[Lt]key\*[Gt]avg-value\*[Lt]/key\*[Gt] \*[Lt]integer\*[Gt]36400\*[Lt]/integer\*[Gt] \*[Lt]key\*[Gt]critical-capacity\*[Lt]/key\*[Gt] \*[Lt]integer\*[Gt]21417\*[Lt]/integer\*[Gt] \*[Lt]key\*[Gt]critical-max-limit\*[Lt]/key\*[Gt] \*[Lt]integer\*[Gt]343150000\*[Lt]/integer\*[Gt] \*[Lt]key\*[Gt]critical-min-limit\*[Lt]/key\*[Gt] \*[Lt]integer\*[Gt]288150000\*[Lt]/integer\*[Gt] \*[Lt]key\*[Gt]cur-value\*[Lt]/key\*[Gt] \*[Lt]integer\*[Gt]406000\*[Lt]/integer\*[Gt] \*[Lt]key\*[Gt]description\*[Lt]/key\*[Gt] \*[Lt]string\*[Gt]sensor0\*[Lt]/string\*[Gt] \*[Lt]key\*[Gt]generic-state-string\*[Lt]/key\*[Gt] \*[Lt]string\*[Gt]NORMAL\*[Lt]/string\*[Gt] \*[Lt]key\*[Gt]max-value\*[Lt]/key\*[Gt] \*[Lt]integer\*[Gt]3894000\*[Lt]/integer\*[Gt] \*[Lt]key\*[Gt]min-value\*[Lt]/key\*[Gt] \*[Lt]integer\*[Gt]2894000\*[Lt]/integer\*[Gt] \*[Lt]key\*[Gt]monitoring-state-critical\*[Lt]/key\*[Gt] \*[Lt]true/\*[Gt] \*[Lt]key\*[Gt]monitoring-state-critover\*[Lt]/key\*[Gt] \*[Lt]true/\*[Gt] \*[Lt]key\*[Gt]monitoring-state-critunder\*[Lt]/key\*[Gt] \*[Lt]true/\*[Gt] \*[Lt]key\*[Gt]monitoring-state-state-changed\*[Lt]/key\*[Gt] \*[Lt]true/\*[Gt] \*[Lt]key\*[Gt]monitoring-state-warnover\*[Lt]/key\*[Gt] \*[Lt]true/\*[Gt] \*[Lt]key\*[Gt]monitoring-state-warnunder\*[Lt]/key\*[Gt] \*[Lt]true/\*[Gt] \*[Lt]key\*[Gt]monitoring-supported\*[Lt]/key\*[Gt] \*[Lt]true/\*[Gt] \*[Lt]key\*[Gt]state\*[Lt]/key\*[Gt] \*[Lt]string\*[Gt]valid\*[Lt]/string\*[Gt] \*[Lt]key\*[Gt]type\*[Lt]/key\*[Gt] \*[Lt]string\*[Gt]Ampere hour\*[Lt]/string\*[Gt] \*[Lt]key\*[Gt]want-percentage\*[Lt]/key\*[Gt] \*[Lt]true/\*[Gt] \*[Lt]/dict\*[Gt] \*[Lt]/array\*[Gt] .Ed
p Let's explain some more about those objects: l -tag -width "monitoring-state-critical-overxx" t Fa avg-value Current average value in the sensor. t Fa critical-capacity Critical capacity set previously by the .Ar ENVSYS_SETDICTIONARY .Xr ioctl 2 . Only available on sensors with the .Em want-percentage object enabled. t Fa critical-max-limit Critical max limit set previously by the .Ar ENVSYS_SETDICTIONARY .Xr ioctl 2 . t Fa critical-min-limit Critical min limit set previously by the .Ar ENVSYS_SETDICTIONARY .Xr ioctl 2 . t Fa cur-value Current value in the sensor. t Fa description Description of the sensor. t Fa generic-state-string This is a generic string that .Xr envstat 8 will use to print as .Em current value . Only used in sensors with type of .Em ENVSYS_GSTRING . t Fa max-value Current max value in the sensor. t Fa min-value Current min value in the sensor. t Fa monitoring-state-critical If true, the driver has enabled the flag to monitor a critical state. t Fa monitoring-state-critical-over If true, the driver has enabled the flag to monitor a critical over state. t Fa monitoring-state-critical-under If true, the driver has enabled the flag to monitor a critical under state. t Fa monitoring-state-state-changed If true, the driver has enabled the flag to monitor for state changes in a drive or Battery state sensor. t Fa monitoring-state-warning-over If true, the driver has enabled the flag to monitor a warning over state. t Fa monitoring-state-warning-under If true, the driver has enabled the flag to monitor a warning under state. t Fa monitoring-supported If true, critical capacity/max/min limits may be set by the .Ar ENVSYS_SETDICTIONARY .Xr ioctl 2 . t Fa state Current state in the sensor. t Fa type Type of unit in the sensor. t Fa want-percentage If true, .Em max-value and .Em cur-value are valid and a percentage may be computed from them. .El .El
p l -tag -width XX -compact t Dv ENVSYS_SETDICTIONARY (prop_dictionary_t)
p This .Xr ioctl 2 is used to send a dictionary with new properties that should be processed by the .Nm framework. Only a set of predefined keywords are recognized by the kernel part. The following is the property list representation of a dictionary with all recognized and required keywords: d -literal \*[Lt]dict\*[Gt] \*[Lt]key\*[Gt]driver-name\*[Lt]/key\*[Gt] \*[Lt]string\*[Gt]driver0\*[Lt]/string\*[Gt] \*[Lt]key\*[Gt]sensor-name\*[Lt]/key\*[Gt] \*[Lt]string\*[Gt]sensor0\*[Lt]/string\*[Gt] \*[Lt]key\*[Gt]new-description\*[Lt]/key\*[Gt] \*[Lt]string\*[Gt]mysensor0\*[Lt]/string\*[Gt] \*[Lt]key\*[Gt]new-rfact\*[Lt]/key\*[Gt] \*[Lt]integer\*[Gt]56000\*[Lt]/integer\*[Gt] \*[Lt]key\*[Gt]critical-capacity\*[Lt]/key\*[Gt] \*[Lt]integer\*[Gt]10\*[Lt]/integer\*[Gt] \*[Lt]key\*[Gt]critical-max-limit\*[Lt]/key\*[Gt] \*[Lt]integer\*[Gt]3400\*[Lt]/integer\*[Gt] \*[Lt]key\*[Gt]critical-min-limit\*[Lt]/key\*[Gt] \*[Lt]integer\*[Gt]2800\*[Lt]/integer\*[Gt] \*[Lt]key\*[Gt]remove-critical-cap\*[Lt]/key\*[Gt] \*[Lt]true/\*[Gt] \*[Lt]key\*[Gt]remove-cmax-limit\*[Lt]/key\*[Gt] \*[Lt]true/\*[Gt] \*[Lt]key\*[Gt]remove-cmin-limit\*[Lt]/key\*[Gt] \*[Lt]true/\*[Gt] \*[Lt]/dict\*[Gt] .Ed
p A dictionary sent to the kernel with this .Xr ioctl 2 must .Sy always have the objects .Ar driver-name and .Ar sensor-name . They are used to specify the .Sy driver and the .Sy sensor that we want to set a property for.
p .Em NOTE : Only one of the following objects must be added into the dictionary at a time: .Ar new-description , .Ar new-rfact , .Ar critical-capacity , .Ar critical-max-limit , .Ar critical-min-limit , .Ar remove-critical-cap , .Ar remove-cmax-limit , and .Ar remove-cmin-limit .
p The following operation is selected depending what object was added into the dictionary:
p l -bullet -offset indent -compact t change a description. t change the rfact in a voltage sensor. t set a critical capacity limit. t set a critical max limit. t set a critical min limit. t remove a critical capacity limit. t remove a critical max limit. t remove a critical min limit. .El
p If an unknown object was sent with the dictionary, .Er EINVAL will be returned, or if the sensor does not support changing rfact (voltage sensors) or critical/capacity limits, .Er ENOTSUP will be returned. .El .Sh NOTES When setting a critical max or min limit with the .Em ENVSYS_SETDICTIONARY .Xr ioctl 2 , the user must be aware that .Xr sysmon_envsys 9 expects to have a proper unit, so the value must be converted. Please see .Xr sysmon_envsys 9 for more information.
p Also when setting a critical capacity limit, the formula to send a proper value to .Xr sysmon_envsys 9 is the following: .Em value = (value / 100) * max value . The max value is available in the sensor's dictionary. .Sh EXAMPLES The following example illustrates how to receive the dictionary and to print it in raw XML/plist format: d -literal #define _DEV_SYSMON /dev/sysmon int main(void) { prop_dictionary_t dict; char *buf; int fd; if ((fd = open(_DEV_SYSMON, O_RDONLY)) == -1) err(EXIT_FAILURE, "open") if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, \*[Am]dict)) { (void)close(fd); err(EINVAL, "prop_dictionary_recv_ioctl"); } buf = prop_dictionary_externalize(dict); (void)printf("%s", buf); prop_object_release(dict); free(buf); (void)close(fd); return EXIT_SUCCESS; } .Ed
p Another example that shows how to use the .Ar ENVSYS_SETDICTIONARY .Xr ioctl 2 to change the description in a sensor: d -literal int main(void) { prop_dictionary_t dict; prop_object_t obj; int fd; dict = prop_dictionary_create(); obj = prop_string_create_cstring_nocopy("aiboost0"); if (obj == NULL || !prop_dictionary_set(dict, "driver-name", obj)) err(EINVAL, "driver-name"); prop_object_release(obj); obj = prop_string_create_cstring_nocopy("CPU Temperature"); if (obj == NULL || !prop_dictionary_set(dict, "sensor-name", obj)) err(EINVAL, "sensor-name"); prop_object_release(obj); /* new description */ obj = prop_string_create_cstring_nocopy("CPU temp"); if (obj == NULL || !prop_dictionary_set(dict, "new-description", obj)) err(EINVAL, "new-description"); prop_object_release(obj); if ((fd = open(_DEV_SYSMON, O_RDONLY)) == -1) err(EXIT_FAILURE, "open") /* we are done, send the dictionary */ error = prop_dictionary_send_ioctl(dict, fd, ENVSYS_SETDICTIONARY); prop_object_release(dict); (void)close(fd); return error; } .Ed .Sh SEE ALSO .Xr envstat 8 , .Xr powerd 8 , .Xr sysmon_envsys 9 .Sh AUTHORS The .Nm 2 framework was designed and implemented by .An Juan Romero Pardines for .Nx 5.0 . Many useful comments for this framework were from Jason R. Thorpe, Tim Rightnour and Michael Lorenz. Previous framework was implemented by Tim Rightnour and Bill Squier.