-
-
Notifications
You must be signed in to change notification settings - Fork 351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
apc_modbus: Support for APC Modbus protocol #2063
Conversation
c55921e
to
607f0c9
Compare
607f0c9
to
70c0448
Compare
❌ Build nut 2.8.0.780-master failed (commit e4872046fa by @EchterAgo) |
70c0448
to
721718b
Compare
❌ Build nut 2.8.0.788-master failed (commit 2aba3787fb by @EchterAgo) |
❌ Build nut 2.8.0.796-master failed (commit 74b8f28f12 by @EchterAgo) |
|
❌ Build nut 2.8.0.799-master failed (commit 0b0da8c317 by @EchterAgo) |
I found more documentation for the Modbus values: https://download.schneider-electric.com/files?p_enDocType=System+user+guide&p_File_Name=990-9840B-EN.pdf&p_Doc_Ref=SPD_LFLG-A32G3L_EN This allowed me to get the efficiency percentage working, which was not properly documented in |
I'd also like to add the "total energy consumed" counter into the output. Can I just chose a custom value name or does it need to be defined? Currently I use |
|
For total energy, I think the point was raised before elsewhere, there is currently no name defined in https://github.com/networkupstools/nut/blob/master/docs/nut-names.txt for that. Try bringing it up in the nut-upsdev mailing list, if anyone has specific ideas for such a value's name and units. Just in case, CCing @aquette and @clepple directly. For the time being, Generally the problem with such "total" readings is that almost no devices provide them, especially as lifetime counters persisted on the device. There are some devices which provide recent average "apparent power" (usually in VA, see precedents in Overall, if you are sure the device can provide the total counter of energy it has brokered over its lifetime (or even just over the uptime), it makes sense to relay that into NUT and come up with naming schemes for that. In fact I would have expected the drivers for metered/managed ePDUs to have something like that, but it seems the current ones rely on |
cf6f633
to
61149cd
Compare
❌ Build nut 2.8.0.805-master failed (commit ace8b0e865 by @EchterAgo) |
FYI: I've asked around for precedents and planned work on energy accounting. It seems there were quite a few ideas, including on vendors' side, but so far nothing got committed and "standardized" in NUT mainline. One of the useful notes was that this is usually done for billing purposes (either by infrastructure providers, or even home users deciding which of their boxes eats too much) - and for that context it is usually prudent to:
|
https://github.com/networkupstools/nut/blob/master/drivers/eaton-pdu-marlin-mib.c#L1128 The mib should describe the rest... |
9cc01c1
to
cbe8bb2
Compare
❌ Build nut 2.8.0.813-master failed (commit 36d573bee4 by @EchterAgo) |
Updated with many new variables, even though there are many new values lacking in the HID driver, there are still some missing:
I haven't found these in the modbus registers yet, although I have some idea for the beeper status. I've also improved the code quite a bit with converters for some types. |
This is what we currently get:
|
Added HID report descriptor scan for RX/TX usages to get their report ids. This also needs the latest changes from my |
|
Oh, I revised your earlier post and think that |
Does that consequently mean libmodbus needs to be built like this? ./configure --with-drivers=apc_modbus --with-usb --with-modbus \
--with-modbus-includes=-I/usr/include/modbus \
--with-modbus-libs="-L/usr -lmodbus"
make
sudo make install But I think maybe I should just wait till you have revised the wiki page. |
Slightly revised the wiki page (to |
It's still failing for me. : 1711001492:0;cd ~/git
|
Aw, schucks! Apparently the code evolved after instructions were written: for Without the flag current code indeed results in:
With that option in libmodbus build I now see its configure mention USB:
and a new object is made that does not happen otherwise:
...and the NUT build succeeds. UPDATE: Checking a hiccup with |
cd ~/git/libmodbus
./autogen.sh
./configure --with-libusb --prefix=/usr/local
sudo make install
cd ~/git/nut
./autogen.sh
./configure --with-drivers=apc_modbus --with-usb --with-modbus \
--with-modbus-includes=-I/usr/local/include/modbus \
--with-modbus-libs="-L/usr/local/lib -lmodbus"
sudo make install success. However... I had to edit zshrc and add export PATH="$PATH:/usr/local/ups/sbin" sudo cp /usr/local/ups/etc/ups.conf.sample /usr/local/ups/etc/ups.conf
sudo nano /usr/local/ups/etc/ups.conf
[SMT1500IC]
driver = apc_modbus
port = auto
comment out retries= But then.... % sudo upsdrvctl start
Network UPS Tools - UPS driver controller 2.8.1-980-gc05ca1fc3
Network UPS Tools - NUT APC Modbus driver 0.10 (2.8.1-980-gc05ca1fc3)
modbus_connect: unable to connect: No such device
upsnotify: notify about state 4 with libsystemd: was requested, but not running as a service unit now, will not spam more about it
upsnotify: failed to notify about state 4: no notification tech defined, will not spam more about it
Driver failed to start (exit status=1) I am using the USB cable from my SMT1500IC and want the modbus stuff, too. It's enabled. a couple tries later:
(3) /usr/local/ups/bin
% ls
adelsystem_cbi belkinunv etapro masterguard nutdrv_siemens-sitop richcomm_usb tripplitesu
al175 bestfcom everups metasys NUT-Monitor riello_ser tripplite_usb
apc_modbus bestfortress gamatronic mge-shut nut-scanner riello_usb upsc
apcsmart bestuferrups generic_modbus mge-utalk oneac safenet upscmd
apcsmart-old bestups genericups microdowell optiups skel upscode2
apcupsd-ups blazer_ser huawei-ups2000 microsol-apc phoenixcontact_modbus sms_ser upslog
asem blazer_usb isbmex netxml-ups pijuice snmp-ups upsrw
bcmxcp clone ivtscd nutconf powercom socomec_jbus upssched-cmd
bcmxcp_usb clone-outlet liebert nutdrv_atcl_usb powerpanel solis usbhid-ups
belkin dummy-ups liebert-esp2 nutdrv_qx rhino tripplite victronups
(3) /usr/local/ups/bin
% sudo ./nut-scanner -U
Scanning USB bus.
[nutdev-usb1]
driver = "usbhid-ups" # alternately: apc_modbus
port = "auto"
vendorid = "051D"
productid = "0003"
product = "Smart-UPS_1500 FW:UPS 03.5 / ID=1015"
serial = "redacted"
vendor = "American Power Conversion"
# bus = "003"
# device = "007"
# busport = "002"
sudo nano ../etc/ups.conf
[nutdev-usb1]
driver = "usbhid-ups" # alternately: apc_modbus
port = "auto" same issue |
Regarding Probably your build also suffers from having different user/group names applied (default Check wiki about "in-place builds" to inherit as much as possible to replace a packaged version if used. Or restart the relevant udev/upower/... implementation service (or reboot) to apply devfs permissions for the supported UPS USB IDs. |
I tried those options... with unfavorable results. Is there an easier way to use it? Some of my usb devices are working through Wine even. |
…nd, but does not support libusb while we want it (and will fail NUT configure later) [networkupstools#2063] Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…ons for USB-capable builds [networkupstools#2063] Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…ons for USB-capable builds [networkupstools#2063] Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…ons for USB-capable builds [networkupstools#2063] Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
"Through Wine" that's probably passed through as Speaking of which, you can try I also did not see recently a log of driver start-up attempt with raised debug verbosity (it would reveal the built-in and attempted user name, which devices it tried and what causes it had to skip them, etc.) |
I have for instance my RME ADI-2 DAC FS on Linux running a Wine Application called "RME Remote" and it works properly. Basically, it communicates through MIDI with the host. In any case, something is awfully wrong with running the compiled nut things on SMT1500IC. I have However, if I use nut from the extra repositories, I get at least data in. Could it be that I need in addition all of those make flags for nut? I'll git clone the repo and try building my own. So that would be ./configure --prefix=/usr \
--datadir=/usr/share/nut \
--libexecdir=/usr/lib/nut \
--sbindir=/usr/bin \
--sysconfdir=/etc/nut \
--disable-static \
--with-user=nut \
--with-group=nut \
--with-altpidpath=/run/nut \
--with-cgipath=/usr/share/nut/cgi \
--with-drvpath=/usr/lib/nut \
--with-htmlpath=/usr/share/nut/html \
--with-pidpath=/run/nut \
--with-statepath=/var/lib/nut \
--with-systemdsystemunitdir=/usr/lib/systemd/system \
--with-udev-dir=/usr/lib/udev \
--with-cgi \
--with-dev \
--with-doc=man \
--with-libltdl \
--with-neon \
--with-openssl \
--with-serial \
--with-snmp \
--with-usb \
--without-avahi \
--without-ipmi \
--without-freeipmi \
--without-powerman \
--without-wrap \
--with-drivers=apc_modbus \
--with-modbus \
--with-modbus-includes=-I/usr/include/modbus \
--with-modbus-libs="-L/usr/lib -lmodbus" I did boot into Windows 10 now and installed |
That is so weird! I can't....
If I put it to apc_modbus, I get this: % sudo upsdrvctl start
Network UPS Tools - UPS driver controller 2.8.1
Network UPS Tools - NUT APC Modbus driver 0.01 (2.8.1)
_apc_modbus_read_registers: Read of 516:604 failed: Connection timed out (auto)
Can't read inventory information from the UPS
upsnotify: notify about state 4 with libsystemd: was requested, but not running as a service unit now, will not spam more about it
upsnotify: failed to notify about state 4: no notification tech defined, will not spam more about it
Driver failed to start (exit status=1) Meanwhile in apcupsd... - and note I want more info like LOAD etc which comes with the apc_modbus... 130 % apcaccess
APC : 001,027,0678
DATE : 2024-03-22 05:00:28 +0100
HOSTNAME : mainrig-MS-7D51
VERSION : 3.14.14 (31 May 2016) unknown
UPSNAME : mainrig-MS-7D51
CABLE : USB Cable
DRIVER : USB UPS Driver
UPSMODE : Stand Alone
STARTTIME: 2024-03-22 04:50:45 +0100
MODEL : Smart-UPS_1500
STATUS : ONLINE
BCHARGE : 100.0 Percent
TIMELEFT : 53.6 Minutes
MBATTCHG : 5 Percent
MINTIMEL : 3 Minutes
MAXTIME : 0 Seconds
ALARMDEL : 30 Seconds
BATTV : 26.3 Volts
NUMXFERS : 0
TONBATT : 0 Seconds
CUMONBATT: 0 Seconds
XOFFBATT : N/A
STATFLAG : 0x05000008
MANDATE : 2018-06-05
SERIALNO : AS1823261711
NOMBATTV : 24.0 Volts
FIRMWARE : UPS 03.5 / ID=1015
END APC : 2024-03-22 05:00:33 +0100 But this is ... just the usb mode. If I activate apc_modbus in apcupsd... Then I'd get invalid data. I mean, look at the BATTV value for instance. 465V at 230V in Germany?> Nope :D
Then... ~/git/nut on master
% sudo systemctl start nut-server
~/git/nut on master
% sudo upsc upsname
battery.charge: 100
battery.charge.low: 10
battery.charge.warning: 50
battery.runtime: -1
battery.runtime.low: 150
battery.type: PbAc
battery.voltage: 26.3
battery.voltage.nominal: 24.0
device.mfr: American Power Conversion
device.model: Smart-UPS_1500
device.serial: AS1823261711
device.type: ups
driver.debug: 0
driver.flag.allow_killpower: 0
driver.name: usbhid-ups
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.parameter.synchronous: auto
driver.state: quiet
driver.version: 2.8.1
driver.version.data: APC HID 0.100
driver.version.internal: 0.52
driver.version.usb: libusb-1.0.27 (API: 0x100010a)
ups.beeper.status: enabled
ups.delay.shutdown: 20
ups.firmware: UPS 03.5 / ID=1015
ups.mfr: American Power Conversion
ups.mfr.date: 2018/06/05
ups.model: Smart-UPS_1500
ups.productid: 0003
ups.serial: redacted
ups.status: OL
ups.timer.reboot: -1
ups.timer.shutdown: 65535
ups.vendorid: 051d |
Update. I had temporary success...
Now I get: battery.charge: 100.00
battery.date: 2024-03-15
battery.date.maintenance: 2028-09-12
battery.runtime: 3081
battery.temperature: 29.47
battery.voltage: 26.31
device.mfr: American Power Conversion
device.model: Smart-UPS 1500
device.serial: redacted
device.type: ups
driver.debug: 0
driver.flag.allow_killpower: 0
driver.name: apc_modbus
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.parameter.synchronous: auto
driver.state: quiet
driver.version: 2.8.1
driver.version.internal: 0.01
driver.version.usb: libusb-1.0.27 (API: 0x100010a)
experimental.output.energy: 534619
input.transfer.high: 253
input.transfer.low: 207
input.transfer.reason: AcceptableInput
input.voltage: 232.41
output.current: 1.47
output.frequency: 50.00
output.voltage: 232.41
ups.delay.reboot: 8
ups.delay.shutdown: 0
ups.delay.start: 0
ups.efficiency: 97.2
ups.firmware: UPS 03.5
ups.id: APC UPS
ups.load: 27.75
ups.mfr: American Power Conversion
ups.mfr.date: 2018-06-05
ups.model: Smart-UPS 1500
ups.power: 344.59
ups.power.nominal: 1500
ups.productid: 0003
ups.realpower: 277.54
ups.realpower.nominal: 1000
ups.serial: redacted
ups.status: OL HE
ups.timer.reboot: -1
ups.timer.shutdown: -1
ups.timer.start: -1
ups.vendorid: 051d with setting:
in /etc/nut/ups.conf. It would be really helpful when I am debugging to know that nut-server has to be running in order to retrieve any data. E.g in the archwiki it is pretty far down. https://wiki.archlinux.org/title/Network_UPS_Tools |
But now I get .... "Error Driver not connected"
meanwhile |
I have found something similar. I've already added MAXAGE 25, but to no avail. Tried https://github.com/netinvent/usb_resetter but with no success. Retrying apcupsdNow I found adding the following to apcupsd.conf ## apcupsd.conf v1.1 ##
UPSCABLE usb
UPSTYPE modbus
DEVICE
LOCKFILE /var/lock
UPSCLASS standalone
UPSMODE disable Followed by replugging the device enabled me to see more values. APC did a poor job for not following USB standard apparently. Edit this is hit or miss. Unreliable USB on SMT1500IC units? YES |
…ons for USB-capable builds [networkupstools#2063] Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…nd, but does not support libusb while we want it (and will fail NUT configure later) [networkupstools#2063] Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
…ons for USB-capable builds [networkupstools#2063] Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
Thanks for the info! Also, just in case for other readers: be sure to run EITHER |
… - with a static library suggestion [networkupstools#2063] Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
FYI: Further tested and updated the Wiki page (and pending man page update) about building NUT vs. custom libmodbus with USB capability, to suggest using a static build of libmodbus (so its object data gets linked directly into the |
@EchterAgo : note that the Could you please act on this quickly before they go into hibernation again? :) |
@EchterAgo, I would like to ask if you plan to create PR for upstream. I would like to see official support for USB modbus directly in the NUT release 🙂. Thank you |
^ +1 Just run into this and not getting load % via the USBHID-UPS driver for an APC SMT1000i2U. Would be awesome if modbus was available as a driver option natively. |
NOTE: There are several distinct issues discussed in this after-party. One is about getting the custom build right - hopefully addressed by evolution of the Wiki page with instructions (including the points on using a static library and so avoiding conflicts and confusion at run-time). Another is about the driver crashing during start - further investigation tracked in #2609 |
Current status
This adds APC Modbus support to address isssue #139. For USB support, this needs a patch for
libmodbus
.To install the patched
libmodbus
, you need to get the code and install it into a prefix somewhere:to compile NUT you need something like this:
There is still a bit of work to be done:
upsdrv_updateinfo
.051d:0003
, any help appreciated.open_dev
callback that decodes the HID report like inusbhid-ups
, checking for the APC Modbus usages to get their ids.reopen_matcher
.Makefile.am
.libusb
versions.GetShould be a separate issue.libmodbus
changes integrated in upstream or add support for custom backends. Also see CI: add support for "custom" dependencies in the codebase? Case in question: how to best handle modbus extensions for NUT drivers? #2076libmodbus
somehow? It needs a way to parse the hid descriptor. Ideally we'd detect this inlibmodbus
but, if we can't, we should provide a way to set the report ids.libmodbus
device selection. Is it OK to just pass a libusb device handle? Can we somehow open a specific device? We do want to use the USB regex matcher.CommandsI'd prefer to add commands in a later PR.InputStatus_BF
Adddevice_path
based auto detection of port type. If unsure it should still default to USB.PR template
General points
Described the changes in the PR submission or a separate issue, e.g.
known published or discovered protocols, applicable hardware (expected
compatible and actually tested/developed against), limitations, etc.
There may be multiple commits in the PR, aligned and commented with
a functional change. Notably, coding style changes better belong in a
separate PR, but certainly in a dedicated commit to simplify reviews
of "real" changes in the other commits. Similarly for typo fixes in
comments or text documents.
Frequent "underwater rocks" for driver addition/update PRs
Revised existing driver families and added a sub-driver if applicable
(
nutdrv_qx
,usbhid-ups
...) or added a brand new driver in the othercase.
Did not extend obsoleted drivers with new hardware support features
(notably
blazer
and other single-device family drivers for Qx protocols,except the new
nutdrv_qx
which should cover them all).For updated existing device drivers, bumped the
DRIVER_VERSION
macroor its equivalent.
For USB devices (HID or not), revised that the driver uses unique
VID/PID combinations, or raised discussions when this is not the case
(several vendors do use same interface chips for unrelated protocols).
For new USB devices, built and committed the changes for the
scripts/upower/95-upower-hid.hwdb
fileProposed NUT data mapping is aligned with existing
docs/nut-names.txt
file. If the device exposes useful data points not listed in the file, the
experimental.*
namespace can be used as documented there, and discussionshould be raised on the NUT Developers mailing list to standardize the new
concept.
Updated
data/driver.list.in
if applicable (new tested device info)Frequent "underwater rocks" for general C code PRs
structure layout and alignment in memory, endianness (layout of bytes and
bits in memory for multi-byte numeric types), or use of generic
int
wherelanguage or libraries dictate the use of
size_t
(orssize_t
sometimes).Progress and errors are handled with
upsdebugx()
,upslogx()
,fatalx()
and related methods, not with directprintf()
orexit()
.Similarly, NUT helpers are used for error-checked memory allocation and
string operations (except where customized error handling is needed,
such as unlocking device ports, etc.)
Coding style (including whitespace for indentations) follows precedent
in the code of the file, and examples/guide in
docs/developers.txt
file.For newly added files, the
Makefile.am
recipes were updated and themake distcheck
target passes.General documentation updates
Updated
docs/acknowledgements.txt
(for vendor-backed device support)Added or updated manual page information in
docs/man/*.txt
filesand corresponding recipe lists in
docs/man/Makefile.am
for new pagesPassed
make spellcheck
, updated spell-checking dictionary in thedocs/nut.dict
file if needed (did not remove any words -- themake
rule printout in case of changes suggests how to maintain it).
Additional work may be needed after posting this PR
Propose a PR for NUT DDL with detailed device data dumps from tests
against real hardware (the more models, the better).
Address NUT CI farm build failures for the PR: testing on numerous
platforms and toolkits can expose issues not seen on just one system.
the changed codebase.
resolves #139