PiSupply / PiJuice

Resources for PiJuice HAT for Raspberry Pi - use your Pi Anywhere
https://uk.pi-supply.com/collections/pijuice/products/pijuice-portable-power-raspberry-pi
GNU General Public License v3.0
436 stars 104 forks source link

'Key Error' When Accessing Array Values Within PiJuice.py Classes #692

Open patman141414 opened 3 years ago

patman141414 commented 3 years ago

I am using the PiJuice.py source code to pull values usually visible only in the PiJuice GUI and utilize them in my own python program for the purposes of active power monitoring, displaying battery info in my separate application, etc.

The base code below is how I am pulling this data from the source code. '

import pijuice as UPSplate

def MonitorForPowerOutage():

    UPS_Interface = UPSplate.PiJuiceInterface() 
    Status_Object = UPSplate.PiJuiceStatus(UPSInterface)
    Power_Object = UPSplate.PiJuicePower(UPSInterface)
    Rtc_Object = UPSplate.PiJuiceRtcAlarm(UPSInterface)

    Current_Power_Readings = Status_Object.GetStatus()                            #Get current power status array
    Five_Volt_Input_Status = Current_Power_Readings['data']['powerInput5vIo']     #Read the GPIO power status

    Battery_Charge = Status_Object.GetChargeLevel()                   #Get current charge of UPS battery
    Current_Battery_Charge = Battery_Charge['data']                                            

    Current_Rtc_Time = Rtc_Object.GetTime()                                 #Get current time from RTC 
    Current_Rtc_Time_Minutes = Current_Rtc_Time['data']['minute']
    Current_Rtc_Time_Seconds = Current_Rtc_Time['data']['second']  

`

This code executes once every second while the program is running. Frequently, but not consistently, the following error is thrown.

Exception in Tkinter callback Traceback (most recent call last): File "/usr/lib/python3.7/tkinter/init.py", line 1705, in call return self.func(args) File "/usr/lib/python3.7/tkinter/init.py", line 749, in callit func(args) File "/usr/lib/python3/dist-packages/guizero/tkmixins.py", line 39, in _call_wrapper function(*args) File "/usr/lib/python3/dist-packages/MD53_Control.py", line 1506, in MonitorForPowerOutage Five_Volt_Input_Status = Current_Power_Readings['data']['powerInput5vIo'] KeyError: 'data'

I can't find a reason for this error at the moment, because when I print the value of 'Current_Power_Readings', the following value is outputted:

{'data': {'isFault': False, 'isButton': False, 'battery': 'CHARGING_FROM_5V_IO', 'powerInput': 'NOT_PRESENT', 'powerInput5vIo': 'PRESENT'}, 'error': 'NO_ERROR'}

The key is very clearly 'data'. This error is also thrown for the variables 'Current_Battery_Charge' and 'Current_Rtc_Time_Minutes'. It happens seemingly at random and only affect the variables I have mentioned, even though there are other variables referencing the exact same array that don't throw the key error.

Once again, this error does not happen as soon as the program begins running, nor can I seem to isolate any condition which triggers the error.

tvoverbeek commented 3 years ago

After the Current_Power_Readings = Status_Object.GetStatus() and Battery_Charge = Status_Object.GetChargeLevel() you should first check if the 'error' key is 'NO_ERROR'. If not "data' contains an error message. I guess this is what is happening. Note that due to varying CPU load the clock varies and with it the I2C clock. THis can cause errors in I2C transactions.

patman141414 commented 3 years ago

Thanks for the help, I will be sure to include code to check the 'error' key.

Is there anything that I would be able to do on my end to reduce the likelihood of those I2C transaction errors?

tvoverbeek commented 3 years ago

Which Pi are you using? On Pi4 in /boot/config/txt set core_freq_min=500 (provided you do not enable enable-tvout or 4kp60). This forces the freq to be constant at 500 (possibly at the expense of battery life).

On other models use force_turbo=1 in /boot/config.txt