networkupstools / nut

The Network UPS Tools repository. UPS management protocol Informational RFC 9271 published by IETF at https://www.rfc-editor.org/info/rfc9271 Please star NUT on GitHub, this helps with sponsorships!
https://networkupstools.org/
Other
1.75k stars 337 forks source link

Server protocol implementation #1873

Open bremenpl opened 1 year ago

bremenpl commented 1 year ago

Hello there, I a developing a custom UPS device. I would like it to be able to communicate with the USB connected host over CDC (serial), using the BUT protocol, so the device is universal.

There is a lot of drivers one can choose amongst. Initially I thought about implementing Blazer ser, but I have found this obsolescence note in it:

https://github.com/networkupstools/nut/blob/master/drivers/blazer_ser.c#L4

Second issue is, I cannot find any documentation describing exactly how is the NUT protocol frame built- for example similar to Modbus protocol description. For example, here is a description of blazer ser, but it is already on some level of abstraction. I have a raw serial port and I need to know how to create the NUT server stack on my device...

I would appreciate all help in this matter.

jimklimov commented 1 year ago

Hello, it seems you misunderstood the NUT architecture here (and I assume "BUT protocol" above meant "NUT protocol"?)

Device talking to host using some protocol becomes "of interest" to NUT as soon as it talks an already supported protocol for which a driver exists (per your example that would be likely a Megatec Qx family dialect, supported by nutdrv_qx with an horde of subdrivers nowadays). If there is a completely new protocol, then new NUT drivers would be needed. If it would be a dialect of existing protocol, a subdriver for existing modular driver may be needed (as in nutdrv_qx and earlier blazer families, as well as others).

Each instance of NUT driver(s) talks to one device using media available on this system (dedicated serial/USB cable, I2C, GPIO... or networked SNMP, modbus, NetXML, IPMI...) using relevant vendor-defined protocol.

The NUT driver(s) talk to an upsd data server on the same system using a socket-file driven protocol, allowing all the different devices to be represented in a common data model and access method.

The "NUT protocol" term (especially as you called it "server protocol" in the title) mostly refers to the online communications protocol between the data server and its clients like upsmon, upsc etc. and does not seem to be what you would want to implement here. There were discussions about (networked) UPSes whose NMC's could serve NUT protocol directly (running upsd or their own implementation on the management card), but I am not aware of any results on the market yet. This would not be relevant for an USB connection (formally, might be relevant, if you made it a TCP/IP capable "NIC" over USB, like smartphone tethering - but...)

An "UPS management protocol Informational RFC 9271" was recently completed at https://www.rfc-editor.org/info/rfc9271 with the original documentation at https://github.com/networkupstools/nut/blob/master/docs/net-protocol.txt (feel free to look at the many other files nearby about other aspects of NUT development).

Overall what I think you are after is finding (licensing?) the Megatec protocol which is what roughly half of USB-capable UPS devices talk (the other roughly half being proper USB HID and not serial-over-USB shims, and a few talking modbus over usb, and some with vendor-specific protocols), and implementing it in your firmware for data points available on your UPS (online/onbatt/charging/bypass/... states, voltages, currents, charge, runtime, outlet controls, etc.) and making sure that nutdrv_qx can talk to it, to read and manage (immediate/delayed on/of, beeper, ...). PRs for the latter bit are welcome :)

jimklimov commented 1 year ago

It would also make sense to subscribe to https://alioth-lists.debian.net/pipermail/nut-upsdev/ mailing list and ask a different slice of NUT community for their inputs, and cross-reference this issue and your new thread there. There are some folks closer to hardware hanging out there.

bremenpl commented 1 year ago

Hi @jimklimov , Thank you for your answer. Sorry for my bad NUT related terminology. In general you are right- I am not after the higher NUT layers. What I am interested is exactly this:

Overall what I think you are after is finding (licensing?) the Megatec protocol which is what roughly half of USB-capable UPS devices talk (the other roughly half being proper USB HID and not serial-over-USB shims, and a few talking modbus over usb, and some with vendor-specific protocols), and implementing it in your firmware for data points available on your UPS (online/onbatt/charging/bypass/... states, voltages, currents, charge, runtime, outlet controls, etc.) and making sure that nutdrv_qx can talk to it, to read and manage (immediate/delayed on/of, beeper, ...).

With the difference that I don't want to reimplement anything. I want to find a readily available, free for usage (in terms of licensing), possibly serial based (as my hardware device implements CDC serial over USB) but USB HID is ok too, documented protocol for "Point to Point" communication:

image

So that my embedded device, when connected via USB to the HOST that has NUT running on linux, can be communicated with an already known protocol.

Every resource I find (including the ones you have provided), are operating on some sort of abstraction (commands like GET something or LIST something), while I don't know how does the raw stream of bytes going between the devices is supposed to look like...

bremenpl commented 1 year ago

For example, I use the NUT-SCANNER tool with -E + serial device options. The serial device points to my connected embedded device. On the other side I see that this tool simply sends 1 byte (non ascii) with some interval. I cannot figure out w How to answer to that 1 byte request, as I cannot find the protocol description...

jimklimov commented 1 year ago

I have to suggest again asking on the mailing list - there may be people better versed with the hardware side. Some of the protocols are published at https://networkupstools.org/ups-protocols.html but I'm not sure those are all that NUT can use - certainly many drivers were contributed as something that works without much more detail. Recently someone posted Megatec docs IIRC, gotta check in recently touched issues...

Can't say anything about licensing either, so as if you may (commercially or not) implement a controller; possibly the part of community on the mailing lists could know better. E.g. for "proper" USB HID you would need a Vendor ID licensed from USB IF organization. There are many devices with unrelated vendors and protocols that sadly identify as 0000, 0001, ffff and such, or identifying as their USB interface chip's OEM vendor, making it hard to guess what the actual UPS is, which protocol it needs to be supported (sort of like guessing from a popular NIC's MAC address alone, who built the computer and which OS it normally runs).

bremenpl commented 1 year ago

Hi, Ok, understood.

E.g. for "proper" USB HID you would need a Vendor ID licensed from USB IF organization. There are many devices with unrelated vendors and protocols that sadly identify as 0000, 0001, ffff and such, or identifying as their USB interface chip's OEM vendor, making it hard to guess what the actual UPS is, which protocol it needs to be supported (sort of like guessing from a popular NIC's MAC address alone, who built the computer and which OS it normally runs).

You are right- thisbis why I thought that a CDC interface would be sort of a less trouble, even if it had to be scanned for manually.

Eiither way, thank you for putting me on the right track- will check it further out there!

jimklimov commented 1 year ago

Actually, regarding the comment about getting registered identifiers to be useful to actually uniquely identify a device model (and thus its persistent spec like supported protocols) - that is not only about USB HID, but any USB devices.

bremenpl commented 1 year ago

Hi again @jimklimov ,

Recently we have stumbled upon this:

https://github.com/networkupstools/nut/pull/1052

It seems that this would allow us to have a generic modbus rtu protocol over usb cdc. Do you know whether this concept has maturelized and is maybe somewhere described?

If I u derstand correctly, we would only need to map our registers in the ups.conf

jimklimov commented 1 year ago

Good question. I only reviewed that PR but did not have the hardware to try it with in practice.

If your USB controller can serve modbus (I see a server is doable like https://github.com/stephane/libmodbus/blob/master/tests/unit-test-server.c), and if the UPS is limited to only a few state settings (OL, OB, LB, HB, RB, CHRG, DISCHRG, FSD per https://github.com/networkupstools/nut/blob/master/docs/man/generic_modbus.txt currently) without any more smartness like outlet control, numeric reports for voltages, charges or runtimes, etc. then it might suffice to pick, test and deliver a "recommended ups.conf section content" of some sort for your device.

Otherwise (for smarter readings and controls) you are back to the need to create a way to serve those on the device side, and create (or use existing) NUT driver for the computer side.