mirror of
https://github.com/meshtastic/python.git
synced 2025-12-30 03:17:54 -05:00
add powermon_sim support
This commit is contained in:
@@ -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
|
||||
@@ -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)."""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
17
meshtastic/powermon/sim.py
Normal file
17
meshtastic/powermon/sim.py
Normal 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
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user