diff --git a/examples/blinky.py b/examples/blinky.py index da2b989..eb605b9 100644 --- a/examples/blinky.py +++ b/examples/blinky.py @@ -4,6 +4,8 @@ from time import sleep if __name__ == '__main__': def main(): + from logging import basicConfig, INFO + basicConfig(level=INFO) bus = Bus() led = LedClient(bus, "led") led.brightness = 0.5 @@ -13,7 +15,7 @@ if __name__ == '__main__': led.set_all((255, 0, 0)) sleep(1) # off - led.set_all((0,0,0)) + led.set_all((0, 0, 0)) sleep(1) main() diff --git a/jacdac/bus.py b/jacdac/bus.py index 199b8c0..333eed5 100644 --- a/jacdac/bus.py +++ b/jacdac/bus.py @@ -1,6 +1,7 @@ from abc import abstractmethod from asyncio.tasks import Task from configparser import ConfigParser +from logging import getLogger, DEBUG, INFO, WARNING, ERROR, NOTSET import threading import asyncio import queue @@ -24,7 +25,7 @@ from .unique_brain.constants import * from .packet import * from .transport import Transport -from .util import now, log, logv +from .util import now, info, debug from .pack import PackTuple, PackType, jdpack, jdunpack EV_CHANGE = "change" @@ -158,7 +159,7 @@ class EventEmitter: if logger: 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) def warn(self, text: str, *args: object): @@ -180,18 +181,23 @@ def _service_matches(dev: 'Device', serv: bytearray): return False return True + def rand_u64(): return bytearray([getrandbits(8) for _ in range(8)]) + def is_raspberrypi(): # https://raspberrypi.stackexchange.com/questions/5100/detect-that-a-python-program-is-running-on-the-pi try: from io import open with open('/sys/firmware/devicetree/base/model', 'r') as m: - if 'raspberry pi' in m.read().lower(): return True - except Exception: pass + if 'raspberry pi' in m.read().lower(): + return True + except Exception: + pass return False + class Bus(EventEmitter): """A Jacdac bus that managed devices, service client, registers.""" @@ -245,7 +251,8 @@ class Bus(EventEmitter): # merge .ctor configuration with files 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"): cfg = config.add_section("jacdac") cfg = config["jacdac"] @@ -288,7 +295,7 @@ class Bus(EventEmitter): self.transports.append(ExecTransport(self.transport_cmd)) if self.hf2_portname: from .transports.hf2 import HF2Transport - self.transports.append(HF2Transport(self.hf2_portname)) + self.transports.append(HF2Transport(self.hf2_portname)) if self.spi: from .transports.spi import SpiTransport self.transports.append(SpiTransport()) @@ -311,7 +318,7 @@ class Bus(EventEmitter): 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): if self.process_thread is threading.current_thread(): @@ -390,10 +397,10 @@ class Bus(EventEmitter): while ptr < 12 + frame[2]: sz = frame[ptr] + 4 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) if ptr > 12: - pkt.requires_ack = False # only ack once + pkt.requires_ack = False # only ack once self.process_packet(pkt) # dispatch to other transports self._queue_core(pkt) @@ -504,7 +511,7 @@ class Bus(EventEmitter): break def process_packet(self, pkt: JDPacket): - logv("route: {}", pkt) + debug("route: {}", pkt) dev_id = pkt.device_id multi_command_class = pkt.multicommand_class service_index = pkt.service_index @@ -540,7 +547,7 @@ class Bus(EventEmitter): elif dev_id == self.self_device.device_id and pkt.is_command: h = self.servers[pkt.service_index] 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) else: if pkt.is_command: @@ -1011,7 +1018,7 @@ class ControlServer(Server): self.auto_bind_cnt = 0 def queue_announce(self): - logv("announce: %d " % self.restart_counter) + debug("announce: %d " % self.restart_counter) self.restart_counter += 1 ids = [s.service_class for s in self.bus. servers] rest = self.restart_counter @@ -1109,7 +1116,8 @@ class LoggerServer(Server): def report(self, priority: int, msg: str, *args: object): if priority >= self.min_priority: - log(msg, *args) + info(msg, *args) + cmd: int = -1 if priority == LoggerPriority.DEBUG: cmd = JD_LOGGER_CMD_DEBUG @@ -1117,7 +1125,7 @@ class LoggerServer(Server): cmd = JD_LOGGER_CMD_LOG elif priority == LoggerPriority.WARNING: cmd = JD_LOGGER_CMD_WARN - elif priority == JD_LOGGER_CMD_ERROR: + elif priority == JD_LOGGER_CMD_ERROR: cmd = JD_LOGGER_CMD_ERROR else: return @@ -1781,10 +1789,11 @@ class Device(EventEmitter): for c in self.clients: if (c.broadcast and c.service_class == service_class) or \ (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.handle_packet_outer(pkt) + class BufferClient(Client): _value: bytearray _dirty: bool @@ -1792,12 +1801,13 @@ class BufferClient(Client): """ 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: super().__init__(bus, service_class, pack_formats, role) self._value = bytearray(0) self._dirty = False - + @property def value(self) -> bytearray: """ @@ -1816,10 +1826,10 @@ class BufferClient(Client): @property def dirty(self) -> bool: return self._dirty - + def set_dirty(self) -> None: self._dirty = True - + def refresh_value(self) -> None: if self._dirty: self.register(JD_REG_VALUE).set_values(self._value) @@ -1833,7 +1843,5 @@ class BufferClient(Client): self._value = self._value + bytearray(length - l) self._dirty = True else: - self._value = self._value[0:length -1] + self._value = self._value[0:length - 1] self._dirty = True - - diff --git a/jacdac/transports/spi.py b/jacdac/transports/spi.py index 2987ffc..9fc4de3 100644 --- a/jacdac/transports/spi.py +++ b/jacdac/transports/spi.py @@ -4,7 +4,7 @@ from typing import List, Optional from time import sleep, monotonic from tokenize import Number 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 spidev import SpiDev # type: ignore from weakref import finalize @@ -45,7 +45,7 @@ class SpiTransport(Transport): self.logger.debug("spi: select chip") self.chip = Chip(RPI_CHIP) # 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.request(consumer = CONSUMER, type = LINE_REQ_EV_RISING_EDGE) self._flip_reset() @@ -67,14 +67,14 @@ class SpiTransport(Transport): chip.close() #print("spi: chip closed") except: - print("error: chip failed to close") + debug("error: chip failed to close") if not spi is None: try: spi.close() - print("spi: device closed") + debug("spi: device closed") except: - print("error: device failed to close") + debug("error: device failed to close") def close(self): self.logger.debug("spi: close") @@ -101,7 +101,7 @@ class SpiTransport(Transport): rst.release() 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._poke() @@ -157,7 +157,7 @@ class SpiTransport(Transport): if not sendtx and not rxReady: 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 txqueue = bytearray(XFER_SIZE) @@ -179,18 +179,18 @@ class SpiTransport(Transport): rxqueue = bytearray(self.spi.xfer2(txqueue)) if rxqueue is None: - print("spi: recv failed") + debug("spi: recv failed") return False framep = 0 while framep + 4 < len(rxqueue): frame2 = rxqueue[framep + 2] if frame2 == 0: - # print("spi: empty frame") + # debug("spi: empty frame") break sz = frame2 + 12 if framep + sz > len(rxqueue): - self.logger.debug("spi: frame size out of range") + debug("spi: frame size out of range") break frame0 = rxqueue[framep] frame1 = rxqueue[framep + 1] @@ -200,7 +200,7 @@ class SpiTransport(Transport): pass else: 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: self.on_receive(buf) sz = (sz + 3) & ~3 diff --git a/jacdac/util.py b/jacdac/util.py index eb5d0e3..48c728c 100644 --- a/jacdac/util.py +++ b/jacdac/util.py @@ -1,9 +1,8 @@ import binascii +from logging import getLogger import time from typing import List, Tuple, Union, cast -logging = True -loggingv = False _hex = "0123456789abcdef" @@ -11,18 +10,19 @@ def now(): return int(time.monotonic() * 1000) -def log(msg: str, *args: object): - if logging: - if len(args): - msg = msg.format(*args) - print(msg) +logger = getLogger(__name__) -def logv(msg: str, *args: object): - if loggingv: - if len(args): - msg = msg.format(*args) - print(msg) +def info(msg: str, *args: object): + if len(args): + msg = msg.format(*args) + logger.info(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): @@ -106,7 +106,7 @@ def crc16(buf: bytes, start: int = 0, end: int = None): 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 """ @@ -127,4 +127,4 @@ def color_to_rgb(rgb: Union[int, Tuple[int, int, int], List[int]], default = (0, r = (lrgb[0]) & 0xff g = (lrgb[1]) & 0xff b = (lrgb[2]) & 0xff - return (r,g,b) + return (r, g, b)