Skip to content

Commit

Permalink
Merge f8eecc6 into cb225e0
Browse files Browse the repository at this point in the history
  • Loading branch information
dvdesolve authored Dec 6, 2024
2 parents cb225e0 + f8eecc6 commit 9495a68
Show file tree
Hide file tree
Showing 8 changed files with 224 additions and 9 deletions.
14 changes: 7 additions & 7 deletions docs/man/nutdrv_qx.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ If you set stayoff in linkman:ups.conf[5] when FSD arises the UPS will call a *s

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


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

*ignoresab*::
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).
Expand Down Expand Up @@ -196,8 +196,8 @@ Safeguard against talking to the wrong one of several identical UPSes on the sam
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.


Q1 PROTOCOL
~~~~~~~~~~~
INNOVART31, Q1 PROTOCOLS
~~~~~~~~~~~~~~~~~~~~~~~~

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


BESTUPS, MECER, MEGATEC, MEGATEC/OLD, MUSTEK, Q1, ZINTO PROTOCOLS
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BESTUPS, INNOVART31, MECER, MEGATEC, MEGATEC/OLD, MUSTEK, Q1, ZINTO PROTOCOLS
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

*test.battery.start* 'value'::
Perform a battery test for the duration of 'value' seconds (truncated to 60 seconds) [+60..5940+].
Expand Down
1 change: 1 addition & 0 deletions docs/nutdrv_qx-subdrivers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1144,6 +1144,7 @@ You can then recompile +nutdrv_qx+, and start experimenting with the new subdriv
For more details, have a look at the currently available subdrivers:

- +nutdrv_qx_bestups.+{+c+,+h+}
- +nutdrv_qx_innovart31.+{+c+,+h+}
- +nutdrv_qx_masterguard.+{+c+,+h+}
- +nutdrv_qx_mecer.+{+c+,+h+}
- +nutdrv_qx_megatec.+{+c+,+h+}
Expand Down
2 changes: 2 additions & 0 deletions drivers/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ nutdrv_qx_SOURCES += $(LIBUSB_IMPL) usb-common.c
nutdrv_qx_LDADD += $(LIBUSB_LIBS)
endif
NUTDRV_QX_SUBDRIVERS = nutdrv_qx_bestups.c nutdrv_qx_blazer-common.c \
nutdrv_qx_innovart31.c \
nutdrv_qx_masterguard.c \
nutdrv_qx_mecer.c nutdrv_qx_megatec.c nutdrv_qx_megatec-old.c \
nutdrv_qx_mustek.c nutdrv_qx_q1.c nutdrv_qx_voltronic.c \
Expand All @@ -404,6 +405,7 @@ dist_noinst_HEADERS = \
upshandler.h usb-common.h usbhid-ups.h powercom-hid.h compaq-mib.h idowell-hid.h \
apcsmart.h apcsmart_tabs.h apcsmart-old.h apcupsd-ups.h cyberpower-mib.h riello.h openups-hid.h \
delta_ups-mib.h nutdrv_qx.h nutdrv_qx_bestups.h nutdrv_qx_blazer-common.h \
nutdrv_qx_innovart31.h \
nutdrv_qx_masterguard.h \
nutdrv_qx_mecer.h nutdrv_qx_ablerex.h \
nutdrv_qx_megatec.h nutdrv_qx_megatec-old.h nutdrv_qx_mustek.h nutdrv_qx_q1.h nutdrv_qx_hunnox.h \
Expand Down
2 changes: 2 additions & 0 deletions drivers/nutdrv_qx.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
/* Include all known subdrivers */
#include "nutdrv_qx_bestups.h"
#include "nutdrv_qx_hunnox.h"
#include "nutdrv_qx_innovart31.h"
#include "nutdrv_qx_mecer.h"
#include "nutdrv_qx_megatec.h"
#include "nutdrv_qx_megatec-old.h"
Expand All @@ -97,6 +98,7 @@ static subdriver_t *subdriver_list[] = {
&masterguard_subdriver,
&hunnox_subdriver,
&ablerex_subdriver,
&innovart31_subdriver,
/* Fallback Q1 subdriver */
&q1_subdriver,
NULL
Expand Down
2 changes: 1 addition & 1 deletion drivers/nutdrv_qx_blazer-common.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* nutdrv_qx_blazer-common.c - Common functions/settings for nutdrv_qx_{mecer,megatec,megatec-old,mustek,q1,voltronic-qs,zinto}.{c,h}
/* nutdrv_qx_blazer-common.c - Common functions/settings for nutdrv_qx_{innovart31,mecer,megatec,megatec-old,mustek,q1,voltronic-qs,zinto}.{c,h}
*
* Copyright (C)
* 2013 Daniele Pezzini <hyouko@gmail.com>
Expand Down
2 changes: 1 addition & 1 deletion drivers/nutdrv_qx_blazer-common.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* nutdrv_qx_blazer-common.h - Common functions/settings for nutdrv_qx_{mecer,megatec,megatec-old,mustek,q1,voltronic-qs,zinto}.{c,h}
/* nutdrv_qx_blazer-common.h - Common functions/settings for nutdrv_qx_{innovart31,mecer,megatec,megatec-old,mustek,q1,voltronic-qs,zinto}.{c,h}
*
* Copyright (C)
* 2013 Daniele Pezzini <hyouko@gmail.com>
Expand Down
181 changes: 181 additions & 0 deletions drivers/nutdrv_qx_innovart31.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
/* nutdrv_qx_innovart31.c - Subdriver for INNOVA RT 3/1 UPSes
*
* Copyright (C)
* 2024 Viktor Drobot <linux776@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/

#include "main.h"
#include "nutdrv_qx.h"
#include "nutdrv_qx_blazer-common.h"

#include "nutdrv_qx_innovart31.h"

#define INNOVART31_VERSION "INNOVART31 0.01"

/* Internal function: used to convert kilo-values to their full representation */
static int innovart31_x1000(item_t *item, char *value, const size_t valuelen) {
float s = 0;

if (sscanf(item->value, "%f", &s) != 1) {
upsdebugx(2, "unparsable ss.ss %s", item->value);
return -1;
}

snprintf(value, valuelen, "%.2f", s * 1000.0);
return 0;
}
/* qx2nut lookup table */
static item_t innovart31_qx2nut[] = {

/*
* > [Q1\r]
* < [(226.0 195.0 226.0 014 49.0 27.5 30.0 00001000\r]
* 01234567890123456789012345678901234567890123456
* 0 1 2 3 4
*/

/*
* > [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]
* 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
* 0 1 2 3 4 5 6 7 8 9 10
*/

/*
* > [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]
* 01234567890123456789012345678901234567890123456789012345678901234567890123456789
* 0 1 2 3 4 5 6 7
*/

/*
* > [BPS\r]
* < [(230.4 000.0 000.0 49.9\r]
* 012345678901234567890123
* 0 1 2
*/

/*
* > [F\r]
* < [#230.0 087 288.0 50.0\r]
* 0123456789012345678901
* 0 1 2
*/

{ "input.voltage", 0, NULL, "Q6\r", "", 110, '(', "", 1, 5, "%.1f", 0, NULL, NULL, NULL },
{ "input.L1-N.voltage", 0, NULL, "Q6\r", "", 110, '(', "", 1, 5, "%.1f", 0, NULL, NULL, NULL },
{ "input.L2-N.voltage", 0, NULL, "Q6\r", "", 110, '(', "", 7, 11, "%.1f", 0, NULL, NULL, NULL },
{ "input.L3-N.voltage", 0, NULL, "Q6\r", "", 110, '(', "", 13, 17, "%.1f", 0, NULL, NULL, NULL },
{ "input.frequency", 0, NULL, "Q6\r", "", 110, '(', "", 19, 22, "%.1f", 0, NULL, NULL, NULL },
{ "input.bypass.voltage", 0, NULL, "BPS\r", "", 24, '(', "", 1, 5, "%.1f", 0, NULL, NULL, NULL },
{ "input.bypass.frequency", 0, NULL, "BPS\r", "", 24, '(', "", 19, 22, "%.1f", 0, NULL, NULL, NULL },
{ "output.voltage", 0, NULL, "Q6\r", "", 110, '(', "", 24, 28, "%.1f", 0, NULL, NULL, NULL },
{ "output.current", 0, NULL, "WA\r", "", 80, '(', "", 49, 53, "%.1f", 0, NULL, NULL, NULL },
{ "output.frequency", 0, NULL, "Q6\r", "", 110, '(', "", 42, 45, "%.1f", 0, NULL, NULL, NULL },
{ "ups.load", 0, NULL, "Q6\r", "", 110, '(', "", 47, 49, "%.0f", 0, NULL, NULL, NULL },
{ "ups.realpower", 0, NULL, "WA\r", "", 80, '(', "", 37, 41, "%.1f", 0, NULL, NULL, innovart31_x1000 },
{ "ups.power", 0, NULL, "WA\r", "", 80, '(', "", 43, 47, "%.1f", 0, NULL, NULL, innovart31_x1000 },
{ "ups.temperature", 0, NULL, "Q6\r", "", 110, '(', "", 71, 74, "%.1f", 0, NULL, NULL, NULL },
{ "battery.voltage", 0, NULL, "Q6\r", "", 110, '(', "", 59, 63, "%.2f", 0, NULL, NULL, qx_multiply_battvolt },
{ "battery.runtime", 0, NULL, "Q6\r", "", 110, '(', "", 76, 80, "%.0f", 0, NULL, NULL, NULL },
/* TODO check if needed */
// { "battery.charge", 0, NULL, "Q6\r", "", 110, '(', "", 82, 84, "%.0f", 0, NULL, NULL, NULL },
/* Status bits */
{ "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Utility Fail (Immediate) */
{ "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Battery Low */
{ "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 */
{ "ups.alarm", 0, NULL, "Q1\r", "", 47, '(', "", 41, 41, NULL, 0, NULL, NULL, blazer_process_status_bits }, /* UPS Failed */
{ "ups.type", 0, NULL, "Q1\r", "", 47, '(', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, NULL, blazer_process_status_bits }, /* UPS Type */
{ "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Test in Progress */
{ "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Shutdown Active */
{ "ups.beeper.status", 0, NULL, "Q1\r", "", 47, '(', "", 45, 45, "%s", 0, NULL, NULL, blazer_process_status_bits }, /* Beeper status */

{ "input.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 1, 5, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL },
{ "input.current.nominal", 0, NULL, "F\r", "", 22, '#', "", 7, 9, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL },
{ "battery.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 11, 15, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL },
{ "input.frequency.nominal", 0, NULL, "F\r", "", 22, '#', "", 17, 20, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL },

/* Instant commands */
{ "beeper.toggle", 0, NULL, "Q\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL },
{ "load.off", 0, NULL, "S00R0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL },
{ "load.on", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL },
{ "shutdown.return", 0, NULL, "S%s\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command },
{ "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command },
{ "shutdown.stop", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL },
{ "test.battery.start", 0, NULL, "T%02d\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command },
{ "test.battery.start.deep", 0, NULL, "TL\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL },
{ "test.battery.start.quick", 0, NULL, "T\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL },
{ "test.battery.stop", 0, NULL, "CT\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL },

/* Server-side settable vars */
{ "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 },
{ "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 },

/* End of structure. */
{ NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL, NULL }
};

/* Testing table */
#ifdef TESTING
static testing_t innovart31_testing[] = {
{ "Q1\r", "(215.0 195.0 230.0 014 49.0 22.7 30.0 00000000\r", -1 },
{ "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 },
{ "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 },
{ "BPS\r", "(230.4 000.0 000.0 49.9\r", -1 },
{ "F\r", "#230.0 087 288.0 50.0\r", -1 },
{ "Q\r", "", -1 },
{ "S03\r", "", -1 }, /* TODO recheck */
{ "C\r", "", -1 }, /* TODO recheck */
{ "S02R0005\r", "", -1 }, /* TODO recheck */
{ "S.5R0000\r", "", -1 }, /* TODO recheck */
{ "T04\r", "ACK", -1 }, /* TODO recheck */
{ "TL\r", "ACK", -1 },
{ "T\r", "ACK", -1 },
{ "CT\r", "ACK", -1 },
{ NULL }
};
#endif /* TESTING */

/* Subdriver-specific initups */
static void innovart31_initups(void)
{
blazer_initups_light(innovart31_qx2nut);
}

/* Subdriver-specific initinfo */
static void innovart31_initinfo(void)
{
dstate_setinfo("input.phases", "%u", 3);
dstate_setinfo("input.bypass.phases", "%u", 1);
dstate_setinfo("output.phases", "%u", 1);
}

/* Subdriver interface */
subdriver_t innovart31_subdriver = {
INNOVART31_VERSION,
blazer_claim_light,
innovart31_qx2nut,
innovart31_initups,
innovart31_initinfo,
blazer_makevartable_light,
"ACK",
"NAK\r",
#ifdef TESTING
innovart31_testing,
#endif /* TESTING */
};
29 changes: 29 additions & 0 deletions drivers/nutdrv_qx_innovart31.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* nutdrv_qx_innovart31.h - Subdriver for INNOVA RT 3/1 UPSes
*
* Copyright (C)
* 2024 Viktor Drobot <linux776@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/

#ifndef NUTDRV_QX_INNOVART31_H
#define NUTDRV_QX_INNOVART31_H

#include "nutdrv_qx.h"

extern subdriver_t innovart31_subdriver;

#endif /* NUTDRV_QX_INNOVART31_H */

0 comments on commit 9495a68

Please sign in to comment.