Nobreak BZ1200-BR, Back UPS RS, 1200VA, 600W, Bivolt/115 NT

Status
Not open for further replies.

Bruno Salvador

Dabbler
Joined
Mar 27, 2014
Messages
25
Hello,

I've bought an UPS from APC model BZ-1200-BR, and it was supposed to use in the Freenas UPS driver.

BUT, here is my problem, the model in fact is from Microsol company, that was aquired by APC here in Brazil.

The cable is USB-Serial, with unknown protocol.
I did some reverse engineering in the protocol and I can read the UPS numbers.

How to integrate it with UPS Service in Freenas?
Is it possible to include custom protocol?

What do you recommend?

Thanks a lot!
 

Bruno Salvador

Dabbler
Joined
Mar 27, 2014
Messages
25
Are there any workaround like tweaks, hacks that I could use?
Even though not using the UPS service.
The idea is to use some kind of script that connect directly to UPS serial and get the information, and shutdown the NAS when is on battery?
 

Bruno Salvador

Dabbler
Joined
Mar 27, 2014
Messages
25
Yeah, I'll need to create a driver and implement in NUT.
Luckly most of hardwork is done on the solis.c file from NUT source code. I just need to make some tweaks.

Hope this works.
 

Bruno Salvador

Dabbler
Joined
Mar 27, 2014
Messages
25
Well, that was hard.
After studying the solis.c from NUT github, I have identified 2 changes in the source code that could make my NoBreak visible and funcional for the FreeNAS.

Changes in solis.c (https://github.com/networkupstools/nut/blob/master/drivers/solis.c)
CommReceive(const char *bufptr, int size)
{
...
...
...
if( ( (RecPack[0] & 0xF0) == 0xA0 ) /* change 0xA0 to 0xB0 to support Back-UPS 1200 from Microsol */
&& ( RecPack[ 24 ] == 254 )
&& ( RecPack[ 23 ] == CheckSum ) ) {
....
....
....
if(!(detected)) {
SolisModel = (int) (RecPack[0] & 0x0F);
if( SolisModel < 13 )
imodel = SolisModel - 10; /* 10 = 0, 11 = 1 */
else
imodel = SolisModel - 11; /* 13 = 2, 14 = 3, 15 = 4 */
detected = true;
}
switch( SolisModel )
{
case 10:
/* ADD TO CASE 10, THE FOLLOWING CODE TO SUPPORT BACK-UPS 1200 FROM MICROSOL
{ ScanReceivePack();
break;
} */
{
ScanReceivePack();
break;
}
case 11:
case 12:
case 13:
case 14:
case 15:
{
ScanReceivePack();
break;
}
...

This modification on solis.c won't bring all the features correct, because I need to update the conversion formulas as well (current, frequency,etc), but the most important for FreeNAS is to know if the UPS is on battery mode or line mode. As this information was already correct, I didn't had to change it, so those 2 modifications on the code was enough to make FreeNAS talk to the UPS.

but here is my journey...

I have installed the NUT source in a jail to poke around with it.
But the hard thing was to discover the configuration parameters, as FreeNAS place the executables, conf files, libraries in a diferent directory from the default.


The closest that I have reached was this:

root@nut:/usr/local/nutado/nut-2.7.2 # ./configure --with-user=root --with-group=nut --exec_prefix=/usr/local prefix=/usr/local --sysconfdir=/etc/local/nut --sbindir=/usr/local/sbin --bindir=/usr/local/bin --with-drvpath=/usr/local/libexec/nut --with-statepath=/var/run --with-pidpath=/var/db/nut

I could talk very easily after this configuration plus the modified solis.c code.
After mount the FreeNAS partition I could talk to the NoBreak via command line.

After that I have mounted the filesystem of FreeNAS in write mode, and replace the solis executable form jail to FreeNAS USB.
It was possible to talk to the UPS via command line, but the UPS service button in the FreeNAS gui was not working, problably due to some differences in the configuration command above.

So, this solution was not Good....
and I was tired to mess with NUT source and compilation settings (I do not know much linux...).

So I downloaded the last FreeNAS iso, mounted in a USB drive and got the original "solis" executable.
The idea was to crack the executable directly to add the patches that I have done in the source of solis.c (hardcore way).

Open up in IDA and voila, the solis Assembly code was way optimizated, very difficult to read, despite the compiled solis from the jail was full with debug info, function names, etc.

After poking a little bit I have patched, 2 bytes was enough to fool the UPS service.

First change (0xA0 to 0xB0)
Original: 3D A0 00 00 00 75 8D 80 3D 77 11 21 00 FE 75 84
Patched: 3D B0 00 00 00 75 8D 80 3D 77 11 21 00 FE 75 84

This patch will force ScanReceivePack() function to be executed always:
Original: 76 29 BF A6 9C 40 00 E8 C7 F9 FF FF E9 15 FF FF
Patched: EB 29 BF A6 9C 40 00 E8 C7 F9 FF FF E9 15 FF FF

This will work for FreeNAS last version 9.2.1.5.

Instructions:
1) Open the "/usr/local/libexec/nut/solis" executable in any hex editor
2) Search for the bytes 3D A0 00 00 00 75 8D 80 3D 77 11 21 00 FE 75 84
3) Change the "A0" to "B0"
4) Search for the bytes: 76 29 BF A6 9C 40 00 E8 C7 F9 FF FF E9 15 FF FF
5) Change the "76" for "EB"
6) Save the file
7) Mount as write the Freenas filesystem using mount -uw /
8) Copy the cracked solis to /usr/local/libexec/nut
9) Mount the filesystem as readonly mount -ur /
10) Reboot.

This problem afects only Brazil Customers from Microsol UPS.
Microsol was bought by APC (Scheneider Electric) and changed the name from Microsol to APC Back-UPS 1200.
I was fooled as I thought this Microsol Model was the same as APC.


Now, this system is working like a charm.


OBSERVATION

If anybody know what are the correct settings to compile NUT for FreeNAS, please let me know.
 
Joined
Dec 1, 2014
Messages
3
Bruno,

comprei o mesmo ups e estou com o mesmo problema... pior que sou completamente ignorante com unix/linux, então não está sendo facil rodar o que você escreveu acima.... qual foi o drive que você escolheu para ativar no freenas?

abs.
 

Bruno Salvador

Dabbler
Joined
Mar 27, 2014
Messages
25
Solis is the driver.
Therefore for the 9.3 version the procedure above do not work.

I have updated the source code for the NUT, so I believe that for the next version of FreeNas will have this item solved.
 

Bruno Salvador

Dabbler
Joined
Mar 27, 2014
Messages
25
It seems that the update that I have did on NUT source code is deployed to FreeNAS.
Your Microsol BZ1200-BR device is not working on freenas with limited funcitonality.
The most important is that it identifies if the nobreak is on battery or line mode.
 

Bruno Salvador

Dabbler
Joined
Mar 27, 2014
Messages
25
It seems that the Solis is working ok now.
I have updated the freenas OS and it identified my nobreak.
 
Joined
Aug 19, 2015
Messages
8
Hello Bruno,

I'm using FreeNAS 9.3 with NUT 2.7.2 (with your update to solis.c) and same UPS model, but the thing is uplcom driver won't recognize the USB/Serial and create the device under /dev/ttyU*. What did you do to solve this? Without a driver I can't even open the serial port to communicate with the UPS, it shows this error: "
freenas notifier: tcgetattr(/dev/ugen0.5): Inappropriate ioctl for device"? Below is the usbconfig output.

[root@freenas ~]# usbconfig -d ugen0.5 dump_device_desc
ugen0.5: <APC USB SERIAL CONVERTER. APC BY SCHNEIDER ELECTRIC> at usbus0, cfg=0
md=HOST spd=FULL (12Mbps) pwr=ON (100mA)

bLength = 0x0012
bDescriptorType = 0x0001
bcdUSB = 0x0200
bDeviceClass = 0x0002
bDeviceSubClass = 0x0000
bDeviceProtocol = 0x0000
bMaxPacketSize0 = 0x0008
idVendor = 0x051d
idProduct = 0xc812
bcdDevice = 0x0100
iManufacturer = 0x0001 <APC BY SCHNEIDER ELECTRIC>
iProduct = 0x0002 <APC USB SERIAL CONVERTER.>
iSerialNumber = 0x0000 <no string>
bNumConfigurations = 0x0001

When I plug another USB/Serial adapter it's correctly identified by uplcom and ucom and the device is created under /dev/ttyU0, so the driver is loaded in the kernel:

Aug 20 01:21:59 freenas ugen0.5: <APC BY SCHNEIDER ELECTRIC> at usbus0
Aug 20 09:20:48 freenas ugen0.5: <APC BY SCHNEIDER ELECTRIC> at usbus0 (disconnected)
Aug 20 09:20:55 freenas ugen0.5: <Prolific Technology Inc.> at usbus0
Aug 20 09:20:55 freenas uplcom0: <Prolific Technology Inc. USB-Serial Controller, class 0/0, rev 1.10/3.00, addr 5

[root@freenas ~]# usbconfig -d ugen0.5 dump_device_desc
ugen0.5: <USB-Serial Controller Prolific Technology Inc.> at usbus0, cfg=0 md=HO
ST spd=FULL (12Mbps) pwr=ON (100mA)

bLength = 0x0012
bDescriptorType = 0x0001
bcdUSB = 0x0110
bDeviceClass = 0x0000
bDeviceSubClass = 0x0000
bDeviceProtocol = 0x0000
bMaxPacketSize0 = 0x0040
idVendor = 0x067b
idProduct = 0x2303
bcdDevice = 0x0300
iManufacturer = 0x0001 <Prolific Technology Inc.>
iProduct = 0x0002 <USB-Serial Controller>
iSerialNumber = 0x0000 <no string>
bNumConfigurations = 0x0001

Any help would be much appreciated.
 

Bruno Salvador

Dabbler
Joined
Mar 27, 2014
Messages
25
Hello,

I cannot access right now my NAS box because it is powered off and I'm at work. You know, the electric power rate has been increased a lot where we live and since some months ago I just power up my NAS on demand.

Despite that, the Microsol do not use USB driver, it uses a serial.
It should not be /dev/ttyUSB something.

In order to know that is the port that your nobreak will comunicate do the following

1) unplug the cable from nas box
2) type in comand line: "tail -f 10 /var/log/messages"
3) plug in the cable
4) Now you should see in the screen some information about the cable being recognized. There you can find the correct port to link in UPS configuration.
 
Joined
Aug 19, 2015
Messages
8
Bruno,

I know, that is just the problem, the USB/Serial driver is not recognizing the APC hardware, so it does not create the corresponding device (it's actually /dev/ttyU).
Can you post, later on, the output of your usbconfig? Are you also running version 9.3? Thanks a lot for the help.
 
Joined
Aug 19, 2015
Messages
8
Look at the console output:

> ugen0.5: <APC BY SCHNEIDER ELECTRIC> at usbus0 (disconnected)
> ugen0.5: <APC BY SCHNEIDER ELECTRIC> at usbus0
> ugen0.5: <APC BY SCHNEIDER ELECTRIC> at usbus0 (disconnected)
*** nothing else happens when I plug the UPS ***

*** Testing with other USB/Serial hardware:
> ugen0.5: <Prolific Technology Inc.> at usbus0
> uplcom0: <Prolific Technology Inc. USB-Serial Controller, class 0/0, rev 1.10/3.00, addr 5> on usbus0
*** here uplcom kicks in and creates the serial device /dev/ttyU0

> ugen0.5: <Prolific Technology Inc.> at usbus0 (disconnected)
> uplcom0: at uhub2, port 2, addr 5 (disconnected)
 
Joined
Aug 19, 2015
Messages
8

Bruno Salvador

Dabbler
Joined
Mar 27, 2014
Messages
25
ugen1.6: <USB - Serial FTDI> at usbus1, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (90mA)
bLength = 0x0012
bDescriptorType = 0x0001
bcdUSB = 0x0110
bDeviceClass = 0x0000
bDeviceSubClass = 0x0000
bDeviceProtocol = 0x0000
bMaxPacketSize0 = 0x0008
idVendor = 0x0403
idProduct = 0x6001
bcdDevice = 0x0400
iManufacturer = 0x0001 <FTDI>
iProduct = 0x0002 <USB - Serial>
iSerialNumber = 0x0000 <no string>
bNumConfigurations = 0x0001

I'm using a standard USB cable. The FTDI serial chip is included in the NoBreak
 
Joined
Aug 19, 2015
Messages
8
Thanks for the reply.

My hardware is different from yours, you see... I've modified the kernel driver and I'll report back after testing it. I guess APC is not using Microsol hardware anymore. Since the USB/Serial hardware is different, I think the UPS driver will also be (APC's own, maybe).

Yours:
idVendor = 0x0403 -> vendor FTDI 0x0403 Future Technology Devices
idProduct = 0x6001 -> product FTDI SERIAL_8U232AM 0x6001 8U232AM Serial

Mine:
idVendor = 0x051d -> vendor APC 0x051d American Power Conversion
idProduct = 0xc812 -> not listed in FreeBSD driver (I've inserted this product ID in uftdi.c, haven't tested it yet).

This is the model I bought: http://accessories.la.dell.com/sna/...s1&sku=008-0272&dgc=ST&cid=261058&lid=4704367
 
Joined
Aug 19, 2015
Messages
8
Bruno,

I've manage to load the umodem driver in FreeNAS (had to recompile nanoBSD kernel and include it). The usb/serial now works fine under (/dev/cuaU0). But the UPS driver (solis.c) is not working. I have captured some packets from my UPS's USB/Serial port:

BA6D88AD0001A089000A1F0100000000000E9849606072FE
BA6E88AE0001A48B000B1F0100000000000E984960607BFE
BA6D87AE0001A48A000C1F0100000000000E9849606079FE
BA6E88AE0001A48C000D1F0100000000000E984960607EFE
BA6D88AE0001A489000E1F0100000000000E984960607BFE
BA6E88AE0001A48C000F1F0100000000000E9849606080FE
Connected to /dev/cuaU0 (speed 9600)

[SIGTERM]

They all have size = 24 bytes, but the driver is reading packets of size 25. I believe this is the problem. Would you help me out one more time? Could capture some packets from your UPS and post it here so I can compare with mine? (Maybe I can write another driver for NUT...).

To capture: (cu -l /dev/cuaU0|hexdump -C) > ups.hex
Be sure to kill any program accessing the /dev/cuaU0 before running the cupture command (i.e.: killall solis)
You 'll have to killall cu from another terminal to stop capturing the serial port, because 'cu' will not respond to keyboard.

Thanks a lot.
 
Status
Not open for further replies.
Top