(eventually I'll move this someplace better - but placing it here for feedback from other meshtastic devs)
different PM states can either be on or off.
changes to PM states are logged for eventual CVS annotation (with measured power consumption)
multiple PM on/off states can exist at a time.
the log messages will be short and complete (see PowerMon.Event in the protobufs for details). something like "PwrMon,C,0x00001234,REASON" where the hex number is the bitmask of all current states. (We use a bitmask for states so that if a log message gets lost it won't be fatal)
a PwrMon message will be emitted for each state change (so an xor of old mask and new mask should indicate which changed)
If a time is known it will be included in the log message header, so there is no need to include time in PowerMon.Event
We serialize the messages as simple text to avoid any dependence on the meshtastic messaging layer (which we might be measuring with this)
PowerMon support can be included in the build via the -DUSE_POWERMON definition. If it is not included the class will still exist but the methods will be NOPs. So interested devs can easily add PowerMon tags as needed (with no runtime cost for users)
If -DUSE_POWERSTRESS is defined the board will automatically walk through a series of power changing actions in hopes of generating a standard/repeatable power report for that particular board type. Eventually: instead have the python code call send a message to the PowerStress class (so we don't need to build particular 'powerstress' builds). Similar to the GPIO by message access we already have (possibly with identical python glue).
PowerMon.clearState(PowerState.DeepSleep, "user released button)
Users should try to call setState/clearState just before/after and significant power consuming device changes. It is assumed that the python code will slightly delay after receiving the log message (100ms?) before capturing the power meter measurement.
PowerStress class
Uses timers to walk the node through a number of different states (using the existing state machine and message sending APIs).
Intended to generate a 'repeatable' powermon report that can be used eventually to prevent regressions in our power management.
While testing if we want to test RX performance without needing a faraday cage, add support for changing the lora framing byte to something non-standard. omg - I'm tired of random SF nodes talking to my test units ;-).
PowerMon states
Use protobuf enums to define these states, so that python and device code can share definitions. Any eng can add new states by just adding a new enum value.
PM0 CPU-DeepSleep
PM1 CPU-Sleep
PM2 CPU-Awake
PM3 Lora-RXOn
PM4 Lora-TXOn
PM5 Lora-RXActive
PM6 BT-On
PM7 LED-On
PM8 Screen-On
PM9 Screen-Drawing
etc...
Runtime report collection
The meshtastic python tool ('meshtastic --powermon') will collect all PM log messages and at the end of the run emit report csv files to powermon//foo.csv. The idea here is that you can just always leave this option set and the data files will go to 'the right place'.
If a power supply is connected to python it will set the power supply to the correct voltage for tests/usage.
If --powerstress is specified it will direct the unit under test (via meshtastic API messages) to enter different test configs for measurement. It will dump report files to powermon//stress/foo.csv. These files will be highly standardized so we can eventually detect regressions.
If a programmable bench supply is connected (initially only Riden supplies are supported), measured power will be included on all rows
If a programmable bench supply is connected we Will export a new record every 100ms even if there are no state changes (to capture measured power levels)
CSV report format
A row heading will be emitted based on the protobuf defs (so spreadsheet will have nice names)
Data rows
time (as decimal seconds, i.e. 4.44 or Unix epoch seconds)
measured power or emptystring
reason or emptystring
pm0 state
pm1 state
etc...
CSV summary report
Summary report (generated afterwards from that csv)
% time on for each of the different states
Somehow try to decouple average power consumption due to each PwrMon state. Perhaps:
Have the python code look 200msish after a transition and do something like powerDueToState = currentPower - preStatePower
Somehow include deviation for each of these power per state estimates, so we can know if we need to capture longer runs.
Graph results
Possibly use excel, but probably plottly-express (i.e. python) to make a nice graph showing stacked bars for states and the total height of the bars be based on the measured power. Each state segment in the bar will be sized based on average power consumption attributed to that state alone.
Structured log messages
We have defined a mini standard for log messages that are intended for machine parsing. We do this in the hopes that these messages will remain mostly stable for use over a long time (i.e. old logs can be compared to new for regression testing).
The standard designed to be short and easily machine parsable. The format for these messages must be:
S:SUBSYS:arg1,arg2,arg3,...
Where "S:" is a string constant prefix always used on such messages. Current defined subsystems:
B: Board info boot message (contains hw model code and sw version)
PM: PowerMon
Current notes-to-self TODO:
DONE use config flag to control powermon
DONE refactor the python power meter classes
DONE add powerstress framework for setting configs, cycling power
add default slog destination based on board type. auto start slogging when we see the board announcement
PowerMon
(eventually I'll move this someplace better - but placing it here for feedback from other meshtastic devs)
On device API
PowerMon class
Users should try to call setState/clearState just before/after and significant power consuming device changes. It is assumed that the python code will slightly delay after receiving the log message (100ms?) before capturing the power meter measurement.
PowerStress class
PowerMon states
Use protobuf enums to define these states, so that python and device code can share definitions. Any eng can add new states by just adding a new enum value.
etc...
Runtime report collection
CSV report format
A row heading will be emitted based on the protobuf defs (so spreadsheet will have nice names)
Data rows
CSV summary report
Summary report (generated afterwards from that csv)
Graph results
Possibly use excel, but probably plottly-express (i.e. python) to make a nice graph showing stacked bars for states and the total height of the bars be based on the measured power. Each state segment in the bar will be sized based on average power consumption attributed to that state alone.
Structured log messages
We have defined a mini standard for log messages that are intended for machine parsing. We do this in the hopes that these messages will remain mostly stable for use over a long time (i.e. old logs can be compared to new for regression testing).
The standard designed to be short and easily machine parsable. The format for these messages must be:
S:SUBSYS:arg1,arg2,arg3,...
Where "S:" is a string constant prefix always used on such messages. Current defined subsystems:
Current notes-to-self TODO: