add powermon_sim support

This commit is contained in:
Kevin Hester
2024-06-25 08:57:37 -07:00
parent 7ce7d73e89
commit 91066f6aed
6 changed files with 56 additions and 17 deletions

View File

@@ -2,4 +2,5 @@
from .power_supply import PowerMeter, PowerSupply, PowerError
from .riden import RidenPowerSupply
from .ppk2 import PPK2PowerSupply
from .ppk2 import PPK2PowerSupply
from .sim import SimPowerSupply

View File

@@ -3,8 +3,10 @@
import math
from datetime import datetime
class PowerError(Exception):
"""An exception class for powermon errors"""
def __init__(self, message):
self.message = message
super().__init__(self.message)
@@ -19,7 +21,7 @@ class PowerMeter:
self.prevWattHour = self._getRawWattHour()
def getWatts(self) -> float:
"""Get the total amount of power that has been consumed since the previous call of this method"""
"""Get the total amount of power that is currently being consumed."""
now = datetime.now()
nowWattHour = self._getRawWattHour()
watts = (
@@ -36,14 +38,13 @@ class PowerMeter:
return math.nan
class PowerSupply(PowerMeter):
"""Abstract class for power supplies."""
def __init__(self):
"""Initialize the PowerSupply object."""
super().__init__()
self.v = 3.3
self.v = 0.0
def powerOn(self):
"""Turn on the power supply (using the voltage set in self.v)."""

View File

@@ -4,8 +4,8 @@ import logging
from typing import *
from ppk2_api import ppk2_api
from .power_supply import PowerSupply, PowerError
from .power_supply import PowerError, PowerSupply
class PPK2PowerSupply(PowerSupply):
@@ -16,32 +16,47 @@ class PPK2PowerSupply(PowerSupply):
def __init__(self, portName: Optional[str] = None):
"""Initialize the PowerSupply object.
portName (str, optional): The port name of the power supply. Defaults to "/dev/ttyACM0".
portName (str, optional): The port name of the power supply. Defaults to "/dev/ttyACM0".
"""
if not portName:
devs = ppk2_api.PPK2_API.list_devices()
if not devs or len(devs) == 0:
raise PowerError("No PPK2 devices found")
elif len(devs) > 1:
raise PowerError("Multiple PPK2 devices found, please specify the portName")
raise PowerError(
"Multiple PPK2 devices found, please specify the portName"
)
else:
portName = devs[0]
self.r = r = ppk2_api.PPK2_MP(portName) # serial port will be different for you
r.get_modifiers()
self.r.start_measuring() # start measuring
logging.info("Connected to PPK2 power supply")
super().__init__() # we call this late so that the port is already open and _getRawWattHour callback works
super().__init__() # we call this late so that the port is already open and _getRawWattHour callback works
def setIsSupply(self, s: bool):
"""If in supply mode we will provide power ourself, otherwise we are just an amp meter."""
if (
not s
): # min power outpuf of PPK2. If less than this assume we want just meter mode.
self.r.use_ampere_meter()
else:
self.r.set_source_voltage(
int(self.v * 1000)
) # set source voltage in mV BEFORE setting source mode
self.r.use_source_meter() # set source meter mode
def powerOn(self):
"""Power on the supply, with reasonable defaults for meshtastic devices."""
self.r.use_source_meter() # set source meter mode
self.r.set_source_voltage(self.v * 1000) # set source voltage in mV
"""Power on the supply."""
self.r.toggle_DUT_power("ON")
self.r.start_measuring() # start measuring
def powerOff(self):
"""Power off the supply."""
self.r.toggle_DUT_power("OFF")
def _getRawWattHour(self) -> float:
"""Get the current watt-hour reading."""
return 4 # FIXME
return 4 # FIXME

View File

@@ -4,8 +4,10 @@ import logging
from datetime import datetime
from riden import Riden
from .power_supply import PowerSupply
class RidenPowerSupply(PowerSupply):
"""Interface for talking to Riden programmable bench-top power supplies.
Only RD6006 tested but others should be similar.
@@ -14,14 +16,14 @@ class RidenPowerSupply(PowerSupply):
def __init__(self, portName: str = "/dev/ttyUSB0"):
"""Initialize the RidenPowerSupply object.
portName (str, optional): The port name of the power supply. Defaults to "/dev/ttyUSB0".
portName (str, optional): The port name of the power supply. Defaults to "/dev/ttyUSB0".
"""
self.r = r = Riden(port=portName, baudrate=115200, address=1)
logging.info(
f"Connected to Riden power supply: model {r.type}, sn {r.sn}, firmware {r.fw}. Date/time updated."
)
r.set_date_time(datetime.now())
super().__init__() # we call this late so that the port is already open and _getRawWattHour callback works
super().__init__() # we call this late so that the port is already open and _getRawWattHour callback works
def setMaxCurrent(self, i: float):
"""Set the maximum current the supply will provide."""
@@ -29,7 +31,9 @@ class RidenPowerSupply(PowerSupply):
def powerOn(self):
"""Power on the supply, with reasonable defaults for meshtastic devices."""
self.r.set_v_set(self.v) # my WM1110 devboard header is directly connected to the 3.3V rail
self.r.set_v_set(
self.v
) # my WM1110 devboard header is directly connected to the 3.3V rail
self.r.set_output(1)
def _getRawWattHour(self) -> float:

View File

@@ -0,0 +1,17 @@
"""code logging power consumption of meshtastic devices."""
import math
import time
from typing import *
from .power_supply import PowerError, PowerSupply
class SimPowerSupply(PowerSupply):
"""A simulated power supply for testing."""
def getWatts(self) -> float:
"""Get the total amount of power that is currently being consumed."""
# Sim a 20mW load that varies sinusoidally
return (20 + 5 * math.sin(time.time())) / 1000

View File

@@ -23,9 +23,10 @@ pypubsub = "^4.0.3"
bleak = "^0.21.1"
packaging = "^24.0"
riden = { git = "https://github.com/geeksville/riden.git#1.2.1" }
pandas = "^2.2.2"
parse = "^1.20.2"
ppk2-api = "^0.9.2"
pyarrow = "^16.1.0"
pyarrow-stubs = "^10.0.1.7"
[tool.poetry.group.dev.dependencies]
hypothesis = "^6.103.2"