mirror of
https://github.com/koreader/koreader.git
synced 2025-12-24 12:14:05 +01:00
SystemStat: Show awake/suspend/standby breakdown in % (#9257)
Add an "awake" field in the process, and switch to `time` to prevent precision loss ;)
This commit is contained in:
@@ -7,6 +7,7 @@ local PowerD = require("device"):getPowerDevice()
|
|||||||
local UIManager = require("ui/uimanager")
|
local UIManager = require("ui/uimanager")
|
||||||
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||||
local dbg = require("dbg")
|
local dbg = require("dbg")
|
||||||
|
local time = require("ui/time")
|
||||||
local util = require("util")
|
local util = require("util")
|
||||||
local _ = require("gettext")
|
local _ = require("gettext")
|
||||||
|
|
||||||
@@ -18,13 +19,13 @@ function State:new(o)
|
|||||||
self.__index = self
|
self.__index = self
|
||||||
if o.percentage == nil or o.timestamp == nil then
|
if o.percentage == nil or o.timestamp == nil then
|
||||||
o.percentage = PowerD:getCapacityHW()
|
o.percentage = PowerD:getCapacityHW()
|
||||||
o.timestamp = os.time()
|
o.timestamp = time.boottime_or_realtime_coarse()
|
||||||
end
|
end
|
||||||
return o
|
return o
|
||||||
end
|
end
|
||||||
|
|
||||||
function State:toString()
|
function State:toString()
|
||||||
return string.format("{%d @ %s}", self.percentage, os.date("%c", self.timestamp))
|
return string.format("{%d @ %s}", self.percentage, os.date("%c", time.to_s(self.timestamp)))
|
||||||
end
|
end
|
||||||
|
|
||||||
local Usage = {}
|
local Usage = {}
|
||||||
@@ -44,14 +45,14 @@ end
|
|||||||
function Usage:append(state)
|
function Usage:append(state)
|
||||||
local curr = State:new()
|
local curr = State:new()
|
||||||
self.percentage = self.percentage + math.abs(state.percentage - curr.percentage)
|
self.percentage = self.percentage + math.abs(state.percentage - curr.percentage)
|
||||||
self.time = self.time + os.difftime(curr.timestamp - state.timestamp)
|
self.time = self.time + curr.timestamp - state.timestamp
|
||||||
end
|
end
|
||||||
|
|
||||||
function Usage:percentageRate()
|
function Usage:percentageRate()
|
||||||
if self.time == 0 then
|
if self.time == 0 then
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
return self.percentage / self.time
|
return self.percentage / time.to_s(self.time)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -84,7 +85,7 @@ end
|
|||||||
|
|
||||||
function Usage:dump(kv_pairs, id)
|
function Usage:dump(kv_pairs, id)
|
||||||
local name = id or _("Consumed:")
|
local name = id or _("Consumed:")
|
||||||
table.insert(kv_pairs, {INDENTATION .. _("Total time:"), duration(self.time) })
|
table.insert(kv_pairs, {INDENTATION .. _("Total time:"), duration(time.to_s(self.time)) })
|
||||||
table.insert(kv_pairs, {INDENTATION .. name, shorten(self.percentage), "%"})
|
table.insert(kv_pairs, {INDENTATION .. name, shorten(self.percentage), "%"})
|
||||||
table.insert(kv_pairs, {INDENTATION .. _("Change per hour:"), shorten(self:percentageRatePerHour())})
|
table.insert(kv_pairs, {INDENTATION .. _("Change per hour:"), shorten(self:percentageRatePerHour())})
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
local Device = require("device")
|
local Device = require("device")
|
||||||
local Dispatcher = require("dispatcher")
|
local Dispatcher = require("dispatcher")
|
||||||
local KeyValuePage = require("ui/widget/keyvaluepage")
|
local KeyValuePage = require("ui/widget/keyvaluepage")
|
||||||
|
local Math = require("optmath")
|
||||||
local UIManager = require("ui/uimanager")
|
local UIManager = require("ui/uimanager")
|
||||||
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
||||||
local time = require("ui/time")
|
local time = require("ui/time")
|
||||||
@@ -8,9 +9,10 @@ local util = require("util")
|
|||||||
local _ = require("gettext")
|
local _ = require("gettext")
|
||||||
|
|
||||||
local SystemStat = {
|
local SystemStat = {
|
||||||
start_sec = os.time(),
|
start_time = time.realtime(),
|
||||||
suspend_sec = nil,
|
start_monotonic_time = time.boottime_or_realtime_coarse(),
|
||||||
resume_sec = nil,
|
suspend_time = nil,
|
||||||
|
resume_time = nil,
|
||||||
wakeup_count = 0,
|
wakeup_count = 0,
|
||||||
sleep_count = 0,
|
sleep_count = 0,
|
||||||
charge_count = 0,
|
charge_count = 0,
|
||||||
@@ -27,6 +29,18 @@ function SystemStat:init()
|
|||||||
elseif Device:isSDL() then
|
elseif Device:isSDL() then
|
||||||
self.storage_filter = "/dev/sd"
|
self.storage_filter = "/dev/sd"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Account for a start-up mid-charge
|
||||||
|
local powerd = Device:getPowerDevice()
|
||||||
|
if Device:hasAuxBattery() and powerd:isAuxBatteryConnected() then
|
||||||
|
if powerd:isAuxCharging() and not powerd:isAuxCharged() then
|
||||||
|
self.charge_count = self.charge_count + 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if powerd:isCharging() and not powerd:isCharged() then
|
||||||
|
self.charge_count = self.charge_count + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SystemStat:put(p)
|
function SystemStat:put(p)
|
||||||
@@ -38,22 +52,39 @@ function SystemStat:putSeparator()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function SystemStat:appendCounters()
|
function SystemStat:appendCounters()
|
||||||
self:put({_("KOReader started at"), os.date("%c", self.start_sec)})
|
self:put({_("KOReader started at"), os.date("%c", time.to_s(self.start_time))})
|
||||||
if self.suspend_sec then
|
if self.suspend_time then
|
||||||
self:put({_(" Last suspend time"), os.date("%c", self.suspend_sec)})
|
self:put({_(" Last suspend time"), os.date("%c", time.to_s(self.suspend_time))})
|
||||||
end
|
end
|
||||||
if self.resume_sec then
|
if self.resume_time then
|
||||||
self:put({_(" Last resume time"), os.date("%c", self.resume_sec)})
|
self:put({_(" Last resume time"), os.date("%c", time.to_s(self.resume_time))})
|
||||||
|
end
|
||||||
|
local uptime = time.boottime_or_realtime_coarse() - self.start_monotonic_time
|
||||||
|
local suspend = 0
|
||||||
|
if Device:canSuspend() then
|
||||||
|
suspend = Device.total_suspend_time
|
||||||
|
end
|
||||||
|
local standby = 0
|
||||||
|
if Device:canStandby() then
|
||||||
|
standby = Device.total_standby_time
|
||||||
end
|
end
|
||||||
self:put({" " .. _("Up time"),
|
self:put({" " .. _("Up time"),
|
||||||
util.secondsToClockDuration("", os.difftime(os.time(), self.start_sec), false, true, true)})
|
util.secondsToClockDuration("", time.to_s(uptime), false, true, true)})
|
||||||
|
if Device:canSuspend() or Device:canStandby() then
|
||||||
|
local awake = uptime - suspend - standby
|
||||||
|
self:put({" " .. _("Time spent awake"),
|
||||||
|
util.secondsToClockDuration("", time.to_s(awake), false, true, true)
|
||||||
|
.. " (" .. Math.round((awake / uptime) * 100) .. "%)"})
|
||||||
|
end
|
||||||
if Device:canSuspend() then
|
if Device:canSuspend() then
|
||||||
self:put({" " .. _("Time in suspend"),
|
self:put({" " .. _("Time in suspend"),
|
||||||
util.secondsToClockDuration("", time.to_number(Device.total_suspend_time), false, true, true)})
|
util.secondsToClockDuration("", time.to_s(suspend), false, true, true)
|
||||||
|
.. " (" .. Math.round((suspend / uptime) * 100) .. "%)"})
|
||||||
end
|
end
|
||||||
if Device:canStandby() then
|
if Device:canStandby() then
|
||||||
self:put({" " .. _("Time in standby"),
|
self:put({" " .. _("Time in standby"),
|
||||||
util.secondsToClockDuration("", time.to_number(Device.total_standby_time), false, true, true)})
|
util.secondsToClockDuration("", time.to_s(standby), false, true, true)
|
||||||
|
.. " (" .. Math.round((standby / uptime) * 100) .. "%)"})
|
||||||
end
|
end
|
||||||
self:put({_("Counters"), ""})
|
self:put({_("Counters"), ""})
|
||||||
self:put({_(" wake-ups"), self.wakeup_count})
|
self:put({_(" wake-ups"), self.wakeup_count})
|
||||||
@@ -226,12 +257,12 @@ function SystemStat:appendStorageInfo()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function SystemStat:onSuspend()
|
function SystemStat:onSuspend()
|
||||||
self.suspend_sec = os.time()
|
self.suspend_time = time.realtime()
|
||||||
self.sleep_count = self.sleep_count + 1
|
self.sleep_count = self.sleep_count + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
function SystemStat:onResume()
|
function SystemStat:onResume()
|
||||||
self.resume_sec = os.time()
|
self.resume_time = time.realtime()
|
||||||
self.wakeup_count = self.wakeup_count + 1
|
self.wakeup_count = self.wakeup_count + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
describe("BatteryState plugin tests #nocov", function()
|
describe("BatteryState plugin tests #nocov", function()
|
||||||
local MockTime, module
|
local MockTime, module, time
|
||||||
|
|
||||||
local stat = function() --luacheck: ignore
|
local stat = function() --luacheck: ignore
|
||||||
return module:new():stat()
|
return module:new():stat()
|
||||||
@@ -9,6 +9,7 @@ describe("BatteryState plugin tests #nocov", function()
|
|||||||
require("commonrequire")
|
require("commonrequire")
|
||||||
package.unloadAll()
|
package.unloadAll()
|
||||||
require("document/canvascontext"):init(require("device"))
|
require("document/canvascontext"):init(require("device"))
|
||||||
|
time = require("ui/time")
|
||||||
MockTime = require("mock_time")
|
MockTime = require("mock_time")
|
||||||
MockTime:install()
|
MockTime:install()
|
||||||
end)
|
end)
|
||||||
@@ -30,9 +31,9 @@ describe("BatteryState plugin tests #nocov", function()
|
|||||||
widget:resetAll()
|
widget:resetAll()
|
||||||
MockTime:increase(1)
|
MockTime:increase(1)
|
||||||
widget:accumulate()
|
widget:accumulate()
|
||||||
assert.are.equal(1, widget.awake.time)
|
assert.are.equal(time.s(1), widget.awake.time)
|
||||||
assert.are.equal(0, widget.sleeping.time)
|
assert.are.equal(0, widget.sleeping.time)
|
||||||
assert.are.equal(1, widget.discharging.time)
|
assert.are.equal(time.s(1), widget.discharging.time)
|
||||||
assert.are.equal(0, widget.charging.time)
|
assert.are.equal(0, widget.charging.time)
|
||||||
|
|
||||||
widget:onCharging()
|
widget:onCharging()
|
||||||
@@ -44,7 +45,7 @@ describe("BatteryState plugin tests #nocov", function()
|
|||||||
assert.are.equal(0, widget.awake.time)
|
assert.are.equal(0, widget.awake.time)
|
||||||
assert.are.equal(0, widget.sleeping.time)
|
assert.are.equal(0, widget.sleeping.time)
|
||||||
assert.are.equal(0, widget.discharging.time)
|
assert.are.equal(0, widget.discharging.time)
|
||||||
assert.are.equal(1, widget.charging.time)
|
assert.are.equal(time.s(1), widget.charging.time)
|
||||||
|
|
||||||
widget:onNotCharging()
|
widget:onNotCharging()
|
||||||
assert.is_false(widget.was_charging)
|
assert.is_false(widget.was_charging)
|
||||||
@@ -52,10 +53,10 @@ describe("BatteryState plugin tests #nocov", function()
|
|||||||
MockTime:increase(1)
|
MockTime:increase(1)
|
||||||
widget:accumulate()
|
widget:accumulate()
|
||||||
-- awake & discharging time should be reset.
|
-- awake & discharging time should be reset.
|
||||||
assert.are.equal(1, widget.awake.time)
|
assert.are.equal(time.s(1), widget.awake.time)
|
||||||
assert.are.equal(0, widget.sleeping.time)
|
assert.are.equal(0, widget.sleeping.time)
|
||||||
assert.are.equal(1, widget.discharging.time)
|
assert.are.equal(time.s(1), widget.discharging.time)
|
||||||
assert.are.equal(1, widget.charging.time)
|
assert.are.equal(time.s(1), widget.charging.time)
|
||||||
|
|
||||||
widget:onCharging()
|
widget:onCharging()
|
||||||
assert.is_true(widget.was_charging)
|
assert.is_true(widget.was_charging)
|
||||||
@@ -66,7 +67,7 @@ describe("BatteryState plugin tests #nocov", function()
|
|||||||
assert.are.equal(0, widget.awake.time)
|
assert.are.equal(0, widget.awake.time)
|
||||||
assert.are.equal(0, widget.sleeping.time)
|
assert.are.equal(0, widget.sleeping.time)
|
||||||
assert.are.equal(0, widget.discharging.time)
|
assert.are.equal(0, widget.discharging.time)
|
||||||
assert.are.equal(1, widget.charging.time)
|
assert.are.equal(time.s(1), widget.charging.time)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("should record suspending time", function()
|
it("should record suspending time", function()
|
||||||
@@ -76,9 +77,9 @@ describe("BatteryState plugin tests #nocov", function()
|
|||||||
widget:resetAll()
|
widget:resetAll()
|
||||||
MockTime:increase(1)
|
MockTime:increase(1)
|
||||||
widget:accumulate()
|
widget:accumulate()
|
||||||
assert.are.equal(1, widget.awake.time)
|
assert.are.equal(time.s(1), widget.awake.time)
|
||||||
assert.are.equal(0, widget.sleeping.time)
|
assert.are.equal(0, widget.sleeping.time)
|
||||||
assert.are.equal(1, widget.discharging.time)
|
assert.are.equal(time.s(1), widget.discharging.time)
|
||||||
assert.are.equal(0, widget.charging.time)
|
assert.are.equal(0, widget.charging.time)
|
||||||
|
|
||||||
widget:onSuspend()
|
widget:onSuspend()
|
||||||
@@ -86,9 +87,9 @@ describe("BatteryState plugin tests #nocov", function()
|
|||||||
assert.is_true(widget.was_suspending)
|
assert.is_true(widget.was_suspending)
|
||||||
MockTime:increase(1)
|
MockTime:increase(1)
|
||||||
widget:accumulate()
|
widget:accumulate()
|
||||||
assert.are.equal(1, widget.awake.time)
|
assert.are.equal(time.s(1), widget.awake.time)
|
||||||
assert.are.equal(1, widget.sleeping.time)
|
assert.are.equal(time.s(1), widget.sleeping.time)
|
||||||
assert.are.equal(2, widget.discharging.time)
|
assert.are.equal(time.s(2), widget.discharging.time)
|
||||||
assert.are.equal(0, widget.charging.time)
|
assert.are.equal(0, widget.charging.time)
|
||||||
|
|
||||||
widget:onResume()
|
widget:onResume()
|
||||||
@@ -96,9 +97,9 @@ describe("BatteryState plugin tests #nocov", function()
|
|||||||
assert.is_false(widget.was_suspending)
|
assert.is_false(widget.was_suspending)
|
||||||
MockTime:increase(1)
|
MockTime:increase(1)
|
||||||
widget:accumulate()
|
widget:accumulate()
|
||||||
assert.are.equal(2, widget.awake.time)
|
assert.are.equal(time.s(2), widget.awake.time)
|
||||||
assert.are.equal(1, widget.sleeping.time)
|
assert.are.equal(time.s(1), widget.sleeping.time)
|
||||||
assert.are.equal(3, widget.discharging.time)
|
assert.are.equal(time.s(3), widget.discharging.time)
|
||||||
assert.are.equal(0, widget.charging.time)
|
assert.are.equal(0, widget.charging.time)
|
||||||
|
|
||||||
widget:onSuspend()
|
widget:onSuspend()
|
||||||
@@ -106,9 +107,9 @@ describe("BatteryState plugin tests #nocov", function()
|
|||||||
assert.is_true(widget.was_suspending)
|
assert.is_true(widget.was_suspending)
|
||||||
MockTime:increase(1)
|
MockTime:increase(1)
|
||||||
widget:accumulate()
|
widget:accumulate()
|
||||||
assert.are.equal(2, widget.awake.time)
|
assert.are.equal(time.s(2), widget.awake.time)
|
||||||
assert.are.equal(2, widget.sleeping.time)
|
assert.are.equal(time.s(2), widget.sleeping.time)
|
||||||
assert.are.equal(4, widget.discharging.time)
|
assert.are.equal(time.s(4), widget.discharging.time)
|
||||||
assert.are.equal(0, widget.charging.time)
|
assert.are.equal(0, widget.charging.time)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -119,9 +120,9 @@ describe("BatteryState plugin tests #nocov", function()
|
|||||||
widget:resetAll()
|
widget:resetAll()
|
||||||
MockTime:increase(1)
|
MockTime:increase(1)
|
||||||
widget:accumulate()
|
widget:accumulate()
|
||||||
assert.are.equal(1, widget.awake.time)
|
assert.are.equal(time.s(1), widget.awake.time)
|
||||||
assert.are.equal(0, widget.sleeping.time)
|
assert.are.equal(0, widget.sleeping.time)
|
||||||
assert.are.equal(1, widget.discharging.time)
|
assert.are.equal(time.s(1), widget.discharging.time)
|
||||||
assert.are.equal(0, widget.charging.time)
|
assert.are.equal(0, widget.charging.time)
|
||||||
|
|
||||||
widget:onCharging()
|
widget:onCharging()
|
||||||
@@ -133,7 +134,7 @@ describe("BatteryState plugin tests #nocov", function()
|
|||||||
assert.are.equal(0, widget.awake.time)
|
assert.are.equal(0, widget.awake.time)
|
||||||
assert.are.equal(0, widget.sleeping.time)
|
assert.are.equal(0, widget.sleeping.time)
|
||||||
assert.are.equal(0, widget.discharging.time)
|
assert.are.equal(0, widget.discharging.time)
|
||||||
assert.are.equal(1, widget.charging.time)
|
assert.are.equal(time.s(1), widget.charging.time)
|
||||||
|
|
||||||
widget:onCharging()
|
widget:onCharging()
|
||||||
assert.is_true(widget.was_charging)
|
assert.is_true(widget.was_charging)
|
||||||
@@ -143,7 +144,7 @@ describe("BatteryState plugin tests #nocov", function()
|
|||||||
assert.are.equal(0, widget.awake.time)
|
assert.are.equal(0, widget.awake.time)
|
||||||
assert.are.equal(0, widget.sleeping.time)
|
assert.are.equal(0, widget.sleeping.time)
|
||||||
assert.are.equal(0, widget.discharging.time)
|
assert.are.equal(0, widget.discharging.time)
|
||||||
assert.are.equal(2, widget.charging.time)
|
assert.are.equal(time.s(2), widget.charging.time)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("should not swap the state when several suspending events fired", function()
|
it("should not swap the state when several suspending events fired", function()
|
||||||
@@ -153,9 +154,9 @@ describe("BatteryState plugin tests #nocov", function()
|
|||||||
widget:resetAll()
|
widget:resetAll()
|
||||||
MockTime:increase(1)
|
MockTime:increase(1)
|
||||||
widget:accumulate()
|
widget:accumulate()
|
||||||
assert.are.equal(1, widget.awake.time)
|
assert.are.equal(time.s(1), widget.awake.time)
|
||||||
assert.are.equal(0, widget.sleeping.time)
|
assert.are.equal(0, widget.sleeping.time)
|
||||||
assert.are.equal(1, widget.discharging.time)
|
assert.are.equal(time.s(1), widget.discharging.time)
|
||||||
assert.are.equal(0, widget.charging.time)
|
assert.are.equal(0, widget.charging.time)
|
||||||
|
|
||||||
widget:onSuspend()
|
widget:onSuspend()
|
||||||
@@ -163,9 +164,9 @@ describe("BatteryState plugin tests #nocov", function()
|
|||||||
assert.is_true(widget.was_suspending)
|
assert.is_true(widget.was_suspending)
|
||||||
MockTime:increase(1)
|
MockTime:increase(1)
|
||||||
widget:accumulate()
|
widget:accumulate()
|
||||||
assert.are.equal(1, widget.awake.time)
|
assert.are.equal(time.s(1), widget.awake.time)
|
||||||
assert.are.equal(1, widget.sleeping.time)
|
assert.are.equal(time.s(1), widget.sleeping.time)
|
||||||
assert.are.equal(2, widget.discharging.time)
|
assert.are.equal(time.s(2), widget.discharging.time)
|
||||||
assert.are.equal(0, widget.charging.time)
|
assert.are.equal(0, widget.charging.time)
|
||||||
|
|
||||||
widget:onSuspend()
|
widget:onSuspend()
|
||||||
@@ -173,9 +174,9 @@ describe("BatteryState plugin tests #nocov", function()
|
|||||||
assert.is_true(widget.was_suspending)
|
assert.is_true(widget.was_suspending)
|
||||||
MockTime:increase(1)
|
MockTime:increase(1)
|
||||||
widget:accumulate()
|
widget:accumulate()
|
||||||
assert.are.equal(1, widget.awake.time)
|
assert.are.equal(time.s(1), widget.awake.time)
|
||||||
assert.are.equal(2, widget.sleeping.time)
|
assert.are.equal(time.s(2), widget.sleeping.time)
|
||||||
assert.are.equal(3, widget.discharging.time)
|
assert.are.equal(time.s(3), widget.discharging.time)
|
||||||
assert.are.equal(0, widget.charging.time)
|
assert.are.equal(0, widget.charging.time)
|
||||||
|
|
||||||
widget:onSuspend()
|
widget:onSuspend()
|
||||||
@@ -183,9 +184,9 @@ describe("BatteryState plugin tests #nocov", function()
|
|||||||
assert.is_true(widget.was_suspending)
|
assert.is_true(widget.was_suspending)
|
||||||
MockTime:increase(1)
|
MockTime:increase(1)
|
||||||
widget:accumulate()
|
widget:accumulate()
|
||||||
assert.are.equal(1, widget.awake.time)
|
assert.are.equal(time.s(1), widget.awake.time)
|
||||||
assert.are.equal(3, widget.sleeping.time)
|
assert.are.equal(time.s(3), widget.sleeping.time)
|
||||||
assert.are.equal(4, widget.discharging.time)
|
assert.are.equal(time.s(4), widget.discharging.time)
|
||||||
assert.are.equal(0, widget.charging.time)
|
assert.are.equal(0, widget.charging.time)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|||||||
Reference in New Issue
Block a user