2017-04-14 19:12:28 +00:00
local Device = require ( " device " )
2017-04-02 21:46:19 +00:00
local KeyValuePage = require ( " ui/widget/keyvaluepage " )
local UIManager = require ( " ui/uimanager " )
local WidgetContainer = require ( " ui/widget/container/widgetcontainer " )
2017-04-14 19:12:28 +00:00
local util = require ( " util " )
2017-04-02 21:46:19 +00:00
local _ = require ( " gettext " )
local SystemStat = {
start_sec = os.time ( ) ,
2017-04-09 17:26:17 +00:00
suspend_sec = nil ,
resume_sec = nil ,
2017-04-02 21:46:19 +00:00
wakeup_count = 0 ,
sleep_count = 0 ,
charge_count = 0 ,
discharge_count = 0 ,
}
2017-04-14 19:12:28 +00:00
function SystemStat : init ( )
2019-05-03 18:38:00 +00:00
if Device : isCervantes ( ) or Device : isPocketBook ( ) then
2017-04-14 19:12:28 +00:00
self.storage_filter = " mmcblk "
2019-05-03 18:38:00 +00:00
elseif Device : isKobo ( ) then
self.storage_filter = " /mnt/ "
2017-04-14 19:12:28 +00:00
elseif Device : isKindle ( ) then
self.storage_filter = " ' /mnt/us$' "
elseif Device : isSDL ( ) then
self.storage_filter = " /dev/sd "
end
end
function SystemStat : put ( p )
table.insert ( self.kv_pairs , p )
end
function SystemStat : appendCounters ( )
2017-04-25 16:49:39 +00:00
self : put ( { _ ( " KOReader started at " ) , os.date ( " %c " , self.start_sec ) } )
2017-04-14 19:12:28 +00:00
if self.suspend_sec then
self : put ( { _ ( " Last suspend time " ) , os.date ( " %c " , self.suspend_sec ) } )
end
if self.resume_sec then
self : put ( { _ ( " Last resume time " ) , os.date ( " %c " , self.resume_sec ) } )
end
self : put ( { _ ( " Up hours " ) ,
string.format ( " %.2f " , os.difftime ( os.time ( ) , self.start_sec ) / 60 / 60 ) } )
self : put ( { _ ( " Counters " ) , " " } )
self : put ( { _ ( " wake-ups " ) , self.wakeup_count } )
2019-08-24 07:25:38 +00:00
-- @translators The number of "sleeps", that is the number of times the device has entered standby. This could also be translated as a rendition of a phrase like "entered sleep".
2017-04-14 19:12:28 +00:00
self : put ( { _ ( " sleeps " ) , self.sleep_count } )
self : put ( { _ ( " charge cycles " ) , self.charge_count } )
self : put ( { _ ( " discharge cycles " ) , self.discharge_count } )
end
local function systemInfo ( )
local result = { }
do
local stat = io.open ( " /proc/stat " , " r " )
if stat ~= nil then
for line in util.gsplit ( stat : read ( " *all " ) , " \n " , false ) do
local t = util.splitToArray ( line , " " )
if # t >= 5 and string.lower ( t [ 1 ] ) == " cpu " then
local n1 , n2 , n3 , n4
n1 = tonumber ( t [ 2 ] )
n2 = tonumber ( t [ 3 ] )
n3 = tonumber ( t [ 4 ] )
n4 = tonumber ( t [ 5 ] )
if n1 ~= nil and n2 ~= nil and n3 ~= nil and n4 ~= nil then
result.cpu = {
user = n1 ,
nice = n2 ,
system = n3 ,
idle = n4 ,
total = n1 + n2 + n3 + n4
}
break
end
end
end
stat : close ( )
end
end
do
local meminfo = io.open ( " /proc/meminfo " , " r " )
if meminfo ~= nil then
result.memory = { }
for line in util.gsplit ( meminfo : read ( " *all " ) , " \n " , false ) do
local t = util.splitToArray ( line , " " )
if # t >= 2 then
if string.lower ( t [ 1 ] ) == " memtotal: " then
local n = tonumber ( t [ 2 ] )
if n ~= nil then
result.memory . total = n
end
elseif string.lower ( t [ 1 ] ) == " memfree: " then
local n = tonumber ( t [ 2 ] )
if n ~= nil then
result.memory . free = n
end
elseif string.lower ( t [ 1 ] ) == " memavailable: " then
local n = tonumber ( t [ 2 ] )
if n ~= nil then
result.memory . available = n
end
end
end
end
meminfo : close ( )
end
end
return result
end
function SystemStat : appendSystemInfo ( )
local stat = systemInfo ( )
if stat.cpu ~= nil then
self : put ( { _ ( " System information " ) , " " } )
2019-08-24 07:25:38 +00:00
-- @translators Ticks is a highly technical term. See https://superuser.com/a/101202 The correct translation is likely to simply be "ticks".
2017-04-14 19:12:28 +00:00
self : put ( { _ ( " Total ticks (million) " ) ,
string.format ( " %.2f " , stat.cpu . total / 1000000 ) } )
2019-08-24 07:25:38 +00:00
-- @translators Ticks is a highly technical term. See https://superuser.com/a/101202 The correct translation is likely to simply be "ticks".
2017-04-14 19:12:28 +00:00
self : put ( { _ ( " Idle ticks (million) " ) ,
string.format ( " %.2f " , stat.cpu . idle / 1000000 ) } )
self : put ( { _ ( " Processor usage % " ) ,
string.format ( " %.2f " , ( 1 - stat.cpu . idle / stat.cpu . total ) * 100 ) } )
end
if stat.memory ~= nil then
if stat.memory . total ~= nil then
self : put ( { _ ( " Total memory (MB) " ) ,
string.format ( " %.2f " , stat.memory . total / 1024 ) } )
end
if stat.memory . free ~= nil then
self : put ( { _ ( " Free memory (MB) " ) ,
string.format ( " %.2f " , stat.memory . free / 1024 ) } )
end
if stat.memory . available ~= nil then
self : put ( { _ ( " Available memory (MB) " ) ,
string.format ( " %.2f " , stat.memory . available / 1024 ) } )
end
end
end
function SystemStat : appendProcessInfo ( )
local stat = io.open ( " /proc/self/stat " , " r " )
if stat == nil then return end
local t = util.splitToArray ( stat : read ( " *all " ) , " " )
stat : close ( )
local n1 , n2
if # t == 0 then return end
self : put ( { _ ( " Process " ) , " " } )
self : put ( { _ ( " ID " ) , t [ 1 ] } )
if # t < 14 then return end
n1 = tonumber ( t [ 14 ] )
n2 = tonumber ( t [ 15 ] )
if n1 ~= nil then
if n2 ~= nil then
n1 = n1 + n2
end
local sys_stat = systemInfo ( )
if sys_stat.cpu ~= nil and sys_stat.cpu . total ~= nil then
self : put ( { _ ( " Processor usage % " ) ,
string.format ( " %.2f " , n1 / sys_stat.cpu . total * 100 ) } )
else
self : put ( { _ ( " Processor usage ticks (million) " ) , n1 / 1000000 } )
end
end
if # t < 20 then return end
n1 = tonumber ( t [ 20 ] )
if n1 ~= nil then
self : put ( { _ ( " Threads " ) , tostring ( n1 ) } )
end
if # t < 23 then return end
n1 = tonumber ( t [ 23 ] )
if n1 ~= nil then
self : put ( { _ ( " Virtual memory (MB) " ) , string.format ( " %.2f " , n1 / 1024 / 1024 ) } )
end
if # t < 24 then return end
n1 = tonumber ( t [ 24 ] )
if n1 ~= nil then
self : put ( { _ ( " RAM usage (MB) " ) , string.format ( " %.2f " , n1 / 256 ) } )
end
end
function SystemStat : appendStorageInfo ( )
if self.storage_filter == nil then return end
local std_out = io.popen (
" df -h | sed -r 's/ +/ /g' | grep " .. self.storage_filter ..
" | sed 's/ / \\ t/g' | cut -f 2,4,5,6 "
)
if not std_out then return end
self : put ( { _ ( " Storage information " ) , " " } )
for line in util.gsplit ( std_out : read ( " *all " ) , " \n " , false ) do
local t = util.splitToArray ( line , " \t " )
if # t ~= 4 then
self : put ( { _ ( " Unexpected " ) , line } )
else
self : put ( { _ ( " Mount point " ) , t [ 4 ] } )
self : put ( { _ ( " Available " ) , t [ 2 ] } )
self : put ( { _ ( " Total " ) , t [ 1 ] } )
self : put ( { _ ( " Used percentage " ) , t [ 3 ] } )
end
end
std_out : close ( )
end
2017-04-02 21:46:19 +00:00
function SystemStat : onSuspend ( )
2017-04-09 17:26:17 +00:00
self.suspend_sec = os.time ( )
2017-04-02 21:46:19 +00:00
self.sleep_count = self.sleep_count + 1
end
function SystemStat : onResume ( )
2017-04-09 17:26:17 +00:00
self.resume_sec = os.time ( )
2017-04-02 21:46:19 +00:00
self.wakeup_count = self.wakeup_count + 1
end
function SystemStat : onCharging ( )
self.charge_count = self.charge_count + 1
end
function SystemStat : onNotCharging ( )
self.discharge_count = self.discharge_count + 1
end
function SystemStat : showStatistics ( )
2017-04-14 19:12:28 +00:00
self.kv_pairs = { }
self : appendCounters ( )
self : appendProcessInfo ( )
self : appendStorageInfo ( )
self : appendSystemInfo ( )
2017-04-02 21:46:19 +00:00
UIManager : show ( KeyValuePage : new {
title = _ ( " System statistics " ) ,
2017-04-14 19:12:28 +00:00
kv_pairs = self.kv_pairs ,
2017-04-02 21:46:19 +00:00
} )
end
2017-04-14 19:12:28 +00:00
SystemStat : init ( )
2017-04-02 21:46:19 +00:00
local SystemStatWidget = WidgetContainer : new {
name = " systemstat " ,
}
function SystemStatWidget : init ( )
self.ui . menu : registerToMainMenu ( self )
end
function SystemStatWidget : addToMainMenu ( menu_items )
menu_items.system_statistics = {
text = _ ( " System statistics " ) ,
2018-09-04 21:55:58 +00:00
keep_menu_open = true ,
2017-04-02 21:46:19 +00:00
callback = function ( )
SystemStat : showStatistics ( )
end ,
}
end
function SystemStatWidget : onSuspend ( )
SystemStat : onSuspend ( )
end
function SystemStatWidget : onResume ( )
SystemStat : onResume ( )
end
function SystemStatWidget : onCharging ( )
SystemStat : onCharging ( )
end
function SystemStatWidget : onNotCharging ( )
SystemStat : onNotCharging ( )
end
return SystemStatWidget