Don't require a full pin scan for the root page.

The full pin scan is slow, and it's slowing me down. Instead, just load
what we know we need for the configured relays unless we are adding a
new relay.
This commit is contained in:
Eli Ribble 2023-05-26 09:44:17 -07:00
parent dd637c2eaa
commit b4027baf68
2 changed files with 61 additions and 49 deletions

View File

@ -87,10 +87,10 @@ class Manager:
self.configpath = configpath
self.has_fakes = has_fakes
# Handles to various chips
self._chips = []
# Info on various pins
self._pins = []
# Handles to various chips, mapped by chip number
self._chips = {}
# Info on various pins, mapped by (chip number, line_number)
self._pins = {}
# Cached info on the relays
self._relays = []
# Connection to single-board computer GPIO
@ -104,7 +104,7 @@ class Manager:
def chips(self) -> List[Chip]:
if not self._chips:
self._load_chips()
return self._chips
return self._chips.values()
def connect(self) -> None:
self.sbc = rgpio.sbc(
@ -116,16 +116,18 @@ class Manager:
self.sbc = None
def get_chip_by_number(self, number: int) -> Chip:
for chip in self.chips:
if chip.number == number:
return chip
raise Exception(f"Can't find chip {number}")
try:
return self._chips[number]
except KeyError:
self._load_chip(number)
return self._chips[number]
def get_pin_by_number(self, chip: Chip, line_number: int) -> Pin:
for pin in self.pins:
if pin.chip == chip and pin.line_number == line_number:
return pin
raise Exception(f"Can't find pin {chip.name}-{line_number}")
try:
return self._pins[(chip.number, line_number)]
except KeyError:
self._load_pin(chip, line_number)
return self._pins[(chip.number, line_number)]
def get_relay_by_pin_id(self, pin_id: str) -> Relay:
for relay in self.relays:
@ -133,11 +135,15 @@ class Manager:
return relay
return None
def load_all_pins(self) -> None:
self._load_chips()
self._load_pins()
@property
def pins(self) -> List[Pin]:
if not self._pins:
self._load_pins()
return self._pins
return self._pins.values()
@property
def relays(self) -> Iterable[Relay]:
@ -177,50 +183,55 @@ class Manager:
def shutdown(self) -> None:
_write_config(self.configpath, self.config)
def _load_chip(self, number: int) -> None:
try:
handle = self.sbc.gpiochip_open(number)
except rgpio.error:
return
if handle < 0:
return
okay, number_of_lines, name, label = self.sbc.gpio_get_chip_info(handle)
LOGGER.info("Chip info: %s %s %s %s", okay, number_of_lines, name, label)
if okay != 0:
LOGGER.warn("Chip %s not okay.", name)
return
self._chips[number] = Chip(
handle=handle,
label=label,
name=name,
number=number,
number_of_lines=number_of_lines,
)
# Talk to the remote pins daemon and get information about the chips
def _load_chips(self) -> None:
for i in range(MAX_CHIPS):
try:
handle = self.sbc.gpiochip_open(i)
except rgpio.error:
continue
if handle < 0:
continue
okay, number_of_lines, name, label = self.sbc.gpio_get_chip_info(handle)
LOGGER.info("Chip info: %s %s %s %s", okay, number_of_lines, name, label)
if okay != 0:
LOGGER.warn("Chip %s not okay.", name)
continue
self._chips.append(Chip(
handle=handle,
label=label,
name=name,
number=i,
number_of_lines=number_of_lines,
))
self._load_chip(i)
def _load_pin(self, chip: Chip, line_number: int) -> None:
okay, offset, flags, name, user = self.sbc.gpio_get_line_info(chip.handle, line_number)
LOGGER.info("Got line info: %s %s %s %s %s", okay, offset, flags, name, user)
assert offset == line_number
if okay != 0:
LOGGER.warn("Line %s is not okay", name)
return
if not name:
LOGGER.warn("Ignoring line %d because it has no name.", line_number)
return
self._pins[(chip.number, line_number)] = Pin(
chip=chip,
flags=flags,
line_number=line_number,
name=name,
user=user,
)
# Talk to the remote pins daemon and get information about the pins
def _load_pins(self) -> None:
LOGGER.info("Loading pins")
for chip in self.chips:
for line in range(chip.number_of_lines):
okay, offset, flags, name, user = self.sbc.gpio_get_line_info(chip.handle, line)
LOGGER.info("Got line info: %s %s %s %s %s", okay, offset, flags, name, user)
assert offset == line
if okay != 0:
LOGGER.warn("Line %s is not okay", name)
continue
if not name:
LOGGER.warn("Ignoring line %d because it has no name.", line)
continue
self._pins.append(Pin(
chip=chip,
flags=flags,
line_number=line,
name=name,
user=user,
))
self._load_pin(chip, line)
def _read_config(configpath: pathlib.Path) -> None:
with open(configpath, "rb") as f:

View File

@ -36,6 +36,7 @@ def index(request: Request):
@app.get("/relay/create")
def relay_create_get(request: Request):
"Get the form to create a new relay."
relays.load_all_pins()
pins = relays.pins
return templates.TemplateResponse("relay-create.template.html", {
"request": request,