ikalchev / HAP-python

A python implementation of the HomeKit Accessory Protocol (HAP)
Other
610 stars 116 forks source link

Calling NeoPixelLightStrip #247

Closed njjerrysmith closed 4 years ago

njjerrysmith commented 4 years ago

I'm trying to use the NeoPixelLightStrip example to get some led tape running. I've gotten everything installed and busy_home runs with no issues.

I'm stuck at where to declare the variables needed by the NeoPixelLightStrip Class in my mashup of the neopixel example and main.py example where I'm using the code at the bottom to spin up the bridge.

My file looks like:

import logging
import signal
import random
from neopixel import *
from pyhap.accessory import Accessory,Bridge
from pyhap.accessory_driver import AccessoryDriver
from pyhap.const import CATEGORY_LIGHTBULB

class NeoPixelLightStrip(Accessory):
    category = CATEGORY_LIGHTBULB

    def __init__(self, LED_Count, is_GRB, LED_pin,
                 LED_freq_hz, LED_DMA, LED_brightness,
                 LED_invert, *args, **kwargs):

        """
        LED_Count - the number of LEDs in the array
        is_GRB - most neopixels are GRB format - Normal:True
        LED_pin - must be PWM pin 18 - Normal:18
        LED_freq_hz - frequency of the neopixel leds - Normal:800000
        LED_DMA - Normal:10
        LED_Brightness - overall brightness - Normal:255
        LED_invert - Normal:False
        For more information regarding these settings
            please review rpi_ws281x source code
        """

        super().__init__(*args, **kwargs)

        # Set our neopixel API services up using Lightbulb base
        serv_light = self.add_preload_service(
            'Lightbulb', chars=['On', 'Hue', 'Saturation', 'Brightness'])

        # Configure our callbacks
        self.char_hue = serv_light.configure_char(
            'Hue', setter_callback=self.set_hue)
        self.char_saturation = serv_light.configure_char(
            'Saturation', setter_callback=self.set_saturation)
        self.char_on = serv_light.configure_char(
            'On', setter_callback=self.set_state)
        self.char_on = serv_light.configure_char(
            'Brightness', setter_callback=self.set_brightness)

        # Set our instance variables
        self.accessory_state = 0  # State of the neo light On/Off
        self.hue = 0  # Hue Value 0 - 360 Homekit API
        self.saturation = 100  # Saturation Values 0 - 100 Homekit API
        self.brightness = 100  # Brightness value 0 - 100 Homekit API

        self.is_GRB = TRUE  # Most neopixels are Green Red Blue
        self.LED_count = LED_count

        self.neo_strip = Adafruit_NeoPixel(LED_count, LED_pin, LED_freq_hz,
                                           LED_DMA, LED_invert, LED_Brightness)
        self.neo_strip.begin()

    def set_state(self, value):
        self.accessory_state = value
        if value == 1:  # On
            self.set_hue(self.hue)
        else:
            self.update_neopixel_with_color(0, 0, 0)  # Off

    def set_hue(self, value):
        # Lets only write the new RGB values if the power is on
        # otherwise update the hue value only
        if self.accessory_state == 1:
            self.hue = value
            rgb_tuple = self.hsv_to_rgb(
                self.hue, self.saturation, self.brightness)
            if len(rgb_tuple) == 3:
                self.update_neopixel_with_color(
                    rgb_tuple[0], rgb_tuple[1], rgb_tuple[2])
        else:
            self.hue = value

    def set_brightness(self, value):
        self.brightness = value
        self.set_hue(self.hue)

    def set_saturation(self, value):
        self.saturation = value
        self.set_hue(self.hue)

    def update_neopixel_with_color(self, red, green, blue):
        for i in range(self.LED_count):
            if(self.is_GRB):
                self.neo_strip.setPixelColor(i, Color(int(green),
                                                      int(red),
                                                      int(blue)))
            else:
                self.neo_strip.setPixelColor(i, Color(int(red),
                                                      int(green),
                                                      int(blue)))

        self.neo_strip.show()

    def hsv_to_rgb(self, h, s, v):
        """
        This function takes
         h - 0 - 360 Deg
         s - 0 - 100 %
         v - 0 - 100 %
        """

        hPri = h / 60
        s = s / 100
        v = v / 100

        if s <= 0.0:
            return int(0), int(0), int(0)

        C = v * s  # Chroma
        X = C * (1 - abs(hPri % 2 - 1))

        RGB_Pri = [0.0, 0.0, 0.0]

        if 0 <= hPri <= 1:
            RGB_Pri = [C, X, 0]
        elif 1 <= hPri <= 2:
            RGB_Pri = [X, C, 0]
        elif 2 <= hPri <= 3:
            RGB_Pri = [0, C, X]
        elif 3 <= hPri <= 4:
            RGB_Pri = [0, X, C]
        elif 4 <= hPri <= 5:
            RGB_Pri = [X, 0, C]
        elif 5 <= hPri <= 6:
            RGB_Pri = [C, 0, X]
        else:
            RGB_Pri = [0, 0, 0]

        m = v - C

        return int((RGB_Pri[0] + m) * 255), int((RGB_Pri[1] + m) * 255), int((RGB_Pri[2] + m) * 255)
def get_bridge(driver):
    """Call this method to get a Bridge instead of a standalone accessory."""
    bridge = Bridge(driver, 'Bridge')
    bridge.add_accessory(NeoPixelLightStrip(driver, 'LED TAPE', 14, 'TRUE', 18, 800000, 10, 255, 'FALSE'))

     return bridge

# Start the accessory on port 51826
driver = AccessoryDriver(port=51826, persist_file='neopixel.state')
# Change `get_accessory` to `get_bridge` if you want to run a Bridge.
driver.add_accessory(accessory=get_bridge(driver))
# We want SIGTERM (terminate) to be handled by the driver itself,
# so that it can gracefully stop the accessory, server and advertising.
signal.signal(signal.SIGTERM, driver.signal_handler)
# Start it!
driver.start()

The error I'm getting is

Traceback (most recent call last):
  File "neopixel.py", line 25, in <module>
    from neopixel import *
  File "/home/pi/hk_project/neopixel.py", line 173, in <module>
    driver.add_accessory(accessory=get_bridge(driver))
  File "/home/pi/hk_project/neopixel.py", line 165, in get_bridge
    bridge.add_accessory(NeoPixelLightStrip(driver, 'LED TAPE', 14, 'TRUE', 18, 800000, 10, 255, 'FALSE'))
  File "/home/pi/hk_project/neopixel.py", line 52, in __init__
    super().__init__(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/pyhap/accessory.py", line 54, in __init__
    self.add_info_service()
  File "/usr/local/lib/python3.7/dist-packages/pyhap/accessory.py", line 83, in add_info_service
    serv_info = self.driver.loader.get_service('AccessoryInformation')
AttributeError: 'int' object has no attribute 'loader'
njjerrysmith commented 4 years ago

Reading is hard. I found an example at (https://github.com/LasCabos/HAP-python/blob/dev/neo_main.py )