light_sampler.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import datetime
  2. import random
  3. import logging
  4. class LightSampler:
  5. """
  6. 根据一天中的时间,以概率方式为光照设置生成下一个状态。
  7. """
  8. def __init__(self, light_ids: list, light_period_start: datetime.time = None, light_period_end: datetime.time = None):
  9. """
  10. 初始化采样器。
  11. :param light_ids: 此采样器应为其生成状态的所有灯光的ID列表。
  12. :param light_period_start: 光周期的开始时间 (datetime.time object)。
  13. :param light_period_end: 光周期的结束时间 (datetime.time object)。
  14. """
  15. self.light_ids = light_ids
  16. self.light_period_start = light_period_start or datetime.time(6, 0)
  17. self.light_period_end = light_period_end or datetime.time(22, 0)
  18. logging.info(f"光照采样器已初始化,光周期为 {self.light_period_start.strftime('%H:%M')} - {self.light_period_end.strftime('%H:%M')}。")
  19. def sample_next_light_state(self) -> dict:
  20. """
  21. 为每个灯光独立采样下一个光照状态,步长为 5%。
  22. :return: 一个状态字典,格式为 {light_id: intensity}。
  23. """
  24. current_time = datetime.datetime.now().time()
  25. next_state = {}
  26. # 定义所有可能的亮度值 (0.0, 0.05, ..., 1.0)
  27. possible_intensities = [round(i * 0.05, 2) for i in range(21)]
  28. # 判断当前是否在光周期内
  29. is_light_period = self.light_period_start <= current_time < self.light_period_end
  30. logging.info(f"开始为 {len(self.light_ids)} 个灯光独立采样,当前为 {'光周期' if is_light_period else '暗周期'}。")
  31. for light_id in self.light_ids:
  32. intensity = 0.0
  33. if is_light_period:
  34. # 光周期:大概率高光照,小概率低光照
  35. if random.random() < 0.95: # 95% 的概率为正常高光照
  36. # 从 [0.8, 0.85, ..., 1.0] 中选择
  37. high_options = [i for i in possible_intensities if 0.8 <= i <= 1.0]
  38. intensity = random.choice(high_options)
  39. else: # 5% 的概率为特殊情况的低光照
  40. # 从 [0.1, 0.15, ..., 0.4] 中选择
  41. low_options = [i for i in possible_intensities if 0.1 <= i <= 0.4]
  42. intensity = random.choice(low_options)
  43. else:
  44. # 暗周期:大概率关闭,极小概率施加光照
  45. if random.random() < 0.99: # 99% 的概率为正常关闭
  46. intensity = 0.0
  47. else: # 1% 的概率为特殊情况的突然光照
  48. # 从 [0.5, 0.55, ..., 1.0] 中选择
  49. sudden_light_options = [i for i in possible_intensities if 0.5 <= i <= 1.0]
  50. intensity = random.choice(sudden_light_options)
  51. next_state[light_id] = intensity
  52. logging.debug(f" - 灯光 {light_id}: 采样亮度 {intensity:.2f}")
  53. logging.info("所有灯光采样完成。")
  54. return next_state