import 'dart:convert'; import '../../programs/models/program.dart'; import '../../programs/models/step.dart'; import 'device_message.dart'; /// 下位机启动任务负载 /// /// 将上位机 [Program] + [Step] 列表转换为下位机协议要求的 `create_task` 数据。 /// 协议示例: /// ```json /// { /// "steps": [ /// {"no": 1, "slot": 1, "name": "混合", "mixtime": 60, "pulltime": 30, "volume": 100, "speed": 5} /// ], /// "temperature": 50, /// "airflowtime": 60 /// } /// ``` class TaskPayload { final List steps; final int temperature; final int airflowTime; const TaskPayload({ required this.steps, required this.temperature, required this.airflowTime, }); /// 从程序和步骤列表构造负载 factory TaskPayload.fromProgram(Program program, List steps) { return TaskPayload( steps: List.from(steps) ..sort((a, b) => a.stepNo.compareTo(b.stepNo)), temperature: program.temperature, airflowTime: program.airflowTime, ); } /// 转换为下位机协议 Map Map toJson() { return { 'steps': steps.map((s) => _stepToJson(s)).toList(), 'temperature': temperature, 'airflowtime': airflowTime, }; } /// 序列化为 JSON 字符串 String encode() => jsonEncode(toJson()); /// 包裹为下位机 [DeviceMessage] DeviceMessage toMessage(String messageId, {bool needAck = true}) { return DeviceMessage.request( messageId: messageId, type: DeviceMessageType.createTask, data: toJson(), needAck: needAck, ); } Map _stepToJson(Step s) { return { 'no': s.stepNo, 'slot': _slotFromPosition(s.position), 'name': s.name, 'mixtime': s.mixTime, 'pulltime': s.magnetTime, 'volume': s.volume, 'speed': s.speed, }; } /// 将孔位(如 "A1")转换为下位机使用的整数编号 /// 协议约定:A1=1, A2=2, ..., A6=6, B1=7, ..., D6=24 static int _slotFromPosition(String position) { if (position.length < 2) return 1; final row = position.codeUnitAt(0) - 'A'.codeUnitAt(0); final col = int.tryParse(position.substring(1)) ?? 1; if (row < 0 || row > 3 || col < 1 || col > 6) return 1; return row * 6 + col; } }