| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- 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)}"
|