Pandbatt

Description of the page content

Forth program to show the status of the Pandora's battery.

Tags:

This program is the logical descendant of xbattbar-check-sysfs; it shows all useful information about the Pandora's battery: status, capacity, time to full and time to empty.

Source code

#! /usr/bin/env gforth 

\ pandbatt.fs
\ Pandbatt (version A-00-20130822)

\ This program, 'Pandbatt', prints the attributes of the
\ Pandora's battery.  It's written in Forth with Gforth.

\ Copyright (C) 2012 Marcos Cruz (programandala.net)

\ 'Pandbatt' is free software; you can redistribute it
\ and/or modify it under the terms of the GNU General Public
\ License as published by the Free Software Foundation; either
\ version 2 of the License, or (at your option) any later
\ version. See:
\
\ http://gnu.org/licenses/
\ http://gnu.org/licenses/gpl-2.0.html

\ History
\
\ 2012-11-04 First version.
\ 2012-11-05 New: 'time_to_empty_avg' attribute.
\ 2013-08-22 Fix: stack notation in 'sconstant'.
\ 2013-08-22 Change: stack notation of strings.

warnings off

: sconstant  (  ca1 len1 "name" -- )
  create  s,
  does>  ( -- a2 u1 )  ( dfa ) count
  ;

s" /sys/class/power_supply/bq27500-0/" sconstant sys_dir

sys_dir s" status" s+ sconstant status_file
sys_dir s" capacity" s+ sconstant capacity_file
sys_dir s" time_to_full_now" s+ sconstant time_to_full_file
sys_dir s" time_to_empty_now" s+ sconstant time_to_empty_file
sys_dir s" time_to_empty_avg" s+ sconstant time_to_empty_avg_file
variable charging?
variable full?

false [if]  \ use Gforth's 'slurp-file'

\ 'slurp-file' does not work with files under /sys/,
\ it causes the error "could not read whole file".

' slurp-file alias content

[else] \ alternative to 'slurp-file'

variable fid  \ file id
256 constant max_line
create line_buffer max_line 2 + allot

\ When the battery status changes (beetwen charging and
\ discharging or vice versa), the reading of the time files
\ fails during some seconds, until the OS updates them. This
\ causes a fatal error because its content is supposed to be a
\ number and EVALUATed. In order to detect this error and print
\ a question mark instead, a flag is used:

variable failed?  \ flag for file reading

: open_file  ( ca len -- )
  \ ca len = file name
  r/o open-file throw fid !
  ;
: close_file  ( -- )
  fid @ close-file throw
  ;
: read_file  ( -- ca len )
  \ Get the content of the open file (only its first line).
  \ ca len = file content (first line)
  line_buffer dup max_line fid @ read-line
  failed? ! and
  ;
: content  ( ca1 len1 -- ca2 len2 )
  \ Get file content; an alternative to 'slurp-file'.
  \ ca1 len1 = file name
  \ ca2 len2 = file content (first line)
  open_file read_file close_file
  ;

[then]

\ Printing of attributes by type

: ((.attribute))  ( ca1 len1 ca2 len2 -- ca3 len3 )
  \ Print an attribute label and return the attribute.
  \ ca1 len1 = file name
  \ ca2 len2 = attribute label
  \ ca3 len3 = file content
  type ." : " content
  ;
: (.attribute)  ( ca1 len1 ca2 len2 -- )
  \ Print a text attribute.
  \ ca1 len1 = file name
  \ ca2 len2 = attribute label
  ((.attribute)) type
  ;
: .attribute  ( ca1 len1 ca2 len2 -- )
  \ Print a text attribute and finish the line.
  \ ca1 len1 = file name
  \ ca2 len2 = attribute label
  (.attribute) cr
  ;
: .00  ( n -- )
  \ Print a number with two digits.
  s>d <# # # #> type
  ;
: seconds>hours  ( n1 -- n2 )
  \ Convert seconds to hours.
  3600 /
  ;
: seconds>minutes  ( n1 -- n2 )
  \ Convert seconds to the minutes remaining after converting
  \ them to hours.
  3600 mod 60 /
  ;
: .hh:mm  ( n -- )
  \ Print seconds in the format "hh:mm".
  dup seconds>hours .00 ." :" seconds>minutes .00
  ;
: .time_attribute  ( ca1 len1 ca2 len2 -- )
  \ Print a time attribute (stored in seconds). 
  \ ca1 len1 = file name
  \ ca2 len2 = attribute label
  ((.attribute)) failed? @
  if    2drop ." ?"
  else  evaluate .hh:mm
  then  cr
  ;
: .percent_attribute  ( ca1 len1 ca2 len2 -- )
  \ Print a percent attribute.
  \ ca1 len1 = file name
  \ ca2 len2 = attribute label
  (.attribute) ." %" cr
  ;

\ Printing of attributes by name

: .capacity  ( -- )
  \ Print the capacity of the battery.
  capacity_file s" Capacity" .percent_attribute
  ;
: flags!  ( ca len -- )
  \ Update the status flags with the content of the status
  \ attribute.
  \ ca len = content of the status attribute
  2dup  s" Full" compare 0= full? !
  s" Discharging" compare charging? !
  ;
: .status  ( -- )
  \ Print the status of the battery.
  status_file s" Status" ((.attribute))
  2dup flags!  type cr
  ;
: (.time_to_full)  ( -- )
  \ Print the time to full.
  time_to_full_file s" Time to full" .time_attribute
  ;
: .time_to_full  ( -- )
  \ Print the time to full if needed.
  full? @ 0= if  (.time_to_full)  then
  ;
: .time_to_empty  ( -- )
  \ Print the time to empty.
  time_to_empty_file s" Time to empty" .time_attribute
  ;
: .time_to_empty_avg  ( -- )
  \ Print the average time to empty.
  time_to_empty_avg_file s" Time to empty (average)" .time_attribute
  ;
: .time  ( -- )
  \ Print the time to full or the time to empty, depending on
  \ the charging status.
  charging? @
  if    .time_to_full
  else  .time_to_empty .time_to_empty_avg
  then
  ;
: .battery  ( -- )
  \ Print all battery info.
  cr .status .capacity .time
  ;
.battery bye

Downloads

Related pages

xbattbar-check-sysfs
Forth program that feeds xbattbar with battery data taken from sysfs.