Imported Upstream version 2.7.4
This commit is contained in:
parent
fd413a3168
commit
c9cb2187ee
290 changed files with 7473 additions and 2607 deletions
|
|
@ -19,7 +19,7 @@ In order to develop a new subdriver for a specific UPS you have to know the idio
|
|||
|
||||
This kind of devices speaks idioms that can be summed up as follows:
|
||||
|
||||
- We send the UPS a query for one or more informations
|
||||
- We send the UPS a query for one or more information
|
||||
|
||||
* If the query is supported by the device, we'll get a reply that is mostly of a fixed length, therefore, in most cases, each information starts and ends always at the same indexes
|
||||
|
||||
|
|
@ -137,8 +137,9 @@ typedef struct item_t {
|
|||
const int to;
|
||||
const char *dfl;
|
||||
unsigned long qxflags;
|
||||
int (*preprocess_command)(struct item_t *item, char *command, const size_t commandlen);
|
||||
int (*preprocess_answer)(struct item_t *item, const int len);
|
||||
int (*preprocess)(struct item_t *item, char *value, size_t valuelen);
|
||||
int (*preprocess)(struct item_t *item, char *value, const size_t valuelen);
|
||||
} item_t;
|
||||
----
|
||||
|
||||
|
|
@ -166,7 +167,7 @@ NOTE: If +QX_FLAG_SETVAR+ is set the value given by the user will be checked aga
|
|||
----
|
||||
typedef struct {
|
||||
char value[SMALLBUF];
|
||||
int (*preprocess)(char *value, size_t len);
|
||||
int (*preprocess)(char *value, const size_t len);
|
||||
} info_rw_t;
|
||||
----
|
||||
|
||||
|
|
@ -187,7 +188,7 @@ Command sent to the UPS to get answer/to execute a instant command/to set a vari
|
|||
*+answer+*::
|
||||
Answer from the UPS, filled at runtime.
|
||||
+
|
||||
NOTE: If you expect a nonvalid C string (e.g.: inner ++\0++s) or need to perform actions before the answer is used (and treated as a null-terminated string), you should set a +preprocess_answer()+ function.
|
||||
NOTE: If you expect a non-valid C string (e.g.: inner ++\0++s) or need to perform actions before the answer is used (and treated as a null-terminated string), you should set a +preprocess_answer()+ function.
|
||||
|
||||
*+answer_len+*::
|
||||
Expected minimum length of the answer.
|
||||
|
|
@ -245,6 +246,12 @@ If there's a problem with a var in +QX_WALKMODE_INIT+, the driver will automagic
|
|||
====
|
||||
--
|
||||
|
||||
*+preprocess_command(item, command, commandlen)+*::
|
||||
Last chance to preprocess the command to be sent to the UPS (e.g. to add CRC, ...).
|
||||
This function is given the currently processed item (+item+), the command to be sent to the UPS (+command+) and its size_t (+commandlen+).
|
||||
Return +-1+ in case of errors, else +0+.
|
||||
+command+ must be filled with the actual command to be sent to the UPS.
|
||||
|
||||
*+preprocess_answer(item, len)+*::
|
||||
Function to preprocess the answer we got from the UPS before we do anything else (e.g. for CRC, decoding, ...).
|
||||
This function is given the currently processed item (+item+) with the answer we got from the UPS unmolested and already stored in +item+'s +answer+ and the length of that answer (+len+).
|
||||
|
|
@ -290,7 +297,7 @@ We know that when the UPS is queried for status with +QGS\r+, it replies with so
|
|||
Here's the +item_t+:
|
||||
|
||||
----
|
||||
{ "output.voltage", 0, NULL, "QGS\r", "", 76, '(', "", 12, 16, "%.1f", 0, NULL, NULL },
|
||||
{ "output.voltage", 0, NULL, "QGS\r", "", 76, '(', "", 12, 16, "%.1f", 0, NULL, NULL, NULL },
|
||||
----
|
||||
|
||||
[horizontal]
|
||||
|
|
@ -333,6 +340,9 @@ Because of that we need to provide a floating point specifier.
|
|||
+qxflags+::
|
||||
+0+
|
||||
|
||||
+preprocess_command+::
|
||||
+NULL+
|
||||
|
||||
+preprocess_answer+::
|
||||
+NULL+
|
||||
|
||||
|
|
@ -355,7 +365,7 @@ Also from +QGS\r+, we want to process the 9th status bit +10000000+*`0`*+001+ th
|
|||
Here's the +item_t+:
|
||||
|
||||
----
|
||||
{ "ups.status", 0, NULL, "QGS\r", "", 76, '(', "", 71, 71, "%s", QX_FLAG_QUICK_POLL, NULL, voltronic_status },
|
||||
{ "ups.status", 0, NULL, "QGS\r", "", 76, '(', "", 71, 71, "%s", QX_FLAG_QUICK_POLL, NULL, NULL, voltronic_status },
|
||||
----
|
||||
|
||||
[horizontal]
|
||||
|
|
@ -398,6 +408,9 @@ Since a +preprocess+ function is defined for this item, this could have been +NU
|
|||
+QX_FLAG_QUICK_POLL+ -> this item will be polled every time the driver will check for updates.
|
||||
Since this item is mandatory to run the driver, if a problem arises in +QX_WALKMODE_INIT+ the driver won't skip it an it'll set +datastale+.
|
||||
|
||||
+preprocess_command+::
|
||||
+NULL+
|
||||
|
||||
+preprocess_answer+::
|
||||
+NULL+
|
||||
|
||||
|
|
@ -423,7 +436,7 @@ Here's the +item_t+:
|
|||
|
||||
----
|
||||
{ "battery.type", ST_FLAG_RW, voltronic_e_batt_type, "QBT\r", "", 4, '(', "", 1, 2, "%s",
|
||||
QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM, NULL, voltronic_p31b },
|
||||
QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM, NULL, NULL, voltronic_p31b },
|
||||
----
|
||||
|
||||
[horizontal]
|
||||
|
|
@ -469,6 +482,9 @@ Since a +preprocess+ function is defined for this item, this could have been +NU
|
|||
+
|
||||
+QX_FLAG_ENUM+ -> this r/w variable is of the enumerated type and the enumerated values are listed in the +info_rw+ structure (i.e. +voltronic_e_batt_type+)
|
||||
|
||||
+preprocess_command+::
|
||||
+NULL+
|
||||
|
||||
+preprocess_answer+::
|
||||
+NULL+
|
||||
|
||||
|
|
@ -477,7 +493,7 @@ Since a +preprocess+ function is defined for this item, this could have been +NU
|
|||
+
|
||||
This function will be called *after* the +command+ has been sent to the UPS and we got back the +answer+ and stored the +value+ in order to process it to NUT standards: in this case we will check if the value is in the range and then publish the human readable form of it (i.e. +Li+, +Flooded+ or +AGM+).
|
||||
|
||||
We also know that we can change battery type with the +PBTnn\r+ command; we are expecting either +(ACK\r+ if the command succeded or +(NAK\r+ if the command is rejected.
|
||||
We also know that we can change battery type with the +PBTnn\r+ command; we are expecting either +(ACK\r+ if the command succeeded or +(NAK\r+ if the command is rejected.
|
||||
|
||||
----
|
||||
> [PBTnn\r] nn = 00/01/02
|
||||
|
|
@ -490,7 +506,7 @@ Here's the +item_t+:
|
|||
|
||||
----
|
||||
{ "battery.type", 0, voltronic_e_batt_type, "PBT%02.0f\r", "", 5, '(', "", 1, 4, NULL,
|
||||
QX_FLAG_SETVAR | QX_FLAG_ENUM, NULL, voltronic_p31b_set },
|
||||
QX_FLAG_SETVAR | QX_FLAG_ENUM, NULL, NULL, voltronic_p31b_set },
|
||||
----
|
||||
|
||||
[horizontal]
|
||||
|
|
@ -534,6 +550,9 @@ Not used for +QX_FLAG_SETVAR+
|
|||
+
|
||||
+QX_FLAG_ENUM+ -> this r/w variable is of the enumerated type and the enumerated values are listed in the +info_rw+ structure (i.e. +voltronic_e_batt_type+)
|
||||
|
||||
+preprocess_command+::
|
||||
+NULL+
|
||||
|
||||
+preprocess_answer+::
|
||||
+NULL+
|
||||
|
||||
|
|
@ -558,7 +577,7 @@ We know that we have to send to the UPS +Tnn\r+ or +T.n\r+ in order to start a b
|
|||
Here's the +item_t+:
|
||||
|
||||
----
|
||||
{ "test.battery.start", 0, NULL, "T%s\r", "", 5, '(', "", 1, 4, NULL, QX_FLAG_CMD, NULL, voltronic_process_command },
|
||||
{ "test.battery.start", 0, NULL, "T%s\r", "", 5, '(', "", 1, 4, NULL, QX_FLAG_CMD, NULL, NULL, voltronic_process_command },
|
||||
----
|
||||
|
||||
[horizontal]
|
||||
|
|
@ -598,6 +617,9 @@ Not used for +QX_FLAG_CMD+
|
|||
+qxflags+::
|
||||
+QX_FLAG_CMD+ -> this item is an instant command that will be fired when +info_type+ (i.e. +test.battery.start+) is called
|
||||
|
||||
+preprocess_command+::
|
||||
+NULL+
|
||||
|
||||
+preprocess_answer+::
|
||||
+NULL+
|
||||
|
||||
|
|
@ -614,7 +636,7 @@ In order to set the server-side var +ups.delay.start+, that will be then used by
|
|||
|
||||
----
|
||||
{ "ups.delay.start", ST_FLAG_RW, voltronic_r_ondelay, NULL, "", 0, 0, "", 0, 0, "180",
|
||||
QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, voltronic_process_setvar },
|
||||
QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, voltronic_process_setvar },
|
||||
----
|
||||
|
||||
[horizontal]
|
||||
|
|
@ -661,13 +683,16 @@ Not used for +QX_FLAG_ABSENT+
|
|||
+
|
||||
+QX_FLAG_RANGE+ -> this r/w variable has a settable range and its boundaries are listed in the +info_rw+ structure (i.e. +voltronic_r_ondelay+)
|
||||
|
||||
+preprocess_command+::
|
||||
+NULL+
|
||||
|
||||
+preprocess_answer+::
|
||||
+NULL+
|
||||
|
||||
+preprocess+::
|
||||
+voltronic_process_setvar+
|
||||
+
|
||||
This function will be called, in setvar, before the driver stores the value in the NUT var: here it's used to truncate the user-provided value to the neareset settable interval.
|
||||
This function will be called, in setvar, before the driver stores the value in the NUT var: here it's used to truncate the user-provided value to the nearest settable interval.
|
||||
|
||||
|
||||
Informations not yet available in NUT
|
||||
|
|
@ -688,7 +713,7 @@ Here's the +item_t+ for input phase angle:
|
|||
|
||||
----
|
||||
{ "input_phase_angle", 0, NULL, "QPD\r", "", 9, '(', "", 1, 3, "%03.0f",
|
||||
QX_FLAG_STATIC | QX_FLAG_NONUT, NULL, voltronic_phase },
|
||||
QX_FLAG_STATIC | QX_FLAG_NONUT, NULL, NULL, voltronic_phase },
|
||||
----
|
||||
|
||||
[horizontal]
|
||||
|
|
@ -735,6 +760,9 @@ Here instead it's used by the +preprocess+ function.
|
|||
+
|
||||
+QX_FLAG_NONUT+ -> this item doesn't have yet a NUT variable
|
||||
|
||||
+preprocess_command+::
|
||||
+NULL+
|
||||
|
||||
+preprocess_answer+::
|
||||
+NULL+
|
||||
|
||||
|
|
@ -747,7 +775,7 @@ Here's the +item_t+ for output phase angle:
|
|||
|
||||
----
|
||||
{ "output_phase_angle", ST_FLAG_RW, voltronic_e_phase, "QPD\r", "", 9, '(', "", 5, 7, "%03.0f",
|
||||
QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM | QX_FLAG_NONUT, NULL, voltronic_phase },
|
||||
QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM | QX_FLAG_NONUT, NULL, NULL, voltronic_phase },
|
||||
----
|
||||
|
||||
[horizontal]
|
||||
|
|
@ -801,6 +829,9 @@ Here instead it's used by the +preprocess+ function.
|
|||
+
|
||||
+QX_FLAG_NONUT+ -> this item doesn't have yet a NUT variable
|
||||
|
||||
+preprocess_command+::
|
||||
+NULL+
|
||||
|
||||
+preprocess_answer+::
|
||||
+NULL+
|
||||
|
||||
|
|
@ -827,7 +858,7 @@ Here's the +item_t+
|
|||
|
||||
----
|
||||
{ "output_phase_angle", 0, voltronic_e_phase, "PPD%03.0f\r", "", 5, '(', "", 1, 4, NULL,
|
||||
QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT, NULL, voltronic_phase_set },
|
||||
QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT, NULL, NULL, voltronic_phase_set },
|
||||
----
|
||||
|
||||
[horizontal]
|
||||
|
|
@ -877,6 +908,9 @@ Not used for +QX_FLAG_SETVAR+
|
|||
+
|
||||
+QX_FLAG_NONUT+ -> this item doesn't have yet a NUT variable
|
||||
|
||||
+preprocess_command+::
|
||||
+NULL+
|
||||
|
||||
+preprocess_answer+::
|
||||
+NULL+
|
||||
|
||||
|
|
@ -892,7 +926,14 @@ Support functions
|
|||
You are already given the following functions:
|
||||
|
||||
*+int instcmd(const char *cmdname, const char *extradata)+*::
|
||||
Execute an instant command.
|
||||
Execute an instant command. In detail:
|
||||
+
|
||||
--
|
||||
- look up the given +cmdname+ in the qx2nut data structure (if not found, try to fallback to commonly known commands);
|
||||
- if +cmdname+ is found, call its preprocess function, passing to it +extradata+, if any, otherwise its +dfl+ value, if any;
|
||||
- send the command to the device and check the reply.
|
||||
--
|
||||
+
|
||||
Return +STAT_INSTCMD_INVALID+ if the command is invalid, +STAT_INSTCMD_FAILED+ if it failed, +STAT_INSTCMD_HANDLED+ on success.
|
||||
|
||||
*+int setvar(const char *varname, const char *val)+*::
|
||||
|
|
@ -905,11 +946,11 @@ Find an item of +item_t+ type in +qx2nut+ data structure by its +info_type+, opt
|
|||
- +noflag+: flags that have to be absent in the item, i.e. if at least one of the flags is set in the item it won't be returned.
|
||||
|
||||
*+int qx_process(item_t *item, const char *command)+*::
|
||||
Send +command+ or, if it is +NULL+, send the command stored in the +item+ to the UPS and process the reply.
|
||||
Send +command+ (a null-terminated byte string) or, if it is +NULL+, send the command stored in the +item+ to the UPS and process the reply, saving it in +item+'s +answer+.
|
||||
Return +-1+ on errors, +0+ on success.
|
||||
|
||||
*+int ups_infoval_set(item_t *item)+*::
|
||||
Process the value we got back from the UPS (set status bits and set the value of other parameters), calling its +preprocess+ function, if any, otherwise executing the standard preprocessing (including trimming if +QX_FLAG_TRIM+ is set).
|
||||
Process the value we got back from the UPS (set status bits and set the value of other parameters), calling the +item+-specific +preprocess+ function, if any, otherwise executing the standard preprocessing (including trimming if +QX_FLAG_TRIM+ is set).
|
||||
Return +-1+ on failure, +0+ for a status update and +1+ in all other cases.
|
||||
|
||||
*+int qx_status(void)+*::
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue