diff --git a/moonraker/plugins/power.py b/moonraker/plugins/power.py index e7fe17e..9c7f2ed 100644 --- a/moonraker/plugins/power.py +++ b/moonraker/plugins/power.py @@ -34,15 +34,7 @@ class PrinterPower: logging.info("Power plugin loading devices: " + str(dev_names)) devices = {} for dev in dev_names: - pin = config.getint(dev + "_pin") - name = config.get(dev + "_name", dev) - active_low = config.getboolean(dev + "_active_low", False) - devices[dev] = { - "name": name, - "pin": pin, - "active_low": int(active_low), - "status": None - } + devices[dev] = GpioDevice(dev, config) ioloop = IOLoop.current() ioloop.spawn_callback(self.initialize_devices, devices) @@ -50,7 +42,7 @@ class PrinterPower: output = {"devices": []} for dev in self.devices: output['devices'].append({ - "name": self.devices[dev]["name"], + "name": self.devices[dev].name, "id": dev }) return output @@ -65,25 +57,21 @@ class PrinterPower: result = {} req = path.split("/")[-1] for dev in args: - if path.startswith("/machine/gpio_power/"): - res = await self._power_dev(dev, req) - if res: - result[dev] = self.devices[dev]["status"] - else: - result[dev] = "device_not_found" - else: + if req not in ("on", "off", "status"): raise self.server.error("Unsupported power request") + if (await self._power_dev(dev, req)): + result[dev] = self.devices[dev].status + else: + result[dev] = "device_not_found" return result async def _power_dev(self, dev, req): if dev not in self.devices: return False - await GPIO.verify_pin(self.devices[dev]["pin"], - self.devices[dev]["active_low"]) if req in ["on", "off"]: - val = 1 if req == "on" else 0 - GPIO.set_pin_value(self.devices[dev]["pin"], val) + await self.devices[dev].power(req) + self.server.send_event("gpio_power:power_changed", { "device": dev, "status": req @@ -91,17 +79,13 @@ class PrinterPower: elif req != "status": raise self.server.error("Unsupported power request") - self.devices[dev]["status"] = GPIO.is_pin_on( - self.devices[dev]["pin"]) + await self.devices[dev].refresh_status() return True async def initialize_devices(self, devices): for name, device in devices.items(): try: - logging.debug( - f"Attempting to configure pin GPIO{device['pin']}") - await GPIO.setup_pin(device["pin"], device["active_low"]) - device["status"] = GPIO.is_pin_on(device["pin"]) + await device.initialize() except Exception: logging.exception( f"Power plugin: ERR Problem configuring the output pin for" @@ -123,6 +107,11 @@ class PrinterPower: ioloop = IOLoop.current() ioloop.spawn_callback(self._power_dev, device, status) + async def add_device(self, dev, device): + await device.initialize() + self.devices[dev] = device + + class GPIO: gpio_root = "/sys/class/gpio" @@ -187,7 +176,6 @@ class GPIO: if GPIO._get_gpio_option(pin, "direction").strip() != "out": GPIO._set_gpio_option(pin, "direction", "out") - @staticmethod def is_pin_on(pin): return "on" if int(GPIO._get_gpio_option(pin, "value")) else "off" @@ -198,5 +186,25 @@ class GPIO: GPIO._set_gpio_option(pin, "value", value) +class GpioDevice: + def __init__(self, dev, config): + self.name = config.get(dev + "_name", dev) + self.status = None + self.pin = config.getint(dev + "_pin") + self.active_low = int(config.getboolean(dev + "_active_low", False)) + + async def initialize(self): + logging.debug(f"Attempting to configure pin GPIO{self.pin}") + await GPIO.setup_pin(self.pin, self.active_low) + await self.refresh_status() + + async def refresh_status(self): + self.status = GPIO.is_pin_on(self.pin) + + async def power(self, status): + await GPIO.verify_pin(self.pin, self.active_low) + GPIO.set_pin_value(self.pin, int(status == "on")) + + def load_plugin(config): return PrinterPower(config)