Page 1 of 1

Update battery values during main loop

Posted: Fri Jun 21, 2019 10:35 am
by AlfaRomeo
Hello,
does anyone knows why the battery values doesn´t are updating during the running time of this program?

Code: Select all

If GetSystemPowerStatus_(PowerStatus.SYSTEM_POWER_STATUS)
  OpenWindow(0,50,50,256,100,"Battery status",#PB_Window_SystemMenu | #PB_Window_MinimizeGadget)

  ACtxt.s=""
  batFlagTxt.s=""
  lifeTimeTxt.s=""
  
  TextGadget(0,10,10,200,14,"")
  TextGadget(1,10,30,200,14,"")
  TextGadget(2,10,50,200,14,"")
  TextGadget(3,10,70,200,14,"")
  
  Repeat
    eventID=WaitWindowEvent()
    
    ac.d=PowerStatus\ACLineStatus              ; 0-Battery, 1-AC, 255 ou $ff-Desconhecido
    If ac=0
      ACtxt="Off"
    Else
      ACtxt="On"
    EndIf
  
    batFlag.d=PowerStatus\BatteryFlag
    ; BatteryFlag bits: 0- carga média, 1-Carga elevada, 2-Carga baixa, 4-Carga critica
                             ; 8-Em carga, 128-sem bateria, 255-Estado desconhecido
  
    If batFlag=0
      batFlagTxt="média"
    ElseIf batFlag=1 
      batFlagTxt="elevada"
    ElseIf batFlag=2 
      batFlagTxt="baixa"
    ElseIf batFlag=4
      batFlagTxt="critico"
    ElseIf batFlag=8 
      batFlagTxt="em carga"
    ElseIf batFlag=128
      batFlagTxt="sem bateria"
    ElseIf batFlag=255
      batFlagTxt="desconhecido"
    EndIf
      
    life100.d=PowerStatus\BatteryLifePercent        ; % de carga restante (255 ou $ff se desconhecida)
  
    lifeTime.l=PowerStatus\BatteryLifeTime           ; n. de segundos restantes (-1 ou $ffffffff se desconhecido)
    lifeTimeMin=lifeTime/60
  
    fullLife.l=PowerStatus\BatteryFullLifeTime       ; n. de segundos de autonomia (-1 ou $ffffffff se desconhecido)
    
    SetGadgetText(0,"Power "+ACtxt)
    SetGadgetText(1,"Carga da bateria: "+batFlagTxt)
    SetGadgetText(2,Str(life100)+" % de bateria restante")
    SetGadgetText(3,Str(lifeTimeMin)+" minutos de bateria restante")
    
  Until eventID=#PB_Event_CloseWindow
  
  CloseWindow(0)
EndIf

Re: Update battery values during main loop

Posted: Fri Jun 21, 2019 11:27 am
by wombats
WaitWindowEvent pauses the loop until an event is fired. Unless you interact with the window or gadgets, no event will be fired and the loop will not run.

You can add a timer that will fire events:

Code: Select all

If GetSystemPowerStatus_(PowerStatus.SYSTEM_POWER_STATUS)
  OpenWindow(0,50,50,256,100,"Battery status",#PB_Window_SystemMenu | #PB_Window_MinimizeGadget)
  
  ACtxt.s=""
  batFlagTxt.s=""
  lifeTimeTxt.s=""
  
  TextGadget(0,10,10,200,14,"")
  TextGadget(1,10,30,200,14,"")
  TextGadget(2,10,50,200,14,"")
  TextGadget(3,10,70,200,14,"")
  
  AddWindowTimer(0, 0, 500)
  
  Repeat
    eventID=WaitWindowEvent()
    
    Select eventID
        
      Case #PB_Event_Timer
        If EventTimer() = 0
          
          ac.d=PowerStatus\ACLineStatus              ; 0-Battery, 1-AC, 255 ou $ff-Desconhecido
          If ac=0
            ACtxt="Off"
          Else
            ACtxt="On"
          EndIf
          
          batFlag.d=PowerStatus\BatteryFlag
          ; BatteryFlag bits: 0- carga média, 1-Carga elevada, 2-Carga baixa, 4-Carga critica
          ; 8-Em carga, 128-sem bateria, 255-Estado desconhecido
          
          If batFlag=0
            batFlagTxt="média"
          ElseIf batFlag=1 
            batFlagTxt="elevada"
          ElseIf batFlag=2 
            batFlagTxt="baixa"
          ElseIf batFlag=4
            batFlagTxt="critico"
          ElseIf batFlag=8 
            batFlagTxt="em carga"
          ElseIf batFlag=128
            batFlagTxt="sem bateria"
          ElseIf batFlag=255
            batFlagTxt="desconhecido"
          EndIf
          
          life100.d=PowerStatus\BatteryLifePercent        ; % de carga restante (255 ou $ff se desconhecida)
          
          lifeTime.l=PowerStatus\BatteryLifeTime           ; n. de segundos restantes (-1 ou $ffffffff se desconhecido)
          lifeTimeMin=lifeTime/60
          
          fullLife.l=PowerStatus\BatteryFullLifeTime       ; n. de segundos de autonomia (-1 ou $ffffffff se desconhecido)
          
          SetGadgetText(0,"Power "+ACtxt)
          SetGadgetText(1,"Carga da bateria: "+batFlagTxt)
          SetGadgetText(2,Str(life100)+" % de bateria restante")
          SetGadgetText(3,Str(lifeTimeMin)+" minutos de bateria restante")
          
        EndIf
        
    EndSelect
    
  Until eventID=#PB_Event_CloseWindow
  
  CloseWindow(0)
EndIf
Edited to correct incorrect use of EventType.

Re: Update battery values during main loop

Posted: Fri Jun 21, 2019 12:31 pm
by spikey
wombats wrote:You can add a timer that will fire events:
That code still won't work though.
1) #PB_Event_Timer is a WaitWindowEvent/WindowEvent result not an EventType result.
2) The call to GetSystemPowerStatus_ needs to be inside the loop to update the values.

Just a thought but querying the battery status twice every second is probably not the greatest idea if, in fact, you are concerned about battery life...

Re: Update battery values during main loop

Posted: Fri Jun 21, 2019 12:38 pm
by AlfaRomeo
Many thanks for your fast reply wombats :)

Will try to implement your solution

@spikey
Just a thought but querying the battery status twice every second is probably not the greatest idea if, in fact, you are concerned about battery life...
Thanks for your advise, maybe your right.
Will try to implement a timer so could delay the querying.

Re: Update battery values during main loop

Posted: Fri Jun 21, 2019 12:41 pm
by RASHAD
Maybe CreateThread() is your good approach

Re: Update battery values during main loop

Posted: Fri Jun 21, 2019 1:00 pm
by AlfaRomeo
spikey wrote: The call to GetSystemPowerStatus_ needs to be inside the loop to update the values.
You´re right spikey, when I moved the call to GetSystemPowerStatus_ to inside the main loop, the battery values started updating.

Thanks for your help :)

Re: Update battery values during main loop

Posted: Fri Jun 21, 2019 1:16 pm
by RASHAD
Using CreateThread()
- No interrupt by any event
- Use any time interval by using Delay()
- Full control when you start or stop

Code: Select all

Global Quitthread

Procedure getbat(par)
  ACtxt.s=""
  batFlagTxt.s=""
  lifeTimeTxt.s=""
  Repeat
    GetSystemPowerStatus_(PowerStatus.SYSTEM_POWER_STATUS)
    ac.d=PowerStatus\ACLineStatus              ; 0-Battery, 1-AC, 255 ou $ff-Desconhecido
    
    If ac=0
      ACtxt="Off"
    Else
      ACtxt="On"
    EndIf
    
    batFlag.d=PowerStatus\BatteryFlag
    ; BatteryFlag bits: 0- carga média, 1-Carga elevada, 2-Carga baixa, 4-Carga critica
                             ; 8-Em carga, 128-sem bateria, 255-Estado desconhecido    
    If batFlag=0
      batFlagTxt="média"
    ElseIf batFlag=1
      batFlagTxt="elevada"
    ElseIf batFlag=2
      batFlagTxt="baixa"
    ElseIf batFlag=4
      batFlagTxt="critico"
    ElseIf batFlag=8
      batFlagTxt="em carga"
    ElseIf batFlag=128
      batFlagTxt="sem bateria"
    ElseIf batFlag=255
      batFlagTxt="desconhecido"
    EndIf
     
    life100.d=PowerStatus\BatteryLifePercent        ; % de carga restante (255 ou $ff se desconhecida)
    
    lifeTime.l=PowerStatus\BatteryLifeTime           ; n. de segundos restantes (-1 ou $ffffffff se desconhecido)
    lifeTimeMin=lifeTime/60
    
    fullLife.l=PowerStatus\BatteryFullLifeTime       ; n. de segundos de autonomia (-1 ou $ffffffff se desconhecido)
    
    SetGadgetText(0,"Power "+ACtxt)
    SetGadgetText(1,"Carga da bateria: "+batFlagTxt)
    SetGadgetText(2,Str(life100)+" % de bateria restante")
    SetGadgetText(3,Str(lifeTimeMin)+Str(x))
    x + 10
    Delay(1000)
  Until Quitthread = 1
EndProcedure

OpenWindow(0,0,0,256,180,"Battery status",#PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
 
  TextGadget(0,10,10,200,20,"",#PB_Text_Border)
  TextGadget(1,10,40,200,20,"",#PB_Text_Border)
  TextGadget(2,10,70,200,20,"",#PB_Text_Border)
  TextGadget(3,10,100,200,20,"",#PB_Text_Border)
  
  ButtonGadget(10,10,130,60,20,"RUN")
  ButtonGadget(20,80,130,60,20,"STOP")  
Repeat
  Select WaitWindowEvent(1) 
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 10
          Quitthread = 0
          Thread = CreateThread(@getbat(),30)
        Case 20
          If IsThread(Thread)
            Quitthread = 1
            Delay(100)
            KillThread(thread)
          EndIf
          Debug IsThread(thread)
      EndSelect
  EndSelect   
Until Quit = 1

Re: Update battery values during main loop

Posted: Fri Jun 21, 2019 1:21 pm
by AlfaRomeo
RASHAD wrote:Maybe CreateThread() is your good approach
Thanks for the hint RASHAD, it´s a good help :)

Re: Update battery values during main loop

Posted: Fri Jun 21, 2019 1:28 pm
by BarryG
spikey wrote:querying the battery status twice every second is probably not the greatest idea if, in fact, you are concerned about battery life
Is this true, or just a worry? Does querying it really use some vast amount of power? I have an app that checks it every minute.

Re: Update battery values during main loop

Posted: Fri Jun 21, 2019 1:39 pm
by Fred
It's best to use a global variable to safely exits the thread instead of using KillThread() (which doesn't clean the stack correctly etc.)

Re: Update battery values during main loop

Posted: Fri Jun 21, 2019 2:06 pm
by RASHAD
Hi Fred
What a shame it is already written in the help :)
Previous post updated

Re: Update battery values during main loop

Posted: Fri Jun 21, 2019 3:21 pm
by spikey
BarryG wrote:
spikey wrote:querying the battery status twice every second is probably not the greatest idea if, in fact, you are concerned about battery life
Is this true, or just a worry? Does querying it really use some vast amount of power? I have an app that checks it every minute.
Once a minute doesn't seem unreasonable - twice a second seems redundant, to me at least. It wouldn't be true to say 'a vast amount' by any stretch of the imagination though. However there is a Scottish proverb which says 'Many a pickle makes a mickle' - which, unpoetically, translates to 'many small amounts make a big amount'...

Re: Update battery values during main loop

Posted: Fri Jun 21, 2019 6:00 pm
by wombats
spikey wrote:
wombats wrote:You can add a timer that will fire events:
That code still won't work though.
1) #PB_Event_Timer is a WaitWindowEvent/WindowEvent result not an EventType result.
2) The call to GetSystemPowerStatus_ needs to be inside the loop to update the values.

Just a thought but querying the battery status twice every second is probably not the greatest idea if, in fact, you are concerned about battery life...
You’re right. I edited my post to correct the first mistake. With the second, I cannot actually run the code since I am on a Mac, so perhaps I shouldn’t have tried to help since my help was wrong. :oops:

Re: Update battery values during main loop

Posted: Sat Jun 22, 2019 1:15 am
by BarryG
spikey wrote:It wouldn't be true to say 'a vast amount'
I never knew that it even used battery at all to query it. This is news to me. Thank you for your advice.