moving to python logging infrastructure

This commit is contained in:
pelikhan 2022-06-27 08:58:10 -07:00
Родитель 6b8cbbf0cb
Коммит 1eeb00cf16
4 изменённых файлов: 57 добавлений и 47 удалений

Просмотреть файл

@ -4,6 +4,8 @@ from time import sleep
if __name__ == '__main__': if __name__ == '__main__':
def main(): def main():
from logging import basicConfig, INFO
basicConfig(level=INFO)
bus = Bus() bus = Bus()
led = LedClient(bus, "led") led = LedClient(bus, "led")
led.brightness = 0.5 led.brightness = 0.5
@ -13,7 +15,7 @@ if __name__ == '__main__':
led.set_all((255, 0, 0)) led.set_all((255, 0, 0))
sleep(1) sleep(1)
# off # off
led.set_all((0,0,0)) led.set_all((0, 0, 0))
sleep(1) sleep(1)
main() main()

Просмотреть файл

@ -1,6 +1,7 @@
from abc import abstractmethod from abc import abstractmethod
from asyncio.tasks import Task from asyncio.tasks import Task
from configparser import ConfigParser from configparser import ConfigParser
from logging import getLogger, DEBUG, INFO, WARNING, ERROR, NOTSET
import threading import threading
import asyncio import asyncio
import queue import queue
@ -24,7 +25,7 @@ from .unique_brain.constants import *
from .packet import * from .packet import *
from .transport import Transport from .transport import Transport
from .util import now, log, logv from .util import now, info, debug
from .pack import PackTuple, PackType, jdpack, jdunpack from .pack import PackTuple, PackType, jdpack, jdunpack
EV_CHANGE = "change" EV_CHANGE = "change"
@ -158,7 +159,7 @@ class EventEmitter:
if logger: if logger:
logger.report(priority, msg, *args) logger.report(priority, msg, *args)
def log(self, text: str, *args: object): def info(self, text: str, *args: object):
self._add_log_report(LoggerPriority.LOG, text, *args) self._add_log_report(LoggerPriority.LOG, text, *args)
def warn(self, text: str, *args: object): def warn(self, text: str, *args: object):
@ -180,18 +181,23 @@ def _service_matches(dev: 'Device', serv: bytearray):
return False return False
return True return True
def rand_u64(): def rand_u64():
return bytearray([getrandbits(8) for _ in range(8)]) return bytearray([getrandbits(8) for _ in range(8)])
def is_raspberrypi(): def is_raspberrypi():
# https://raspberrypi.stackexchange.com/questions/5100/detect-that-a-python-program-is-running-on-the-pi # https://raspberrypi.stackexchange.com/questions/5100/detect-that-a-python-program-is-running-on-the-pi
try: try:
from io import open from io import open
with open('/sys/firmware/devicetree/base/model', 'r') as m: with open('/sys/firmware/devicetree/base/model', 'r') as m:
if 'raspberry pi' in m.read().lower(): return True if 'raspberry pi' in m.read().lower():
except Exception: pass return True
except Exception:
pass
return False return False
class Bus(EventEmitter): class Bus(EventEmitter):
"""A Jacdac bus that managed devices, service client, registers.""" """A Jacdac bus that managed devices, service client, registers."""
@ -245,7 +251,8 @@ class Bus(EventEmitter):
# merge .ctor configuration with files # merge .ctor configuration with files
config = ConfigParser() config = ConfigParser()
config.read(["./jacdac.ini", os.path.expanduser("~") + "/.jacdac/config.ini", "./setup.cfg"]) config.read(["./jacdac.ini", os.path.expanduser("~") +
"/.jacdac/config.ini", "./setup.cfg"])
if not config.has_section("jacdac"): if not config.has_section("jacdac"):
cfg = config.add_section("jacdac") cfg = config.add_section("jacdac")
cfg = config["jacdac"] cfg = config["jacdac"]
@ -288,7 +295,7 @@ class Bus(EventEmitter):
self.transports.append(ExecTransport(self.transport_cmd)) self.transports.append(ExecTransport(self.transport_cmd))
if self.hf2_portname: if self.hf2_portname:
from .transports.hf2 import HF2Transport from .transports.hf2 import HF2Transport
self.transports.append(HF2Transport(self.hf2_portname)) self.transports.append(HF2Transport(self.hf2_portname))
if self.spi: if self.spi:
from .transports.spi import SpiTransport from .transports.spi import SpiTransport
self.transports.append(SpiTransport()) self.transports.append(SpiTransport())
@ -311,7 +318,7 @@ class Bus(EventEmitter):
self.process_thread.start() self.process_thread.start()
print("starting jacdac, self device {}".format(self.self_device)) info("starting jacdac, self device {}".format(self.self_device))
def run(self, cb: Callable[..., None], *args: Any): def run(self, cb: Callable[..., None], *args: Any):
if self.process_thread is threading.current_thread(): if self.process_thread is threading.current_thread():
@ -390,10 +397,10 @@ class Bus(EventEmitter):
while ptr < 12 + frame[2]: while ptr < 12 + frame[2]:
sz = frame[ptr] + 4 sz = frame[ptr] + 4
pktbytes = frame[0:12] + frame[ptr:ptr+sz] pktbytes = frame[0:12] + frame[ptr:ptr+sz]
# log("PKT: {}-{} / {}", ptr, len(frame), pktbytes.hex()) # info("PKT: {}-{} / {}", ptr, len(frame), pktbytes.hex())
pkt = JDPacket(frombytes=pktbytes, sender=sender) pkt = JDPacket(frombytes=pktbytes, sender=sender)
if ptr > 12: if ptr > 12:
pkt.requires_ack = False # only ack once pkt.requires_ack = False # only ack once
self.process_packet(pkt) self.process_packet(pkt)
# dispatch to other transports # dispatch to other transports
self._queue_core(pkt) self._queue_core(pkt)
@ -504,7 +511,7 @@ class Bus(EventEmitter):
break break
def process_packet(self, pkt: JDPacket): def process_packet(self, pkt: JDPacket):
logv("route: {}", pkt) debug("route: {}", pkt)
dev_id = pkt.device_id dev_id = pkt.device_id
multi_command_class = pkt.multicommand_class multi_command_class = pkt.multicommand_class
service_index = pkt.service_index service_index = pkt.service_index
@ -540,7 +547,7 @@ class Bus(EventEmitter):
elif dev_id == self.self_device.device_id and pkt.is_command: elif dev_id == self.self_device.device_id and pkt.is_command:
h = self.servers[pkt.service_index] h = self.servers[pkt.service_index]
if h: if h:
# log(`handle pkt at ${h.name} cmd=${pkt.service_command}`) # info(`handle pkt at ${h.name} cmd=${pkt.service_command}`)
h.handle_packet_outer(pkt) h.handle_packet_outer(pkt)
else: else:
if pkt.is_command: if pkt.is_command:
@ -1011,7 +1018,7 @@ class ControlServer(Server):
self.auto_bind_cnt = 0 self.auto_bind_cnt = 0
def queue_announce(self): def queue_announce(self):
logv("announce: %d " % self.restart_counter) debug("announce: %d " % self.restart_counter)
self.restart_counter += 1 self.restart_counter += 1
ids = [s.service_class for s in self.bus. servers] ids = [s.service_class for s in self.bus. servers]
rest = self.restart_counter rest = self.restart_counter
@ -1109,7 +1116,8 @@ class LoggerServer(Server):
def report(self, priority: int, msg: str, *args: object): def report(self, priority: int, msg: str, *args: object):
if priority >= self.min_priority: if priority >= self.min_priority:
log(msg, *args) info(msg, *args)
cmd: int = -1 cmd: int = -1
if priority == LoggerPriority.DEBUG: if priority == LoggerPriority.DEBUG:
cmd = JD_LOGGER_CMD_DEBUG cmd = JD_LOGGER_CMD_DEBUG
@ -1117,7 +1125,7 @@ class LoggerServer(Server):
cmd = JD_LOGGER_CMD_LOG cmd = JD_LOGGER_CMD_LOG
elif priority == LoggerPriority.WARNING: elif priority == LoggerPriority.WARNING:
cmd = JD_LOGGER_CMD_WARN cmd = JD_LOGGER_CMD_WARN
elif priority == JD_LOGGER_CMD_ERROR: elif priority == JD_LOGGER_CMD_ERROR:
cmd = JD_LOGGER_CMD_ERROR cmd = JD_LOGGER_CMD_ERROR
else: else:
return return
@ -1781,10 +1789,11 @@ class Device(EventEmitter):
for c in self.clients: for c in self.clients:
if (c.broadcast and c.service_class == service_class) or \ if (c.broadcast and c.service_class == service_class) or \
(not c.broadcast and c.service_index == pkt.service_index): (not c.broadcast and c.service_index == pkt.service_index):
# log(`handle pkt at ${client.role} rep=${pkt.serviceCommand}`) # info(`handle pkt at ${client.role} rep=${pkt.serviceCommand}`)
c.device = self c.device = self
c.handle_packet_outer(pkt) c.handle_packet_outer(pkt)
class BufferClient(Client): class BufferClient(Client):
_value: bytearray _value: bytearray
_dirty: bool _dirty: bool
@ -1792,12 +1801,13 @@ class BufferClient(Client):
""" """
A client that handles a double-buffer bytes buffer A client that handles a double-buffer bytes buffer
""" """
def __init__(self, bus: Bus, service_class: int, pack_formats: Dict[int, str], role: str) -> None: def __init__(self, bus: Bus, service_class: int, pack_formats: Dict[int, str], role: str) -> None:
super().__init__(bus, service_class, pack_formats, role) super().__init__(bus, service_class, pack_formats, role)
self._value = bytearray(0) self._value = bytearray(0)
self._dirty = False self._dirty = False
@property @property
def value(self) -> bytearray: def value(self) -> bytearray:
""" """
@ -1816,10 +1826,10 @@ class BufferClient(Client):
@property @property
def dirty(self) -> bool: def dirty(self) -> bool:
return self._dirty return self._dirty
def set_dirty(self) -> None: def set_dirty(self) -> None:
self._dirty = True self._dirty = True
def refresh_value(self) -> None: def refresh_value(self) -> None:
if self._dirty: if self._dirty:
self.register(JD_REG_VALUE).set_values(self._value) self.register(JD_REG_VALUE).set_values(self._value)
@ -1833,7 +1843,5 @@ class BufferClient(Client):
self._value = self._value + bytearray(length - l) self._value = self._value + bytearray(length - l)
self._dirty = True self._dirty = True
else: else:
self._value = self._value[0:length -1] self._value = self._value[0:length - 1]
self._dirty = True self._dirty = True

Просмотреть файл

@ -4,7 +4,7 @@ from typing import List, Optional
from time import sleep, monotonic from time import sleep, monotonic
from tokenize import Number from tokenize import Number
from jacdac.transport import Transport from jacdac.transport import Transport
from jacdac.util import buf2hex, hex2buf, now from jacdac.util import buf2hex, hex2buf, debug, now
from gpiod import Chip, Line, LineBulk, LINE_REQ_EV_RISING_EDGE, LINE_REQ_FLAG_ACTIVE_LOW, LINE_REQ_DIR_OUT # type: ignore from gpiod import Chip, Line, LineBulk, LINE_REQ_EV_RISING_EDGE, LINE_REQ_FLAG_ACTIVE_LOW, LINE_REQ_DIR_OUT # type: ignore
from spidev import SpiDev # type: ignore from spidev import SpiDev # type: ignore
from weakref import finalize from weakref import finalize
@ -45,7 +45,7 @@ class SpiTransport(Transport):
self.logger.debug("spi: select chip") self.logger.debug("spi: select chip")
self.chip = Chip(RPI_CHIP) self.chip = Chip(RPI_CHIP)
# monitor rx,tx in bulk # monitor rx,tx in bulk
print("spi: request rx,tx") debug("spi: request rx,tx")
self.rxtx = self.chip.get_lines([RPI_PIN_RX_READY, RPI_PIN_TX_READY]) self.rxtx = self.chip.get_lines([RPI_PIN_RX_READY, RPI_PIN_TX_READY])
self.rxtx.request(consumer = CONSUMER, type = LINE_REQ_EV_RISING_EDGE) self.rxtx.request(consumer = CONSUMER, type = LINE_REQ_EV_RISING_EDGE)
self._flip_reset() self._flip_reset()
@ -67,14 +67,14 @@ class SpiTransport(Transport):
chip.close() chip.close()
#print("spi: chip closed") #print("spi: chip closed")
except: except:
print("error: chip failed to close") debug("error: chip failed to close")
if not spi is None: if not spi is None:
try: try:
spi.close() spi.close()
print("spi: device closed") debug("spi: device closed")
except: except:
print("error: device failed to close") debug("error: device failed to close")
def close(self): def close(self):
self.logger.debug("spi: close") self.logger.debug("spi: close")
@ -101,7 +101,7 @@ class SpiTransport(Transport):
rst.release() rst.release()
def send(self, pkt: bytes) -> None: def send(self, pkt: bytes) -> None:
#print("JD %d %s TX" % (millis(), buf2hex(pkt))) #debug("JD %d %s TX" % (millis(), buf2hex(pkt)))
self.sendQueue.append(pkt) self.sendQueue.append(pkt)
self._poke() self._poke()
@ -157,7 +157,7 @@ class SpiTransport(Transport):
if not sendtx and not rxReady: if not sendtx and not rxReady:
return False return False
# print("spi: transfer rx:" + str(rx) + ", tx: " + str(tx) + ", queue: " + str(len(self.sendQueue))) # debug("spi: transfer rx:" + str(rx) + ", tx: " + str(tx) + ", queue: " + str(len(self.sendQueue)))
# allocate transfer buffers # allocate transfer buffers
txqueue = bytearray(XFER_SIZE) txqueue = bytearray(XFER_SIZE)
@ -179,18 +179,18 @@ class SpiTransport(Transport):
rxqueue = bytearray(self.spi.xfer2(txqueue)) rxqueue = bytearray(self.spi.xfer2(txqueue))
if rxqueue is None: if rxqueue is None:
print("spi: recv failed") debug("spi: recv failed")
return False return False
framep = 0 framep = 0
while framep + 4 < len(rxqueue): while framep + 4 < len(rxqueue):
frame2 = rxqueue[framep + 2] frame2 = rxqueue[framep + 2]
if frame2 == 0: if frame2 == 0:
# print("spi: empty frame") # debug("spi: empty frame")
break break
sz = frame2 + 12 sz = frame2 + 12
if framep + sz > len(rxqueue): if framep + sz > len(rxqueue):
self.logger.debug("spi: frame size out of range") debug("spi: frame size out of range")
break break
frame0 = rxqueue[framep] frame0 = rxqueue[framep]
frame1 = rxqueue[framep + 1] frame1 = rxqueue[framep + 1]
@ -200,7 +200,7 @@ class SpiTransport(Transport):
pass pass
else: else:
buf = bytearray(rxqueue[framep:framep+sz]) buf = bytearray(rxqueue[framep:framep+sz])
#print("JD %d %s RX" % (millis(), buf2hex(buf))) #debug("JD %d %s RX" % (millis(), buf2hex(buf)))
if buf and self.on_receive: if buf and self.on_receive:
self.on_receive(buf) self.on_receive(buf)
sz = (sz + 3) & ~3 sz = (sz + 3) & ~3

Просмотреть файл

@ -1,9 +1,8 @@
import binascii import binascii
from logging import getLogger
import time import time
from typing import List, Tuple, Union, cast from typing import List, Tuple, Union, cast
logging = True
loggingv = False
_hex = "0123456789abcdef" _hex = "0123456789abcdef"
@ -11,18 +10,19 @@ def now():
return int(time.monotonic() * 1000) return int(time.monotonic() * 1000)
def log(msg: str, *args: object): logger = getLogger(__name__)
if logging:
if len(args):
msg = msg.format(*args)
print(msg)
def logv(msg: str, *args: object): def info(msg: str, *args: object):
if loggingv: if len(args):
if len(args): msg = msg.format(*args)
msg = msg.format(*args) logger.info(msg)
print(msg)
def debug(msg: str, *args: object):
if len(args):
msg = msg.format(*args)
logger.debug(msg)
def hex_num(n: int, len: int = 8): def hex_num(n: int, len: int = 8):
@ -106,7 +106,7 @@ def crc16(buf: bytes, start: int = 0, end: int = None):
return crc return crc
def color_to_rgb(rgb: Union[int, Tuple[int, int, int], List[int]], default = (0,0,0)) -> Tuple[int, int, int]: def color_to_rgb(rgb: Union[int, Tuple[int, int, int], List[int]], default=(0, 0, 0)) -> Tuple[int, int, int]:
""" """
Maps various format to a r,g,b tuple Maps various format to a r,g,b tuple
""" """
@ -127,4 +127,4 @@ def color_to_rgb(rgb: Union[int, Tuple[int, int, int], List[int]], default = (0,
r = (lrgb[0]) & 0xff r = (lrgb[0]) & 0xff
g = (lrgb[1]) & 0xff g = (lrgb[1]) & 0xff
b = (lrgb[2]) & 0xff b = (lrgb[2]) & 0xff
return (r,g,b) return (r, g, b)