# main.py import logging import sys import argparse from pathlib import Path # --- 路径设置 --- SRC_DIR = Path(__file__).resolve().parent / 'src' sys.path.append(str(SRC_DIR)) # --- 模块导入 --- from PFAL_SysControl.Controller.cultivation_rack import CultivationRack from PFAL_SysControl.Core.task_runner import TaskRunner from PFAL_SysControl.Utils.utils import load_config def main(): """ 程序主入口,负责解析命令行参数并执行相应操作。 """ parser = argparse.ArgumentParser( description="PFAL 系统命令行控制器。" ) subparsers = parser.add_subparsers( dest='command', required=True, help='可执行的具体命令' ) # --- 任务调度命令 --- subparsers.add_parser( 'schedule', help='启动一个由 task.yml 定义的长期数据采集和光照采样任务。' ) # --- 手动灯光控制命令 (扁平化结构) --- def add_rack_name_arg(p): p.add_argument('rack_name', help="要操作的栽培架/控制器名称 (例如 'controller1')") parser_on = subparsers.add_parser('on', help='打开指定栽培架上的所有灯光') add_rack_name_arg(parser_on) parser_off = subparsers.add_parser('off', help='关闭指定栽培架上的所有灯光') add_rack_name_arg(parser_off) parser_layer_on = subparsers.add_parser('layer-on', help='打开指定层') add_rack_name_arg(parser_layer_on) parser_layer_on.add_argument('layer_id', type=int, help='层ID') parser_layer_off = subparsers.add_parser('layer-off', help='关闭指定层') add_rack_name_arg(parser_layer_off) parser_layer_off.add_argument('layer_id', type=int, help='层ID') parser_layer_intensity = subparsers.add_parser('layer-intensity', help='设置指定层的亮度') add_rack_name_arg(parser_layer_intensity) parser_layer_intensity.add_argument('layer_id', type=int, help='层ID') parser_layer_intensity.add_argument('intensity', type=float, help='亮度值 (0.0-1.0)') parser_light_name = subparsers.add_parser('light-by-name', help='按名称设置灯光') add_rack_name_arg(parser_light_name) parser_light_name.add_argument('name', help='灯光名称') parser_light_name.add_argument('intensity', type=float, help='亮度值 (0.0-1.0)') parser_light_id = subparsers.add_parser('light-by-id', help='按ID设置灯光') add_rack_name_arg(parser_light_id) parser_light_id.add_argument('light_id', type=int, help='灯光寄存器ID') parser_light_id.add_argument('intensity', type=float, help='亮度值 (0.0-1.0)') args = parser.parse_args() try: if args.command == 'schedule': logging.info("接收到 'schedule' 指令,正在启动任务运行器...") task_runner = TaskRunner() task_runner.run() else: # 所有其他命令都是手动命令,需要 rack_name logging.info(f"接收到手动指令: 命令='{args.command}', 栽培架='{args.rack_name}'") config = load_config() rack = CultivationRack(args.rack_name, config) if args.command == 'layer-intensity': if not (0.0 <= args.intensity <= 1.0): raise ValueError("亮度值需在0.0-1.0之间") rack.set_layer_intensity(args.layer_id, args.intensity) elif args.command == 'on': rack.turn_on_all() elif args.command == 'off': rack.turn_off_all() elif args.command == 'layer-on': rack.turn_on_layer(args.layer_id) elif args.command == 'layer-off': rack.turn_off_layer(args.layer_id) elif args.command == 'light-by-name': if not (0.0 <= args.intensity <= 1.0): raise ValueError("亮度值需在0.0-1.0之间") rack.set_light_by_name(args.name, args.intensity) elif args.command == 'light-by-id': if not (0.0 <= args.intensity <= 1.0): raise ValueError("亮度值需在0.0-1.0之间") rack.set_light_by_id(args.light_id, args.intensity) except (ValueError, KeyError, ConnectionError, IOError) as e: logging.error(f"操作失败: {e}", exc_info=True) except Exception as e: logging.error(f"发生未知错误: {e}", exc_info=True) if __name__ == "__main__": logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) main()