ragtech: new driver for Ragtech UPSes (USB CDC-ACM, family 10)#3447
Open
juslex wants to merge 1 commit into
Open
ragtech: new driver for Ragtech UPSes (USB CDC-ACM, family 10)#3447juslex wants to merge 1 commit into
juslex wants to merge 1 commit into
Conversation
58ce033 to
dd33df6
Compare
|
A ZIP file with standard source tarball and another tarball with pre-built docs for commit 92cd420 is temporarily available: NUT-tarballs-PR-3447.zip. |
f52069c to
03195a7
Compare
|
❌ Build nut 2.8.5.4730-master failed (commit be8146e980 by @juslex) |
03195a7 to
a844e27
Compare
a844e27 to
c7f1687
Compare
c7f1687 to
8f1fdea
Compare
Targets Brazilian-built Ragtech "Easy Pro" / NEP / TORO / INNERGIE / OneUP
devices that present themselves as USB CDC-ACM (VID 0x04D8, PID 0x000A,
Microchip PIC firmware). Validated end-to-end against an Easy 2000 TI
(reg 0x9A model id = 16) read out of a working OneUP Nitro 2000.
Protocol -- three opcodes observed in OEM traffic:
0x01 ADDR_HI ADDR_LO VALUE CKSUM write byte
0x02 ADDR_HI ADDR_LO MASK CKSUM AND mask (atomic bit-clear)
0x04 ADDR_HI ADDR_LO COUNT CKSUM read range
CKSUM = (ADDR_HI + ADDR_LO + VALUE) & 0xFF
The CDC-ACM channel ignores baud at the wire but DTR/RTS are interpreted
by some Ragtech families as a remote shutdown signal -- the driver forces
both low after open and does NOT call ser_set_speed() to avoid the
tcsetattr() DTR pulse that some Linux tty drivers perform.
The full 30-byte main range (0x80..0x9D) plus V_IOUTCALIB (0xF3) and the
oscillator calibration pair (0x202/0x203) are read; output frequency is
interpolated per devices.xml formula rather than hard-coded.
Twenty models from the family-10 device table populate ups.model,
ups.realpower.nominal, output.voltage scaling, output.current scaling and
battery voltage scaling. input.voltage.nominal switches between 115V and
220V dynamically based on the measured input.
Instcmds implemented:
shutdown.stayoff -- aa 02 00 80 fe (clear AUTOSTART) + aa 01 00 98 N.
Byte-for-byte identical to the OEM supsvc sequence.
Validated: cuts output and stays off until manual
power-on, in both AC and battery modes.
shutdown.return -- falls back to shutdown.stayoff with a warning.
The atomic OR opcode that would set F_AUTOSTART
has not been captured yet; read-modify-write with
0x01 sends the bytes but does not trip the
firmware's shutdown state machine.
shutdown.stop -- aa 01 00 98 00 (write V_SHUTDOWNTIMER = 0).
Confirmed to abort an armed countdown.
test.battery.start.deep -- bit writes on regs 0x90 / 0x95 (fullDischarge
in devices.xml). Flagged as unverified for the
same reason as shutdown.return.
Read primitive uses ser_get_buf() in a manual loop rather than
ser_get_buf_len() (which discards partial reads on timeout -- CDC fragments
replies into 1-8 byte chunks). ser_flush_io() is used before each TX to
clear the kernel CDC buffer (ser_flush_in() only does a select+read loop
that misses queued bytes under O_NONBLOCK).
Reverse engineering primarily from the OEM devices.xml table for register
layout / scaling / flags / actions, and from strace of the OEM supsvc
binary capturing both read polls and the LED/shutdown write sequences.
Cross-checked against UPS_ESP32_tinySrv (https://github.com/antunesls/UPS_ESP32_tinySrv).
Signed-off-by: juslex <66561713+juslex@users.noreply.github.com>
8f1fdea to
92cd420
Compare
|
✅ Build nut 2.8.5.4737-master completed (commit 6ac18c0a7b by @juslex)
|
|
✅ Build nut 2.8.5.4737-master completed (commit 6ac18c0a7b by @juslex) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a new
ragtechdriver supporting the Ragtech "Easy Pro" family ofline-interactive UPS units (also sold under the NEP, TORO,
INNERGIE and OneUP brands in Brazil). Devices expose a USB CDC-ACM
serial interface (
VID 0x04D8/PID 0x000A, Microchip PIC firmware) andspeak a proprietary 6-byte register-access protocol.
drivers/ragtech.c(no sharedsub-driver layer — Ragtech is not a Megatec/Qx variant).
ups.model,ups.realpower.nominal, output voltage/current scaling and batteryvoltage scaling.
input.voltage.nominalswitches between 115V and 220V dynamically basedon the measured input (TI vs M2 variants).
straceof the OEMsupsvcbinary and the OEMdevices.xml, cross-checked againstantunesls/UPS_ESP32_tinySrv.
Protocol (decoded from OEM traffic)
Every command on the wire is 6 bytes:
0xAA OPCODE ADDR_HI ADDR_LO VALUE CHECKSUMwhere
CHECKSUM = (ADDR_HI + ADDR_LO + VALUE) & 0xFF.0x010x020x030x04Instant commands
shutdown.stayoff— byte-for-byte identical to the OEMsupsvcsequence.Verified on hardware: cuts output and stays off until manual power-on
in both AC and battery modes.
shutdown.stop— aborts an armed countdown. Verified on hardware.shutdown.return— implemented as ashutdown.stayoffwith aLOG_WARNING. The Easy 2000 TI firmware does not auto-restart onmains return; the operator must press the power button. The driver
surfaces this consistently to
upsmoncallers rather than silentlyfailing.
test.battery.start.deep— bit writes matching the OEMfullDischargeaction. Implemented but not yet verified end-to-end (would empty the
battery during testing).
Safety: shutdowns are opt-in by default
Because the firmware does not auto-restart, an unintended
shutdown.return(e.g. from
upsmonon a low-battery event) would leave the UPS off untilsomebody physically presses the power button. To avoid silent-fail
integrations, every
shutdown.*andtest.battery.start.deepinstcmd isgated behind
allow_shutdowninups.conf:rejected with
STAT_INSTCMD_INVALID, andupsdrv_shutdownexits withfailure rather than cutting output.
The default-deny posture is conservative on purpose; a future Ragtech model
with working auto-restart could carry a
firmware_returnscapability inthe model table to flip the default.
Wire-level notes
ser_get_buf_len()is all-or-nothing: it discards already-collectedbytes on timeout. CDC-ACM fragments replies into 1–8 byte chunks, so the
driver uses
ser_get_buf()in a manual loop.ser_flush_in()does not calltcflush(); underO_NONBLOCKUSB CDCbytes inside the tty layer survive its select+read loop. The driver uses
ser_flush_io()(which callstcflush(TCIOFLUSH)) before each TX.ser_set_speed()on the CDC-ACM endpoint —tcsetattr(TCSANOW)pulses DTR on some Linux tty drivers, which theRagtech firmware can interpret as a shutdown signal. CDC-ACM ignores
baud at the wire anyway.
ser_open(the UPS readsnon-zero levels as a remote-shutdown signal).
tcdrain()+ ~50 ms of slack after everyser_send_buf()to let thefirmware compose the reply.
Files changed
drivers/ragtech.c— new driver (single C file).drivers/Makefile.am— registered inSERIAL_DRIVERLIST,ragtech_SOURCES,ragtech_LDADD.docs/man/ragtech.txt— new AsciiDoc man page.docs/man/Makefile.am— three registrations (.txt,MAN_SECTION_CMD_SYS,.html).data/driver.list.in— 20 entries for the family-10 models (level "1",reverse engineering).
docs/nut.dict— addedINNERGIE,NEP,OneUP,Ragtech,TOROandbumped the word count.
NEWS.adoc— new-driver entry under 2.8.6.Driver status
DRV_EXPERIMENTALat version0.04. Only the Easy 2000 TI has beenvalidated end-to-end with hardware; the other 19 models share the same
register layout and scaling table but have not been hardware-tested yet.
Test plan
ups.*variables on Easy 2000 TI — verified.shutdown.stayoff— verified on hardware (AC and battery modes).shutdown.stop— verified on hardware (aborts armed countdown).iout_caliboverride viaups.conf— verified.allow_shutdowndefault-deny posture — verified (instcmds notregistered,
upsdrv_shutdownexits with failure).shutdown.returnend-to-end — not verified (firmware does notauto-restart; surfaces as
stayoff+ warning).test.battery.start.deep— implemented but not verified(deliberately not exercised during RE — would discharge battery).
Welcoming feedback on the
shutdown.returndesign (currently warns andstays off), and on whether to fold the model discrimination into a
per-model scaling table once a second model is verified.