geeekpi / upsplus

UPS Plus is a new generation of UPS power management module. It is an improved version of the original UPS prototype. It has been fixed the bug that UPS could not charge and automatically power off during work time. It can not only perform good battery power management, but also provide stable voltage output and RTC functions. At the same time,it support for FCP, AFC, SFCP fast charge protocol, support BC1.2 charging protocol, support battery terminal current/voltage monitoring and support two-way monitoring of charge and discharge. It can provide programmable PVD function. Power Voltage Detector (PVD) can be used to detect if batteries voltage is below or above configured voltage. Once this function has been enabled, it will monitoring your batteries voltage, and you can control whether or not shut down Raspberry Pi via simple bash script or python script. This function will protect your batteries from damage caused by excessive discharge. It can provide Adjustable data sampling Rate. This function allows you to adjust the data sampling rate so that you can get more detailed battery information and also it will consume some power. The data sampling information can communicate with the upper computer device through the I2C protocol. UPS Plus supports the OTA firmware upgrade function. Once there is a new firmware update, it is very convenient for you to upgrade firmware for UPS Plus. The firmware upgrade can be completed only by connecting to the Internet,and execute a python script. Support battery temperature monitoring and power-down memory function. UPS Plus can be set to automatically start the Raspberry Pi after the external power comes on. The programmable shutdown and forced restart function will provide you with a remote power-off restart management method. That means you don’t need to go Unplug the power cable or press the power button to cut off the power again. You can set the program to disconnect the power supply after a few seconds after the Raspberry Pi is shut down properly. And you can also reconnect the power supply after a forced power failure to achieve a remote power-off and restart operation. Once it was setting up, you don't need to press power button to boot up your device which is very suitable for smart home application scenarios.
https://wiki.52pi.com/index.php?title=UPS_Plus_SKU:_EP-0136
MIT License
73 stars 25 forks source link

OSError: [Errno 121] Remote I/O error #130

Closed p1r473 closed 9 months ago

p1r473 commented 1 year ago

Usually, the application works for me. However some times, I get the following error:

------------------------------------------------------------
-------------------Batteries information-------------------
------------------------------------------------------------
Voltage of Batteries: 3.560 V
Battery Current (discharge) Rate: -2283.902 mA
Current Battery Power Consumption: 8024.390 mW
------------------------------------------------------------
Traceback (most recent call last):
  File "/home/pi/upsplus/upsplus.py", line 66, in <module>
    aReceiveBuf.append(bus.read_byte_data(DEVICE_ADDR, i))
  File "/usr/local/lib/python3.9/dist-packages/smbus2/smbus2.py", line 433, in read_byte_data
    ioctl(self.fd, I2C_SMBUS, msg)
OSError: [Errno 121] Remote I/O error                  
botboe commented 1 year ago

I can confirm this behavior.

dacarson commented 1 year ago

When I try to do an OTA update, I do get the same error:

pi@raspberrypi:~/bin/upsplus $ python3 OTA_firmware_upgrade.py 
Traceback (most recent call last):
  File "/home/pi/bin/upsplus/OTA_firmware_upgrade.py", line 23, in <module>
    aReceiveBuf.append(bus.read_byte_data(DEVICE_ADDR, i))
  File "/home/pi/.local/lib/python3.9/site-packages/smbus2/smbus2.py", line 433, in read_byte_data
    ioctl(self.fd, I2C_SMBUS, msg)
OSError: [Errno 121] Remote I/O error

However, other commands work:


raspberrypi:~/bin $ python3 upsPlus.py 
------------------------------------------------------------
------Current information of the detected Raspberry Pi------
------------------------------------------------------------
Raspberry Pi Supply Voltage: 4.936 V
Raspberry Pi Current Current Consumption: 1012.447 mA
Raspberry Pi Current Power Consumption: 5076.535 mW
------------------------------------------------------------
-------------------Batteries information-------------------
------------------------------------------------------------
Voltage of Batteries: 4.200 V
Battery Current (Charging) Rate: 778.049 mA
Current Battery Power Supplement: 3278.049 mW
Successfully set the protection voltage to: 3700 mV
------------------------------------------------------------
Currently charging via Micro USB Port.
dacarson commented 1 year ago

I have not seen this error once I closed the bus when I finished with it. That is, adding: bus.close() to the end of the python script (or where it exited) addressed the issue for me.

sfatula commented 1 year ago

To do the firmware update, are you putting the UPS into firmware update mode? That error indicates it is not in the mode.

dacarson commented 1 year ago

I was able to work out the issue with my installation. Summary, I had run out of file handles.

The library ina219.py opens a handle to the i2c bus, but the API does not provide a way to close the handle. You have to exit your python application, which releases the handle. If you use any of the python scripts provided here, you must exit after each call. I was continually calling the library through a systemctl service to provide information to grafana (via influxdb) to log status. I would run out of handles, and run into this 'Remote I/O error'. I changed it to a cron job and haven't see the issue happen again.

sfatula commented 1 year ago

Hmm, I was speaking of your post while doing python3 OTA_firmware_upgrade.py

That requires putting the UPS in firmware update mode first was my only point. That is not run via cron.

dacarson commented 1 year ago

For me, I had run out of file handles when I tried to use python3 OTA_firmware_upgrade.py

p1r473 commented 9 months ago

Only fix that worked for me was putting it in a loop that attempts the operation 3 times, because sometimes it just fails.