from typing import List, Optional, Dict, Any class WledSegment: """ WLED分段控制类 用于控制LED灯条的分段效果,包括位置、颜色、特效等参数 """ def __init__(self, start: int = 0, stop: int = 150, segment_id: int = 0, group: int = 5, on: bool = True, colors: list = None, effect: int = 6, speed: int = 230, intensity: int = 255, palette: int = 0, reverse: bool = False, selected: bool = True): """ 初始化WLED分段 Args: start: 分段起始灯珠编号 stop: 分段结束灯珠编号(不包含此编号) segment_id: 分段ID,用于唯一标识 group: 分组数量,每N个灯珠为1组运行特效 on: 分段开关状态 colors: 颜色配置,3个颜色通道[主色, 辅助色, 第三色] effect: 特效ID speed: 特效速度 (0-255) intensity: 特效强度 (0-255) palette: 调色板ID reverse: 方向反转 selected: 分段选中状态 """ self.start = start self.stop = stop self.id = segment_id self.grp = group self.on = on self.col = colors or [[0, 0, 255], [0, 0, 0], [0, 0, 0]] # 默认蓝色主色 self.fx = effect self.sx = speed self.ix = intensity self.pal = palette self.rev = reverse self.sel = selected def to_dict(self) -> dict: """ 将分段配置转换为字典格式,用于API调用 Returns: dict: 分段配置字典 """ return { "start": self.start, "stop": self.stop, "id": self.id, "grp": self.grp, "on": self.on, "col": self.col, "fx": self.fx, "sx": self.sx, "ix": self.ix, "pal": self.pal, "rev": self.rev, "sel": self.sel } def set_color(self, primary_color: tuple, secondary_color: tuple = (0, 0, 0), tertiary_color: tuple = (0, 0, 0)): """ 设置分段颜色 Args: primary_color: 主色 RGB元组 secondary_color: 辅助色 RGB元组 tertiary_color: 第三色 RGB元组 """ self.col = [list(primary_color), list(secondary_color), list(tertiary_color)] def set_effect(self, effect_id: int, speed: int = None, intensity: int = None): """ 设置分段特效 Args: effect_id: 特效ID speed: 特效速度 (0-255) intensity: 特效强度 (0-255) """ self.fx = effect_id if speed is not None: self.sx = max(0, min(255, speed)) if intensity is not None: self.ix = max(0, min(255, intensity)) def set_position(self, start: int, stop: int): """ 设置分段位置 Args: start: 起始灯珠编号 stop: 结束灯珠编号(不包含) """ self.start = start self.stop = stop def set_group_size(self, group_size: int): """ 设置分组大小 Args: group_size: 每组的灯珠数量 """ self.grp = group_size def toggle(self): """切换分段开关状态""" self.on = not self.on def select(self): """选中此分段""" self.sel = True def deselect(self): """取消选中此分段""" self.sel = False def reverse(self): """切换方向反转状态""" self.rev = not self.rev def __str__(self) -> str: """返回分段的字符串表示""" return f"WLED Segment {self.id}: LEDs {self.start}-{self.stop-1}, " \ f"Effect {self.fx}, Color {self.col[0]}, {'ON' if self.on else 'OFF'}" class WledState: """ WLED设备状态控制类 用于管理WLED设备的全局状态,包括开关、亮度、过渡时间等参数 """ def __init__(self, on: bool = True, brightness: int = 255, transition: int = 10, segments: list = None): """ 初始化WLED设备状态 Args: on: 设备总开关,True=开启,False=关闭(全局生效,分段开关需配合此值) brightness: 全局亮度,取值 0-255,255=最大亮度(所有分段的亮度均基于此值) transition: 过渡时间,单位 100ms,10=1秒(颜色/特效切换时的平滑过渡时长) segments: 分段数组,存放多个独立控制的灯珠段 """ self.on = on self.bri = max(0, min(255, brightness)) # 限制亮度范围 0-255 self.transition = max(0, transition) # 过渡时间不能为负数 self.seg = segments or [] # 分段数组,默认为空列表 def add_segment(self, segment: WledSegment): """ 添加一个分段到设备状态中 Args: segment: wled_segment对象 """ self.seg.append(segment) def remove_segment(self, segment_id: int): """ 根据ID移除分段 Args: segment_id: 要移除的分段ID """ self.seg = [seg for seg in self.seg if seg.id != segment_id] def get_segment(self, segment_id: int) -> Optional[WledSegment]: """ 根据ID获取分段 Args: segment_id: 分段ID Returns: wled_segment对象,如果未找到返回None """ for seg in self.seg: if seg.id == segment_id: return seg return None def set_global_brightness(self, brightness: int): """ 设置全局亮度 Args: brightness: 亮度值 0-255 """ self.bri = max(0, min(255, brightness)) def set_transition_time(self, transition: int): """ 设置过渡时间 Args: transition: 过渡时间,单位 100ms """ self.transition = max(0, transition) def toggle_power(self): """切换设备总开关状态""" self.on = not self.on def turn_on(self): """开启设备""" self.on = True def turn_off(self): """关闭设备""" self.on = False def to_dict(self) -> dict: """ 将设备状态转换为字典格式,用于API调用 Returns: dict: 设备状态字典,符合WLED API格式 """ return { "on": self.on, "bri": self.bri, "transition": self.transition, "seg": [segment.to_dict() for segment in self.seg] } def from_dict(self, state_dict: dict): """ 从字典格式加载设备状态 Args: state_dict: 包含设备状态的字典 """ self.on = state_dict.get("on", True) self.bri = state_dict.get("bri", 255) self.transition = state_dict.get("transition", 10) # 清空现有分段 self.seg = [] # 加载分段数据 segments_data = state_dict.get("seg", []) for seg_data in segments_data: segment = WledSegment( start=seg_data.get("start", 0), stop=seg_data.get("stop", 150), segment_id=seg_data.get("id", 0), group=seg_data.get("grp", 5), on=seg_data.get("on", True), colors=seg_data.get("col", [[0, 0, 255], [0, 0, 0], [0, 0, 0]]), effect=seg_data.get("fx", 6), speed=seg_data.get("sx", 230), intensity=seg_data.get("ix", 255), palette=seg_data.get("pal", 0), reverse=seg_data.get("rev", False), selected=seg_data.get("sel", True) ) self.add_segment(segment) def get_segments_count(self) -> int: """获取分段数量""" return len(self.seg) def get_total_leds(self) -> int: """获取总LED数量(基于最后一个分段的结束位置)""" if not self.seg: return 0 return max(seg.stop for seg in self.seg) def clone(self) -> 'WledState': """ 深度克隆WledState对象 Returns: WledState: 克隆的新对象 """ # 创建新的WledState对象 cloned_state = WledState( on=self.on, brightness=self.bri, transition=self.transition ) # 深度克隆所有分段 for segment in self.seg: cloned_segment = WledSegment( start=segment.start, stop=segment.stop, segment_id=segment.id, group=segment.grp, on=segment.on, colors=[color[:] for color in segment.col], # 深拷贝颜色数组 effect=segment.fx, speed=segment.sx, intensity=segment.ix, palette=segment.pal, reverse=segment.rev, selected=segment.sel ) cloned_state.add_segment(cloned_segment) return cloned_state def merge_segments(self) -> 'WledState': """ 合并所有分段为一个完整的分段,用于控制整条灯带 Returns: WledState: 合并后的状态对象 """ if not self.seg: return self.clone() # 计算总LED数量 total_leds = self.get_total_leds() # 创建合并后的状态 merged_state = WledState( on=self.on, brightness=self.bri, transition=self.transition ) # 创建单个分段覆盖整个灯带 merged_segment = WledSegment( start=0, stop=total_leds, segment_id=0, group=self.seg[0].grp if self.seg else 5, on=True, colors=[[0, 0, 255], [0, 0, 0], [0, 0, 0]], # 默认蓝色 effect=6, # 默认彩虹特效 speed=230, intensity=255, palette=0, reverse=False, selected=True ) merged_state.add_segment(merged_segment) return merged_state def __str__(self) -> str: """返回设备状态的字符串表示""" status = "ON" if self.on else "OFF" return f"WLED State: {status}, Brightness: {self.bri}, " \ f"Transition: {self.transition}ms, Segments: {len(self.seg)}"