Closed aquette closed 11 months ago
Great to hear this.
Good to see that it reads the delays correctly on yours:
0.196059 [D5] send_to_all: SETINFO ups.delay.shutdown "180"
0.196089 [D5] send_to_all: SETINFO ups.delay.start "0"
0.196120 [D5] send_to_all: SETINFO ups.delay.reboot "8"
On mine it somehow reads 0 here despite there being a delay when doing shutdown, maybe a firmware bug, I'll try upgrading to latest soon.
All looks pretty good. battery.date.maintenance is not what I see on the front panel, I see battery.date which is what I set when I replaced the batteries last.
This is what I used for battery.date.maintenance
:
And this is what I used for battery.date
:
On my unit battery.date
matches what I can see in the menu, not sure how battery.date.maintenance
is calculated though. I wonder why your maintenance timestamp is before the installation timestamp.
Thanks for the dev work! Make sure the readme for this driver includes the (obvious) step to enable Modbus on the device itself.
You're welcome. Yes, there should be a section on how to enable Modbus in the manual page.
I will follow this ticket for a stable enough commit to build and run this on my main system.
Note that at least on Debian you can build it like this and integrate it with the Debian package by copying the apc_modbus
driver into /lib/nut
:
./configure \
--with-drivers=usbhid-ups,apc_modbus \
--with-usb \
--prefix= --sysconfdir=/etc/nut --with-statepath=/run/nut \
--with-user=nut --with-group=nut \
--with-modbus --with-modbus-includes=-I/home/ago/src/libmodbus/prefix/include/modbus --with-modbus-libs="-L/home/ago/src/libmodbus/prefix/lib -lmodbus"
Note that you'll have to keep around the libmodbus
prefix for that to work.
Thanks, have done that!
Would it be possible to get Output.ApparentPowerRating
and Output.RealPowerRating
, or ideally return output.power
as Output.RealPowerRating * Output[0].RealPower_Pct
? It'd be nice to record load in W not %.
Not sure how other nut drivers handle this.
edit:
This is what I used for battery.date.maintenance: And this is what I used for battery.date:
nut battery.date
(modus Battery.DateSetting
) is definitely when I changed the batteries. I am not sure what battery.date.maintenance
(modbus Battery.Date
) is referring to. It's approx 2 years after manufacture.
When nothing else helps, RTFM ;)
Per https://networkupstools.org/docs/developer-guide.chunked/apas02.html :
The *.power
reports should be "apparent power (Volt-Amps)" and for Watts there's *.realpower
as "real power (Watts)".
Thanks, seems like they are mapped to the correct nut name!
The
*.power
reports should be "apparent power (Volt-Amps)" and for Watts there's*.realpower
as "real power (Watts)".
Currently the driver is reporting the device values directly which are a % of total available capacity. The device also reports capacity, so the value in Watts/VA could be calculated.
Current load is about 180W
ups.power: 29.04
ups.realpower: 29.40
@galapogos01 I pushed a commit that changes power/realpower to absolute numbers. Edit: Also added the nominal values.
Great work! Looking good here.
ups.power: 218.00
ups.power.nominal: 750.00
ups.realpower: 173.86
ups.realpower.nominal: 600.00
Thank you so much again - it's great to see these very popular models finally get proper support in nut.
@PrplHaz4 thanks, both of those should work, it would be interesting to test the X version because it has a higher firmware version than mine (9.x)
Great work! Amazing to see this coming alive after 9yrs! 🥇
Does Modbus TCP output help at all?
@PrplHaz4 it is great to know it is working, thanks for testing! What would also be of interest is whether reconnection is handled well. Like if you remove the cable and it times out or if the UPS closes the connection (not sure how to test that).
As for your bind /srcnut/state/apc_modbus-apcups failed: Permission denied
error, you probably need to adjust permissions or just set NUT_STATEPATH=/tmp
which should work as well.
@PrplHaz4 it is great to know it is working, thanks for testing! What would also be of interest is whether reconnection is handled well. Like if you remove the cable and it times out or if the UPS closes the connection (not sure how to test that).
As for your
bind /srcnut/state/apc_modbus-apcups failed: Permission denied
error, you probably need to adjust permissions or just setNUT_STATEPATH=/tmp
which should work as well.
Thanks for the tip on /tmp - that worked to keep it running. I put the full build in a docker container, so other things might be going on, but after some time (maybe 5 mins?) the TCP connection times out and seems to loop on error (logs below). the TCP timeout might be a valid failure mode in general. I'll work on a plug/replug USB test as well.
Invalid transaction ID received 0x142 (not 0x143)
This indicates that it is getting a response to a previous command. There likely needs to be a buffer flush somewhere. I just pushed a commit for testing that does buffer flushing on reconnect and open.
Do I need the patched libmodbus
if I am using ModBus over a serial link (with APC AP940-0625A cable)? As far as I understand the patched libmodbus
is only required for Modbus-over-USB.
Right now I am querying my SMT1500 using a custom Python script and pymodbus through this serial cable but I'd prefer to use NUT for this.
@EetuRasilainen you don't need a patched libmodbus for serial.
Invalid transaction ID received 0x142 (not 0x143)
This indicates that it is getting a response to a previous command. There likely needs to be a buffer flush somewhere. I just pushed a commit for testing that does buffer flushing on reconnect and open.
Thanks again! Still seeing these on 10071db after about 5 mins.
Still looks like it receives a response packet that was expected for the previous command.
Could you maybe do a Wireshark
/ tcpdump
packet capture on the Modbus port or the UPS IP address and send it to me privately (derago at gmail.com
)? For tcpdump you can do tcpdump -s 1500 -w modbus.cap port 502
, I need the modbus.cap
this creates.
I asked APC/SE to send me a NMC to test this but so far they only replied telling me where to buy one, and I'm not going to spend multiple hundred bucks on that :\
Maybe I should try to make a RS232 to TCP Modbus converter on a Raspberry Pi Pico.
There is also something very similar here: https://github.com/stephane/libmodbus/issues/525, https://github.com/stephane/libmodbus/issues/255
Also, the serial backend of libmodbus handles such timeouts just fine, but I'll try some more to see if i can produce such a problem.
@PrplHaz4 I made another change, give it a try. I haven't actually tested this yet because I am currently changing the USB modbus driver, but I think it might work.
@PrplHaz4 I made another change, give it a try. I haven't actually tested this yet because I am currently changing the USB modbus driver, but I think it might work.
First look the additional flush seems to be allowing it to re-connect after timeout and resume displaying values (quickly) after that - so definitely a win there. There definitely seems to be a lot of noise in the output right now - I will get some better data tonight. I know nothing about modbus - is there a really short timeout expected between messages (due to it being more of a stream than a poll) or something like that?
Great. What kind of noise do you mean? I also don't know much about modbus, but the need for a delay between frames seems to be because modbus frames do not really have a uniquely identifiable start condition / preamble, so there is a need to wait a certain time to make sure there is not a message currently transferring. I got this from the APC manual and initially I sometimes hit this delay, but in the current version at least on my computer it wasn't hit.
Great. What kind of noise do you mean? I also don't know much about modbus, but the need for a delay between frames seems to be because modbus frames do not really have a uniquely identifiable start condition / preamble, so there is a need to wait a certain time to make sure there is not a message currently transferring. I got this from the APC manual and initially I sometimes hit this delay, but in the current version at least on my computer it wasn't hit.
Here is my capture from the train this morning (with a very spotty network connection - so the noise may be related to that). You can see a lot of connection timed out
, invalid data
and read failed
...etc.
Oh, you did the capture through the spotty network? That does look like what I would expect there.
I wonder if we actually need a higher timeout somewhere, it seems your connection is disconnecting when sending a command and already reconnecting before the response is received, then the response comes, sits in a buffer and gets received (now flushed) when sending the next command.
I'll have to read the modbus TCP code for this some more.
I'm also not sure if this is an issue with the APC firmware or libmodbus, but I don't think it is actually a problem in nut. We could also try just waiting some time after a reconnect, before flusing.
@PrplHaz4 I pushed another commit that removes the flushing before register reads, but instead adds a 1 second delay between connecting and buffer flush. If this works we should try finding a good value for the delay because 1 second is just arbitrarily chosen by me.
@PrplHaz4 I pushed another commit that removes the flushing before register reads, but instead adds a 1 second delay between connecting and buffer flush. If this works we should try finding a good value for the delay because 1 second is just arbitrarily chosen by me.
Yes, the capture above was on a spotty network. This capture is from a stable network. It looks like the failures start 184s into the run, and continues until at least 321s without "recovering". The previous capture from the spotty network appears to have recovered after some time, and went in and out of being able to pull full values.
I'm not sure how to help on the timing of the flush - I'm sure it doesn't help providing data from two drastically different networking environments.
Thanks for testing this. Could you maybe privately (or publicly if you want) share a packet capture from Wireshark or tcpdump on port 502?
With Wireshark you can put a capture filter somewhere, just use port 502
, start capturing, reproduce the problem and save the capture file.
With tcpdump you can use something like tcpdump -i <interface> -s 1500 -w apc.cap port 502
and send me the apc.cap
.
Hi, Good to see this work. If it helps, I just wanted to add that I found an APC SMT2200RMI2UC made in July 2019 didn't work with apcupsd 3.14.14 running on Windows Server 2016 via modbus over USB. modbus over serial was OK. With USB, it looked like an ordering error (responses out of order). apcupsd on Windows (2008 R2) was OK with modbus over USB with a SmartUPS 1500 LCD SMT1500I (vendor id 051d, product id 0003) made in 2015. Not with linux though, where it gave immediate errors. Also I note the new(ish) range of APC Smart-UPS's with Lithium batteries only support modbus over serial, not USB, at least in the brochures. So I wonder if working modbus over USB is restricted to older APC Smart UPS models ? Thanks.
Hi, Good to see this work. If it helps, I just wanted to add that I found an APC SMT2200RMI2UC made in July 2019 didn't work with apcupsd 3.14.14 running on Windows Server 2016 via modbus over USB. modbus over serial was OK. With USB, it looked like an ordering error (responses out of order). apcupsd on Windows (2008 R2) was OK with modbus over USB with a SmartUPS 1500 LCD SMT1500I (vendor id 051d, product id 0003) made in 2015. Not with linux though, where it gave immediate errors. Also I note the new(ish) range of APC Smart-UPS's with Lithium batteries only support modbus over serial, not USB, at least in the brochures. So I wonder if working modbus over USB is restricted to older APC Smart UPS models ? Thanks.
I haven't really had experience with newer APC units, mine is from 2015. If it works with on one OS and not on the other the issue must be software.
It would be nice if you could try the code I posted in #2063, maybe we can diagnose what is going on. The implementation of this is not based on apcupsd
so it might even work, in which case the bug is in apcupsd
.
@PrplHaz4 I think I know what the issue with TCP is and how to fix it, but I continued the discussion in #2063.
From APCUPSD (http://apcupsd.cvs.sourceforge.net/viewvc/apcupsd/apcupsd/ReleaseNotes?pathrev=Release-3_14_11): "APC publicly released documentation[1] on a new UPS control and monitoring protocol, loosely referred to as MODBUS (after the historic industrial control protocol it is based on). The new protocol operates over RS232 serial lines as well as USB connections and is intended to supplement APC's proprietary Microlink protocol. Microlink is not going away, but APC has realized that third parties require access to UPS status and control information. Rather than publicly open Microlink, they have created another protocol to operate along side it.
Many existing Microlink UPSes can be upgraded to support MODBUS via a firmware update. See [2]. Certain older models are not upgradeable. APC support will be your best contact for determining if your UPS supports a MODBUS upgrade the information linked below does not make it clear."
[1] http://www.apc.com/whitepaper/?an=176 [2] http://www.schneider-electric.us/support/index?page=content&country=ITB&lang=EN&id=FA164737 [3] http://www.apcupsd.com/manual/manual.html
Add support for MODBUS over RS232 and USB in NUT. This effort must be synchronized with the general Modbus support in NUT ( #50 )
Implementation notes: