main.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. # main.py
  2. import logging
  3. import sys
  4. import argparse
  5. from pathlib import Path
  6. # --- 路径设置 ---
  7. SRC_DIR = Path(__file__).resolve().parent / 'src'
  8. sys.path.append(str(SRC_DIR))
  9. # --- 模块导入 ---
  10. from PFAL_SysControl.Controller.cultivation_rack import CultivationRack
  11. from PFAL_SysControl.Core.task_runner import TaskRunner
  12. from PFAL_SysControl.Utils.utils import load_config
  13. def main():
  14. """
  15. 程序主入口,负责解析命令行参数并执行相应操作。
  16. """
  17. parser = argparse.ArgumentParser(
  18. description="PFAL 系统命令行控制器。"
  19. )
  20. subparsers = parser.add_subparsers(
  21. dest='command',
  22. required=True,
  23. help='可执行的具体命令'
  24. )
  25. # --- 任务调度命令 ---
  26. subparsers.add_parser(
  27. 'schedule',
  28. help='启动一个由 task.yml 定义的长期数据采集和光照采样任务。'
  29. )
  30. # --- 手动灯光控制命令 (扁平化结构) ---
  31. def add_rack_name_arg(p):
  32. p.add_argument('rack_name', help="要操作的栽培架/控制器名称 (例如 'controller1')")
  33. parser_on = subparsers.add_parser('on', help='打开指定栽培架上的所有灯光')
  34. add_rack_name_arg(parser_on)
  35. parser_off = subparsers.add_parser('off', help='关闭指定栽培架上的所有灯光')
  36. add_rack_name_arg(parser_off)
  37. parser_layer_on = subparsers.add_parser('layer-on', help='打开指定层')
  38. add_rack_name_arg(parser_layer_on)
  39. parser_layer_on.add_argument('layer_id', type=int, help='层ID')
  40. parser_layer_off = subparsers.add_parser('layer-off', help='关闭指定层')
  41. add_rack_name_arg(parser_layer_off)
  42. parser_layer_off.add_argument('layer_id', type=int, help='层ID')
  43. parser_layer_intensity = subparsers.add_parser('layer-intensity', help='设置指定层的亮度')
  44. add_rack_name_arg(parser_layer_intensity)
  45. parser_layer_intensity.add_argument('layer_id', type=int, help='层ID')
  46. parser_layer_intensity.add_argument('intensity', type=float, help='亮度值 (0.0-1.0)')
  47. parser_light_name = subparsers.add_parser('light-by-name', help='按名称设置灯光')
  48. add_rack_name_arg(parser_light_name)
  49. parser_light_name.add_argument('name', help='灯光名称')
  50. parser_light_name.add_argument('intensity', type=float, help='亮度值 (0.0-1.0)')
  51. parser_light_id = subparsers.add_parser('light-by-id', help='按ID设置灯光')
  52. add_rack_name_arg(parser_light_id)
  53. parser_light_id.add_argument('light_id', type=int, help='灯光寄存器ID')
  54. parser_light_id.add_argument('intensity', type=float, help='亮度值 (0.0-1.0)')
  55. args = parser.parse_args()
  56. try:
  57. if args.command == 'schedule':
  58. logging.info("接收到 'schedule' 指令,正在启动任务运行器...")
  59. task_runner = TaskRunner()
  60. task_runner.run()
  61. else:
  62. # 所有其他命令都是手动命令,需要 rack_name
  63. logging.info(f"接收到手动指令: 命令='{args.command}', 栽培架='{args.rack_name}'")
  64. config = load_config()
  65. rack = CultivationRack(args.rack_name, config)
  66. if args.command == 'layer-intensity':
  67. if not (0.0 <= args.intensity <= 1.0): raise ValueError("亮度值需在0.0-1.0之间")
  68. rack.set_layer_intensity(args.layer_id, args.intensity)
  69. elif args.command == 'on':
  70. rack.turn_on_all()
  71. elif args.command == 'off':
  72. rack.turn_off_all()
  73. elif args.command == 'layer-on':
  74. rack.turn_on_layer(args.layer_id)
  75. elif args.command == 'layer-off':
  76. rack.turn_off_layer(args.layer_id)
  77. elif args.command == 'light-by-name':
  78. if not (0.0 <= args.intensity <= 1.0): raise ValueError("亮度值需在0.0-1.0之间")
  79. rack.set_light_by_name(args.name, args.intensity)
  80. elif args.command == 'light-by-id':
  81. if not (0.0 <= args.intensity <= 1.0): raise ValueError("亮度值需在0.0-1.0之间")
  82. rack.set_light_by_id(args.light_id, args.intensity)
  83. except (ValueError, KeyError, ConnectionError, IOError) as e:
  84. logging.error(f"操作失败: {e}", exc_info=True)
  85. except Exception as e:
  86. logging.error(f"发生未知错误: {e}", exc_info=True)
  87. if __name__ == "__main__":
  88. logging.basicConfig(
  89. level=logging.INFO,
  90. format='%(asctime)s - %(levelname)s - %(message)s'
  91. )
  92. main()