Monitoring Voltronic Power Axpert MEX inverter under Linux

I am using the SKYMAX Expert MEX 3K-24 inverter. In fact it is identical with Voltronic Power Axpert MEX 3K-24, it was just rebranded by a Polish company.


It is a 24 volts model, so I am using a two 12V 100Ah batteries connected in series (lead-acid automotive batteries):

I hope it will work longer then the batteries for APC 1400VA UPS, which I had before (and had to buy and replace batteries very often).
The model is not a hybrid one, which I’d love to have but for my purposes it is working really great so far.
The inverter has an integrated USB connector, so there is a way to communicate with the device.

There is some creepy monitoring software called WatchPower, which is moreover written in Java:

There is even also a console version of the management software which can be run on Linux, but it also need Java (JRE) 😮
Monitoring the inverter with this software on Raspberry Pi would be painful, so it was a time to discover how to do it the proper way 😉

After plugging the USB to the Raspberry I’ve got in dmesg:

 [  523.116132] usb 1-2: new low-speed USB device number 2 using uhci_hcd
 [  523.329148] usb 1-2: New USB device found, idVendor=0665, idProduct=5161
 [  523.329160] usb 1-2: New USB device strings: Mfr=3, Product=1, SerialNumber=0

 [  525.073328] hidraw: raw HID events driver (C) Jiri Kosina
 [  525.111176] usbcore: registered new interface driver usbhid
 [  525.111184] usbhid: USB HID core driver
 [  525.213484] hid-generic 0003:0665:5161.0001: hiddev0,hidraw0: USB HID v1.11 Device [HID 0665:5161] on usb-0000:00:1d.0-2/input0

So it is a HID device visible in lsusb as:

Bus 001 Device 002: ID 0665:5161 Cypress Semiconductor USB to Serial

I sniffed with wireshark how the original program is talking to the device and I see that it is some pseudo-ASCII protocol.
The commands generally starts with Q letter, ie: QPI, QSID, QPIRI, QDI, QPIGS and the responses started with the ‘(‘ mark, and the results like this:

(230.1 49.9 230.1 49.9 0529 0483 020 393 27.03 000 100 0040 0000 000.0 00.00 00000 00010101 00 00 00000 110

At the end of the line is a two-byte CRC and new line character.

I’ve entered some of the command into Google to get some information about this protocol.
I have found great Australian and New Zealand forums with much information about the protocol and the hardware (maybe it’s more common at those markets). The most valuable for me was these two threads:
http://powerforum.co.za/topic/323-infinisolar-3k-plus-realtime-values-and-logging/
http://forums.aeva.asn.au/forums/pip4048ms-inverter_topic4332.html

Based on this information I was able to integrate the support for the inverter in my Raspberry Pi.
There is no HID driver for the inverter, so I just used a generic device file: /dev/hidraw0.

In fact the most interesting commands for my constant monitoring was:
QPIGS – status (input, output voltages, currents, load, etc.)
QMOD – current mode (power-on, standby, line mode, battery mode, etc.)

So now instead of using the bloated Java software, I am just using simple and pure C code for monitoring the inverter on my RPi.
I created a sample demo project on github, so you can have a look or test how to query the inverter:
https://github.com/manio/skymax-demo

As usual I am providing some sample grafana plots, which I like very much in contrast to original software 😉

Comments

  1. Hi. Would you be willing to put this in github? I’m looking to do a similar project and I’d prefer to build on something rather than reinventing the wheel. Thanks, Daryl

    1. Hi Daryl, I have it integrated in a larger home automation project which I am not willing to make public for several reasons. Anyway – I could try to make some small “demo” project which is using this skymax class and put it to the github. Is that ok to you?

      Update: I just pushed a sample code to the gihub, article is updated. Thanks! 🙂

  2. Hi,
    I wonder if you could help. On my Raspberry Pi, it seems like the USB device reconnects every now and then, and a new device number being assigned to it. This results in your code stopping working after some time.

    Apr 30 21:36:11 raspberrypi kernel: [105134.832478] usb 1-1.2: USB disconnect, device number 12
    Apr 30 21:36:12 raspberrypi kernel: [105135.090308] usb 1-1.2: new low-speed USB device number 13 using dwc_otg
    Apr 30 21:36:12 raspberrypi kernel: [105135.233364] usb 1-1.2: New USB device found, idVendor=0665, idProduct=5161
    Apr 30 21:36:12 raspberrypi kernel: [105135.233387] usb 1-1.2: New USB device strings: Mfr=3, Product=1, SerialNumber=0
    Apr 30 21:36:12 raspberrypi kernel: [105135.262741] hid-generic 0003:0665:5161.000A: hiddev0,hidraw0: USB HID v1.11 Device [HID 0665:5161] on usb-3f980000.usb-1.2/input0

    pi@raspberrypi:~/skymax-demo/out $ ./skymax
    Sun Apr 30 21:55:55 2017 MAIN LOOP
    Sun Apr 30 21:55:55 2017 Unable to open device file (errno=13 Permission denied)
    ^C
    pi@raspberrypi:~/skymax-demo/out $ ll /dev/skymax
    lrwxrwxrwx 1 root root 12 Apr 30 11:43 /dev/skymax -> /dev/hidraw0
    pi@raspberrypi:~/skymax-demo/out $ ll /dev/hidraw0
    crw——- 1 root root 247, 0 Apr 30 21:36 /dev/hidraw0
    pi@raspberrypi:~/skymax-demo/out $ ls -lha /dev/hidraw0
    crw——- 1 root root 247, 0 Apr 30 21:36 /dev/hidraw0
    pi@raspberrypi:~/skymax-demo/out $ dmesg | grep hidraw
    [ 4.851059] hidraw: raw HID events driver (C) Jiri Kosina
    [ 6.063636] hid-generic 0003:0665:5161.0001: hiddev0,hidraw0: USB HID v1.11 Device [HID 0665:5161] on usb-3f980000.usb-1.4/input0
    [38893.331337] hid-generic 0003:0665:5161.0002: hiddev0,hidraw0: USB HID v1.11 Device [HID 0665:5161] on usb-3f980000.usb-1.4/input0
    [39134.255937] hid-generic 0003:0665:5161.0003: hiddev0,hidraw0: USB HID v1.11 Device [HID 0665:5161] on usb-3f980000.usb-1.4/input0
    [67552.001148] hid-generic 0003:0665:5161.0004: hiddev0,hidraw0: USB HID v1.11 Device [HID 0665:5161] on usb-3f980000.usb-1.2/input0
    [68779.180311] hid-generic 0003:0665:5161.0005: hiddev0,hidraw0: USB HID v1.11 Device [HID 0665:5161] on usb-3f980000.usb-1.2/input0
    [80602.567898] hid-generic 0003:0665:5161.0006: hiddev0,hidraw0: USB HID v1.11 Device [HID 0665:5161] on usb-3f980000.usb-1.2/input0
    [88754.726696] hid-generic 0003:0665:5161.0007: hiddev0,hidraw0: USB HID v1.11 Device [HID 0665:5161] on usb-3f980000.usb-1.2/input0
    [88814.625493] hid-generic 0003:0665:5161.0008: hiddev0,hidraw0: USB HID v1.11 Device [HID 0665:5161] on usb-3f980000.usb-1.2/input0
    [95764.943032] hid-generic 0003:0665:5161.0009: hiddev0,hidraw0: USB HID v1.11 Device [HID 0665:5161] on usb-3f980000.usb-1.2/input0
    [105135.262741] hid-generic 0003:0665:5161.000A: hiddev0,hidraw0: USB HID v1.11 Device [HID 0665:5161] on usb-3f980000.usb-1.2/input0

    1. Hi Rudi,
      I am using a 7.5m long USB A/B cable from the inverter to the Raspberry. First it was connected directly to the RPi, now I am using a powered USB hub. In both cases I have some transmission errors from time to time (I think it may be because of cable length), but I never had problems with disconnecting USB device – like you have currently. This kind of problem sometimes happens on my remote serial converter (also long cable), but it is rare.
      One way or another my point is that I’d just try to stabilize it somehow – maybe you could try to change the cable, connect it via USB hub, play with some kernel USB parameters…?
      Or even try to raise the power voltage. I had problems using other USB device without USB hub: when I raised the RPi power voltage by 100mV (from 5.0V to 5.1V) – then it was working more stable.
      Of course you can try to fix it in software, trying to detect such problems, but I’d rather fix it in hardware first. You can also try to connect it to the laptop/PC to check if the same problem exists…

  3. Good day Manio

    Do you know if it is possible to use an Arduino to log data from this inverter onto an SD card?
    We have a 5 kVA version of this inverter, which has a serial RS232 output.
    I will be able to connect the Arduino to the serial port through something like a MAX232 chip. I’m just not sure how I will receive and interpret the data from the inverter. Do you have any information available that will help?
    Also, do these inverters constantly send out a data stream through the serial/usb ports or do you need to request information before it is sent?
    Any information will be very helpful.
    Regards

    1. Hi Egon,
      If the RS232 protocol is similar/same, then it should be easy to do it. Of course I assume you know how to log the data to SD card :).
      As you can see in my article, I’ve created a sample demo application. The mentioned protocol is a query-response based, so answering your question: you need to request specific information and the inverter is then responding back.

  4. Hi there, i use a inverter pip 2424 from mpp solar i know it works similar . I was able to access the pcx60 charger via rs232 using a small pyhton script and send the datas to emoncms.

    The pcs60 was easy to access with raspberry pi and integrated functions. Bt thepip i connect va USB I am not able yet to access with the pi. Could you short descripe how you create that “/dev/hidraw0” ,

    is it possible open the divice same as an seriell device eg /ttyAMA0 ?

    Thanks for your help 🙂

    1. Hi! There was no need to create the /dev/hidraw device. All HID devices that are detected by kernel (no matter if they are handled by dedicated kernel modules or not) are also available using the HIDRAW API:
      https://www.kernel.org/doc/Documentation/hid/hidraw.txt

      If there is a loaded kernel module for the specific HID device, then the device can be handled using additional device files (depending on module). But in this case there is no such module available, so the only way to communicate with the inverter was using the hidraw device.

      And answering your question: No, without the driver there is no serial emulation and no serial devices are available.

      ps. you have a nice dashboard 😉

  5. Hi, I am getting
    Thu Mar 8 09:33:25 2007 MAIN LOOP
    Thu Mar 8 09:33:28 2007 Skymax: QPIGS read timeout
    Thu Mar 8 09:33:28 2007 Skymax: QPIGS reply too short (0 bytes)
    Thu Mar 8 09:33:31 2007 Skymax: QMOD read timeout
    Thu Mar 8 09:33:31 2007 Skymax: QMOD reply too short (0 bytes)

    How can I sort this problem out? I created a symbolic link to /dev/ttyS0 (RS232 communication) and how can I get this to graph to grafana?

    1. Hi Raymond,
      I don’t know what hardware you are using, but the sample code was tested on the USB-HID inverters (eg. via a /dev/hidraw0 device file). You are passing a regular serial port /dev/ttyS0 instead of the USB one. I did not tested it over a serial port. I am not even sure if it us using the same protocol. The best thing for you would be if you can sniff the serial communication when using official software and compare the commands…

      Regarding grafana: It is too big topic to response here in the reply. You just need to create some script which is passing the values from the inverter to the graph storage you are using. If you are not using grafana currently, then there are plenty of tutorials how to install and using it. Google is your friend here 🙂

      Some basics are eg here:
      https://www.digitalocean.com/community/tutorials/an-introduction-to-tracking-statistics-with-graphite-statsd-and-collectd
      https://lkhill.com/using-influxdb-grafana-to-display-network-statistics/

  6. Hello. I am working with the Voltronic Infini 10K hybrid solar inverter. According to several posts all over the internet the communication interface on the USB side and the RS-232 side should be the same or at least very similar to the device you are using. I fetched your code from github and adapted it so that it would just query the protocol id (QPI) and the device id (QID). Whatever command I am sending to the hidraw device I always get exactly eight Bytes back (0x 5e 30 1b e3 0d 00 00 00). Also quite often I get errno 32 (broken pipe) when trying to write to the device. The open command executes successfully.

    I am not quite clear on how the interface to the hidraw device works. I was under the impression, that USB expects very specific frames (reports) of data in which the payload is embedded. And that there is a specific procedure to initiate the USB device before it may be used through some special control reports. Could you point me in the right direction on this? Any help is greatly appreciated.

    Sincerely,
    Freddy

    1. Hi Freddy,
      To be honest I don’t know what the response means. In ASCII it looks like:
      “^0”. I assume you don’t have a valid responses also for the QPI or QID commands…
      I just don’t bother about USB HID protocol “reports” – it is an upper layer which the kernel is doing itself. I am just only opening the hidraw device and writing the commands directly (with it’s checksums). Then and I can read from the device to obtain the inverter response.
      If you have broken pipe, then it seems that there is something wrong with the hidraw device? USB cable problems? what is in your dmesg in this case?

      My tip for you: try to run official software eg. on some window laptop, run eg. wireshark in the same time and sniff what commands are passed to the inverter and how it is responding. It will be a good ground to start adapting the sample code…

Leave a Reply

Your email address will not be published. Required fields are marked *