light.py factory test - iot-root/garden-of-eden GitHub Wiki

from gpiozero import PWMLED
from gpiozero.pins.pigpio import PiGPIOFactory
import pigpio

class GPIOController:
    def __init__(self, pin, pin_factory=None):
        self.pin = pin
        self.factory = pin_factory
        self.pi = None
        if self.factory:
            self.pi = self.factory.pi()  # Use factory's method to get pigpio instance if factory is provided
        
        # Check if pigpio instance is created and connected
        if self.pi and not self.pi.connected:
            raise RuntimeError("Failed to connect to pigpiod daemon. Ensure it's running and accessible.")

    def set_frequency(self, frequency):
        if not self.pi:
            raise RuntimeError("pigpio.pi client is not initialized.")
        self.pi.set_PWM_frequency(self.pin, frequency)
    
    def close(self):
        if self.pi:
            self.pi.stop()

class Light:
    def __init__(self, pin=18, frequency=8000, pin_factory=None):
        self.pin_factory = pin_factory if pin_factory else PiGPIOFactory()
        self.led = PWMLED(pin, pin_factory=self.pin_factory)
        self.gpio = GPIOController(pin, pin_factory=self.pin_factory)
        self.set_frequency(frequency)

    def on(self):
        if self.led.value > 0:
            print("Light already on, skipping")
            return
        print("Turning light on")
        self.led.value = 1

    def off(self):
        print("Turning light off")
        self.led.value = 0

    def set_frequency(self, frequency):
        print(f"Setting light frequency to {frequency}")
        self.gpio.set_frequency(frequency)

    def set_brightness(self, brightness_percentage):
        if not (0 <= brightness_percentage <= 100):
            raise ValueError("Brightness must be between 0 and 100")
        duty = brightness_percentage / 100.0
        print(f"Setting light brightness to {brightness_percentage}%")
        self.led.value = duty

    def get_brightness(self):
        return self.led.value * 100

    def close(self):
        self.led.close()
        self.gpio.close()

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Control an IoT light.')
    parser.add_argument('--on', action='store_true', help='Turn the light on.')
    parser.add_argument('--off', action='store_true', help='Turn the light off.')
    parser.add_argument('--brightness', type=int, default=None, help='Set the brightness level (0-100).')

    args = parser.parse_args()
    light = Light()  # Default frequency of 8kHz

    try:
        if args.on:
            light.on()
            if args.brightness is not None:
                light.set_brightness(args.brightness)
        elif args.off:
            light.off()
        elif args.brightness is not None:
            light.on()
            light.set_brightness(args.brightness)
        else:
            print("No action specified. Use --on, --off, or --brightness.")
    finally:
        light.close()