Skip to content

Commit 9495a68

Browse files
authored
Merge f8eecc6 into cb225e0
2 parents cb225e0 + f8eecc6 commit 9495a68

File tree

8 files changed

+224
-9
lines changed

8 files changed

+224
-9
lines changed

docs/man/nutdrv_qx.txt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ If you set stayoff in linkman:ups.conf[5] when FSD arises the UPS will call a *s
6767

6868
*protocol =* 'string'::
6969
Skip autodetection of the protocol to use and only use the one specified.
70-
Supported values: 'bestups', 'hunnox', 'masterguard', 'mecer', 'megatec', 'megatec/old', 'mustek', 'q1', 'voltronic', 'voltronic-qs', 'voltronic-qs-hex' and 'zinto'.
70+
Supported values: 'bestups', 'hunnox', 'innovart31', 'masterguard', 'mecer', 'megatec', 'megatec/old', 'mustek', 'q1', 'voltronic', 'voltronic-qs', 'voltronic-qs-hex' and 'zinto'.
7171
+
7272
Run the driver program with the `--help` option to see the exact list of
7373
`protocol` values it would currently recognize.
@@ -147,8 +147,8 @@ If not specified, the driver defaults to 10%.
147147
Only used if *runtimecal* is also specified.
148148

149149

150-
BESTUPS, MECER, MEGATAEC, MEGATEC/OLD, MUSTEK, Q1, VOLTRONIC-QS, VOLTRONIC-QS-HEX, ZINTO PROTOCOLS
151-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
150+
BESTUPS, INNOVART31, MECER, MEGATEC, MEGATEC/OLD, MUSTEK, Q1, VOLTRONIC-QS, VOLTRONIC-QS-HEX, ZINTO PROTOCOLS
151+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
152152

153153
*ignoresab*::
154154
Some UPSes incorrectly report the `Shutdown Active' bit as always on, consequently making the driver believe the UPS is nearing a shutdown (and, as a result, ups.status always contains +FSD+... and you know what this means).
@@ -196,8 +196,8 @@ Safeguard against talking to the wrong one of several identical UPSes on the sam
196196
Note that when changing *ups.id* (through linkman:upsrw[8]) the driver will continue to talk to the UPS with the new 'slave address', but won't claim it again on restart until the *slave_addr* parameter is adjusted.
197197

198198

199-
Q1 PROTOCOL
200-
~~~~~~~~~~~
199+
INNOVART31, Q1 PROTOCOLS
200+
~~~~~~~~~~~~~~~~~~~~~~~~
201201

202202
*ondelay*::
203203
The acceptable range is +0..599940+ seconds.
@@ -439,8 +439,8 @@ Stop a running battery test.
439439
(Not available on some hardware)
440440

441441

442-
BESTUPS, MECER, MEGATEC, MEGATEC/OLD, MUSTEK, Q1, ZINTO PROTOCOLS
443-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
442+
BESTUPS, INNOVART31, MECER, MEGATEC, MEGATEC/OLD, MUSTEK, Q1, ZINTO PROTOCOLS
443+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
444444

445445
*test.battery.start* 'value'::
446446
Perform a battery test for the duration of 'value' seconds (truncated to 60 seconds) [+60..5940+].

docs/nutdrv_qx-subdrivers.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,7 @@ You can then recompile +nutdrv_qx+, and start experimenting with the new subdriv
11441144
For more details, have a look at the currently available subdrivers:
11451145

11461146
- +nutdrv_qx_bestups.+{+c+,+h+}
1147+
- +nutdrv_qx_innovart31.+{+c+,+h+}
11471148
- +nutdrv_qx_masterguard.+{+c+,+h+}
11481149
- +nutdrv_qx_mecer.+{+c+,+h+}
11491150
- +nutdrv_qx_megatec.+{+c+,+h+}

drivers/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ nutdrv_qx_SOURCES += $(LIBUSB_IMPL) usb-common.c
379379
nutdrv_qx_LDADD += $(LIBUSB_LIBS)
380380
endif
381381
NUTDRV_QX_SUBDRIVERS = nutdrv_qx_bestups.c nutdrv_qx_blazer-common.c \
382+
nutdrv_qx_innovart31.c \
382383
nutdrv_qx_masterguard.c \
383384
nutdrv_qx_mecer.c nutdrv_qx_megatec.c nutdrv_qx_megatec-old.c \
384385
nutdrv_qx_mustek.c nutdrv_qx_q1.c nutdrv_qx_voltronic.c \
@@ -404,6 +405,7 @@ dist_noinst_HEADERS = \
404405
upshandler.h usb-common.h usbhid-ups.h powercom-hid.h compaq-mib.h idowell-hid.h \
405406
apcsmart.h apcsmart_tabs.h apcsmart-old.h apcupsd-ups.h cyberpower-mib.h riello.h openups-hid.h \
406407
delta_ups-mib.h nutdrv_qx.h nutdrv_qx_bestups.h nutdrv_qx_blazer-common.h \
408+
nutdrv_qx_innovart31.h \
407409
nutdrv_qx_masterguard.h \
408410
nutdrv_qx_mecer.h nutdrv_qx_ablerex.h \
409411
nutdrv_qx_megatec.h nutdrv_qx_megatec-old.h nutdrv_qx_mustek.h nutdrv_qx_q1.h nutdrv_qx_hunnox.h \

drivers/nutdrv_qx.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
/* Include all known subdrivers */
7272
#include "nutdrv_qx_bestups.h"
7373
#include "nutdrv_qx_hunnox.h"
74+
#include "nutdrv_qx_innovart31.h"
7475
#include "nutdrv_qx_mecer.h"
7576
#include "nutdrv_qx_megatec.h"
7677
#include "nutdrv_qx_megatec-old.h"
@@ -97,6 +98,7 @@ static subdriver_t *subdriver_list[] = {
9798
&masterguard_subdriver,
9899
&hunnox_subdriver,
99100
&ablerex_subdriver,
101+
&innovart31_subdriver,
100102
/* Fallback Q1 subdriver */
101103
&q1_subdriver,
102104
NULL

drivers/nutdrv_qx_blazer-common.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* nutdrv_qx_blazer-common.c - Common functions/settings for nutdrv_qx_{mecer,megatec,megatec-old,mustek,q1,voltronic-qs,zinto}.{c,h}
1+
/* nutdrv_qx_blazer-common.c - Common functions/settings for nutdrv_qx_{innovart31,mecer,megatec,megatec-old,mustek,q1,voltronic-qs,zinto}.{c,h}
22
*
33
* Copyright (C)
44
* 2013 Daniele Pezzini <hyouko@gmail.com>

drivers/nutdrv_qx_blazer-common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* nutdrv_qx_blazer-common.h - Common functions/settings for nutdrv_qx_{mecer,megatec,megatec-old,mustek,q1,voltronic-qs,zinto}.{c,h}
1+
/* nutdrv_qx_blazer-common.h - Common functions/settings for nutdrv_qx_{innovart31,mecer,megatec,megatec-old,mustek,q1,voltronic-qs,zinto}.{c,h}
22
*
33
* Copyright (C)
44
* 2013 Daniele Pezzini <hyouko@gmail.com>

drivers/nutdrv_qx_innovart31.c

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/* nutdrv_qx_innovart31.c - Subdriver for INNOVA RT 3/1 UPSes
2+
*
3+
* Copyright (C)
4+
* 2024 Viktor Drobot <linux776@gmail.com>
5+
*
6+
* This program is free software; you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation; either version 2 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program; if not, write to the Free Software
18+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19+
*
20+
*/
21+
22+
#include "main.h"
23+
#include "nutdrv_qx.h"
24+
#include "nutdrv_qx_blazer-common.h"
25+
26+
#include "nutdrv_qx_innovart31.h"
27+
28+
#define INNOVART31_VERSION "INNOVART31 0.01"
29+
30+
/* Internal function: used to convert kilo-values to their full representation */
31+
static int innovart31_x1000(item_t *item, char *value, const size_t valuelen) {
32+
float s = 0;
33+
34+
if (sscanf(item->value, "%f", &s) != 1) {
35+
upsdebugx(2, "unparsable ss.ss %s", item->value);
36+
return -1;
37+
}
38+
39+
snprintf(value, valuelen, "%.2f", s * 1000.0);
40+
return 0;
41+
}
42+
/* qx2nut lookup table */
43+
static item_t innovart31_qx2nut[] = {
44+
45+
/*
46+
* > [Q1\r]
47+
* < [(226.0 195.0 226.0 014 49.0 27.5 30.0 00001000\r]
48+
* 01234567890123456789012345678901234567890123456
49+
* 0 1 2 3 4
50+
*/
51+
52+
/*
53+
* > [Q6\r]
54+
* < [(227.0 225.6 230.0 50.0 229.9 000.0 000.0 49.9 007 000 000 327.8 000.0 23.0 06932 100 32 00000000 00000000 11\r]
55+
* 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
56+
* 0 1 2 3 4 5 6 7 8 9 10
57+
*/
58+
59+
/*
60+
* > [WA\r]
61+
* < [(001.4 000.0 000.0 001.4 000.0 000.0 001.4 001.4 006.5 000.0 000.0 007 00000000\r]
62+
* 01234567890123456789012345678901234567890123456789012345678901234567890123456789
63+
* 0 1 2 3 4 5 6 7
64+
*/
65+
66+
/*
67+
* > [BPS\r]
68+
* < [(230.4 000.0 000.0 49.9\r]
69+
* 012345678901234567890123
70+
* 0 1 2
71+
*/
72+
73+
/*
74+
* > [F\r]
75+
* < [#230.0 087 288.0 50.0\r]
76+
* 0123456789012345678901
77+
* 0 1 2
78+
*/
79+
80+
{ "input.voltage", 0, NULL, "Q6\r", "", 110, '(', "", 1, 5, "%.1f", 0, NULL, NULL, NULL },
81+
{ "input.L1-N.voltage", 0, NULL, "Q6\r", "", 110, '(', "", 1, 5, "%.1f", 0, NULL, NULL, NULL },
82+
{ "input.L2-N.voltage", 0, NULL, "Q6\r", "", 110, '(', "", 7, 11, "%.1f", 0, NULL, NULL, NULL },
83+
{ "input.L3-N.voltage", 0, NULL, "Q6\r", "", 110, '(', "", 13, 17, "%.1f", 0, NULL, NULL, NULL },
84+
{ "input.frequency", 0, NULL, "Q6\r", "", 110, '(', "", 19, 22, "%.1f", 0, NULL, NULL, NULL },
85+
{ "input.bypass.voltage", 0, NULL, "BPS\r", "", 24, '(', "", 1, 5, "%.1f", 0, NULL, NULL, NULL },
86+
{ "input.bypass.frequency", 0, NULL, "BPS\r", "", 24, '(', "", 19, 22, "%.1f", 0, NULL, NULL, NULL },
87+
{ "output.voltage", 0, NULL, "Q6\r", "", 110, '(', "", 24, 28, "%.1f", 0, NULL, NULL, NULL },
88+
{ "output.current", 0, NULL, "WA\r", "", 80, '(', "", 49, 53, "%.1f", 0, NULL, NULL, NULL },
89+
{ "output.frequency", 0, NULL, "Q6\r", "", 110, '(', "", 42, 45, "%.1f", 0, NULL, NULL, NULL },
90+
{ "ups.load", 0, NULL, "Q6\r", "", 110, '(', "", 47, 49, "%.0f", 0, NULL, NULL, NULL },
91+
{ "ups.realpower", 0, NULL, "WA\r", "", 80, '(', "", 37, 41, "%.1f", 0, NULL, NULL, innovart31_x1000 },
92+
{ "ups.power", 0, NULL, "WA\r", "", 80, '(', "", 43, 47, "%.1f", 0, NULL, NULL, innovart31_x1000 },
93+
{ "ups.temperature", 0, NULL, "Q6\r", "", 110, '(', "", 71, 74, "%.1f", 0, NULL, NULL, NULL },
94+
{ "battery.voltage", 0, NULL, "Q6\r", "", 110, '(', "", 59, 63, "%.2f", 0, NULL, NULL, qx_multiply_battvolt },
95+
{ "battery.runtime", 0, NULL, "Q6\r", "", 110, '(', "", 76, 80, "%.0f", 0, NULL, NULL, NULL },
96+
/* TODO check if needed */
97+
// { "battery.charge", 0, NULL, "Q6\r", "", 110, '(', "", 82, 84, "%.0f", 0, NULL, NULL, NULL },
98+
/* Status bits */
99+
{ "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Utility Fail (Immediate) */
100+
{ "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Battery Low */
101+
{ "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Bypass/Boost or Buck Active */
102+
{ "ups.alarm", 0, NULL, "Q1\r", "", 47, '(', "", 41, 41, NULL, 0, NULL, NULL, blazer_process_status_bits }, /* UPS Failed */
103+
{ "ups.type", 0, NULL, "Q1\r", "", 47, '(', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, NULL, blazer_process_status_bits }, /* UPS Type */
104+
{ "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Test in Progress */
105+
{ "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Shutdown Active */
106+
{ "ups.beeper.status", 0, NULL, "Q1\r", "", 47, '(', "", 45, 45, "%s", 0, NULL, NULL, blazer_process_status_bits }, /* Beeper status */
107+
108+
{ "input.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 1, 5, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL },
109+
{ "input.current.nominal", 0, NULL, "F\r", "", 22, '#', "", 7, 9, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL },
110+
{ "battery.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 11, 15, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL },
111+
{ "input.frequency.nominal", 0, NULL, "F\r", "", 22, '#', "", 17, 20, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL },
112+
113+
/* Instant commands */
114+
{ "beeper.toggle", 0, NULL, "Q\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL },
115+
{ "load.off", 0, NULL, "S00R0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL },
116+
{ "load.on", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL },
117+
{ "shutdown.return", 0, NULL, "S%s\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command },
118+
{ "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command },
119+
{ "shutdown.stop", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL },
120+
{ "test.battery.start", 0, NULL, "T%02d\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command },
121+
{ "test.battery.start.deep", 0, NULL, "TL\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL },
122+
{ "test.battery.start.quick", 0, NULL, "T\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL },
123+
{ "test.battery.stop", 0, NULL, "CT\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL },
124+
125+
/* Server-side settable vars */
126+
{ "ups.delay.start", ST_FLAG_RW, blazer_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar },
127+
{ "ups.delay.shutdown", ST_FLAG_RW, blazer_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar },
128+
129+
/* End of structure. */
130+
{ NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL, NULL }
131+
};
132+
133+
/* Testing table */
134+
#ifdef TESTING
135+
static testing_t innovart31_testing[] = {
136+
{ "Q1\r", "(215.0 195.0 230.0 014 49.0 22.7 30.0 00000000\r", -1 },
137+
{ "Q6\r", "(227.0 225.6 230.0 50.0 229.9 000.0 000.0 49.9 007 000 000 327.8 000.0 23.0 06932 100 32 00000000 00000000 11\r", -1 },
138+
{ "WA\r", "(001.4 000.0 000.0 001.4 000.0 000.0 001.4 001.4 006.5 000.0 000.0 007 00000000\r", -1 },
139+
{ "BPS\r", "(230.4 000.0 000.0 49.9\r", -1 },
140+
{ "F\r", "#230.0 087 288.0 50.0\r", -1 },
141+
{ "Q\r", "", -1 },
142+
{ "S03\r", "", -1 }, /* TODO recheck */
143+
{ "C\r", "", -1 }, /* TODO recheck */
144+
{ "S02R0005\r", "", -1 }, /* TODO recheck */
145+
{ "S.5R0000\r", "", -1 }, /* TODO recheck */
146+
{ "T04\r", "ACK", -1 }, /* TODO recheck */
147+
{ "TL\r", "ACK", -1 },
148+
{ "T\r", "ACK", -1 },
149+
{ "CT\r", "ACK", -1 },
150+
{ NULL }
151+
};
152+
#endif /* TESTING */
153+
154+
/* Subdriver-specific initups */
155+
static void innovart31_initups(void)
156+
{
157+
blazer_initups_light(innovart31_qx2nut);
158+
}
159+
160+
/* Subdriver-specific initinfo */
161+
static void innovart31_initinfo(void)
162+
{
163+
dstate_setinfo("input.phases", "%u", 3);
164+
dstate_setinfo("input.bypass.phases", "%u", 1);
165+
dstate_setinfo("output.phases", "%u", 1);
166+
}
167+
168+
/* Subdriver interface */
169+
subdriver_t innovart31_subdriver = {
170+
INNOVART31_VERSION,
171+
blazer_claim_light,
172+
innovart31_qx2nut,
173+
innovart31_initups,
174+
innovart31_initinfo,
175+
blazer_makevartable_light,
176+
"ACK",
177+
"NAK\r",
178+
#ifdef TESTING
179+
innovart31_testing,
180+
#endif /* TESTING */
181+
};

drivers/nutdrv_qx_innovart31.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/* nutdrv_qx_innovart31.h - Subdriver for INNOVA RT 3/1 UPSes
2+
*
3+
* Copyright (C)
4+
* 2024 Viktor Drobot <linux776@gmail.com>
5+
*
6+
* This program is free software; you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation; either version 2 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program; if not, write to the Free Software
18+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19+
*
20+
*/
21+
22+
#ifndef NUTDRV_QX_INNOVART31_H
23+
#define NUTDRV_QX_INNOVART31_H
24+
25+
#include "nutdrv_qx.h"
26+
27+
extern subdriver_t innovart31_subdriver;
28+
29+
#endif /* NUTDRV_QX_INNOVART31_H */

0 commit comments

Comments
 (0)