import esphome.codegen as cg from esphome.components import light, spi import esphome.config_validation as cv from esphome.const import CONF_CHIPSET, CONF_NUM_LEDS, CONF_OUTPUT_ID from esphome.types import ConfigType spi_led_strip_ns = cg.esphome_ns.namespace("spi_led_strip") SpiLedStrip = spi_led_strip_ns.class_( "SpiLedStrip", light.AddressableLight, spi.SPIDevice ) SpiLedChipset = spi_led_strip_ns.enum("SpiLedChipset", is_class=True) CHIPSET_APA102 = "APA102" CHIPSET_WS2801 = "WS2801" CHIPSETS = { CHIPSET_APA102: SpiLedChipset.SPI_LED_CHIPSET_APA102, CHIPSET_WS2801: SpiLedChipset.SPI_LED_CHIPSET_WS2801, } BASE_SCHEMA = light.ADDRESSABLE_LIGHT_SCHEMA.extend( { cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(SpiLedStrip), cv.Optional(CONF_NUM_LEDS, default=1): cv.positive_not_null_int, } ) CONFIG_SCHEMA = cv.typed_schema( { CHIPSET_APA102: BASE_SCHEMA.extend(spi.spi_device_schema(False, "1MHz")), # WS2801 latches the data when the clock stays low, so the clock must idle low CHIPSET_WS2801: BASE_SCHEMA.extend( spi.spi_device_schema(False, "1MHz", "MODE0") ), }, key=CONF_CHIPSET, default_type=CHIPSET_APA102, enum=CHIPSETS, upper=True, ) async def to_code(config: ConfigType) -> None: chipset = config[CONF_CHIPSET] if chipset == CHIPSET_WS2801: cg.add_define("USE_SPI_LED_STRIP_WS2801") var = cg.new_Pvariable(config[CONF_OUTPUT_ID], config[CONF_NUM_LEDS], chipset) await light.register_light(var, config) await spi.register_spi_device(var, config) await cg.register_component(var, config)