diff --git a/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/api/EdgeMicrophoneController.java b/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/api/EdgeMicrophoneController.java index c2c2f8b..99827ac 100644 --- a/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/api/EdgeMicrophoneController.java +++ b/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/api/EdgeMicrophoneController.java @@ -44,8 +44,7 @@ public class EdgeMicrophoneController { @PreAuthorize("@ss.hasPermi('system:microphone:stop')") @PostMapping("/stop") public AjaxResult stopRecord(@RequestBody EdgeCommonVO edgeCommonVO) { - microphoneService.stopRecord(edgeCommonVO); - return AjaxResult.success(); + return AjaxResult.success(microphoneService.stopRecord(edgeCommonVO)); } @ApiOperation("暂停录音") diff --git a/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/api/EdgeSystemController.java b/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/api/EdgeSystemController.java index fd2906b..fdb528f 100644 --- a/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/api/EdgeSystemController.java +++ b/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/api/EdgeSystemController.java @@ -5,6 +5,7 @@ import com.cmvr.common.core.controller.BaseController; import com.cmvr.common.core.domain.AjaxResult; import com.cmvr.edge.client.model.system.EdgeSystemJsonCommandVO; import com.cmvr.edge.client.model.system.EdgeSystemUpdateParamsVO; +import com.cmvr.edge.client.model.system.EdgeActionQueueVO; import com.cmvr.edge.client.service.EdgeSystemService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -48,6 +49,12 @@ public class EdgeSystemController extends BaseController { return success(JSON.toJSONString(edgeSystemService.executeJsonCommand(request))); } + @ApiOperation("Execute an edge-local serial action queue") + @PostMapping("/actionQueue") + public AjaxResult executeActionQueue(@RequestBody EdgeActionQueueVO request) { + return success(JSON.toJSONString(edgeSystemService.executeActionQueue(request))); + } + @ApiOperation("停止所有设备") @GetMapping("/stopAll") public AjaxResult stopAll(@RequestParam("robotId") String robotId) { diff --git a/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/test/TeFlowiseController.java b/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/test/TeFlowiseController.java index d1b168d..4aac77b 100644 --- a/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/test/TeFlowiseController.java +++ b/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/test/TeFlowiseController.java @@ -16,6 +16,7 @@ import com.google.gson.JsonObject; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -50,8 +51,9 @@ public class TeFlowiseController extends BaseController { .put("test", request.getQuestion()); runParams.put("5bb26d52e1861c6936f3c3149eaf17e8", runParams1); TeTaskExecuteNormalVO taskExecuteNormalVO = TeTaskExecuteNormalVO.builder() - .taskId("b6ab5ffff783d9b25d0dc34f13be222d") - .robotId("4ed1246c465b97975f96c9ef8371a3bd") + .taskId(StringUtils.defaultIfBlank(request.getTaskId(), "b6ab5ffff783d9b25d0dc34f13be222d")) + .robotId(StringUtils.defaultIfBlank(request.getRobotId(), "4ed1246c465b97975f96c9ef8371a3bd")) + .runtimeAssignments(request.getRuntimeAssignments()) .runParams(JSONObject.from(runParams)).build(); if (!taskInstIdList.isEmpty()) { try { @@ -112,4 +114,4 @@ public class TeFlowiseController extends BaseController { public AjaxResult actionStop() { return AjaxResult.ok(flowiseActionService.actionStop()); } -} \ No newline at end of file +} diff --git a/cmvr-iot-admin/src/main/resources/application.yml b/cmvr-iot-admin/src/main/resources/application.yml index 0dd4850..2d17ba5 100644 --- a/cmvr-iot-admin/src/main/resources/application.yml +++ b/cmvr-iot-admin/src/main/resources/application.yml @@ -48,6 +48,9 @@ user: # Spring配置 spring: + jackson: + date-format: "yyyy-MM-dd HH:mm:ss" + time-zone: Asia/Shanghai sql: init: mode: always diff --git a/cmvr-iot-aima/src/main/java/com/cmvr/aima/domain/AimaTestLog.java b/cmvr-iot-aima/src/main/java/com/cmvr/aima/domain/AimaTestLog.java index 74142dc..62b881d 100644 --- a/cmvr-iot-aima/src/main/java/com/cmvr/aima/domain/AimaTestLog.java +++ b/cmvr-iot-aima/src/main/java/com/cmvr/aima/domain/AimaTestLog.java @@ -2,6 +2,7 @@ package com.cmvr.aima.domain; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.*; @@ -46,6 +47,18 @@ public class AimaTestLog extends BaseEntity @ApiModelProperty("测试用例ID") private String testCaseId; + /** 工作流检测项 ID,仅用于接口和 WebSocket 展示,不落日志表。 */ + @TableField(exist = false) + private String itemId; + + /** 当前绑定项的执行位置,从 1 开始。 */ + @TableField(exist = false) + private Integer itemOrder; + + /** 同一检测项在任务中第几次出现。 */ + @TableField(exist = false) + private Integer itemOccurrence; + @Excel(name = "用例名称") @ApiModelProperty("用例名称") private String caseName; diff --git a/cmvr-iot-aima/src/main/java/com/cmvr/aima/domain/vo/AimaTaskStartVO.java b/cmvr-iot-aima/src/main/java/com/cmvr/aima/domain/vo/AimaTaskStartVO.java index 46dccaf..7520745 100644 --- a/cmvr-iot-aima/src/main/java/com/cmvr/aima/domain/vo/AimaTaskStartVO.java +++ b/cmvr-iot-aima/src/main/java/com/cmvr/aima/domain/vo/AimaTaskStartVO.java @@ -1,5 +1,6 @@ package com.cmvr.aima.domain.vo; +import com.alibaba.fastjson2.JSONObject; import com.cmvr.test.model.vo.ResourceRuntimeAssignmentVO; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -17,4 +18,7 @@ public class AimaTaskStartVO { @ApiModelProperty("机器人角色运行分配") private List runtimeAssignments = new ArrayList<>(); + + @ApiModelProperty("按检测项和出现序号组织的本次运行参数") + private JSONObject runParams = new JSONObject(); } diff --git a/cmvr-iot-aima/src/main/java/com/cmvr/aima/listener/AimaFlowExecutionListener.java b/cmvr-iot-aima/src/main/java/com/cmvr/aima/listener/AimaFlowExecutionListener.java index 58c4ecb..20796d7 100644 --- a/cmvr-iot-aima/src/main/java/com/cmvr/aima/listener/AimaFlowExecutionListener.java +++ b/cmvr-iot-aima/src/main/java/com/cmvr/aima/listener/AimaFlowExecutionListener.java @@ -1,16 +1,19 @@ package com.cmvr.aima.listener; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSONObject; import com.cmvr.common.utils.DateUtils; import com.cmvr.framework.websocket.service.MessagePushService; import com.cmvr.aima.domain.AimaTaskInstance; import com.cmvr.aima.domain.AimaTestLog; import com.cmvr.aima.enums.AimaTaskStatusEnum; import com.cmvr.aima.service.IAimaTaskInstanceService; +import com.cmvr.aima.service.IAimaTaskService; import com.cmvr.aima.service.IAimaTestLogService; import com.cmvr.test.flow.runtime.event.FlowExecutionEvent; import com.cmvr.test.flow.runtime.event.FlowExecutionListener; import com.cmvr.test.flow.runtime.event.FlowExecutionModuleCodes; +import com.cmvr.test.flow.runtime.operator.FlowMediaParamResolver; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -28,18 +31,23 @@ import java.util.*; public class AimaFlowExecutionListener implements FlowExecutionListener { private final IAimaTaskInstanceService aimaTaskInstanceService; private final IAimaTestLogService aimaTestLogService; + private final IAimaTaskService aimaTaskService; private final MessagePushService messagePushService; /** key:itemId, value:已完成节点集合 */ - private final Map> itemNodeExecutMap = new HashMap<>(); + private final Map> itemNodeExecutMap = new java.util.concurrent.ConcurrentHashMap<>(); /** key:taskInsId(流程实例id), value:已执行item集合 */ - private final Map> taskItemExecutMap = new HashMap<>(); + private final Map> taskItemExecutMap = new java.util.concurrent.ConcurrentHashMap<>(); + /** key: flow instance ID, value: test case IDs in binding order. */ + private final Map> taskCaseBindingMap = new java.util.concurrent.ConcurrentHashMap<>(); public AimaFlowExecutionListener(IAimaTaskInstanceService aimaTaskInstanceService, IAimaTestLogService aimaTestLogService, + IAimaTaskService aimaTaskService, MessagePushService messagePushService) { this.aimaTaskInstanceService = aimaTaskInstanceService; this.aimaTestLogService = aimaTestLogService; + this.aimaTaskService = aimaTaskService; this.messagePushService = messagePushService; } @@ -60,11 +68,13 @@ public class AimaFlowExecutionListener implements FlowExecutionListener { // 1.节点完成才记录当前item下node if (StrUtil.isNotBlank(itemId) && StrUtil.isNotBlank(nodeId) && FlowExecutionEvent.EventType.NODE_COMPLETED == event.getEventType()) { - itemNodeExecutMap.computeIfAbsent(itemId, k -> new HashSet<>()).add(nodeId); + itemNodeExecutMap.computeIfAbsent(itemExecutionKey(instId, event), + k -> java.util.concurrent.ConcurrentHashMap.newKeySet()).add(nodeId); } // 任意事件:当前任务绑定item(item一启动就入Map) if (StrUtil.isNotBlank(instId) && StrUtil.isNotBlank(itemId)) { - taskItemExecutMap.computeIfAbsent(instId, k -> new HashSet<>()).add(itemId); + taskItemExecutMap.computeIfAbsent(instId, + k -> java.util.concurrent.ConcurrentHashMap.newKeySet()).add(itemExecutionKey(instId, event)); } // 查询任务实例 @@ -114,11 +124,14 @@ public class AimaFlowExecutionListener implements FlowExecutionListener { int finishedItemNum = itemTotal - 1; // 当前item已完成节点数 - Set finishedNodeSet = itemNodeExecutMap.getOrDefault(itemId, new HashSet<>()); + Set finishedNodeSet = itemNodeExecutMap.getOrDefault(itemExecutionKey(instId, event), new HashSet<>()); int finishedNode = finishedNodeSet.size(); int totalNode = event.getNodeCount() == 0 ? 1 : event.getNodeCount(); // 已完整跑完用例占比 + if (event.getItemOrder() != null && event.getItemOrder() > 0) { + finishedItemNum = event.getItemOrder() - 1; + } double itemTotalRatio = finishedItemNum / (double) totalCases; // 当前运行item内部节点占比 double innerRatio = finishedNode / (double) totalNode / totalCases; @@ -134,16 +147,27 @@ public class AimaFlowExecutionListener implements FlowExecutionListener { String logId = UUID.randomUUID().toString().replace("-", ""); // 四舍五入保留2位小数 progress = Math.round(progress * 100) / 100.0; + JSONObject outputParams = event.getOutputParams(); + String imageUrl = FlowMediaParamResolver.lastUrl(outputParams, "imageUrl"); + String videoUrl = FlowMediaParamResolver.lastUrl(outputParams, "videoUrl"); + String testCaseId = resolveTestCaseId(instId, taskInstance.getTaskId(), event); // 保存日志到数据库 AimaTestLog testLog = AimaTestLog.builder() .id(logId) .taskInstanceId(taskInstance.getId()) .taskId(taskInstance.getTaskId()) - .testCaseId(itemId) + .testCaseId(testCaseId) + .itemId(itemId) + .itemOrder(event.getItemOrder()) + .itemOccurrence(event.getItemOccurrence()) .logLevel("INFO") .logType("执行日志") .logContent("节点【" + event.getNodeName() + "】" + info) + .actualResult(outputParams == null || outputParams.isEmpty() + ? null : outputParams.toJSONString()) + .screenshotUrl(imageUrl) + .videoUrl(videoUrl) .logTime(now) .status(targetStatus) .executionStep(event.getNodeName()) @@ -172,6 +196,24 @@ public class AimaFlowExecutionListener implements FlowExecutionListener { Set itemList = taskItemExecutMap.getOrDefault(taskInsId, new HashSet<>()); itemList.forEach(itemNodeExecutMap::remove); taskItemExecutMap.remove(taskInsId); + taskCaseBindingMap.remove(taskInsId); + } + + private String itemExecutionKey(String taskInsId, FlowExecutionEvent event) { + if (event.getItemOrder() != null && event.getItemOrder() > 0) { + return taskInsId + "|" + event.getItemOrder(); + } + return taskInsId + "|" + event.getItemId(); + } + + private String resolveTestCaseId(String taskInsId, String taskId, FlowExecutionEvent event) { + if (event.getItemOrder() == null || event.getItemOrder() < 1) { + return event.getItemId(); + } + List testCaseIds = taskCaseBindingMap.computeIfAbsent(taskInsId, + key -> aimaTaskService.getTestCaseIds(taskId).stream().map(testCase -> testCase.getId()).toList()); + int index = event.getItemOrder() - 1; + return index < testCaseIds.size() ? testCaseIds.get(index) : event.getItemId(); } /** diff --git a/cmvr-iot-aima/src/main/java/com/cmvr/aima/mapper/AimaTaskTestCaseMapper.java b/cmvr-iot-aima/src/main/java/com/cmvr/aima/mapper/AimaTaskTestCaseMapper.java index 555e8ca..b74061a 100644 --- a/cmvr-iot-aima/src/main/java/com/cmvr/aima/mapper/AimaTaskTestCaseMapper.java +++ b/cmvr-iot-aima/src/main/java/com/cmvr/aima/mapper/AimaTaskTestCaseMapper.java @@ -5,6 +5,7 @@ import java.util.List; import com.github.yulichang.base.MPJBaseMapper; import org.apache.ibatis.annotations.Param; import com.cmvr.aima.domain.AimaTaskTestCase; +import com.cmvr.aima.domain.AimaTestCase; /** * 爱玛任务与测试用例关联Mapper接口 @@ -38,6 +39,9 @@ public interface AimaTaskTestCaseMapper extends MPJBaseMapper */ List selectTestCaseIdsByTaskId(String taskId); + /** 按任务中的位置查询用例,重复用例会返回多条独立记录。 */ + List selectTestCasesByTaskId(String taskId); + /** * 批量删除任务-测试用例关联 * diff --git a/cmvr-iot-aima/src/main/java/com/cmvr/aima/service/impl/AimaTaskInstanceServiceImpl.java b/cmvr-iot-aima/src/main/java/com/cmvr/aima/service/impl/AimaTaskInstanceServiceImpl.java index b5fef16..6e99d33 100644 --- a/cmvr-iot-aima/src/main/java/com/cmvr/aima/service/impl/AimaTaskInstanceServiceImpl.java +++ b/cmvr-iot-aima/src/main/java/com/cmvr/aima/service/impl/AimaTaskInstanceServiceImpl.java @@ -2,6 +2,7 @@ package com.cmvr.aima.service.impl; import java.util.List; import java.util.UUID; +import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.spring.service.impl.ServiceImpl; import com.cmvr.aima.domain.dto.AimaTaskInstanceQuery; @@ -13,6 +14,7 @@ import com.cmvr.test.flow.control.FlowControlService; import com.cmvr.test.flow.runtime.engine.FlowTaskRuntimeService; import com.cmvr.test.flow.runtime.event.FlowExecutionModuleCodes; import com.cmvr.test.model.vo.TeTaskExecuteNormalVO; +import com.cmvr.test.model.vo.TeTaskOrchestraVO; import com.cmvr.test.service.ITeTaskOrchestrationService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; @@ -25,6 +27,9 @@ import com.cmvr.aima.enums.AimaTaskStatusEnum; import com.cmvr.aima.service.IAimaTaskService; import com.cmvr.aima.domain.AimaTask; import org.springframework.transaction.annotation.Transactional; +import java.util.stream.Collectors; +import java.util.HashMap; +import java.util.Map; /** * 爱玛任务执行实例Service业务层处理 @@ -138,12 +143,37 @@ public class AimaTaskInstanceServiceImpl extends ServiceImpl runParams.put(item.getItemId(), new JSONObject())); + if (aimaTask == null || StrUtil.isBlank(aimaTask.getTaskConfigId())) { + throw new ServiceException("智能测试任务没有关联流程编排"); } + List orderedItemIds = aimaTaskService.getTestCaseIds(instance.getTaskId()).stream() + .map(com.cmvr.aima.domain.AimaTestCase::getDetectItemId) + .filter(StrUtil::isNotBlank) + .collect(Collectors.toList()); + if (orderedItemIds.isEmpty()) { + throw new ServiceException("智能测试任务没有绑定可执行的测试用例"); + } + teTaskOrchestrationService.insertTeTaskOrchestration(TeTaskOrchestraVO.builder() + .taskId(aimaTask.getTaskConfigId()) + .itemIds(orderedItemIds) + .build()); + JSONObject runParams = new JSONObject(); + JSONObject requestedRunParams = startVO == null ? null : startVO.getRunParams(); + Map itemOccurrences = new HashMap<>(); + // 从test模块的任务编排中获取所有的检测项id + teTaskOrchestrationService.queryByTaskId(aimaTask.getTaskConfigId()).forEach(item -> { + int occurrence = itemOccurrences.merge(item.getItemId(), 1, Integer::sum); + JSONObject submitted = requestedRunParams == null ? null + : requestedRunParams.getJSONObject(item.getItemId() + ":" + occurrence); + if (submitted == null && requestedRunParams != null) { + submitted = requestedRunParams.getJSONObject(item.getItemId()); + } + JSONObject itemParams = submitted == null ? new JSONObject() : new JSONObject(submitted); + itemParams.put("phoneId", instance.getPhoneId()); + itemParams.put("vehicleId", instance.getVehicleId()); + itemParams.put("taskInstanceId", instance.getId()); + runParams.put(item.getItemId() + ":" + occurrence, itemParams); + }); // 调用流程引擎执行 String insId = flowTaskRuntimeService.executeTask( TeTaskExecuteNormalVO.builder() diff --git a/cmvr-iot-aima/src/main/java/com/cmvr/aima/service/impl/AimaTaskServiceImpl.java b/cmvr-iot-aima/src/main/java/com/cmvr/aima/service/impl/AimaTaskServiceImpl.java index 110d74e..14cf561 100644 --- a/cmvr-iot-aima/src/main/java/com/cmvr/aima/service/impl/AimaTaskServiceImpl.java +++ b/cmvr-iot-aima/src/main/java/com/cmvr/aima/service/impl/AimaTaskServiceImpl.java @@ -6,7 +6,6 @@ import java.util.List; import java.util.UUID; import java.util.stream.Collectors; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.spring.service.impl.ServiceImpl; import com.cmvr.aima.domain.AimaTaskTestCase; import com.cmvr.aima.domain.AimaTestCase; @@ -111,6 +110,21 @@ public class AimaTaskServiceImpl extends ServiceImpl i @Override public void bindTestCases(String taskId, List testCaseIds) { + aimaTaskTestCaseMapper.deleteTaskTestCaseByTaskId(taskId); + AimaTask existingTask = aimaTaskMapper.selectAimaTaskById(taskId); + if (existingTask == null) { + throw new IllegalArgumentException("任务不存在: " + taskId); + } + if (testCaseIds == null || testCaseIds.isEmpty()) { + AimaTask emptyTask = new AimaTask(); + emptyTask.setId(taskId); + emptyTask.setTestCaseCount(0); + aimaTaskMapper.updateAimaTask(emptyTask); + if (existingTask.getTaskConfigId() != null) { + teTaskOrchestrationService.deleteByTaskId(existingTask.getTaskConfigId()); + } + return; + } // 先删除旧的关联 aimaTaskTestCaseMapper.deleteTaskTestCaseByTaskId(taskId); @@ -121,7 +135,7 @@ public class AimaTaskServiceImpl extends ServiceImpl i AimaTaskTestCase taskTestCase = new AimaTaskTestCase(); taskTestCase.setTaskId(taskId); taskTestCase.setTestCaseId(testCaseIds.get(i)); - taskTestCase.setSortOrder(i); + taskTestCase.setSortOrder(i + 1); list.add(taskTestCase); } aimaTaskTestCaseMapper.batchInsertTaskTestCase(list); @@ -133,27 +147,27 @@ public class AimaTaskServiceImpl extends ServiceImpl i aimaTaskMapper.updateAimaTask(task); // 查询测试用例,获取detectItemId列表 - List testCases = aimaTestCaseMapper.selectBatchIds(testCaseIds); + List testCases = getTestCaseIds(taskId); List detectItemIds = testCases.stream() .map(AimaTestCase::getDetectItemId) .filter(itemId -> itemId != null && !itemId.isEmpty()) .collect(Collectors.toList()); // 同步任务编排到test模块 - if (!detectItemIds.isEmpty()) { - AimaTask aimaTask = aimaTaskMapper.selectAimaTaskById(taskId); + if (!detectItemIds.isEmpty() && existingTask.getTaskConfigId() != null) { TeTaskOrchestraVO teTaskOrchestraVO = TeTaskOrchestraVO.builder() - .taskId(aimaTask.getTaskConfigId()) + .taskId(existingTask.getTaskConfigId()) .itemIds(detectItemIds) .build(); teTaskOrchestrationService.insertTeTaskOrchestration(teTaskOrchestraVO); + } else if (existingTask.getTaskConfigId() != null) { + teTaskOrchestrationService.deleteByTaskId(existingTask.getTaskConfigId()); } } } @Override public List getTestCaseIds(String taskId) { - List ids = aimaTaskTestCaseMapper.selectTestCaseIdsByTaskId(taskId); - return aimaTestCaseMapper.selectList(new QueryWrapper().in("id", ids)); + return aimaTaskTestCaseMapper.selectTestCasesByTaskId(taskId); } } diff --git a/cmvr-iot-aima/src/main/resources/mapper/aima/AimaTaskTestCaseMapper.xml b/cmvr-iot-aima/src/main/resources/mapper/aima/AimaTaskTestCaseMapper.xml index 4ed38ac..f68d9a5 100644 --- a/cmvr-iot-aima/src/main/resources/mapper/aima/AimaTaskTestCaseMapper.xml +++ b/cmvr-iot-aima/src/main/resources/mapper/aima/AimaTaskTestCaseMapper.xml @@ -16,7 +16,32 @@ + + diff --git a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/model/system/EdgeActionQueueVO.java b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/model/system/EdgeActionQueueVO.java new file mode 100644 index 0000000..e97d9fa --- /dev/null +++ b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/model/system/EdgeActionQueueVO.java @@ -0,0 +1,24 @@ +package com.cmvr.edge.client.model.system; + +import com.alibaba.fastjson2.JSONObject; +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +@Data +public class EdgeActionQueueVO { + private String robotId; + private String actionId; + private Integer totalTimeoutMs; + private List steps = new ArrayList<>(); + + @Data + public static class Step { + private String stepId; + private String type; + private String deviceId; + private Integer timeoutMs; + private JSONObject params = new JSONObject(); + } +} diff --git a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/EdgeCameraService.java b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/EdgeCameraService.java index c0a91ea..02919b7 100644 --- a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/EdgeCameraService.java +++ b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/EdgeCameraService.java @@ -5,6 +5,7 @@ import com.cmvr.edge.client.model.EdgeCommonVO; import com.cmvr.edge.client.model.camera.EdgeCameraPtzVO; import io.grpc.stub.StreamObserver; +import java.io.File; import java.io.OutputStream; /** @@ -49,6 +50,12 @@ public interface EdgeCameraService { */ public String stopRecording(EdgeCommonVO edgeCommonVO); + /** Starts a backend-local recording session from the robot camera stream. */ + String startWorkflowRecording(EdgeCommonVO edgeCommonVO); + + /** Stops and finalizes a backend-local workflow recording. */ + File stopWorkflowRecording(EdgeCommonVO edgeCommonVO, String recordingId); + /** * 获取相机图片组 */ diff --git a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/EdgeMicrophoneService.java b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/EdgeMicrophoneService.java index 6d66a8b..75beeb6 100644 --- a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/EdgeMicrophoneService.java +++ b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/EdgeMicrophoneService.java @@ -4,6 +4,8 @@ import cmvr.api.MicrophoneCommand; import com.cmvr.edge.client.model.EdgeCommonVO; import com.cmvr.edge.client.model.microphone.EdgeMicrophoneVolumeVO; +import java.io.File; + /** * 边缘麦克风服务接口 * 定义了与边缘麦克风进行交互的所有方法 @@ -25,6 +27,12 @@ public interface EdgeMicrophoneService { */ String stopRecord(EdgeCommonVO edgeCommonVO); + /** Starts a backend-local WAV recording from the robot microphone stream. */ + String startWorkflowRecording(EdgeCommonVO edgeCommonVO); + + /** Stops and finalizes a backend-local workflow recording. */ + File stopWorkflowRecording(EdgeCommonVO edgeCommonVO, String recordingId); + /** * 暂停录音 */ @@ -44,4 +52,4 @@ public interface EdgeMicrophoneService { * 获取当前音量 */ int getVolume(EdgeCommonVO edgeCommonVO); -} \ No newline at end of file +} diff --git a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/EdgeSystemService.java b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/EdgeSystemService.java index 6042306..121f7d1 100644 --- a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/EdgeSystemService.java +++ b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/EdgeSystemService.java @@ -5,6 +5,7 @@ import cmvr.api.SystemCommand; import com.cmvr.device.domain.DeDeviceRegistration; import com.cmvr.edge.client.model.system.EdgeSystemJsonCommandVO; import com.cmvr.edge.client.model.system.EdgeSystemUpdateParamsVO; +import com.cmvr.edge.client.model.system.EdgeActionQueueVO; import java.util.List; @@ -24,6 +25,8 @@ public interface EdgeSystemService { Common.JsonDeviceCommand.Feedback executeJsonCommand(EdgeSystemJsonCommandVO request); + SystemCommand.ActionQueueCommand.Feedback executeActionQueue(EdgeActionQueueVO request); + public List deviceList(String robotId); diff --git a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/impl/EdgeCameraServiceImpl.java b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/impl/EdgeCameraServiceImpl.java index c79c994..b72cba1 100644 --- a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/impl/EdgeCameraServiceImpl.java +++ b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/impl/EdgeCameraServiceImpl.java @@ -22,9 +22,11 @@ import com.cmvr.system.service.ISysFileService; import com.google.protobuf.ByteString; import io.grpc.Status; import io.grpc.stub.StreamObserver; +import jakarta.annotation.PreDestroy; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.MediaType; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -45,6 +47,7 @@ import java.awt.image.WritableRaster; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; @@ -53,7 +56,11 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Base64; import java.util.Iterator; +import java.util.Map; +import java.util.UUID; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; @@ -64,18 +71,26 @@ import java.util.concurrent.atomic.AtomicReference; @RequiredArgsConstructor public class EdgeCameraServiceImpl implements EdgeCameraService, EdgeStreamService { + private static final long RECORDING_FINALIZE_TIMEOUT_SECONDS = 15L; + private static final long RECORDING_FIRST_FRAME_TIMEOUT_SECONDS = 10L; + private static final long RECORDING_MAX_AGE_MILLIS = TimeUnit.HOURS.toMillis(6L); + private final GrpcServiceManager grpcServiceManager; private final ISysFileService sysFileService; private final MessagePushService messagePushService; + private final Map workflowRecordings = new ConcurrentHashMap<>(); + @Override public CameraCommand.CameraState status(EdgeCommonVO edgeCommonVO) { CameraServiceGrpc.CameraServiceBlockingStub stub = grpcServiceManager.getGrpcClient(edgeCommonVO.getRobotId(), CameraServiceGrpc.CameraServiceBlockingStub.class); CameraCommand.GetCameraStateCommand.Request request = CameraCommand.GetCameraStateCommand.Request.newBuilder() .setHeader(EdgeCommonUtil.buildRequest(edgeCommonVO.getDeviceId())) .build(); - return executeGrpcCall(() -> stub.getStatus(request)).getState(); + CameraCommand.GetCameraStateCommand.Feedback feedback = executeGrpcCall(() -> stub.getStatus(request)); + requireSuccess(feedback.getHeader(), "获取相机状态"); + return feedback.getState(); } @Override @@ -94,6 +109,7 @@ public class EdgeCameraServiceImpl implements EdgeCameraService, EdgeStreamServi .setHeader(EdgeCommonUtil.buildRequest(edgeCommonVO.getDeviceId())) .build(); Common.CommandHeader.Feedback header = executeGrpcCall(() -> stub.startCamera(request)).getHeader(); + requireSuccess(header, "开启相机"); return JSON.toJSONString(header); } @@ -103,7 +119,9 @@ public class EdgeCameraServiceImpl implements EdgeCameraService, EdgeStreamServi CameraCommand.StopCameraCommand.Request request = CameraCommand.StopCameraCommand.Request.newBuilder() .setHeader(EdgeCommonUtil.buildRequest(edgeCommonVO.getDeviceId())) .build(); + abortWorkflowRecordings(edgeCommonVO); Common.CommandHeader.Feedback header = executeGrpcCall(() -> stub.stopCamera(request)).getHeader(); + requireSuccess(header, "关闭相机"); return JSON.toJSONString(header); } @@ -118,20 +136,23 @@ public class EdgeCameraServiceImpl implements EdgeCameraService, EdgeStreamServi .setHeader(EdgeCommonUtil.buildRequest(edgeCommonVO.getDeviceId())) .build(); CameraCommand.GetRGBImageCommand.Feedback feedback = executeGrpcCall(() -> stub.getRGBImage(request)); + requireSuccess(feedback.getHeader(), "获取相机图片"); CameraCommand.FrameData frame = feedback.getColorFrame(); if (!feedback.hasColorFrame() || frame.getWidth() <= 0 || frame.getHeight() <= 0) { - throw new GlobalException("响应图片数据无效"); + throw new GlobalException("获取相机图片失败: 响应图片数据无效"); } - String filePath = saveImage(frame.getData(), frame.getWidth(), frame.getHeight()); + String filePath = saveColorImage(frame); try { MultipartFile file = convertFileToMultipartFile(filePath); - return sysFileService.uploadFile(file, FileType.IMAGE.code()); + String imageUrl = sysFileService.uploadFile(file, FileType.IMAGE.code()); + if (StrUtil.isBlank(imageUrl)) { + throw new GlobalException("获取相机图片失败: 文件上传未返回图片地址"); + } + return imageUrl; } catch (IOException e) { - throw new GlobalException("图片上传失败: " + e.getMessage()); + throw new GlobalException("获取相机图片失败: " + e.getMessage()); } finally { deleteTempFile(filePath); -// todo 暂时不关闭摄像头 -// stop(robotId, deviceId); } } @@ -186,6 +207,70 @@ public class EdgeCameraServiceImpl implements EdgeCameraService, EdgeStreamServi return JSON.toJSONString(header); } + @Override + public String startWorkflowRecording(EdgeCommonVO edgeCommonVO) { + String recordingId = UUID.randomUUID().toString().replace("-", ""); + File outputFile; + try { + outputFile = File.createTempFile("cmvr-recording-" + recordingId + "-", ".mp4"); + } catch (IOException exception) { + throw new GlobalException("创建录像临时文件失败: " + exception.getMessage()); + } + + WorkflowRecordingSession session = new WorkflowRecordingSession( + recordingId, edgeCommonVO.getRobotId(), edgeCommonVO.getDeviceId(), outputFile); + workflowRecordings.put(recordingId, session); + try { + session.start(); + return recordingId; + } catch (RuntimeException exception) { + workflowRecordings.remove(recordingId); + session.abort(); + throw exception; + } + } + + @Override + public File stopWorkflowRecording(EdgeCommonVO edgeCommonVO, String recordingId) { + WorkflowRecordingSession session = workflowRecordings.remove(recordingId); + if (session == null) { + throw new GlobalException("录像会话不存在或已结束: " + recordingId); + } + if (!session.matches(edgeCommonVO.getRobotId(), edgeCommonVO.getDeviceId())) { + session.abort(); + throw new GlobalException("开始录像和结束录像使用的机器人或摄像头不一致"); + } + return session.finish(); + } + + private void abortWorkflowRecordings(EdgeCommonVO edgeCommonVO) { + workflowRecordings.forEach((recordingId, session) -> { + if (session.matches(edgeCommonVO.getRobotId(), edgeCommonVO.getDeviceId()) + && workflowRecordings.remove(recordingId, session)) { + log.info("关闭相机并终止关联的工作流录像: recordingId={}, robotId={}, deviceId={}", + recordingId, session.robotId, session.deviceId); + session.abort(); + } + }); + } + + @Scheduled(fixedDelay = 60_000L) + public void cleanExpiredWorkflowRecordings() { + workflowRecordings.forEach((recordingId, session) -> { + if (session.isExpired() && workflowRecordings.remove(recordingId, session)) { + log.warn("清理超时的工作流录像会话: recordingId={}, robotId={}, deviceId={}", + recordingId, session.robotId, session.deviceId); + session.abort(); + } + }); + } + + @PreDestroy + public void closeWorkflowRecordings() { + workflowRecordings.forEach((recordingId, session) -> session.abort()); + workflowRecordings.clear(); + } + @Override public String getRGBDImages(EdgeCommonVO edgeCommonVO) { if (!checkStatus(edgeCommonVO)) { @@ -483,6 +568,228 @@ public class EdgeCameraServiceImpl implements EdgeCameraService, EdgeStreamServi } + private final class WorkflowRecordingSession { + private final String recordingId; + private final String robotId; + private final String deviceId; + private final File outputFile; + private final long startedAtMillis = System.currentTimeMillis(); + private final AtomicBoolean stopped = new AtomicBoolean(false); + private final AtomicReference failure = new AtomicReference<>(); + private final AtomicReference> requestObserver = + new AtomicReference<>(); + + private FileOutputStream outputStream; + private H265Fmp4Transcoder transcoder; + private long firstFrameReadyAtMillis; + + private WorkflowRecordingSession(String recordingId, String robotId, String deviceId, File outputFile) { + this.recordingId = recordingId; + this.robotId = robotId; + this.deviceId = deviceId; + this.outputFile = outputFile; + } + + private void start() { + EdgeCommonVO target = new EdgeCommonVO(); + target.setRobotId(robotId); + target.setDeviceId(deviceId); + CameraCommand.CameraState cameraState = status(target); + if (cameraState.getIsError()) { + throw new GlobalException("Camera is in error state"); + } + if (!cameraState.getIsOpened() || !cameraState.getIsStreaming()) { + EdgeCameraServiceImpl.this.start(target); + cameraState = status(target); + } + + try { + outputStream = new FileOutputStream(outputFile); + transcoder = new H265Fmp4Transcoder( + "recording-" + recordingId, + cameraState.getFps(), + chunk -> writeChunk(chunk), + throwable -> { + recordFailure(throwable); + cancelStream(); + }); + transcoder.start(); + } catch (IOException exception) { + throw new GlobalException("初始化录像失败: " + exception.getMessage()); + } + + CameraServiceGrpc.CameraServiceStub stub = grpcServiceManager.getGrpcClient( + robotId, CameraServiceGrpc.CameraServiceStub.class); + StreamObserver responseObserver = + new StreamObserver() { + @Override + public void onNext(CameraCommand.GetRGBImageStreamCommand.Feedback value) { + if (!value.getHeader().getSuccess()) { + recordFailure(new GlobalException(value.getHeader().getErrorMessage())); + cancelStream(); + return; + } + try { + CameraCommand.FrameData frame = value.getColorFrame(); + transcoder.write(frame.getData().toByteArray(), frame.getIsKeyFrame(), frame.getCodec()); + } catch (IOException exception) { + recordFailure(exception); + cancelStream(); + } + } + + @Override + public void onError(Throwable throwable) { + if (!stopped.get() && Status.fromThrowable(throwable).getCode() != Status.Code.CANCELLED) { + recordFailure(throwable); + } + } + + @Override + public void onCompleted() { + if (!stopped.get()) { + recordFailure(new GlobalException("摄像头视频流提前结束")); + } + } + }; + + try { + StreamObserver observer = + stub.getRGBImageStream(responseObserver); + requestObserver.set(observer); + observer.onNext(CameraCommand.GetRGBImageStreamCommand.Request.newBuilder() + .setHeader(EdgeCommonUtil.buildRequest(deviceId)) + .setEof(false) + .build()); + awaitFirstRecordedFrame(); + } catch (RuntimeException exception) { + recordFailure(exception); + throw exception; + } + } + + private void awaitFirstRecordedFrame() { + try { + if (!transcoder.awaitFirstFrame(RECORDING_FIRST_FRAME_TIMEOUT_SECONDS, TimeUnit.SECONDS)) { + throw new GlobalException("启动录像失败: 10秒内未收到可写入的视频帧"); + } + } catch (InterruptedException exception) { + Thread.currentThread().interrupt(); + throw new GlobalException("等待录像首帧时被中断"); + } + Throwable transcoderFailure = failure.get(); + if (transcoderFailure != null) { + throw new GlobalException("启动录像失败: " + transcoderFailure.getMessage()); + } + firstFrameReadyAtMillis = System.currentTimeMillis(); + } + + private boolean matches(String expectedRobotId, String expectedDeviceId) { + return robotId.equals(expectedRobotId) && deviceId.equals(expectedDeviceId); + } + + private boolean isExpired() { + return System.currentTimeMillis() - startedAtMillis > RECORDING_MAX_AGE_MILLIS; + } + + private File finish() { + if (!stopped.compareAndSet(false, true)) { + throw new GlobalException("录像会话已结束: " + recordingId); + } + try { + cancelStream(); + if (transcoder != null) { + transcoder.close(); + try { + if (!transcoder.awaitTermination(RECORDING_FINALIZE_TIMEOUT_SECONDS, TimeUnit.SECONDS)) { + throw new GlobalException("录像文件封装超时"); + } + } catch (InterruptedException exception) { + Thread.currentThread().interrupt(); + throw new GlobalException("等待录像文件封装时被中断"); + } finally { + closeOutputStream(); + } + } else { + closeOutputStream(); + } + + Throwable sessionFailure = failure.get(); + if (sessionFailure != null) { + throw new GlobalException("录像失败: " + sessionFailure.getMessage()); + } + if (!outputFile.isFile() || outputFile.length() == 0L) { + throw new GlobalException("录像文件为空,请确认摄像头视频流正常"); + } + log.info("Workflow recording finalized: recordingId={}, robotId={}, deviceId={}, " + + "wallDurationMs={}, mediaTimelineMs={}, writtenFrames={}, fileBytes={}", + recordingId, robotId, deviceId, + firstFrameReadyAtMillis == 0L ? 0L : System.currentTimeMillis() - firstFrameReadyAtMillis, + Math.max(0L, transcoder.getLastWrittenTimestampMicros() / 1_000L), + transcoder.getWrittenFrameCount(), outputFile.length()); + return outputFile; + } catch (RuntimeException exception) { + deleteOutputFile(); + throw exception; + } + } + + private void abort() { + stopped.set(true); + cancelStream(); + if (transcoder != null) { + transcoder.close(); + try { + transcoder.awaitTermination(RECORDING_FINALIZE_TIMEOUT_SECONDS, TimeUnit.SECONDS); + } catch (InterruptedException exception) { + Thread.currentThread().interrupt(); + } + } + closeOutputStream(); + deleteOutputFile(); + } + + private void writeChunk(byte[] chunk) { + try { + outputStream.write(chunk); + } catch (IOException exception) { + throw new CameraStreamWriteException(exception); + } + } + + private void recordFailure(Throwable throwable) { + failure.compareAndSet(null, throwable); + } + + private void cancelStream() { + StreamObserver observer = requestObserver.getAndSet(null); + if (observer != null) { + try { + observer.onError(Status.CANCELLED.withDescription("workflow recording stopped").asRuntimeException()); + } catch (RuntimeException ignored) { + } + } + } + + private void closeOutputStream() { + if (outputStream != null) { + try { + outputStream.close(); + } catch (IOException exception) { + recordFailure(exception); + } finally { + outputStream = null; + } + } + } + + private void deleteOutputFile() { + if (outputFile.exists() && !outputFile.delete()) { + log.warn("删除录像临时文件失败: {}", outputFile.getAbsolutePath()); + } + } + } + @FunctionalInterface private interface GrpcCall { T call() throws Exception; @@ -496,6 +803,15 @@ public class EdgeCameraServiceImpl implements EdgeCameraService, EdgeStreamServi } } + private void requireSuccess(Common.CommandHeader.Feedback header, String operation) { + if (header == null || !header.getSuccess()) { + String detail = header == null || StrUtil.isBlank(header.getErrorMessage()) + ? "机器人未返回成功状态" + : header.getErrorMessage(); + throw new GlobalException(operation + "失败: " + detail); + } + } + private String rgbToBase64Bmp(byte[] rgbData, int width, int height) throws IOException { int rowSize = (width * 3 + 3) & ~3; // BMP 行对齐 int imageSize = rowSize * height; @@ -580,6 +896,42 @@ public class EdgeCameraServiceImpl implements EdgeCameraService, EdgeStreamServi return filePath; } + private String saveColorImage(CameraCommand.FrameData frame) { + int pixelCount = Math.multiplyExact(frame.getWidth(), frame.getHeight()); + byte[] source = frame.getData().toByteArray(); + switch (frame.getType()) { + case U8C1: + requireFrameBytes(source, pixelCount, frame.getType()); + return saveImage(ByteString.copyFrom(source, 0, pixelCount), + frame.getWidth(), frame.getHeight(), true); + case U8C3: + int colorBytes = Math.multiplyExact(pixelCount, 3); + requireFrameBytes(source, colorBytes, frame.getType()); + return saveImage(ByteString.copyFrom(source, 0, colorBytes), + frame.getWidth(), frame.getHeight()); + case U16C3: + int sourceBytes = Math.multiplyExact(pixelCount, 6); + requireFrameBytes(source, sourceBytes, frame.getType()); + byte[] eightBitColor = new byte[Math.multiplyExact(pixelCount, 3)]; + for (int targetIndex = 0, sourceIndex = 0; + targetIndex < eightBitColor.length; + targetIndex++, sourceIndex += Short.BYTES) { + // Camera frames use little-endian unsigned 16-bit channels. Keep the high byte for JPEG. + eightBitColor[targetIndex] = source[sourceIndex + 1]; + } + return saveImage(ByteString.copyFrom(eightBitColor), frame.getWidth(), frame.getHeight()); + default: + throw new GlobalException("获取相机图片失败: 不支持的彩色帧类型 " + frame.getType()); + } + } + + private void requireFrameBytes(byte[] source, int requiredBytes, CameraCommand.FrameData.FrameType type) { + if (source.length < requiredBytes) { + throw new GlobalException("获取相机图片失败: " + type + " 图片数据长度不足,期望至少 " + + requiredBytes + " 字节,实际 " + source.length + " 字节"); + } + } + private String saveImage(ByteString pixelData, int width, int height, boolean isDepth) { File tempDir = new File(System.getProperty("java.io.tmpdir")); FileUtil.mkdir(tempDir); diff --git a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/impl/EdgeMicrophoneServiceImpl.java b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/impl/EdgeMicrophoneServiceImpl.java index 0f33e15..797e3fa 100644 --- a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/impl/EdgeMicrophoneServiceImpl.java +++ b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/impl/EdgeMicrophoneServiceImpl.java @@ -1,19 +1,37 @@ package com.cmvr.edge.client.service.impl; +import cmvr.api.Common; import cmvr.api.MicPhoneServiceGrpc; import cmvr.api.MicrophoneCommand; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson2.JSON; +import com.cmvr.common.exception.GlobalException; import com.cmvr.edge.client.manage.GrpcServiceManager; import com.cmvr.edge.client.model.EdgeCommonVO; import com.cmvr.edge.client.model.microphone.EdgeMicrophoneVolumeVO; import com.cmvr.edge.client.service.EdgeMicrophoneService; import com.cmvr.edge.client.utils.EdgeCommonUtil; +import io.grpc.Status; +import io.grpc.stub.ClientCallStreamObserver; +import io.grpc.stub.ClientResponseObserver; +import jakarta.annotation.PreDestroy; import lombok.RequiredArgsConstructor; +import org.springframework.scheduling.annotation.Scheduled; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + /** * 边缘麦克风服务实现类 * 用于与边缘麦克风进行gRPC通信,控制麦克风录音和状态 @@ -22,6 +40,19 @@ import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor public class EdgeMicrophoneServiceImpl implements EdgeMicrophoneService { + private static final int WAV_HEADER_BYTES = 44; + private static final int PCM_BITS_PER_SAMPLE = 16; + private static final int DEFAULT_SAMPLE_RATE = 48_000; + private static final int DEFAULT_CHANNELS = 1; + private static final String PCM_CODEC = "PCM_S16LE"; + private static final int NORMALIZED_PEAK_AMPLITUDE = 26_000; + private static final double MAX_RECORDING_GAIN = 8.0D; + private static final int PCM_PROCESS_BUFFER_BYTES = 64 * 1024; + private static final String RECORDING_STREAM_CONFLICT = + "cannot start streaming while microphone recording is active"; + private static final long RECORDING_MAX_AGE_MILLIS = TimeUnit.HOURS.toMillis(6L); + private static final long FIRST_AUDIO_FRAME_TIMEOUT_SECONDS = 5L; + private static final int RECORDING_STOP_CONFIRM_ATTEMPTS = 5; /** * 日志记录器 * 用于记录服务运行过程中的各种状态和错误信息 @@ -34,6 +65,9 @@ public class EdgeMicrophoneServiceImpl implements EdgeMicrophoneService { */ private final GrpcServiceManager grpcServiceManager; + private final Map workflowRecordings = new ConcurrentHashMap<>(); + private final Map workflowRecordingTargets = new ConcurrentHashMap<>(); + /** * 获取麦克风当前状态 * 通过gRPC调用获取麦克风的运行状态,包括是否正在录音、音量等信息 @@ -41,16 +75,10 @@ public class EdgeMicrophoneServiceImpl implements EdgeMicrophoneService { @Override public String getStatus(EdgeCommonVO edgeCommonVO) { try { - MicPhoneServiceGrpc.MicPhoneServiceBlockingStub stub = grpcServiceManager.getGrpcClient(edgeCommonVO.getRobotId(), MicPhoneServiceGrpc.MicPhoneServiceBlockingStub.class); - MicrophoneCommand.GetMicStateCommand.Request request = MicrophoneCommand.GetMicStateCommand.Request.newBuilder() - .setHeader(EdgeCommonUtil.buildRequest(edgeCommonVO.getDeviceId())) - .build(); - // 直接返回完整的 Feedback - MicrophoneCommand.GetMicStateCommand.Feedback feedback = stub.getStatus(request); - return JSON.toJSONString(feedback.getState()); + return JSON.toJSONString(getMicrophoneState(edgeCommonVO)); } catch (Exception e) { logger.error("获取麦克风状态失败", e); - throw new RuntimeException("获取麦克风状态失败", e); + throw operationFailure("获取麦克风状态", e); } } @@ -60,24 +88,19 @@ public class EdgeMicrophoneServiceImpl implements EdgeMicrophoneService { */ @Override public String startRecord(EdgeCommonVO edgeCommonVO) { - String deviceId = edgeCommonVO.getDeviceId(); try { - // 获取gRPC客户端存根 - MicPhoneServiceGrpc.MicPhoneServiceBlockingStub stub = grpcServiceManager.getGrpcClient(edgeCommonVO.getRobotId(), MicPhoneServiceGrpc.MicPhoneServiceBlockingStub.class); - String filePath = StrUtil.format("{}/{}_{}.wav", "/home/share/assets/video", deviceId, System.currentTimeMillis()); - - // 构建请求消息 - MicrophoneCommand.StartMicRecordingCommand.Request request = MicrophoneCommand.StartMicRecordingCommand.Request.newBuilder() - .setHeader(EdgeCommonUtil.buildRequest(deviceId)) - .setFilePath(filePath) - .build(); - - // 发送请求 - stub.startRecord(request); + if (workflowRecordingTargets.containsKey( + recordingTargetKey(edgeCommonVO.getRobotId(), edgeCommonVO.getDeviceId()))) { + throw new GlobalException("该机器人麦克风正在被工作流录音占用"); + } + String filePath = StrUtil.format("{}/{}_{}.wav", "/home/share/assets/video", + edgeCommonVO.getDeviceId(), + UUID.randomUUID().toString().replace("-", "")); + startTerminalRecording(edgeCommonVO, filePath); return filePath; } catch (Exception e) { logger.error("开始录音失败", e); - throw new RuntimeException("开始录音失败", e); + throw operationFailure("开始录音", e); } } @@ -88,23 +111,98 @@ public class EdgeMicrophoneServiceImpl implements EdgeMicrophoneService { @Override public String stopRecord(EdgeCommonVO edgeCommonVO) { try { - // 获取gRPC客户端存根 - MicPhoneServiceGrpc.MicPhoneServiceBlockingStub stub = grpcServiceManager.getGrpcClient(edgeCommonVO.getRobotId(), MicPhoneServiceGrpc.MicPhoneServiceBlockingStub.class); - - // 构建请求消息 - MicrophoneCommand.StopMicRecordingCommand.Request request = MicrophoneCommand.StopMicRecordingCommand.Request.newBuilder() - .setHeader(EdgeCommonUtil.buildRequest(edgeCommonVO.getDeviceId())) - .build(); - - // 发送请求 - MicrophoneCommand.StopMicRecordingCommand.Feedback feedback = stub.stopRecord(request); - return JSON.toJSONString(feedback.getHeader()); + abortWorkflowRecordings(edgeCommonVO); + return JSON.toJSONString(stopTerminalRecording(edgeCommonVO)); } catch (Exception e) { logger.error("停止录音失败", e); - throw new RuntimeException("停止录音失败", e); + throw operationFailure("结束录音", e); } } + @Override + public String startWorkflowRecording(EdgeCommonVO edgeCommonVO) { + String recordingId = UUID.randomUUID().toString().replace("-", ""); + String targetKey = recordingTargetKey(edgeCommonVO.getRobotId(), edgeCommonVO.getDeviceId()); + String activeRecordingId = workflowRecordingTargets.putIfAbsent(targetKey, recordingId); + if (activeRecordingId != null) { + throw new GlobalException("该机器人麦克风已有进行中的录音,请先结束当前录音"); + } + File outputFile; + try { + outputFile = File.createTempFile("cmvr-audio-" + recordingId + "-", ".wav"); + } catch (IOException exception) { + workflowRecordingTargets.remove(targetKey, recordingId); + throw new GlobalException("创建录音临时文件失败: " + exception.getMessage()); + } + + WorkflowAudioRecordingSession session = new WorkflowAudioRecordingSession( + recordingId, edgeCommonVO.getRobotId(), edgeCommonVO.getDeviceId(), outputFile); + workflowRecordings.put(recordingId, session); + try { + prepareWorkflowStreaming(edgeCommonVO); + session.start(); + return recordingId; + } catch (RuntimeException exception) { + workflowRecordings.remove(recordingId, session); + workflowRecordingTargets.remove(targetKey, recordingId); + session.abort(); + throw exception; + } + } + + @Override + public File stopWorkflowRecording(EdgeCommonVO edgeCommonVO, String recordingId) { + WorkflowAudioRecordingSession session = workflowRecordings.remove(recordingId); + if (session == null) { + throw new GlobalException("录音会话不存在或已结束: " + recordingId); + } + if (!session.matches(edgeCommonVO.getRobotId(), edgeCommonVO.getDeviceId())) { + workflowRecordingTargets.remove(session.targetKey(), recordingId); + session.abort(); + throw new GlobalException("开始录音和结束录音使用的机器人或麦克风不一致"); + } + try { + session.prepareToFinish(); + return session.finish(); + } catch (RuntimeException exception) { + session.abort(); + throw exception; + } finally { + workflowRecordingTargets.remove(session.targetKey(), recordingId); + } + } + + private void abortWorkflowRecordings(EdgeCommonVO edgeCommonVO) { + workflowRecordings.forEach((recordingId, session) -> { + if (session.matches(edgeCommonVO.getRobotId(), edgeCommonVO.getDeviceId()) + && workflowRecordings.remove(recordingId, session)) { + workflowRecordingTargets.remove(session.targetKey(), recordingId); + logger.info("停止麦克风并终止关联的工作流录音: recordingId={}, robotId={}, deviceId={}", + recordingId, session.robotId, session.deviceId); + session.abort(); + } + }); + } + + @Scheduled(fixedDelay = 60_000L) + public void cleanExpiredWorkflowRecordings() { + workflowRecordings.forEach((recordingId, session) -> { + if (session.isExpired() && workflowRecordings.remove(recordingId, session)) { + workflowRecordingTargets.remove(session.targetKey(), recordingId); + logger.warn("清理超时的工作流录音会话: recordingId={}, robotId={}, deviceId={}", + recordingId, session.robotId, session.deviceId); + session.abort(); + } + }); + } + + @PreDestroy + public void closeWorkflowRecordings() { + workflowRecordings.forEach((recordingId, session) -> session.abort()); + workflowRecordings.clear(); + workflowRecordingTargets.clear(); + } + /** * 暂停录音 * 通过gRPC调用暂停麦克风的当前录音 @@ -198,4 +296,470 @@ public class EdgeMicrophoneServiceImpl implements EdgeMicrophoneService { throw new RuntimeException("获取麦克风音量失败", e); } } -} \ No newline at end of file + + private void requireSuccess(Common.CommandHeader.Feedback header, String operation) { + if (header == null || !header.getSuccess()) { + String detail = header == null || StrUtil.isBlank(header.getErrorMessage()) + ? "机器人未返回成功状态" + : header.getErrorMessage(); + throw new GlobalException(operation + "失败: " + detail); + } + } + + private MicrophoneCommand.MicState getMicrophoneState(EdgeCommonVO edgeCommonVO) { + MicPhoneServiceGrpc.MicPhoneServiceBlockingStub stub = grpcServiceManager.getGrpcClient( + edgeCommonVO.getRobotId(), MicPhoneServiceGrpc.MicPhoneServiceBlockingStub.class); + MicrophoneCommand.GetMicStateCommand.Request request = + MicrophoneCommand.GetMicStateCommand.Request.newBuilder() + .setHeader(EdgeCommonUtil.buildRequest(edgeCommonVO.getDeviceId())) + .build(); + MicrophoneCommand.GetMicStateCommand.Feedback feedback = stub.getStatus(request); + requireSuccess(feedback.getHeader(), "获取麦克风状态"); + return feedback.getState(); + } + + private void prepareWorkflowStreaming(EdgeCommonVO edgeCommonVO) { + MicrophoneCommand.MicState state = getMicrophoneState(edgeCommonVO); + if (!state.getIsRecording()) { + return; + } + if (!StrUtil.containsIgnoreCase(state.getErrorMessage(), RECORDING_STREAM_CONFLICT)) { + throw new GlobalException("麦克风正在执行文件录音,请先结束当前录音再启动工作流"); + } + + logger.warn("工作流启动前发现麦克风仍处于文件录音状态,将先停止遗留录音: robotId={}, deviceId={}, error={}", + edgeCommonVO.getRobotId(), edgeCommonVO.getDeviceId(), state.getErrorMessage()); + stopTerminalRecording(edgeCommonVO); + + for (int attempt = 0; attempt < RECORDING_STOP_CONFIRM_ATTEMPTS; attempt++) { + state = getMicrophoneState(edgeCommonVO); + if (!state.getIsRecording()) { + return; + } + try { + TimeUnit.MILLISECONDS.sleep(100L); + } catch (InterruptedException exception) { + Thread.currentThread().interrupt(); + throw new GlobalException("等待麦克风停止文件录音时被中断"); + } + } + throw new GlobalException("麦克风文件录音未能停止,无法启动工作流录音"); + } + + private void startTerminalRecording(EdgeCommonVO edgeCommonVO, String filePath) { + MicPhoneServiceGrpc.MicPhoneServiceBlockingStub stub = grpcServiceManager.getGrpcClient( + edgeCommonVO.getRobotId(), MicPhoneServiceGrpc.MicPhoneServiceBlockingStub.class); + MicrophoneCommand.StartMicRecordingCommand.Request request = + MicrophoneCommand.StartMicRecordingCommand.Request.newBuilder() + .setHeader(EdgeCommonUtil.buildRequest(edgeCommonVO.getDeviceId())) + .setFilePath(filePath) + .build(); + MicrophoneCommand.StartMicRecordingCommand.Feedback feedback = stub.startRecord(request); + requireSuccess(feedback.getHeader(), "开始录音"); + } + + private Common.CommandHeader.Feedback stopTerminalRecording(EdgeCommonVO edgeCommonVO) { + MicPhoneServiceGrpc.MicPhoneServiceBlockingStub stub = grpcServiceManager.getGrpcClient( + edgeCommonVO.getRobotId(), MicPhoneServiceGrpc.MicPhoneServiceBlockingStub.class); + MicrophoneCommand.StopMicRecordingCommand.Request request = + MicrophoneCommand.StopMicRecordingCommand.Request.newBuilder() + .setHeader(EdgeCommonUtil.buildRequest(edgeCommonVO.getDeviceId())) + .build(); + Common.CommandHeader.Feedback header = stub.stopRecord(request).getHeader(); + requireSuccess(header, "结束录音"); + return header; + } + + private String recordingTargetKey(String robotId, String deviceId) { + return String.valueOf(robotId) + '\0' + String.valueOf(deviceId); + } + + private GlobalException operationFailure(String operation, Exception exception) { + if (exception instanceof GlobalException globalException) { + return globalException; + } + return new GlobalException(operation + "失败: " + exception.getMessage()); + } + + private final class WorkflowAudioRecordingSession { + private final String recordingId; + private final String robotId; + private final String deviceId; + private final File outputFile; + private final long startedAtMillis = System.currentTimeMillis(); + private final Object fileLock = new Object(); + private final AtomicBoolean stopped = new AtomicBoolean(false); + private final AtomicReference failure = new AtomicReference<>(); + private final CountDownLatch firstAudioFrame = new CountDownLatch(1); + private final AtomicReference> + requestObserver = new AtomicReference<>(); + + private RandomAccessFile output; + private long pcmBytes; + private long sampleCount; + private long sampleSum; + private long nonZeroSamples; + private int peakAmplitude; + private int sampleRate; + private int channels; + + private WorkflowAudioRecordingSession(String recordingId, String robotId, String deviceId, File outputFile) { + this.recordingId = recordingId; + this.robotId = robotId; + this.deviceId = deviceId; + this.outputFile = outputFile; + } + + private void start() { + try { + output = new RandomAccessFile(outputFile, "rw"); + output.setLength(0L); + output.write(new byte[WAV_HEADER_BYTES]); + } catch (IOException exception) { + throw new GlobalException("初始化录音文件失败: " + exception.getMessage()); + } + + MicPhoneServiceGrpc.MicPhoneServiceStub stub = grpcServiceManager.getGrpcClient( + robotId, MicPhoneServiceGrpc.MicPhoneServiceStub.class); + MicrophoneCommand.StreamMicAudioCommand.Request request = + MicrophoneCommand.StreamMicAudioCommand.Request.newBuilder() + .setHeader(EdgeCommonUtil.buildRequest(deviceId)) + .build(); + + stub.streamAudio(request, + new ClientResponseObserver() { + @Override + public void beforeStart(ClientCallStreamObserver stream) { + if (stopped.get()) { + stream.cancel("workflow recording already stopped", null); + return; + } + requestObserver.set(stream); + if (stopped.get() && requestObserver.compareAndSet(stream, null)) { + stream.cancel("workflow recording already stopped", null); + } + } + + @Override + public void onNext(MicrophoneCommand.StreamMicAudioCommand.Feedback feedback) { + if (stopped.get()) { + return; + } + if (feedback.hasHeader() && !feedback.getHeader().getSuccess()) { + fail(new GlobalException("录音音频流失败: " + feedback.getHeader().getErrorMessage())); + firstAudioFrame.countDown(); + cancelStream("microphone feedback failed"); + return; + } + if (feedback.hasAudio()) { + writeAudio(feedback.getAudio()); + firstAudioFrame.countDown(); + } + } + + @Override + public void onError(Throwable throwable) { + if (!stopped.get() && Status.fromThrowable(throwable).getCode() != Status.Code.CANCELLED) { + fail(throwable); + } + firstAudioFrame.countDown(); + } + + @Override + public void onCompleted() { + if (!stopped.get()) { + fail(new GlobalException("麦克风音频流提前结束")); + } + firstAudioFrame.countDown(); + } + }); + + awaitFirstAudioFrame(); + } + + private void awaitFirstAudioFrame() { + try { + if (!firstAudioFrame.await(FIRST_AUDIO_FRAME_TIMEOUT_SECONDS, TimeUnit.SECONDS)) { + throw new GlobalException("启动录音失败: 5秒内未收到麦克风音频数据"); + } + } catch (InterruptedException exception) { + Thread.currentThread().interrupt(); + throw new GlobalException("等待麦克风音频数据时被中断"); + } + Throwable streamFailure = failure.get(); + if (streamFailure != null) { + throw new GlobalException("启动录音失败: " + streamFailure.getMessage()); + } + if (pcmBytes == 0L) { + throw new GlobalException("启动录音失败: 麦克风首帧没有有效 PCM 数据"); + } + } + + private void writeAudio(Common.AudioData audio) { + if (audio.getFormat() != Common.AudioData.AudioFormat.PCM) { + fail(new GlobalException("不支持的录音音频格式: " + audio.getFormat())); + cancelStream("unsupported audio format"); + return; + } + if (StrUtil.isNotBlank(audio.getCodec()) && !PCM_CODEC.equalsIgnoreCase(audio.getCodec())) { + fail(new GlobalException("不支持的录音音频编码: " + audio.getCodec())); + cancelStream("unsupported audio codec"); + return; + } + byte[] pcm = audio.getData().toByteArray(); + if (pcm.length == 0) { + return; + } + if ((pcm.length & 1) != 0) { + fail(new GlobalException("录音 PCM 数据长度不是 16 位采样的整数倍")); + cancelStream("invalid pcm data"); + return; + } + + int frameSampleRate = audio.getSampleRate() > 0 ? audio.getSampleRate() : DEFAULT_SAMPLE_RATE; + int frameChannels = audio.getChannels() > 0 ? audio.getChannels() : DEFAULT_CHANNELS; + synchronized (fileLock) { + if (stopped.get()) { + return; + } + if (sampleRate == 0) { + sampleRate = frameSampleRate; + channels = frameChannels; + } else if (sampleRate != frameSampleRate || channels != frameChannels) { + fail(new GlobalException("录音过程中音频采样格式发生变化")); + cancelStream("audio format changed"); + return; + } + try { + output.write(pcm); + pcmBytes += pcm.length; + updateSignalStats(pcm); + } catch (IOException exception) { + fail(exception); + cancelStream("write audio failed"); + } + } + } + + private void prepareToFinish() { + if (!stopped.compareAndSet(false, true)) { + throw new GlobalException("录音会话已结束: " + recordingId); + } + cancelStream("workflow recording stopped"); + } + + private File finish() { + synchronized (fileLock) { + Throwable recordingFailure = failure.get(); + if (recordingFailure != null) { + closeFile(); + deleteOutputFile(); + throw new GlobalException("录音失败: " + recordingFailure.getMessage()); + } + if (pcmBytes == 0L) { + closeFile(); + deleteOutputFile(); + throw new GlobalException("录音文件为空,请确认麦克风音频流正常"); + } + if (nonZeroSamples == 0L) { + closeFile(); + deleteOutputFile(); + throw new GlobalException("录音数据全为静音,请检查机器人麦克风采集状态和输入设备"); + } + logger.info("工作流录音采集完成: recordingId={}, robotId={}, deviceId={}, pcmBytes={}, " + + "nonZeroSamples={}, peakAmplitude={}, sampleRate={}, channels={}", + recordingId, robotId, deviceId, pcmBytes, nonZeroSamples, peakAmplitude, + sampleRate, channels); + try { + RecordingSignalAdjustment adjustment = normalizePcmSignal( + output, pcmBytes, sampleCount, sampleSum); + if (adjustment.sourcePeak() == 0) { + closeFile(); + deleteOutputFile(); + throw new GlobalException("录音数据仅包含固定偏置,没有采集到有效声音"); + } + logger.info("工作流录音电平处理完成: recordingId={}, dcOffset={}, sourcePeak={}, " + + "normalizedPeak={}, gain={}", + recordingId, adjustment.dcOffset(), adjustment.sourcePeak(), + adjustment.normalizedPeak(), adjustment.gain()); + writeWavHeader(output, pcmBytes, sampleRate, channels); + closeFile(); + return outputFile; + } catch (IOException exception) { + closeFile(); + deleteOutputFile(); + throw new GlobalException("封装 WAV 录音失败: " + exception.getMessage()); + } + } + } + + private void updateSignalStats(byte[] pcm) { + for (int index = 0; index + 1 < pcm.length; index += 2) { + int sample = (short) ((pcm[index] & 0xff) | (pcm[index + 1] << 8)); + if (sample != 0) { + nonZeroSamples++; + } + sampleCount++; + sampleSum += sample; + peakAmplitude = Math.max(peakAmplitude, Math.abs(sample)); + } + } + + private void abort() { + stopped.set(true); + cancelStream("workflow recording aborted"); + synchronized (fileLock) { + closeFile(); + deleteOutputFile(); + } + } + + private boolean matches(String expectedRobotId, String expectedDeviceId) { + return StrUtil.equals(robotId, expectedRobotId) && StrUtil.equals(deviceId, expectedDeviceId); + } + + private String targetKey() { + return recordingTargetKey(robotId, deviceId); + } + + private boolean isExpired() { + return System.currentTimeMillis() - startedAtMillis > RECORDING_MAX_AGE_MILLIS; + } + + private void fail(Throwable throwable) { + failure.compareAndSet(null, throwable); + } + + private void cancelStream(String reason) { + ClientCallStreamObserver observer = + requestObserver.getAndSet(null); + if (observer != null) { + observer.cancel(reason, null); + } + } + + private void closeFile() { + if (output != null) { + try { + output.close(); + } catch (IOException exception) { + fail(exception); + } finally { + output = null; + } + } + } + + private void deleteOutputFile() { + if (outputFile.exists() && !outputFile.delete()) { + outputFile.deleteOnExit(); + } + } + } + + private void writeWavHeader(RandomAccessFile output, long pcmBytes, int sampleRate, int channels) + throws IOException { + if (pcmBytes > 0xffff_ffffL - 36L) { + throw new IOException("录音文件超过 WAV 4GB 限制"); + } + int blockAlign = channels * PCM_BITS_PER_SAMPLE / 8; + long byteRate = (long) sampleRate * blockAlign; + output.seek(0L); + output.writeBytes("RIFF"); + writeLittleEndianInt(output, pcmBytes + 36L); + output.writeBytes("WAVE"); + output.writeBytes("fmt "); + writeLittleEndianInt(output, 16L); + writeLittleEndianShort(output, 1); + writeLittleEndianShort(output, channels); + writeLittleEndianInt(output, sampleRate); + writeLittleEndianInt(output, byteRate); + writeLittleEndianShort(output, blockAlign); + writeLittleEndianShort(output, PCM_BITS_PER_SAMPLE); + output.writeBytes("data"); + writeLittleEndianInt(output, pcmBytes); + } + + private RecordingSignalAdjustment normalizePcmSignal( + RandomAccessFile output, long pcmBytes, long sampleCount, long sampleSum) throws IOException { + if (pcmBytes <= 0L || sampleCount <= 0L) { + return new RecordingSignalAdjustment(0, 0, 0, 1.0D); + } + + int dcOffset = (int) Math.round(sampleSum / (double) sampleCount); + int sourcePeak = scanCenteredPeak(output, pcmBytes, dcOffset); + if (sourcePeak == 0) { + return new RecordingSignalAdjustment(dcOffset, 0, 0, 1.0D); + } + double gain = Math.min(MAX_RECORDING_GAIN, + NORMALIZED_PEAK_AMPLITUDE / (double) sourcePeak); + int normalizedPeak = rewritePcmSignal(output, pcmBytes, dcOffset, gain); + return new RecordingSignalAdjustment(dcOffset, sourcePeak, normalizedPeak, gain); + } + + private int scanCenteredPeak(RandomAccessFile output, long pcmBytes, int dcOffset) throws IOException { + byte[] buffer = new byte[PCM_PROCESS_BUFFER_BYTES]; + long remaining = pcmBytes; + int peak = 0; + output.seek(WAV_HEADER_BYTES); + while (remaining > 0L) { + int bytesToRead = (int) Math.min(buffer.length, remaining); + int bytesRead = output.read(buffer, 0, bytesToRead); + if (bytesRead < 0) { + throw new IOException("录音 PCM 数据提前结束"); + } + for (int index = 0; index + 1 < bytesRead; index += 2) { + int sample = (short) ((buffer[index] & 0xff) | (buffer[index + 1] << 8)); + peak = Math.max(peak, Math.abs(sample - dcOffset)); + } + remaining -= bytesRead; + } + return peak; + } + + private int rewritePcmSignal(RandomAccessFile output, long pcmBytes, int dcOffset, double gain) + throws IOException { + byte[] buffer = new byte[PCM_PROCESS_BUFFER_BYTES]; + long remaining = pcmBytes; + long position = WAV_HEADER_BYTES; + int peak = 0; + while (remaining > 0L) { + int bytesToRead = (int) Math.min(buffer.length, remaining); + output.seek(position); + int bytesRead = output.read(buffer, 0, bytesToRead); + if (bytesRead < 0) { + throw new IOException("录音 PCM 数据提前结束"); + } + for (int index = 0; index + 1 < bytesRead; index += 2) { + int sample = (short) ((buffer[index] & 0xff) | (buffer[index + 1] << 8)); + int adjusted = (int) Math.round((sample - dcOffset) * gain); + adjusted = Math.max(Short.MIN_VALUE, Math.min(Short.MAX_VALUE, adjusted)); + peak = Math.max(peak, Math.abs(adjusted)); + buffer[index] = (byte) (adjusted & 0xff); + buffer[index + 1] = (byte) ((adjusted >>> 8) & 0xff); + } + output.seek(position); + output.write(buffer, 0, bytesRead); + position += bytesRead; + remaining -= bytesRead; + } + return peak; + } + + private record RecordingSignalAdjustment( + int dcOffset, int sourcePeak, int normalizedPeak, double gain) { + } + + private void writeLittleEndianInt(RandomAccessFile output, long value) throws IOException { + output.write((int) (value & 0xff)); + output.write((int) ((value >>> 8) & 0xff)); + output.write((int) ((value >>> 16) & 0xff)); + output.write((int) ((value >>> 24) & 0xff)); + } + + private void writeLittleEndianShort(RandomAccessFile output, int value) throws IOException { + output.write(value & 0xff); + output.write((value >>> 8) & 0xff); + } +} diff --git a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/impl/EdgeSystemServiceImpl.java b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/impl/EdgeSystemServiceImpl.java index 96734fb..1d4429f 100644 --- a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/impl/EdgeSystemServiceImpl.java +++ b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/service/impl/EdgeSystemServiceImpl.java @@ -2,6 +2,9 @@ package com.cmvr.edge.client.service.impl; import cmvr.api.Common; import cmvr.api.ArmServiceGrpc; +import cmvr.api.ArmCommand; +import cmvr.api.AgvCommand; +import cmvr.msgs.AgvUtils; import cmvr.api.SystemCommand; import cmvr.api.SystemServiceGrpc; import com.alibaba.fastjson2.JSON; @@ -9,6 +12,7 @@ import com.cmvr.device.domain.DeDeviceRegistration; import com.cmvr.edge.client.manage.GrpcServiceManager; import com.cmvr.edge.client.model.system.EdgeSystemJsonCommandVO; import com.cmvr.edge.client.model.system.EdgeSystemUpdateParamsVO; +import com.cmvr.edge.client.model.system.EdgeActionQueueVO; import com.cmvr.edge.client.service.EdgeSystemService; import com.cmvr.edge.client.utils.EdgeCommonUtil; import com.cmvr.common.exception.GlobalException; @@ -21,6 +25,10 @@ import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Base64; import java.util.List; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.TimeUnit; /** * 边缘系统服务实现类 @@ -69,6 +77,159 @@ public class EdgeSystemServiceImpl implements EdgeSystemService { return stub.executeJsonCommand(grpcRequest); } + @Override + public SystemCommand.ActionQueueCommand.Feedback executeActionQueue(EdgeActionQueueVO request) { + if (request == null || request.getRobotId() == null || request.getRobotId().trim().isEmpty()) { + throw new GlobalException("Robot ID cannot be empty"); + } + if (request.getSteps() == null || request.getSteps().isEmpty()) { + throw new GlobalException("Action queue must contain at least one step"); + } + SystemCommand.GetSystemInfoCommand.Feedback systemInfo = getSystemInfo(request.getRobotId()); + if (systemInfo == null || !systemInfo.hasHeader() || !systemInfo.getHeader().getSuccess()) { + throw new GlobalException("Unable to read edge action service information"); + } + String serviceInstanceId = systemInfo.getActionServiceInstanceId(); + if (serviceInstanceId == null || serviceInstanceId.isEmpty()) { + throw new GlobalException("Edge action service instance ID is unavailable"); + } + int totalTimeoutMs = request.getTotalTimeoutMs() == null ? 0 : Math.max(request.getTotalTimeoutMs(), 0); + String actionId = request.getActionId() == null || request.getActionId().trim().isEmpty() + ? UUID.randomUUID().toString() : request.getActionId().trim(); + SystemCommand.ActionQueueCommand.Request.Builder builder = SystemCommand.ActionQueueCommand.Request.newBuilder() + .setActionId(actionId) + .setExpectedServiceInstanceId(serviceInstanceId) + .setTotalTimeoutMs(totalTimeoutMs); + Set stepIds = new HashSet<>(); + for (int index = 0; index < request.getSteps().size(); index++) { + EdgeActionQueueVO.Step step = request.getSteps().get(index); + String stepId = step.getStepId() == null || step.getStepId().trim().isEmpty() + ? "step_" + (index + 1) : step.getStepId().trim(); + if (!stepIds.add(stepId)) { + throw new GlobalException("Duplicate action queue step ID: " + stepId); + } + builder.addSteps(buildActionStep(step, stepId)); + } + SystemServiceGrpc.SystemServiceBlockingStub stub = grpcServiceManager.getGrpcClient( + request.getRobotId(), SystemServiceGrpc.SystemServiceBlockingStub.class); + long deadlineMs = totalTimeoutMs > 0 ? totalTimeoutMs + 5000L : 65000L; + return stub.withDeadlineAfter(deadlineMs, TimeUnit.MILLISECONDS).executeActionQueue(builder.build()); + } + + private SystemCommand.ActionStep buildActionStep(EdgeActionQueueVO.Step step, String stepId) { + if (step == null || step.getType() == null) { + throw new GlobalException("Action queue step type cannot be empty"); + } + com.alibaba.fastjson2.JSONObject params = step.getParams() == null + ? new com.alibaba.fastjson2.JSONObject() : step.getParams(); + SystemCommand.ActionStep.Builder builder = SystemCommand.ActionStep.newBuilder().setStepId(stepId); + if (step.getTimeoutMs() != null && step.getTimeoutMs() > 0) builder.setTimeoutMs(step.getTimeoutMs()); + switch (step.getType().trim().toUpperCase()) { + case "ARM_MOVE_J": + List positions = params.getList("positions", Double.class); + if (positions == null || positions.isEmpty()) { + throw new GlobalException("Arm joint positions cannot be empty"); + } + builder.setArmMoveJ(ArmCommand.MoveJ.Request.newBuilder() + .setHeader(requiredDeviceHeader(step)) + .setTarget(ArmCommand.JointPositionCommand.newBuilder() + .addAllPosition(positions)) + .setOptions(buildArmOptions(params))); + break; + case "ARM_MOVE_L": + builder.setArmMoveL(ArmCommand.MoveL.Request.newBuilder() + .setHeader(requiredDeviceHeader(step)) + .setTarget(ArmCommand.CartesianPose.newBuilder() + .setX(params.getDoubleValue("x")).setY(params.getDoubleValue("y")) + .setZ(params.getDoubleValue("z")).setRx(params.getDoubleValue("rx")) + .setRy(params.getDoubleValue("ry")).setRz(params.getDoubleValue("rz"))) + .setFrame(parseArmFrame(params.getString("frame"))) + .setOptions(buildArmOptions(params))); + break; + case "AGV_NAVIGATE_TO_POSE": + builder.setAgvNavigateToPose(AgvCommand.AgvNavigateToPoseCommand.Request.newBuilder() + .setHeader(requiredDeviceHeader(step)) + .setPose(AgvUtils.AgvPose2d.newBuilder().setX(params.getDoubleValue("x")) + .setY(params.getDoubleValue("y")).setTheta(params.getDoubleValue("theta"))) + .setOptions(buildAgvOptions(params))); + break; + case "AGV_NAVIGATE_TO_STATION": + builder.setAgvNavigateToStation(AgvCommand.AgvNavigateToStationCommand.Request.newBuilder() + .setHeader(requiredDeviceHeader(step)).setStationId(requiredText(params, "stationId")) + .setOptions(buildAgvOptions(params))); + break; + case "AGV_FOLLOW_PATH": + AgvCommand.AgvFollowPathCommand.Request.Builder path = AgvCommand.AgvFollowPathCommand.Request.newBuilder() + .setHeader(requiredDeviceHeader(step)).setOptions(buildAgvOptions(params)); + com.alibaba.fastjson2.JSONArray segments = params.getJSONArray("path"); + if (segments == null || segments.isEmpty()) throw new GlobalException("AGV path cannot be empty"); + for (int i = 0; i < segments.size(); i++) { + com.alibaba.fastjson2.JSONObject segment = segments.getJSONObject(i); + if (segment == null) throw new GlobalException("AGV path segment cannot be empty"); + path.addPath(AgvUtils.AgvPathSegment.newBuilder() + .setSourceStation(requiredText(segment, "sourceStation")) + .setTargetStation(requiredText(segment, "targetStation"))); + } + builder.setAgvFollowPath(path); + break; + case "DELAY": + int durationMs = params.getIntValue("durationMs"); + if (durationMs < 0) throw new GlobalException("Delay duration cannot be negative"); + builder.setDelay(SystemCommand.DelayAction.newBuilder().setDurationMs(durationMs)); + break; + default: + throw new GlobalException("Unsupported action queue step type: " + step.getType()); + } + return builder.build(); + } + + private Common.CommandHeader.Request requiredDeviceHeader(EdgeActionQueueVO.Step step) { + if (step.getDeviceId() == null || step.getDeviceId().trim().isEmpty()) { + throw new GlobalException("Device ID cannot be empty for step " + step.getStepId()); + } + return EdgeCommonUtil.buildRequest(step.getDeviceId().trim()); + } + + private ArmCommand.MotionOptions buildArmOptions(com.alibaba.fastjson2.JSONObject params) { + return ArmCommand.MotionOptions.newBuilder() + .setVelocity(params.getDoubleValue("velocity")) + .setAcceleration(params.getDoubleValue("acceleration")) + .setBlendRadius(params.getDoubleValue("blendRadius")) + .setJerk(params.getDoubleValue("jerk")) + .setAsynchronous(false) + .build(); + } + + private AgvUtils.AgvMotionOptions buildAgvOptions(com.alibaba.fastjson2.JSONObject params) { + return AgvUtils.AgvMotionOptions.newBuilder() + .setMaxSpeed(params.getDoubleValue("maxSpeed")) + .setMaxAngularSpeed(params.getDoubleValue("maxAngularSpeed")) + .setMaxAcceleration(params.getDoubleValue("maxAcceleration")) + .setMaxAngularAcceleration(params.getDoubleValue("maxAngularAcceleration")) + .setReachDistance(params.getDoubleValue("reachDistance")) + .setReachAngle(params.getDoubleValue("reachAngle")) + .setSpeedRatio(params.getDoubleValue("speedRatio")) + .setWaitTimeoutMs(params.getIntValue("waitTimeoutMs")) + .setPollIntervalMs(params.getIntValue("pollIntervalMs")) + .setAsynchronous(false) + .build(); + } + + private ArmCommand.ArmFrameType parseArmFrame(String value) { + if (value == null || value.trim().isEmpty()) return ArmCommand.ArmFrameType.ARM_FRAME_BASE; + try { + return ArmCommand.ArmFrameType.valueOf("ARM_FRAME_" + value.trim().toUpperCase()); + } catch (IllegalArgumentException exception) { + throw new GlobalException("Unsupported arm frame: " + value); + } + } + + private String requiredText(com.alibaba.fastjson2.JSONObject params, String name) { + String value = params.getString(name); + if (value == null || value.trim().isEmpty()) throw new GlobalException(name + " cannot be empty"); + return value.trim(); + } + private Common.ConfigParam buildParam(EdgeSystemUpdateParamsVO.Param param) { if (param == null || param.getName() == null || param.getName().trim().isEmpty()) { throw new GlobalException("Parameter name cannot be empty"); diff --git a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/utils/H265Fmp4Transcoder.java b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/utils/H265Fmp4Transcoder.java index c4f9495..9c61197 100644 --- a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/utils/H265Fmp4Transcoder.java +++ b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/utils/H265Fmp4Transcoder.java @@ -14,7 +14,9 @@ import java.io.OutputStream; import java.util.ArrayDeque; import java.util.Deque; import java.util.Locale; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.CountDownLatch; import java.util.function.Consumer; /** @@ -32,10 +34,13 @@ public final class H265Fmp4Transcoder implements AutoCloseable { private final LiveEncodedVideoInputStream inputStream; private final MediaChunkOutputStream outputStream; private final AtomicBoolean closed = new AtomicBoolean(false); + private final CountDownLatch firstFrameWritten = new CountDownLatch(1); private final Thread worker; private volatile FFmpegFrameGrabber grabber; private volatile FFmpegFrameRecorder recorder; + private volatile long writtenFrameCount; + private volatile long lastWrittenTimestampMicros = -1L; public H265Fmp4Transcoder(String streamName, int configuredFrameRate, @@ -66,6 +71,19 @@ public final class H265Fmp4Transcoder implements AutoCloseable { inputStream.offer(encodedFrame, keyFrame, codec); } + /** Waits until the transcoder has written its first decoded frame to MP4. */ + public boolean awaitFirstFrame(long timeout, TimeUnit unit) throws InterruptedException { + return firstFrameWritten.await(timeout, unit); + } + + public long getWrittenFrameCount() { + return writtenFrameCount; + } + + public long getLastWrittenTimestampMicros() { + return lastWrittenTimestampMicros; + } + private void transcode() { try { InputCodec inputCodec = inputStream.awaitInputCodec(); @@ -99,7 +117,6 @@ public final class H265Fmp4Transcoder implements AutoCloseable { sourceFrameRate = Math.max(5D, Math.min(sourceFrameRate, 60D)); double outputFrameRate = Math.min(sourceFrameRate, 25D); int gopSize = Math.max(1, (int) Math.round(outputFrameRate * 0.4D)); - long sourceFrameDurationMicros = Math.max(1L, Math.round(1_000_000D / sourceFrameRate)); long outputFrameDurationMicros = Math.max(1L, Math.round(1_000_000D / outputFrameRate)); log.info("Camera stream {} uses {} source fps, {} output fps and a {} frame GOP", streamName, sourceFrameRate, outputFrameRate, gopSize); @@ -119,17 +136,22 @@ public final class H265Fmp4Transcoder implements AutoCloseable { recorder.start(); outputStream.publishAvailable(); - long sourceFrameIndex = 0L; - long nextOutputTimestampMicros = 0L; + long firstFrameMonotonicNanos = System.nanoTime(); + long previousTimestampMicros = -1L; do { - long sourceTimestampMicros = sourceFrameIndex * sourceFrameDurationMicros; - if (sourceTimestampMicros + sourceFrameDurationMicros / 2 >= nextOutputTimestampMicros) { - recorder.setTimestamp(nextOutputTimestampMicros); - recorder.record(frame); - nextOutputTimestampMicros += outputFrameDurationMicros; - outputStream.publishAvailable(); + long timestampMicros = timelineTimestampMicros( + firstFrameMonotonicNanos, System.nanoTime(), previousTimestampMicros, + outputFrameDurationMicros); + if (timestampMicros < 0L) { + continue; } - sourceFrameIndex++; + recorder.setTimestamp(timestampMicros); + recorder.record(frame); + previousTimestampMicros = timestampMicros; + writtenFrameCount++; + lastWrittenTimestampMicros = timestampMicros; + firstFrameWritten.countDown(); + outputStream.publishAvailable(); } while (!closed.get() && (frame = grabber.grabImage()) != null); } catch (Throwable throwable) { if (!closed.get()) { @@ -143,9 +165,23 @@ public final class H265Fmp4Transcoder implements AutoCloseable { } inputStream.close(); closed.set(true); + firstFrameWritten.countDown(); } } + static long timelineTimestampMicros(long firstFrameNanos, long currentFrameNanos, + long previousTimestampMicros, long frameDurationMicros) { + long elapsedMicros = TimeUnit.NANOSECONDS.toMicros( + Math.max(0L, currentFrameNanos - firstFrameNanos)); + if (previousTimestampMicros < 0L) { + return 0L; + } + long safeFrameDuration = Math.max(1L, frameDurationMicros); + long alignedTimestamp = ((elapsedMicros + safeFrameDuration / 2L) / safeFrameDuration) + * safeFrameDuration; + return alignedTimestamp > previousTimestampMicros ? alignedTimestamp : -1L; + } + @Override public void close() { if (!closed.compareAndSet(false, true)) { @@ -155,6 +191,15 @@ public final class H265Fmp4Transcoder implements AutoCloseable { worker.interrupt(); } + /** + * Waits for FFmpeg to flush and release the output container after close(). + */ + public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { + long timeoutMillis = Math.max(1L, unit.toMillis(timeout)); + worker.join(timeoutMillis); + return !worker.isAlive(); + } + private void releaseNativeResources() { FFmpegFrameRecorder currentRecorder = recorder; recorder = null; diff --git a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/java/cmvr/api/SystemCommand.java b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/java/cmvr/api/SystemCommand.java index 89a3eea..71435bc 100644 --- a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/java/cmvr/api/SystemCommand.java +++ b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/java/cmvr/api/SystemCommand.java @@ -713,6 +713,321 @@ public final class SystemCommand { // @@protoc_insertion_point(enum_scope:cmvr.api.SystemDeviceHealth) } + /** + *
+   * Final outcome of one ActionQueue execution.
+   * 
+ * + * Protobuf enum {@code cmvr.api.ActionResultCode} + */ + public enum ActionResultCode + implements com.google.protobuf.ProtocolMessageEnum { + /** + * ACTION_RESULT_CODE_UNSPECIFIED = 0; + */ + ACTION_RESULT_CODE_UNSPECIFIED(0), + /** + * ACTION_RESULT_CODE_COMPLETED = 1; + */ + ACTION_RESULT_CODE_COMPLETED(1), + /** + * ACTION_RESULT_CODE_FAILED = 2; + */ + ACTION_RESULT_CODE_FAILED(2), + /** + * ACTION_RESULT_CODE_CANCELED = 3; + */ + ACTION_RESULT_CODE_CANCELED(3), + /** + * ACTION_RESULT_CODE_TIMED_OUT = 4; + */ + ACTION_RESULT_CODE_TIMED_OUT(4), + /** + * ACTION_RESULT_CODE_REJECTED = 5; + */ + ACTION_RESULT_CODE_REJECTED(5), + UNRECOGNIZED(-1), + ; + + /** + * ACTION_RESULT_CODE_UNSPECIFIED = 0; + */ + public static final int ACTION_RESULT_CODE_UNSPECIFIED_VALUE = 0; + /** + * ACTION_RESULT_CODE_COMPLETED = 1; + */ + public static final int ACTION_RESULT_CODE_COMPLETED_VALUE = 1; + /** + * ACTION_RESULT_CODE_FAILED = 2; + */ + public static final int ACTION_RESULT_CODE_FAILED_VALUE = 2; + /** + * ACTION_RESULT_CODE_CANCELED = 3; + */ + public static final int ACTION_RESULT_CODE_CANCELED_VALUE = 3; + /** + * ACTION_RESULT_CODE_TIMED_OUT = 4; + */ + public static final int ACTION_RESULT_CODE_TIMED_OUT_VALUE = 4; + /** + * ACTION_RESULT_CODE_REJECTED = 5; + */ + public static final int ACTION_RESULT_CODE_REJECTED_VALUE = 5; + + + public final int getNumber() { + if (this == UNRECOGNIZED) { + throw new java.lang.IllegalArgumentException( + "Can't get the number of an unknown enum value."); + } + return value; + } + + /** + * @param value The numeric wire value of the corresponding enum entry. + * @return The enum associated with the given numeric wire value. + * @deprecated Use {@link #forNumber(int)} instead. + */ + @java.lang.Deprecated + public static ActionResultCode valueOf(int value) { + return forNumber(value); + } + + /** + * @param value The numeric wire value of the corresponding enum entry. + * @return The enum associated with the given numeric wire value. + */ + public static ActionResultCode forNumber(int value) { + switch (value) { + case 0: return ACTION_RESULT_CODE_UNSPECIFIED; + case 1: return ACTION_RESULT_CODE_COMPLETED; + case 2: return ACTION_RESULT_CODE_FAILED; + case 3: return ACTION_RESULT_CODE_CANCELED; + case 4: return ACTION_RESULT_CODE_TIMED_OUT; + case 5: return ACTION_RESULT_CODE_REJECTED; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static final com.google.protobuf.Internal.EnumLiteMap< + ActionResultCode> internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public ActionResultCode findValueByNumber(int number) { + return ActionResultCode.forNumber(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + if (this == UNRECOGNIZED) { + throw new java.lang.IllegalStateException( + "Can't get the descriptor of an unrecognized enum value."); + } + return getDescriptor().getValues().get(ordinal()); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return cmvr.api.SystemCommand.getDescriptor().getEnumTypes().get(4); + } + + private static final ActionResultCode[] VALUES = values(); + + public static ActionResultCode valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + if (desc.getIndex() == -1) { + return UNRECOGNIZED; + } + return VALUES[desc.getIndex()]; + } + + private final int value; + + private ActionResultCode(int value) { + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:cmvr.api.ActionResultCode) + } + + /** + *
+   * Describes whether this RPC admitted a new action or observed an existing
+   * idempotency record. Clients must not infer this from an error string.
+   * 
+ * + * Protobuf enum {@code cmvr.api.ActionDeduplicationStatus} + */ + public enum ActionDeduplicationStatus + implements com.google.protobuf.ProtocolMessageEnum { + /** + * ACTION_DEDUPLICATION_STATUS_UNSPECIFIED = 0; + */ + ACTION_DEDUPLICATION_STATUS_UNSPECIFIED(0), + /** + * ACTION_DEDUPLICATION_STATUS_ACCEPTED_NEW = 1; + */ + ACTION_DEDUPLICATION_STATUS_ACCEPTED_NEW(1), + /** + * ACTION_DEDUPLICATION_STATUS_JOINED_IN_FLIGHT = 2; + */ + ACTION_DEDUPLICATION_STATUS_JOINED_IN_FLIGHT(2), + /** + * ACTION_DEDUPLICATION_STATUS_CACHED_RESULT = 3; + */ + ACTION_DEDUPLICATION_STATUS_CACHED_RESULT(3), + /** + * ACTION_DEDUPLICATION_STATUS_RESULT_EVICTED = 4; + */ + ACTION_DEDUPLICATION_STATUS_RESULT_EVICTED(4), + /** + * ACTION_DEDUPLICATION_STATUS_LEDGER_EXHAUSTED = 5; + */ + ACTION_DEDUPLICATION_STATUS_LEDGER_EXHAUSTED(5), + /** + * ACTION_DEDUPLICATION_STATUS_ACTION_ID_CONFLICT = 6; + */ + ACTION_DEDUPLICATION_STATUS_ACTION_ID_CONFLICT(6), + /** + * ACTION_DEDUPLICATION_STATUS_SERVICE_INSTANCE_MISMATCH = 7; + */ + ACTION_DEDUPLICATION_STATUS_SERVICE_INSTANCE_MISMATCH(7), + UNRECOGNIZED(-1), + ; + + /** + * ACTION_DEDUPLICATION_STATUS_UNSPECIFIED = 0; + */ + public static final int ACTION_DEDUPLICATION_STATUS_UNSPECIFIED_VALUE = 0; + /** + * ACTION_DEDUPLICATION_STATUS_ACCEPTED_NEW = 1; + */ + public static final int ACTION_DEDUPLICATION_STATUS_ACCEPTED_NEW_VALUE = 1; + /** + * ACTION_DEDUPLICATION_STATUS_JOINED_IN_FLIGHT = 2; + */ + public static final int ACTION_DEDUPLICATION_STATUS_JOINED_IN_FLIGHT_VALUE = 2; + /** + * ACTION_DEDUPLICATION_STATUS_CACHED_RESULT = 3; + */ + public static final int ACTION_DEDUPLICATION_STATUS_CACHED_RESULT_VALUE = 3; + /** + * ACTION_DEDUPLICATION_STATUS_RESULT_EVICTED = 4; + */ + public static final int ACTION_DEDUPLICATION_STATUS_RESULT_EVICTED_VALUE = 4; + /** + * ACTION_DEDUPLICATION_STATUS_LEDGER_EXHAUSTED = 5; + */ + public static final int ACTION_DEDUPLICATION_STATUS_LEDGER_EXHAUSTED_VALUE = 5; + /** + * ACTION_DEDUPLICATION_STATUS_ACTION_ID_CONFLICT = 6; + */ + public static final int ACTION_DEDUPLICATION_STATUS_ACTION_ID_CONFLICT_VALUE = 6; + /** + * ACTION_DEDUPLICATION_STATUS_SERVICE_INSTANCE_MISMATCH = 7; + */ + public static final int ACTION_DEDUPLICATION_STATUS_SERVICE_INSTANCE_MISMATCH_VALUE = 7; + + + public final int getNumber() { + if (this == UNRECOGNIZED) { + throw new java.lang.IllegalArgumentException( + "Can't get the number of an unknown enum value."); + } + return value; + } + + /** + * @param value The numeric wire value of the corresponding enum entry. + * @return The enum associated with the given numeric wire value. + * @deprecated Use {@link #forNumber(int)} instead. + */ + @java.lang.Deprecated + public static ActionDeduplicationStatus valueOf(int value) { + return forNumber(value); + } + + /** + * @param value The numeric wire value of the corresponding enum entry. + * @return The enum associated with the given numeric wire value. + */ + public static ActionDeduplicationStatus forNumber(int value) { + switch (value) { + case 0: return ACTION_DEDUPLICATION_STATUS_UNSPECIFIED; + case 1: return ACTION_DEDUPLICATION_STATUS_ACCEPTED_NEW; + case 2: return ACTION_DEDUPLICATION_STATUS_JOINED_IN_FLIGHT; + case 3: return ACTION_DEDUPLICATION_STATUS_CACHED_RESULT; + case 4: return ACTION_DEDUPLICATION_STATUS_RESULT_EVICTED; + case 5: return ACTION_DEDUPLICATION_STATUS_LEDGER_EXHAUSTED; + case 6: return ACTION_DEDUPLICATION_STATUS_ACTION_ID_CONFLICT; + case 7: return ACTION_DEDUPLICATION_STATUS_SERVICE_INSTANCE_MISMATCH; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static final com.google.protobuf.Internal.EnumLiteMap< + ActionDeduplicationStatus> internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public ActionDeduplicationStatus findValueByNumber(int number) { + return ActionDeduplicationStatus.forNumber(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + if (this == UNRECOGNIZED) { + throw new java.lang.IllegalStateException( + "Can't get the descriptor of an unrecognized enum value."); + } + return getDescriptor().getValues().get(ordinal()); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return cmvr.api.SystemCommand.getDescriptor().getEnumTypes().get(5); + } + + private static final ActionDeduplicationStatus[] VALUES = values(); + + public static ActionDeduplicationStatus valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + if (desc.getIndex() == -1) { + return UNRECOGNIZED; + } + return VALUES[desc.getIndex()]; + } + + private final int value; + + private ActionDeduplicationStatus(int value) { + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:cmvr.api.ActionDeduplicationStatus) + } + public interface DeviceListOrBuilder extends // @@protoc_insertion_point(interface_extends:cmvr.api.DeviceList) com.google.protobuf.MessageOrBuilder { @@ -5640,6 +5955,28 @@ public final class SystemCommand { */ com.google.protobuf.ByteString getArchitectureBytes(); + + /** + *
+       * Changes whenever the in-process ActionQueue idempotency ledger is
+       * recreated. Clients bind submissions and retries to this value.
+       * 
+ * + * string action_service_instance_id = 8; + * @return The actionServiceInstanceId. + */ + java.lang.String getActionServiceInstanceId(); + /** + *
+       * Changes whenever the in-process ActionQueue idempotency ledger is
+       * recreated. Clients bind submissions and retries to this value.
+       * 
+ * + * string action_service_instance_id = 8; + * @return The bytes for actionServiceInstanceId. + */ + com.google.protobuf.ByteString + getActionServiceInstanceIdBytes(); } /** * Protobuf type {@code cmvr.api.GetSystemInfoCommand.Feedback} @@ -5660,6 +5997,7 @@ public final class SystemCommand { os_ = ""; kernelVersion_ = ""; architecture_ = ""; + actionServiceInstanceId_ = ""; } @java.lang.Override @@ -5941,6 +6279,54 @@ public final class SystemCommand { } } + public static final int ACTION_SERVICE_INSTANCE_ID_FIELD_NUMBER = 8; + private volatile java.lang.Object actionServiceInstanceId_; + /** + *
+       * Changes whenever the in-process ActionQueue idempotency ledger is
+       * recreated. Clients bind submissions and retries to this value.
+       * 
+ * + * string action_service_instance_id = 8; + * @return The actionServiceInstanceId. + */ + @java.lang.Override + public java.lang.String getActionServiceInstanceId() { + java.lang.Object ref = actionServiceInstanceId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + actionServiceInstanceId_ = s; + return s; + } + } + /** + *
+       * Changes whenever the in-process ActionQueue idempotency ledger is
+       * recreated. Clients bind submissions and retries to this value.
+       * 
+ * + * string action_service_instance_id = 8; + * @return The bytes for actionServiceInstanceId. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getActionServiceInstanceIdBytes() { + java.lang.Object ref = actionServiceInstanceId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + actionServiceInstanceId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + private byte memoizedIsInitialized = -1; @java.lang.Override public final boolean isInitialized() { @@ -5976,6 +6362,9 @@ public final class SystemCommand { if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(architecture_)) { com.google.protobuf.GeneratedMessageV3.writeString(output, 7, architecture_); } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(actionServiceInstanceId_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 8, actionServiceInstanceId_); + } getUnknownFields().writeTo(output); } @@ -6007,6 +6396,9 @@ public final class SystemCommand { if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(architecture_)) { size += com.google.protobuf.GeneratedMessageV3.computeStringSize(7, architecture_); } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(actionServiceInstanceId_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(8, actionServiceInstanceId_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -6039,6 +6431,8 @@ public final class SystemCommand { .equals(other.getKernelVersion())) return false; if (!getArchitecture() .equals(other.getArchitecture())) return false; + if (!getActionServiceInstanceId() + .equals(other.getActionServiceInstanceId())) return false; if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @@ -6066,6 +6460,8 @@ public final class SystemCommand { hash = (53 * hash) + getKernelVersion().hashCode(); hash = (37 * hash) + ARCHITECTURE_FIELD_NUMBER; hash = (53 * hash) + getArchitecture().hashCode(); + hash = (37 * hash) + ACTION_SERVICE_INSTANCE_ID_FIELD_NUMBER; + hash = (53 * hash) + getActionServiceInstanceId().hashCode(); hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -6212,6 +6608,8 @@ public final class SystemCommand { architecture_ = ""; + actionServiceInstanceId_ = ""; + return this; } @@ -6249,6 +6647,7 @@ public final class SystemCommand { result.os_ = os_; result.kernelVersion_ = kernelVersion_; result.architecture_ = architecture_; + result.actionServiceInstanceId_ = actionServiceInstanceId_; onBuilt(); return result; } @@ -6324,6 +6723,10 @@ public final class SystemCommand { architecture_ = other.architecture_; onChanged(); } + if (!other.getActionServiceInstanceId().isEmpty()) { + actionServiceInstanceId_ = other.actionServiceInstanceId_; + onChanged(); + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -6387,6 +6790,11 @@ public final class SystemCommand { break; } // case 58 + case 66: { + actionServiceInstanceId_ = input.readStringRequireUtf8(); + + break; + } // case 66 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag @@ -6977,6 +7385,107 @@ public final class SystemCommand { onChanged(); return this; } + + private java.lang.Object actionServiceInstanceId_ = ""; + /** + *
+         * Changes whenever the in-process ActionQueue idempotency ledger is
+         * recreated. Clients bind submissions and retries to this value.
+         * 
+ * + * string action_service_instance_id = 8; + * @return The actionServiceInstanceId. + */ + public java.lang.String getActionServiceInstanceId() { + java.lang.Object ref = actionServiceInstanceId_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + actionServiceInstanceId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + *
+         * Changes whenever the in-process ActionQueue idempotency ledger is
+         * recreated. Clients bind submissions and retries to this value.
+         * 
+ * + * string action_service_instance_id = 8; + * @return The bytes for actionServiceInstanceId. + */ + public com.google.protobuf.ByteString + getActionServiceInstanceIdBytes() { + java.lang.Object ref = actionServiceInstanceId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + actionServiceInstanceId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
+         * Changes whenever the in-process ActionQueue idempotency ledger is
+         * recreated. Clients bind submissions and retries to this value.
+         * 
+ * + * string action_service_instance_id = 8; + * @param value The actionServiceInstanceId to set. + * @return This builder for chaining. + */ + public Builder setActionServiceInstanceId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + actionServiceInstanceId_ = value; + onChanged(); + return this; + } + /** + *
+         * Changes whenever the in-process ActionQueue idempotency ledger is
+         * recreated. Clients bind submissions and retries to this value.
+         * 
+ * + * string action_service_instance_id = 8; + * @return This builder for chaining. + */ + public Builder clearActionServiceInstanceId() { + + actionServiceInstanceId_ = getDefaultInstance().getActionServiceInstanceId(); + onChanged(); + return this; + } + /** + *
+         * Changes whenever the in-process ActionQueue idempotency ledger is
+         * recreated. Clients bind submissions and retries to this value.
+         * 
+ * + * string action_service_instance_id = 8; + * @param value The bytes for actionServiceInstanceId to set. + * @return This builder for chaining. + */ + public Builder setActionServiceInstanceIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + actionServiceInstanceId_ = value; + onChanged(); + return this; + } @java.lang.Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { @@ -13092,6 +13601,5699 @@ public final class SystemCommand { } + public interface DelayActionOrBuilder extends + // @@protoc_insertion_point(interface_extends:cmvr.api.DelayAction) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * Delay duration in milliseconds. The server applies a bounded maximum.
+     * 
+ * + * uint32 duration_ms = 1; + * @return The durationMs. + */ + int getDurationMs(); + } + /** + *
+   * Edge-local delay between two device commands.
+   * 
+ * + * Protobuf type {@code cmvr.api.DelayAction} + */ + public static final class DelayAction extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cmvr.api.DelayAction) + DelayActionOrBuilder { + private static final long serialVersionUID = 0L; + // Use DelayAction.newBuilder() to construct. + private DelayAction(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private DelayAction() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new DelayAction(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_DelayAction_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_DelayAction_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cmvr.api.SystemCommand.DelayAction.class, cmvr.api.SystemCommand.DelayAction.Builder.class); + } + + public static final int DURATION_MS_FIELD_NUMBER = 1; + private int durationMs_; + /** + *
+     * Delay duration in milliseconds. The server applies a bounded maximum.
+     * 
+ * + * uint32 duration_ms = 1; + * @return The durationMs. + */ + @java.lang.Override + public int getDurationMs() { + return durationMs_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (durationMs_ != 0) { + output.writeUInt32(1, durationMs_); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (durationMs_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeUInt32Size(1, durationMs_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cmvr.api.SystemCommand.DelayAction)) { + return super.equals(obj); + } + cmvr.api.SystemCommand.DelayAction other = (cmvr.api.SystemCommand.DelayAction) obj; + + if (getDurationMs() + != other.getDurationMs()) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + DURATION_MS_FIELD_NUMBER; + hash = (53 * hash) + getDurationMs(); + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cmvr.api.SystemCommand.DelayAction parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cmvr.api.SystemCommand.DelayAction parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cmvr.api.SystemCommand.DelayAction parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cmvr.api.SystemCommand.DelayAction parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cmvr.api.SystemCommand.DelayAction parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cmvr.api.SystemCommand.DelayAction parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cmvr.api.SystemCommand.DelayAction parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cmvr.api.SystemCommand.DelayAction parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cmvr.api.SystemCommand.DelayAction parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cmvr.api.SystemCommand.DelayAction parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cmvr.api.SystemCommand.DelayAction parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cmvr.api.SystemCommand.DelayAction parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cmvr.api.SystemCommand.DelayAction prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Edge-local delay between two device commands.
+     * 
+ * + * Protobuf type {@code cmvr.api.DelayAction} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cmvr.api.DelayAction) + cmvr.api.SystemCommand.DelayActionOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_DelayAction_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_DelayAction_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cmvr.api.SystemCommand.DelayAction.class, cmvr.api.SystemCommand.DelayAction.Builder.class); + } + + // Construct using cmvr.api.SystemCommand.DelayAction.newBuilder() + private Builder() { + + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + durationMs_ = 0; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_DelayAction_descriptor; + } + + @java.lang.Override + public cmvr.api.SystemCommand.DelayAction getDefaultInstanceForType() { + return cmvr.api.SystemCommand.DelayAction.getDefaultInstance(); + } + + @java.lang.Override + public cmvr.api.SystemCommand.DelayAction build() { + cmvr.api.SystemCommand.DelayAction result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cmvr.api.SystemCommand.DelayAction buildPartial() { + cmvr.api.SystemCommand.DelayAction result = new cmvr.api.SystemCommand.DelayAction(this); + result.durationMs_ = durationMs_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cmvr.api.SystemCommand.DelayAction) { + return mergeFrom((cmvr.api.SystemCommand.DelayAction)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cmvr.api.SystemCommand.DelayAction other) { + if (other == cmvr.api.SystemCommand.DelayAction.getDefaultInstance()) return this; + if (other.getDurationMs() != 0) { + setDurationMs(other.getDurationMs()); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + durationMs_ = input.readUInt32(); + + break; + } // case 8 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + + private int durationMs_ ; + /** + *
+       * Delay duration in milliseconds. The server applies a bounded maximum.
+       * 
+ * + * uint32 duration_ms = 1; + * @return The durationMs. + */ + @java.lang.Override + public int getDurationMs() { + return durationMs_; + } + /** + *
+       * Delay duration in milliseconds. The server applies a bounded maximum.
+       * 
+ * + * uint32 duration_ms = 1; + * @param value The durationMs to set. + * @return This builder for chaining. + */ + public Builder setDurationMs(int value) { + + durationMs_ = value; + onChanged(); + return this; + } + /** + *
+       * Delay duration in milliseconds. The server applies a bounded maximum.
+       * 
+ * + * uint32 duration_ms = 1; + * @return This builder for chaining. + */ + public Builder clearDurationMs() { + + durationMs_ = 0; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cmvr.api.DelayAction) + } + + // @@protoc_insertion_point(class_scope:cmvr.api.DelayAction) + private static final cmvr.api.SystemCommand.DelayAction DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cmvr.api.SystemCommand.DelayAction(); + } + + public static cmvr.api.SystemCommand.DelayAction getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public DelayAction parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cmvr.api.SystemCommand.DelayAction getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface ActionStepOrBuilder extends + // @@protoc_insertion_point(interface_extends:cmvr.api.ActionStep) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * Client-provided identifier used for diagnostics. It must be unique within
+     * one ActionQueue request.
+     * 
+ * + * string step_id = 1; + * @return The stepId. + */ + java.lang.String getStepId(); + /** + *
+     * Client-provided identifier used for diagnostics. It must be unique within
+     * one ActionQueue request.
+     * 
+ * + * string step_id = 1; + * @return The bytes for stepId. + */ + com.google.protobuf.ByteString + getStepIdBytes(); + + /** + *
+     * Per-step timeout in milliseconds. Zero inherits the remaining action
+     * timeout or the server default.
+     * 
+ * + * uint32 timeout_ms = 2; + * @return The timeoutMs. + */ + int getTimeoutMs(); + + /** + * .cmvr.api.MoveJ.Request arm_move_j = 10; + * @return Whether the armMoveJ field is set. + */ + boolean hasArmMoveJ(); + /** + * .cmvr.api.MoveJ.Request arm_move_j = 10; + * @return The armMoveJ. + */ + cmvr.api.ArmCommand.MoveJ.Request getArmMoveJ(); + /** + * .cmvr.api.MoveJ.Request arm_move_j = 10; + */ + cmvr.api.ArmCommand.MoveJ.RequestOrBuilder getArmMoveJOrBuilder(); + + /** + * .cmvr.api.MoveL.Request arm_move_l = 11; + * @return Whether the armMoveL field is set. + */ + boolean hasArmMoveL(); + /** + * .cmvr.api.MoveL.Request arm_move_l = 11; + * @return The armMoveL. + */ + cmvr.api.ArmCommand.MoveL.Request getArmMoveL(); + /** + * .cmvr.api.MoveL.Request arm_move_l = 11; + */ + cmvr.api.ArmCommand.MoveL.RequestOrBuilder getArmMoveLOrBuilder(); + + /** + * .cmvr.api.AgvNavigateToPoseCommand.Request agv_navigate_to_pose = 20; + * @return Whether the agvNavigateToPose field is set. + */ + boolean hasAgvNavigateToPose(); + /** + * .cmvr.api.AgvNavigateToPoseCommand.Request agv_navigate_to_pose = 20; + * @return The agvNavigateToPose. + */ + cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request getAgvNavigateToPose(); + /** + * .cmvr.api.AgvNavigateToPoseCommand.Request agv_navigate_to_pose = 20; + */ + cmvr.api.AgvCommand.AgvNavigateToPoseCommand.RequestOrBuilder getAgvNavigateToPoseOrBuilder(); + + /** + * .cmvr.api.AgvNavigateToStationCommand.Request agv_navigate_to_station = 21; + * @return Whether the agvNavigateToStation field is set. + */ + boolean hasAgvNavigateToStation(); + /** + * .cmvr.api.AgvNavigateToStationCommand.Request agv_navigate_to_station = 21; + * @return The agvNavigateToStation. + */ + cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request getAgvNavigateToStation(); + /** + * .cmvr.api.AgvNavigateToStationCommand.Request agv_navigate_to_station = 21; + */ + cmvr.api.AgvCommand.AgvNavigateToStationCommand.RequestOrBuilder getAgvNavigateToStationOrBuilder(); + + /** + * .cmvr.api.AgvFollowPathCommand.Request agv_follow_path = 22; + * @return Whether the agvFollowPath field is set. + */ + boolean hasAgvFollowPath(); + /** + * .cmvr.api.AgvFollowPathCommand.Request agv_follow_path = 22; + * @return The agvFollowPath. + */ + cmvr.api.AgvCommand.AgvFollowPathCommand.Request getAgvFollowPath(); + /** + * .cmvr.api.AgvFollowPathCommand.Request agv_follow_path = 22; + */ + cmvr.api.AgvCommand.AgvFollowPathCommand.RequestOrBuilder getAgvFollowPathOrBuilder(); + + /** + * .cmvr.api.DelayAction delay = 90; + * @return Whether the delay field is set. + */ + boolean hasDelay(); + /** + * .cmvr.api.DelayAction delay = 90; + * @return The delay. + */ + cmvr.api.SystemCommand.DelayAction getDelay(); + /** + * .cmvr.api.DelayAction delay = 90; + */ + cmvr.api.SystemCommand.DelayActionOrBuilder getDelayOrBuilder(); + + public cmvr.api.SystemCommand.ActionStep.CommandCase getCommandCase(); + } + /** + *
+   * One finite, synchronous command in an ActionQueue request.
+   * 
+ * + * Protobuf type {@code cmvr.api.ActionStep} + */ + public static final class ActionStep extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cmvr.api.ActionStep) + ActionStepOrBuilder { + private static final long serialVersionUID = 0L; + // Use ActionStep.newBuilder() to construct. + private ActionStep(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private ActionStep() { + stepId_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new ActionStep(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionStep_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionStep_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cmvr.api.SystemCommand.ActionStep.class, cmvr.api.SystemCommand.ActionStep.Builder.class); + } + + private int commandCase_ = 0; + private java.lang.Object command_; + public enum CommandCase + implements com.google.protobuf.Internal.EnumLite, + com.google.protobuf.AbstractMessage.InternalOneOfEnum { + ARM_MOVE_J(10), + ARM_MOVE_L(11), + AGV_NAVIGATE_TO_POSE(20), + AGV_NAVIGATE_TO_STATION(21), + AGV_FOLLOW_PATH(22), + DELAY(90), + COMMAND_NOT_SET(0); + private final int value; + private CommandCase(int value) { + this.value = value; + } + /** + * @param value The number of the enum to look for. + * @return The enum associated with the given number. + * @deprecated Use {@link #forNumber(int)} instead. + */ + @java.lang.Deprecated + public static CommandCase valueOf(int value) { + return forNumber(value); + } + + public static CommandCase forNumber(int value) { + switch (value) { + case 10: return ARM_MOVE_J; + case 11: return ARM_MOVE_L; + case 20: return AGV_NAVIGATE_TO_POSE; + case 21: return AGV_NAVIGATE_TO_STATION; + case 22: return AGV_FOLLOW_PATH; + case 90: return DELAY; + case 0: return COMMAND_NOT_SET; + default: return null; + } + } + public int getNumber() { + return this.value; + } + }; + + public CommandCase + getCommandCase() { + return CommandCase.forNumber( + commandCase_); + } + + public static final int STEP_ID_FIELD_NUMBER = 1; + private volatile java.lang.Object stepId_; + /** + *
+     * Client-provided identifier used for diagnostics. It must be unique within
+     * one ActionQueue request.
+     * 
+ * + * string step_id = 1; + * @return The stepId. + */ + @java.lang.Override + public java.lang.String getStepId() { + java.lang.Object ref = stepId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + stepId_ = s; + return s; + } + } + /** + *
+     * Client-provided identifier used for diagnostics. It must be unique within
+     * one ActionQueue request.
+     * 
+ * + * string step_id = 1; + * @return The bytes for stepId. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getStepIdBytes() { + java.lang.Object ref = stepId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + stepId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TIMEOUT_MS_FIELD_NUMBER = 2; + private int timeoutMs_; + /** + *
+     * Per-step timeout in milliseconds. Zero inherits the remaining action
+     * timeout or the server default.
+     * 
+ * + * uint32 timeout_ms = 2; + * @return The timeoutMs. + */ + @java.lang.Override + public int getTimeoutMs() { + return timeoutMs_; + } + + public static final int ARM_MOVE_J_FIELD_NUMBER = 10; + /** + * .cmvr.api.MoveJ.Request arm_move_j = 10; + * @return Whether the armMoveJ field is set. + */ + @java.lang.Override + public boolean hasArmMoveJ() { + return commandCase_ == 10; + } + /** + * .cmvr.api.MoveJ.Request arm_move_j = 10; + * @return The armMoveJ. + */ + @java.lang.Override + public cmvr.api.ArmCommand.MoveJ.Request getArmMoveJ() { + if (commandCase_ == 10) { + return (cmvr.api.ArmCommand.MoveJ.Request) command_; + } + return cmvr.api.ArmCommand.MoveJ.Request.getDefaultInstance(); + } + /** + * .cmvr.api.MoveJ.Request arm_move_j = 10; + */ + @java.lang.Override + public cmvr.api.ArmCommand.MoveJ.RequestOrBuilder getArmMoveJOrBuilder() { + if (commandCase_ == 10) { + return (cmvr.api.ArmCommand.MoveJ.Request) command_; + } + return cmvr.api.ArmCommand.MoveJ.Request.getDefaultInstance(); + } + + public static final int ARM_MOVE_L_FIELD_NUMBER = 11; + /** + * .cmvr.api.MoveL.Request arm_move_l = 11; + * @return Whether the armMoveL field is set. + */ + @java.lang.Override + public boolean hasArmMoveL() { + return commandCase_ == 11; + } + /** + * .cmvr.api.MoveL.Request arm_move_l = 11; + * @return The armMoveL. + */ + @java.lang.Override + public cmvr.api.ArmCommand.MoveL.Request getArmMoveL() { + if (commandCase_ == 11) { + return (cmvr.api.ArmCommand.MoveL.Request) command_; + } + return cmvr.api.ArmCommand.MoveL.Request.getDefaultInstance(); + } + /** + * .cmvr.api.MoveL.Request arm_move_l = 11; + */ + @java.lang.Override + public cmvr.api.ArmCommand.MoveL.RequestOrBuilder getArmMoveLOrBuilder() { + if (commandCase_ == 11) { + return (cmvr.api.ArmCommand.MoveL.Request) command_; + } + return cmvr.api.ArmCommand.MoveL.Request.getDefaultInstance(); + } + + public static final int AGV_NAVIGATE_TO_POSE_FIELD_NUMBER = 20; + /** + * .cmvr.api.AgvNavigateToPoseCommand.Request agv_navigate_to_pose = 20; + * @return Whether the agvNavigateToPose field is set. + */ + @java.lang.Override + public boolean hasAgvNavigateToPose() { + return commandCase_ == 20; + } + /** + * .cmvr.api.AgvNavigateToPoseCommand.Request agv_navigate_to_pose = 20; + * @return The agvNavigateToPose. + */ + @java.lang.Override + public cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request getAgvNavigateToPose() { + if (commandCase_ == 20) { + return (cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request) command_; + } + return cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request.getDefaultInstance(); + } + /** + * .cmvr.api.AgvNavigateToPoseCommand.Request agv_navigate_to_pose = 20; + */ + @java.lang.Override + public cmvr.api.AgvCommand.AgvNavigateToPoseCommand.RequestOrBuilder getAgvNavigateToPoseOrBuilder() { + if (commandCase_ == 20) { + return (cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request) command_; + } + return cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request.getDefaultInstance(); + } + + public static final int AGV_NAVIGATE_TO_STATION_FIELD_NUMBER = 21; + /** + * .cmvr.api.AgvNavigateToStationCommand.Request agv_navigate_to_station = 21; + * @return Whether the agvNavigateToStation field is set. + */ + @java.lang.Override + public boolean hasAgvNavigateToStation() { + return commandCase_ == 21; + } + /** + * .cmvr.api.AgvNavigateToStationCommand.Request agv_navigate_to_station = 21; + * @return The agvNavigateToStation. + */ + @java.lang.Override + public cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request getAgvNavigateToStation() { + if (commandCase_ == 21) { + return (cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request) command_; + } + return cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request.getDefaultInstance(); + } + /** + * .cmvr.api.AgvNavigateToStationCommand.Request agv_navigate_to_station = 21; + */ + @java.lang.Override + public cmvr.api.AgvCommand.AgvNavigateToStationCommand.RequestOrBuilder getAgvNavigateToStationOrBuilder() { + if (commandCase_ == 21) { + return (cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request) command_; + } + return cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request.getDefaultInstance(); + } + + public static final int AGV_FOLLOW_PATH_FIELD_NUMBER = 22; + /** + * .cmvr.api.AgvFollowPathCommand.Request agv_follow_path = 22; + * @return Whether the agvFollowPath field is set. + */ + @java.lang.Override + public boolean hasAgvFollowPath() { + return commandCase_ == 22; + } + /** + * .cmvr.api.AgvFollowPathCommand.Request agv_follow_path = 22; + * @return The agvFollowPath. + */ + @java.lang.Override + public cmvr.api.AgvCommand.AgvFollowPathCommand.Request getAgvFollowPath() { + if (commandCase_ == 22) { + return (cmvr.api.AgvCommand.AgvFollowPathCommand.Request) command_; + } + return cmvr.api.AgvCommand.AgvFollowPathCommand.Request.getDefaultInstance(); + } + /** + * .cmvr.api.AgvFollowPathCommand.Request agv_follow_path = 22; + */ + @java.lang.Override + public cmvr.api.AgvCommand.AgvFollowPathCommand.RequestOrBuilder getAgvFollowPathOrBuilder() { + if (commandCase_ == 22) { + return (cmvr.api.AgvCommand.AgvFollowPathCommand.Request) command_; + } + return cmvr.api.AgvCommand.AgvFollowPathCommand.Request.getDefaultInstance(); + } + + public static final int DELAY_FIELD_NUMBER = 90; + /** + * .cmvr.api.DelayAction delay = 90; + * @return Whether the delay field is set. + */ + @java.lang.Override + public boolean hasDelay() { + return commandCase_ == 90; + } + /** + * .cmvr.api.DelayAction delay = 90; + * @return The delay. + */ + @java.lang.Override + public cmvr.api.SystemCommand.DelayAction getDelay() { + if (commandCase_ == 90) { + return (cmvr.api.SystemCommand.DelayAction) command_; + } + return cmvr.api.SystemCommand.DelayAction.getDefaultInstance(); + } + /** + * .cmvr.api.DelayAction delay = 90; + */ + @java.lang.Override + public cmvr.api.SystemCommand.DelayActionOrBuilder getDelayOrBuilder() { + if (commandCase_ == 90) { + return (cmvr.api.SystemCommand.DelayAction) command_; + } + return cmvr.api.SystemCommand.DelayAction.getDefaultInstance(); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(stepId_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, stepId_); + } + if (timeoutMs_ != 0) { + output.writeUInt32(2, timeoutMs_); + } + if (commandCase_ == 10) { + output.writeMessage(10, (cmvr.api.ArmCommand.MoveJ.Request) command_); + } + if (commandCase_ == 11) { + output.writeMessage(11, (cmvr.api.ArmCommand.MoveL.Request) command_); + } + if (commandCase_ == 20) { + output.writeMessage(20, (cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request) command_); + } + if (commandCase_ == 21) { + output.writeMessage(21, (cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request) command_); + } + if (commandCase_ == 22) { + output.writeMessage(22, (cmvr.api.AgvCommand.AgvFollowPathCommand.Request) command_); + } + if (commandCase_ == 90) { + output.writeMessage(90, (cmvr.api.SystemCommand.DelayAction) command_); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(stepId_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, stepId_); + } + if (timeoutMs_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeUInt32Size(2, timeoutMs_); + } + if (commandCase_ == 10) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(10, (cmvr.api.ArmCommand.MoveJ.Request) command_); + } + if (commandCase_ == 11) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(11, (cmvr.api.ArmCommand.MoveL.Request) command_); + } + if (commandCase_ == 20) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(20, (cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request) command_); + } + if (commandCase_ == 21) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(21, (cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request) command_); + } + if (commandCase_ == 22) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(22, (cmvr.api.AgvCommand.AgvFollowPathCommand.Request) command_); + } + if (commandCase_ == 90) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(90, (cmvr.api.SystemCommand.DelayAction) command_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cmvr.api.SystemCommand.ActionStep)) { + return super.equals(obj); + } + cmvr.api.SystemCommand.ActionStep other = (cmvr.api.SystemCommand.ActionStep) obj; + + if (!getStepId() + .equals(other.getStepId())) return false; + if (getTimeoutMs() + != other.getTimeoutMs()) return false; + if (!getCommandCase().equals(other.getCommandCase())) return false; + switch (commandCase_) { + case 10: + if (!getArmMoveJ() + .equals(other.getArmMoveJ())) return false; + break; + case 11: + if (!getArmMoveL() + .equals(other.getArmMoveL())) return false; + break; + case 20: + if (!getAgvNavigateToPose() + .equals(other.getAgvNavigateToPose())) return false; + break; + case 21: + if (!getAgvNavigateToStation() + .equals(other.getAgvNavigateToStation())) return false; + break; + case 22: + if (!getAgvFollowPath() + .equals(other.getAgvFollowPath())) return false; + break; + case 90: + if (!getDelay() + .equals(other.getDelay())) return false; + break; + case 0: + default: + } + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + STEP_ID_FIELD_NUMBER; + hash = (53 * hash) + getStepId().hashCode(); + hash = (37 * hash) + TIMEOUT_MS_FIELD_NUMBER; + hash = (53 * hash) + getTimeoutMs(); + switch (commandCase_) { + case 10: + hash = (37 * hash) + ARM_MOVE_J_FIELD_NUMBER; + hash = (53 * hash) + getArmMoveJ().hashCode(); + break; + case 11: + hash = (37 * hash) + ARM_MOVE_L_FIELD_NUMBER; + hash = (53 * hash) + getArmMoveL().hashCode(); + break; + case 20: + hash = (37 * hash) + AGV_NAVIGATE_TO_POSE_FIELD_NUMBER; + hash = (53 * hash) + getAgvNavigateToPose().hashCode(); + break; + case 21: + hash = (37 * hash) + AGV_NAVIGATE_TO_STATION_FIELD_NUMBER; + hash = (53 * hash) + getAgvNavigateToStation().hashCode(); + break; + case 22: + hash = (37 * hash) + AGV_FOLLOW_PATH_FIELD_NUMBER; + hash = (53 * hash) + getAgvFollowPath().hashCode(); + break; + case 90: + hash = (37 * hash) + DELAY_FIELD_NUMBER; + hash = (53 * hash) + getDelay().hashCode(); + break; + case 0: + default: + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cmvr.api.SystemCommand.ActionStep parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cmvr.api.SystemCommand.ActionStep parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionStep parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cmvr.api.SystemCommand.ActionStep parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionStep parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cmvr.api.SystemCommand.ActionStep parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionStep parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cmvr.api.SystemCommand.ActionStep parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionStep parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cmvr.api.SystemCommand.ActionStep parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionStep parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cmvr.api.SystemCommand.ActionStep parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cmvr.api.SystemCommand.ActionStep prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * One finite, synchronous command in an ActionQueue request.
+     * 
+ * + * Protobuf type {@code cmvr.api.ActionStep} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cmvr.api.ActionStep) + cmvr.api.SystemCommand.ActionStepOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionStep_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionStep_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cmvr.api.SystemCommand.ActionStep.class, cmvr.api.SystemCommand.ActionStep.Builder.class); + } + + // Construct using cmvr.api.SystemCommand.ActionStep.newBuilder() + private Builder() { + + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + stepId_ = ""; + + timeoutMs_ = 0; + + if (armMoveJBuilder_ != null) { + armMoveJBuilder_.clear(); + } + if (armMoveLBuilder_ != null) { + armMoveLBuilder_.clear(); + } + if (agvNavigateToPoseBuilder_ != null) { + agvNavigateToPoseBuilder_.clear(); + } + if (agvNavigateToStationBuilder_ != null) { + agvNavigateToStationBuilder_.clear(); + } + if (agvFollowPathBuilder_ != null) { + agvFollowPathBuilder_.clear(); + } + if (delayBuilder_ != null) { + delayBuilder_.clear(); + } + commandCase_ = 0; + command_ = null; + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionStep_descriptor; + } + + @java.lang.Override + public cmvr.api.SystemCommand.ActionStep getDefaultInstanceForType() { + return cmvr.api.SystemCommand.ActionStep.getDefaultInstance(); + } + + @java.lang.Override + public cmvr.api.SystemCommand.ActionStep build() { + cmvr.api.SystemCommand.ActionStep result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cmvr.api.SystemCommand.ActionStep buildPartial() { + cmvr.api.SystemCommand.ActionStep result = new cmvr.api.SystemCommand.ActionStep(this); + result.stepId_ = stepId_; + result.timeoutMs_ = timeoutMs_; + if (commandCase_ == 10) { + if (armMoveJBuilder_ == null) { + result.command_ = command_; + } else { + result.command_ = armMoveJBuilder_.build(); + } + } + if (commandCase_ == 11) { + if (armMoveLBuilder_ == null) { + result.command_ = command_; + } else { + result.command_ = armMoveLBuilder_.build(); + } + } + if (commandCase_ == 20) { + if (agvNavigateToPoseBuilder_ == null) { + result.command_ = command_; + } else { + result.command_ = agvNavigateToPoseBuilder_.build(); + } + } + if (commandCase_ == 21) { + if (agvNavigateToStationBuilder_ == null) { + result.command_ = command_; + } else { + result.command_ = agvNavigateToStationBuilder_.build(); + } + } + if (commandCase_ == 22) { + if (agvFollowPathBuilder_ == null) { + result.command_ = command_; + } else { + result.command_ = agvFollowPathBuilder_.build(); + } + } + if (commandCase_ == 90) { + if (delayBuilder_ == null) { + result.command_ = command_; + } else { + result.command_ = delayBuilder_.build(); + } + } + result.commandCase_ = commandCase_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cmvr.api.SystemCommand.ActionStep) { + return mergeFrom((cmvr.api.SystemCommand.ActionStep)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cmvr.api.SystemCommand.ActionStep other) { + if (other == cmvr.api.SystemCommand.ActionStep.getDefaultInstance()) return this; + if (!other.getStepId().isEmpty()) { + stepId_ = other.stepId_; + onChanged(); + } + if (other.getTimeoutMs() != 0) { + setTimeoutMs(other.getTimeoutMs()); + } + switch (other.getCommandCase()) { + case ARM_MOVE_J: { + mergeArmMoveJ(other.getArmMoveJ()); + break; + } + case ARM_MOVE_L: { + mergeArmMoveL(other.getArmMoveL()); + break; + } + case AGV_NAVIGATE_TO_POSE: { + mergeAgvNavigateToPose(other.getAgvNavigateToPose()); + break; + } + case AGV_NAVIGATE_TO_STATION: { + mergeAgvNavigateToStation(other.getAgvNavigateToStation()); + break; + } + case AGV_FOLLOW_PATH: { + mergeAgvFollowPath(other.getAgvFollowPath()); + break; + } + case DELAY: { + mergeDelay(other.getDelay()); + break; + } + case COMMAND_NOT_SET: { + break; + } + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + stepId_ = input.readStringRequireUtf8(); + + break; + } // case 10 + case 16: { + timeoutMs_ = input.readUInt32(); + + break; + } // case 16 + case 82: { + input.readMessage( + getArmMoveJFieldBuilder().getBuilder(), + extensionRegistry); + commandCase_ = 10; + break; + } // case 82 + case 90: { + input.readMessage( + getArmMoveLFieldBuilder().getBuilder(), + extensionRegistry); + commandCase_ = 11; + break; + } // case 90 + case 162: { + input.readMessage( + getAgvNavigateToPoseFieldBuilder().getBuilder(), + extensionRegistry); + commandCase_ = 20; + break; + } // case 162 + case 170: { + input.readMessage( + getAgvNavigateToStationFieldBuilder().getBuilder(), + extensionRegistry); + commandCase_ = 21; + break; + } // case 170 + case 178: { + input.readMessage( + getAgvFollowPathFieldBuilder().getBuilder(), + extensionRegistry); + commandCase_ = 22; + break; + } // case 178 + case 722: { + input.readMessage( + getDelayFieldBuilder().getBuilder(), + extensionRegistry); + commandCase_ = 90; + break; + } // case 722 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int commandCase_ = 0; + private java.lang.Object command_; + public CommandCase + getCommandCase() { + return CommandCase.forNumber( + commandCase_); + } + + public Builder clearCommand() { + commandCase_ = 0; + command_ = null; + onChanged(); + return this; + } + + + private java.lang.Object stepId_ = ""; + /** + *
+       * Client-provided identifier used for diagnostics. It must be unique within
+       * one ActionQueue request.
+       * 
+ * + * string step_id = 1; + * @return The stepId. + */ + public java.lang.String getStepId() { + java.lang.Object ref = stepId_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + stepId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + *
+       * Client-provided identifier used for diagnostics. It must be unique within
+       * one ActionQueue request.
+       * 
+ * + * string step_id = 1; + * @return The bytes for stepId. + */ + public com.google.protobuf.ByteString + getStepIdBytes() { + java.lang.Object ref = stepId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + stepId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
+       * Client-provided identifier used for diagnostics. It must be unique within
+       * one ActionQueue request.
+       * 
+ * + * string step_id = 1; + * @param value The stepId to set. + * @return This builder for chaining. + */ + public Builder setStepId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + stepId_ = value; + onChanged(); + return this; + } + /** + *
+       * Client-provided identifier used for diagnostics. It must be unique within
+       * one ActionQueue request.
+       * 
+ * + * string step_id = 1; + * @return This builder for chaining. + */ + public Builder clearStepId() { + + stepId_ = getDefaultInstance().getStepId(); + onChanged(); + return this; + } + /** + *
+       * Client-provided identifier used for diagnostics. It must be unique within
+       * one ActionQueue request.
+       * 
+ * + * string step_id = 1; + * @param value The bytes for stepId to set. + * @return This builder for chaining. + */ + public Builder setStepIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + stepId_ = value; + onChanged(); + return this; + } + + private int timeoutMs_ ; + /** + *
+       * Per-step timeout in milliseconds. Zero inherits the remaining action
+       * timeout or the server default.
+       * 
+ * + * uint32 timeout_ms = 2; + * @return The timeoutMs. + */ + @java.lang.Override + public int getTimeoutMs() { + return timeoutMs_; + } + /** + *
+       * Per-step timeout in milliseconds. Zero inherits the remaining action
+       * timeout or the server default.
+       * 
+ * + * uint32 timeout_ms = 2; + * @param value The timeoutMs to set. + * @return This builder for chaining. + */ + public Builder setTimeoutMs(int value) { + + timeoutMs_ = value; + onChanged(); + return this; + } + /** + *
+       * Per-step timeout in milliseconds. Zero inherits the remaining action
+       * timeout or the server default.
+       * 
+ * + * uint32 timeout_ms = 2; + * @return This builder for chaining. + */ + public Builder clearTimeoutMs() { + + timeoutMs_ = 0; + onChanged(); + return this; + } + + private com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.ArmCommand.MoveJ.Request, cmvr.api.ArmCommand.MoveJ.Request.Builder, cmvr.api.ArmCommand.MoveJ.RequestOrBuilder> armMoveJBuilder_; + /** + * .cmvr.api.MoveJ.Request arm_move_j = 10; + * @return Whether the armMoveJ field is set. + */ + @java.lang.Override + public boolean hasArmMoveJ() { + return commandCase_ == 10; + } + /** + * .cmvr.api.MoveJ.Request arm_move_j = 10; + * @return The armMoveJ. + */ + @java.lang.Override + public cmvr.api.ArmCommand.MoveJ.Request getArmMoveJ() { + if (armMoveJBuilder_ == null) { + if (commandCase_ == 10) { + return (cmvr.api.ArmCommand.MoveJ.Request) command_; + } + return cmvr.api.ArmCommand.MoveJ.Request.getDefaultInstance(); + } else { + if (commandCase_ == 10) { + return armMoveJBuilder_.getMessage(); + } + return cmvr.api.ArmCommand.MoveJ.Request.getDefaultInstance(); + } + } + /** + * .cmvr.api.MoveJ.Request arm_move_j = 10; + */ + public Builder setArmMoveJ(cmvr.api.ArmCommand.MoveJ.Request value) { + if (armMoveJBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + command_ = value; + onChanged(); + } else { + armMoveJBuilder_.setMessage(value); + } + commandCase_ = 10; + return this; + } + /** + * .cmvr.api.MoveJ.Request arm_move_j = 10; + */ + public Builder setArmMoveJ( + cmvr.api.ArmCommand.MoveJ.Request.Builder builderForValue) { + if (armMoveJBuilder_ == null) { + command_ = builderForValue.build(); + onChanged(); + } else { + armMoveJBuilder_.setMessage(builderForValue.build()); + } + commandCase_ = 10; + return this; + } + /** + * .cmvr.api.MoveJ.Request arm_move_j = 10; + */ + public Builder mergeArmMoveJ(cmvr.api.ArmCommand.MoveJ.Request value) { + if (armMoveJBuilder_ == null) { + if (commandCase_ == 10 && + command_ != cmvr.api.ArmCommand.MoveJ.Request.getDefaultInstance()) { + command_ = cmvr.api.ArmCommand.MoveJ.Request.newBuilder((cmvr.api.ArmCommand.MoveJ.Request) command_) + .mergeFrom(value).buildPartial(); + } else { + command_ = value; + } + onChanged(); + } else { + if (commandCase_ == 10) { + armMoveJBuilder_.mergeFrom(value); + } else { + armMoveJBuilder_.setMessage(value); + } + } + commandCase_ = 10; + return this; + } + /** + * .cmvr.api.MoveJ.Request arm_move_j = 10; + */ + public Builder clearArmMoveJ() { + if (armMoveJBuilder_ == null) { + if (commandCase_ == 10) { + commandCase_ = 0; + command_ = null; + onChanged(); + } + } else { + if (commandCase_ == 10) { + commandCase_ = 0; + command_ = null; + } + armMoveJBuilder_.clear(); + } + return this; + } + /** + * .cmvr.api.MoveJ.Request arm_move_j = 10; + */ + public cmvr.api.ArmCommand.MoveJ.Request.Builder getArmMoveJBuilder() { + return getArmMoveJFieldBuilder().getBuilder(); + } + /** + * .cmvr.api.MoveJ.Request arm_move_j = 10; + */ + @java.lang.Override + public cmvr.api.ArmCommand.MoveJ.RequestOrBuilder getArmMoveJOrBuilder() { + if ((commandCase_ == 10) && (armMoveJBuilder_ != null)) { + return armMoveJBuilder_.getMessageOrBuilder(); + } else { + if (commandCase_ == 10) { + return (cmvr.api.ArmCommand.MoveJ.Request) command_; + } + return cmvr.api.ArmCommand.MoveJ.Request.getDefaultInstance(); + } + } + /** + * .cmvr.api.MoveJ.Request arm_move_j = 10; + */ + private com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.ArmCommand.MoveJ.Request, cmvr.api.ArmCommand.MoveJ.Request.Builder, cmvr.api.ArmCommand.MoveJ.RequestOrBuilder> + getArmMoveJFieldBuilder() { + if (armMoveJBuilder_ == null) { + if (!(commandCase_ == 10)) { + command_ = cmvr.api.ArmCommand.MoveJ.Request.getDefaultInstance(); + } + armMoveJBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.ArmCommand.MoveJ.Request, cmvr.api.ArmCommand.MoveJ.Request.Builder, cmvr.api.ArmCommand.MoveJ.RequestOrBuilder>( + (cmvr.api.ArmCommand.MoveJ.Request) command_, + getParentForChildren(), + isClean()); + command_ = null; + } + commandCase_ = 10; + onChanged();; + return armMoveJBuilder_; + } + + private com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.ArmCommand.MoveL.Request, cmvr.api.ArmCommand.MoveL.Request.Builder, cmvr.api.ArmCommand.MoveL.RequestOrBuilder> armMoveLBuilder_; + /** + * .cmvr.api.MoveL.Request arm_move_l = 11; + * @return Whether the armMoveL field is set. + */ + @java.lang.Override + public boolean hasArmMoveL() { + return commandCase_ == 11; + } + /** + * .cmvr.api.MoveL.Request arm_move_l = 11; + * @return The armMoveL. + */ + @java.lang.Override + public cmvr.api.ArmCommand.MoveL.Request getArmMoveL() { + if (armMoveLBuilder_ == null) { + if (commandCase_ == 11) { + return (cmvr.api.ArmCommand.MoveL.Request) command_; + } + return cmvr.api.ArmCommand.MoveL.Request.getDefaultInstance(); + } else { + if (commandCase_ == 11) { + return armMoveLBuilder_.getMessage(); + } + return cmvr.api.ArmCommand.MoveL.Request.getDefaultInstance(); + } + } + /** + * .cmvr.api.MoveL.Request arm_move_l = 11; + */ + public Builder setArmMoveL(cmvr.api.ArmCommand.MoveL.Request value) { + if (armMoveLBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + command_ = value; + onChanged(); + } else { + armMoveLBuilder_.setMessage(value); + } + commandCase_ = 11; + return this; + } + /** + * .cmvr.api.MoveL.Request arm_move_l = 11; + */ + public Builder setArmMoveL( + cmvr.api.ArmCommand.MoveL.Request.Builder builderForValue) { + if (armMoveLBuilder_ == null) { + command_ = builderForValue.build(); + onChanged(); + } else { + armMoveLBuilder_.setMessage(builderForValue.build()); + } + commandCase_ = 11; + return this; + } + /** + * .cmvr.api.MoveL.Request arm_move_l = 11; + */ + public Builder mergeArmMoveL(cmvr.api.ArmCommand.MoveL.Request value) { + if (armMoveLBuilder_ == null) { + if (commandCase_ == 11 && + command_ != cmvr.api.ArmCommand.MoveL.Request.getDefaultInstance()) { + command_ = cmvr.api.ArmCommand.MoveL.Request.newBuilder((cmvr.api.ArmCommand.MoveL.Request) command_) + .mergeFrom(value).buildPartial(); + } else { + command_ = value; + } + onChanged(); + } else { + if (commandCase_ == 11) { + armMoveLBuilder_.mergeFrom(value); + } else { + armMoveLBuilder_.setMessage(value); + } + } + commandCase_ = 11; + return this; + } + /** + * .cmvr.api.MoveL.Request arm_move_l = 11; + */ + public Builder clearArmMoveL() { + if (armMoveLBuilder_ == null) { + if (commandCase_ == 11) { + commandCase_ = 0; + command_ = null; + onChanged(); + } + } else { + if (commandCase_ == 11) { + commandCase_ = 0; + command_ = null; + } + armMoveLBuilder_.clear(); + } + return this; + } + /** + * .cmvr.api.MoveL.Request arm_move_l = 11; + */ + public cmvr.api.ArmCommand.MoveL.Request.Builder getArmMoveLBuilder() { + return getArmMoveLFieldBuilder().getBuilder(); + } + /** + * .cmvr.api.MoveL.Request arm_move_l = 11; + */ + @java.lang.Override + public cmvr.api.ArmCommand.MoveL.RequestOrBuilder getArmMoveLOrBuilder() { + if ((commandCase_ == 11) && (armMoveLBuilder_ != null)) { + return armMoveLBuilder_.getMessageOrBuilder(); + } else { + if (commandCase_ == 11) { + return (cmvr.api.ArmCommand.MoveL.Request) command_; + } + return cmvr.api.ArmCommand.MoveL.Request.getDefaultInstance(); + } + } + /** + * .cmvr.api.MoveL.Request arm_move_l = 11; + */ + private com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.ArmCommand.MoveL.Request, cmvr.api.ArmCommand.MoveL.Request.Builder, cmvr.api.ArmCommand.MoveL.RequestOrBuilder> + getArmMoveLFieldBuilder() { + if (armMoveLBuilder_ == null) { + if (!(commandCase_ == 11)) { + command_ = cmvr.api.ArmCommand.MoveL.Request.getDefaultInstance(); + } + armMoveLBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.ArmCommand.MoveL.Request, cmvr.api.ArmCommand.MoveL.Request.Builder, cmvr.api.ArmCommand.MoveL.RequestOrBuilder>( + (cmvr.api.ArmCommand.MoveL.Request) command_, + getParentForChildren(), + isClean()); + command_ = null; + } + commandCase_ = 11; + onChanged();; + return armMoveLBuilder_; + } + + private com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request, cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request.Builder, cmvr.api.AgvCommand.AgvNavigateToPoseCommand.RequestOrBuilder> agvNavigateToPoseBuilder_; + /** + * .cmvr.api.AgvNavigateToPoseCommand.Request agv_navigate_to_pose = 20; + * @return Whether the agvNavigateToPose field is set. + */ + @java.lang.Override + public boolean hasAgvNavigateToPose() { + return commandCase_ == 20; + } + /** + * .cmvr.api.AgvNavigateToPoseCommand.Request agv_navigate_to_pose = 20; + * @return The agvNavigateToPose. + */ + @java.lang.Override + public cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request getAgvNavigateToPose() { + if (agvNavigateToPoseBuilder_ == null) { + if (commandCase_ == 20) { + return (cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request) command_; + } + return cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request.getDefaultInstance(); + } else { + if (commandCase_ == 20) { + return agvNavigateToPoseBuilder_.getMessage(); + } + return cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request.getDefaultInstance(); + } + } + /** + * .cmvr.api.AgvNavigateToPoseCommand.Request agv_navigate_to_pose = 20; + */ + public Builder setAgvNavigateToPose(cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request value) { + if (agvNavigateToPoseBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + command_ = value; + onChanged(); + } else { + agvNavigateToPoseBuilder_.setMessage(value); + } + commandCase_ = 20; + return this; + } + /** + * .cmvr.api.AgvNavigateToPoseCommand.Request agv_navigate_to_pose = 20; + */ + public Builder setAgvNavigateToPose( + cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request.Builder builderForValue) { + if (agvNavigateToPoseBuilder_ == null) { + command_ = builderForValue.build(); + onChanged(); + } else { + agvNavigateToPoseBuilder_.setMessage(builderForValue.build()); + } + commandCase_ = 20; + return this; + } + /** + * .cmvr.api.AgvNavigateToPoseCommand.Request agv_navigate_to_pose = 20; + */ + public Builder mergeAgvNavigateToPose(cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request value) { + if (agvNavigateToPoseBuilder_ == null) { + if (commandCase_ == 20 && + command_ != cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request.getDefaultInstance()) { + command_ = cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request.newBuilder((cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request) command_) + .mergeFrom(value).buildPartial(); + } else { + command_ = value; + } + onChanged(); + } else { + if (commandCase_ == 20) { + agvNavigateToPoseBuilder_.mergeFrom(value); + } else { + agvNavigateToPoseBuilder_.setMessage(value); + } + } + commandCase_ = 20; + return this; + } + /** + * .cmvr.api.AgvNavigateToPoseCommand.Request agv_navigate_to_pose = 20; + */ + public Builder clearAgvNavigateToPose() { + if (agvNavigateToPoseBuilder_ == null) { + if (commandCase_ == 20) { + commandCase_ = 0; + command_ = null; + onChanged(); + } + } else { + if (commandCase_ == 20) { + commandCase_ = 0; + command_ = null; + } + agvNavigateToPoseBuilder_.clear(); + } + return this; + } + /** + * .cmvr.api.AgvNavigateToPoseCommand.Request agv_navigate_to_pose = 20; + */ + public cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request.Builder getAgvNavigateToPoseBuilder() { + return getAgvNavigateToPoseFieldBuilder().getBuilder(); + } + /** + * .cmvr.api.AgvNavigateToPoseCommand.Request agv_navigate_to_pose = 20; + */ + @java.lang.Override + public cmvr.api.AgvCommand.AgvNavigateToPoseCommand.RequestOrBuilder getAgvNavigateToPoseOrBuilder() { + if ((commandCase_ == 20) && (agvNavigateToPoseBuilder_ != null)) { + return agvNavigateToPoseBuilder_.getMessageOrBuilder(); + } else { + if (commandCase_ == 20) { + return (cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request) command_; + } + return cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request.getDefaultInstance(); + } + } + /** + * .cmvr.api.AgvNavigateToPoseCommand.Request agv_navigate_to_pose = 20; + */ + private com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request, cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request.Builder, cmvr.api.AgvCommand.AgvNavigateToPoseCommand.RequestOrBuilder> + getAgvNavigateToPoseFieldBuilder() { + if (agvNavigateToPoseBuilder_ == null) { + if (!(commandCase_ == 20)) { + command_ = cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request.getDefaultInstance(); + } + agvNavigateToPoseBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request, cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request.Builder, cmvr.api.AgvCommand.AgvNavigateToPoseCommand.RequestOrBuilder>( + (cmvr.api.AgvCommand.AgvNavigateToPoseCommand.Request) command_, + getParentForChildren(), + isClean()); + command_ = null; + } + commandCase_ = 20; + onChanged();; + return agvNavigateToPoseBuilder_; + } + + private com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request, cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request.Builder, cmvr.api.AgvCommand.AgvNavigateToStationCommand.RequestOrBuilder> agvNavigateToStationBuilder_; + /** + * .cmvr.api.AgvNavigateToStationCommand.Request agv_navigate_to_station = 21; + * @return Whether the agvNavigateToStation field is set. + */ + @java.lang.Override + public boolean hasAgvNavigateToStation() { + return commandCase_ == 21; + } + /** + * .cmvr.api.AgvNavigateToStationCommand.Request agv_navigate_to_station = 21; + * @return The agvNavigateToStation. + */ + @java.lang.Override + public cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request getAgvNavigateToStation() { + if (agvNavigateToStationBuilder_ == null) { + if (commandCase_ == 21) { + return (cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request) command_; + } + return cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request.getDefaultInstance(); + } else { + if (commandCase_ == 21) { + return agvNavigateToStationBuilder_.getMessage(); + } + return cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request.getDefaultInstance(); + } + } + /** + * .cmvr.api.AgvNavigateToStationCommand.Request agv_navigate_to_station = 21; + */ + public Builder setAgvNavigateToStation(cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request value) { + if (agvNavigateToStationBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + command_ = value; + onChanged(); + } else { + agvNavigateToStationBuilder_.setMessage(value); + } + commandCase_ = 21; + return this; + } + /** + * .cmvr.api.AgvNavigateToStationCommand.Request agv_navigate_to_station = 21; + */ + public Builder setAgvNavigateToStation( + cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request.Builder builderForValue) { + if (agvNavigateToStationBuilder_ == null) { + command_ = builderForValue.build(); + onChanged(); + } else { + agvNavigateToStationBuilder_.setMessage(builderForValue.build()); + } + commandCase_ = 21; + return this; + } + /** + * .cmvr.api.AgvNavigateToStationCommand.Request agv_navigate_to_station = 21; + */ + public Builder mergeAgvNavigateToStation(cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request value) { + if (agvNavigateToStationBuilder_ == null) { + if (commandCase_ == 21 && + command_ != cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request.getDefaultInstance()) { + command_ = cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request.newBuilder((cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request) command_) + .mergeFrom(value).buildPartial(); + } else { + command_ = value; + } + onChanged(); + } else { + if (commandCase_ == 21) { + agvNavigateToStationBuilder_.mergeFrom(value); + } else { + agvNavigateToStationBuilder_.setMessage(value); + } + } + commandCase_ = 21; + return this; + } + /** + * .cmvr.api.AgvNavigateToStationCommand.Request agv_navigate_to_station = 21; + */ + public Builder clearAgvNavigateToStation() { + if (agvNavigateToStationBuilder_ == null) { + if (commandCase_ == 21) { + commandCase_ = 0; + command_ = null; + onChanged(); + } + } else { + if (commandCase_ == 21) { + commandCase_ = 0; + command_ = null; + } + agvNavigateToStationBuilder_.clear(); + } + return this; + } + /** + * .cmvr.api.AgvNavigateToStationCommand.Request agv_navigate_to_station = 21; + */ + public cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request.Builder getAgvNavigateToStationBuilder() { + return getAgvNavigateToStationFieldBuilder().getBuilder(); + } + /** + * .cmvr.api.AgvNavigateToStationCommand.Request agv_navigate_to_station = 21; + */ + @java.lang.Override + public cmvr.api.AgvCommand.AgvNavigateToStationCommand.RequestOrBuilder getAgvNavigateToStationOrBuilder() { + if ((commandCase_ == 21) && (agvNavigateToStationBuilder_ != null)) { + return agvNavigateToStationBuilder_.getMessageOrBuilder(); + } else { + if (commandCase_ == 21) { + return (cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request) command_; + } + return cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request.getDefaultInstance(); + } + } + /** + * .cmvr.api.AgvNavigateToStationCommand.Request agv_navigate_to_station = 21; + */ + private com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request, cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request.Builder, cmvr.api.AgvCommand.AgvNavigateToStationCommand.RequestOrBuilder> + getAgvNavigateToStationFieldBuilder() { + if (agvNavigateToStationBuilder_ == null) { + if (!(commandCase_ == 21)) { + command_ = cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request.getDefaultInstance(); + } + agvNavigateToStationBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request, cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request.Builder, cmvr.api.AgvCommand.AgvNavigateToStationCommand.RequestOrBuilder>( + (cmvr.api.AgvCommand.AgvNavigateToStationCommand.Request) command_, + getParentForChildren(), + isClean()); + command_ = null; + } + commandCase_ = 21; + onChanged();; + return agvNavigateToStationBuilder_; + } + + private com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.AgvCommand.AgvFollowPathCommand.Request, cmvr.api.AgvCommand.AgvFollowPathCommand.Request.Builder, cmvr.api.AgvCommand.AgvFollowPathCommand.RequestOrBuilder> agvFollowPathBuilder_; + /** + * .cmvr.api.AgvFollowPathCommand.Request agv_follow_path = 22; + * @return Whether the agvFollowPath field is set. + */ + @java.lang.Override + public boolean hasAgvFollowPath() { + return commandCase_ == 22; + } + /** + * .cmvr.api.AgvFollowPathCommand.Request agv_follow_path = 22; + * @return The agvFollowPath. + */ + @java.lang.Override + public cmvr.api.AgvCommand.AgvFollowPathCommand.Request getAgvFollowPath() { + if (agvFollowPathBuilder_ == null) { + if (commandCase_ == 22) { + return (cmvr.api.AgvCommand.AgvFollowPathCommand.Request) command_; + } + return cmvr.api.AgvCommand.AgvFollowPathCommand.Request.getDefaultInstance(); + } else { + if (commandCase_ == 22) { + return agvFollowPathBuilder_.getMessage(); + } + return cmvr.api.AgvCommand.AgvFollowPathCommand.Request.getDefaultInstance(); + } + } + /** + * .cmvr.api.AgvFollowPathCommand.Request agv_follow_path = 22; + */ + public Builder setAgvFollowPath(cmvr.api.AgvCommand.AgvFollowPathCommand.Request value) { + if (agvFollowPathBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + command_ = value; + onChanged(); + } else { + agvFollowPathBuilder_.setMessage(value); + } + commandCase_ = 22; + return this; + } + /** + * .cmvr.api.AgvFollowPathCommand.Request agv_follow_path = 22; + */ + public Builder setAgvFollowPath( + cmvr.api.AgvCommand.AgvFollowPathCommand.Request.Builder builderForValue) { + if (agvFollowPathBuilder_ == null) { + command_ = builderForValue.build(); + onChanged(); + } else { + agvFollowPathBuilder_.setMessage(builderForValue.build()); + } + commandCase_ = 22; + return this; + } + /** + * .cmvr.api.AgvFollowPathCommand.Request agv_follow_path = 22; + */ + public Builder mergeAgvFollowPath(cmvr.api.AgvCommand.AgvFollowPathCommand.Request value) { + if (agvFollowPathBuilder_ == null) { + if (commandCase_ == 22 && + command_ != cmvr.api.AgvCommand.AgvFollowPathCommand.Request.getDefaultInstance()) { + command_ = cmvr.api.AgvCommand.AgvFollowPathCommand.Request.newBuilder((cmvr.api.AgvCommand.AgvFollowPathCommand.Request) command_) + .mergeFrom(value).buildPartial(); + } else { + command_ = value; + } + onChanged(); + } else { + if (commandCase_ == 22) { + agvFollowPathBuilder_.mergeFrom(value); + } else { + agvFollowPathBuilder_.setMessage(value); + } + } + commandCase_ = 22; + return this; + } + /** + * .cmvr.api.AgvFollowPathCommand.Request agv_follow_path = 22; + */ + public Builder clearAgvFollowPath() { + if (agvFollowPathBuilder_ == null) { + if (commandCase_ == 22) { + commandCase_ = 0; + command_ = null; + onChanged(); + } + } else { + if (commandCase_ == 22) { + commandCase_ = 0; + command_ = null; + } + agvFollowPathBuilder_.clear(); + } + return this; + } + /** + * .cmvr.api.AgvFollowPathCommand.Request agv_follow_path = 22; + */ + public cmvr.api.AgvCommand.AgvFollowPathCommand.Request.Builder getAgvFollowPathBuilder() { + return getAgvFollowPathFieldBuilder().getBuilder(); + } + /** + * .cmvr.api.AgvFollowPathCommand.Request agv_follow_path = 22; + */ + @java.lang.Override + public cmvr.api.AgvCommand.AgvFollowPathCommand.RequestOrBuilder getAgvFollowPathOrBuilder() { + if ((commandCase_ == 22) && (agvFollowPathBuilder_ != null)) { + return agvFollowPathBuilder_.getMessageOrBuilder(); + } else { + if (commandCase_ == 22) { + return (cmvr.api.AgvCommand.AgvFollowPathCommand.Request) command_; + } + return cmvr.api.AgvCommand.AgvFollowPathCommand.Request.getDefaultInstance(); + } + } + /** + * .cmvr.api.AgvFollowPathCommand.Request agv_follow_path = 22; + */ + private com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.AgvCommand.AgvFollowPathCommand.Request, cmvr.api.AgvCommand.AgvFollowPathCommand.Request.Builder, cmvr.api.AgvCommand.AgvFollowPathCommand.RequestOrBuilder> + getAgvFollowPathFieldBuilder() { + if (agvFollowPathBuilder_ == null) { + if (!(commandCase_ == 22)) { + command_ = cmvr.api.AgvCommand.AgvFollowPathCommand.Request.getDefaultInstance(); + } + agvFollowPathBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.AgvCommand.AgvFollowPathCommand.Request, cmvr.api.AgvCommand.AgvFollowPathCommand.Request.Builder, cmvr.api.AgvCommand.AgvFollowPathCommand.RequestOrBuilder>( + (cmvr.api.AgvCommand.AgvFollowPathCommand.Request) command_, + getParentForChildren(), + isClean()); + command_ = null; + } + commandCase_ = 22; + onChanged();; + return agvFollowPathBuilder_; + } + + private com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.SystemCommand.DelayAction, cmvr.api.SystemCommand.DelayAction.Builder, cmvr.api.SystemCommand.DelayActionOrBuilder> delayBuilder_; + /** + * .cmvr.api.DelayAction delay = 90; + * @return Whether the delay field is set. + */ + @java.lang.Override + public boolean hasDelay() { + return commandCase_ == 90; + } + /** + * .cmvr.api.DelayAction delay = 90; + * @return The delay. + */ + @java.lang.Override + public cmvr.api.SystemCommand.DelayAction getDelay() { + if (delayBuilder_ == null) { + if (commandCase_ == 90) { + return (cmvr.api.SystemCommand.DelayAction) command_; + } + return cmvr.api.SystemCommand.DelayAction.getDefaultInstance(); + } else { + if (commandCase_ == 90) { + return delayBuilder_.getMessage(); + } + return cmvr.api.SystemCommand.DelayAction.getDefaultInstance(); + } + } + /** + * .cmvr.api.DelayAction delay = 90; + */ + public Builder setDelay(cmvr.api.SystemCommand.DelayAction value) { + if (delayBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + command_ = value; + onChanged(); + } else { + delayBuilder_.setMessage(value); + } + commandCase_ = 90; + return this; + } + /** + * .cmvr.api.DelayAction delay = 90; + */ + public Builder setDelay( + cmvr.api.SystemCommand.DelayAction.Builder builderForValue) { + if (delayBuilder_ == null) { + command_ = builderForValue.build(); + onChanged(); + } else { + delayBuilder_.setMessage(builderForValue.build()); + } + commandCase_ = 90; + return this; + } + /** + * .cmvr.api.DelayAction delay = 90; + */ + public Builder mergeDelay(cmvr.api.SystemCommand.DelayAction value) { + if (delayBuilder_ == null) { + if (commandCase_ == 90 && + command_ != cmvr.api.SystemCommand.DelayAction.getDefaultInstance()) { + command_ = cmvr.api.SystemCommand.DelayAction.newBuilder((cmvr.api.SystemCommand.DelayAction) command_) + .mergeFrom(value).buildPartial(); + } else { + command_ = value; + } + onChanged(); + } else { + if (commandCase_ == 90) { + delayBuilder_.mergeFrom(value); + } else { + delayBuilder_.setMessage(value); + } + } + commandCase_ = 90; + return this; + } + /** + * .cmvr.api.DelayAction delay = 90; + */ + public Builder clearDelay() { + if (delayBuilder_ == null) { + if (commandCase_ == 90) { + commandCase_ = 0; + command_ = null; + onChanged(); + } + } else { + if (commandCase_ == 90) { + commandCase_ = 0; + command_ = null; + } + delayBuilder_.clear(); + } + return this; + } + /** + * .cmvr.api.DelayAction delay = 90; + */ + public cmvr.api.SystemCommand.DelayAction.Builder getDelayBuilder() { + return getDelayFieldBuilder().getBuilder(); + } + /** + * .cmvr.api.DelayAction delay = 90; + */ + @java.lang.Override + public cmvr.api.SystemCommand.DelayActionOrBuilder getDelayOrBuilder() { + if ((commandCase_ == 90) && (delayBuilder_ != null)) { + return delayBuilder_.getMessageOrBuilder(); + } else { + if (commandCase_ == 90) { + return (cmvr.api.SystemCommand.DelayAction) command_; + } + return cmvr.api.SystemCommand.DelayAction.getDefaultInstance(); + } + } + /** + * .cmvr.api.DelayAction delay = 90; + */ + private com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.SystemCommand.DelayAction, cmvr.api.SystemCommand.DelayAction.Builder, cmvr.api.SystemCommand.DelayActionOrBuilder> + getDelayFieldBuilder() { + if (delayBuilder_ == null) { + if (!(commandCase_ == 90)) { + command_ = cmvr.api.SystemCommand.DelayAction.getDefaultInstance(); + } + delayBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.SystemCommand.DelayAction, cmvr.api.SystemCommand.DelayAction.Builder, cmvr.api.SystemCommand.DelayActionOrBuilder>( + (cmvr.api.SystemCommand.DelayAction) command_, + getParentForChildren(), + isClean()); + command_ = null; + } + commandCase_ = 90; + onChanged();; + return delayBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cmvr.api.ActionStep) + } + + // @@protoc_insertion_point(class_scope:cmvr.api.ActionStep) + private static final cmvr.api.SystemCommand.ActionStep DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cmvr.api.SystemCommand.ActionStep(); + } + + public static cmvr.api.SystemCommand.ActionStep getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public ActionStep parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cmvr.api.SystemCommand.ActionStep getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface ActionQueueCommandOrBuilder extends + // @@protoc_insertion_point(interface_extends:cmvr.api.ActionQueueCommand) + com.google.protobuf.MessageOrBuilder { + } + /** + *
+   * Atomically submits a complete command sequence for edge-local serial
+   * execution. Device motion alternatives must use synchronous execution.
+   * 
+ * + * Protobuf type {@code cmvr.api.ActionQueueCommand} + */ + public static final class ActionQueueCommand extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cmvr.api.ActionQueueCommand) + ActionQueueCommandOrBuilder { + private static final long serialVersionUID = 0L; + // Use ActionQueueCommand.newBuilder() to construct. + private ActionQueueCommand(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private ActionQueueCommand() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new ActionQueueCommand(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionQueueCommand_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionQueueCommand_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cmvr.api.SystemCommand.ActionQueueCommand.class, cmvr.api.SystemCommand.ActionQueueCommand.Builder.class); + } + + public interface RequestOrBuilder extends + // @@protoc_insertion_point(interface_extends:cmvr.api.ActionQueueCommand.Request) + com.google.protobuf.MessageOrBuilder { + + /** + *
+       * Client-generated globally unique idempotency key. During one Action
+       * service instance, retrying an identical accepted request with the
+       * same action_id does not dispatch its steps a second time. Recent
+       * terminal results can be returned; older accepted IDs are rejected
+       * fail-closed after their result is evicted. Deduplication is not
+       * persisted across an edge-service restart; the required instance
+       * epoch below prevents an old retry from being replayed after restart.
+       * 
+ * + * string action_id = 1; + * @return The actionId. + */ + java.lang.String getActionId(); + /** + *
+       * Client-generated globally unique idempotency key. During one Action
+       * service instance, retrying an identical accepted request with the
+       * same action_id does not dispatch its steps a second time. Recent
+       * terminal results can be returned; older accepted IDs are rejected
+       * fail-closed after their result is evicted. Deduplication is not
+       * persisted across an edge-service restart; the required instance
+       * epoch below prevents an old retry from being replayed after restart.
+       * 
+ * + * string action_id = 1; + * @return The bytes for actionId. + */ + com.google.protobuf.ByteString + getActionIdBytes(); + + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + java.util.List + getStepsList(); + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + cmvr.api.SystemCommand.ActionStep getSteps(int index); + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + int getStepsCount(); + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + java.util.List + getStepsOrBuilderList(); + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + cmvr.api.SystemCommand.ActionStepOrBuilder getStepsOrBuilder( + int index); + + /** + *
+       * Total queue-wait plus execution timeout in milliseconds. Zero uses a
+       * bounded server default.
+       * 
+ * + * uint32 total_timeout_ms = 3; + * @return The totalTimeoutMs. + */ + int getTotalTimeoutMs(); + + /** + *
+       * Required instance epoch obtained from GetSystemInfo. A mismatch
+       * means the process-local deduplication ledger was recreated, so the
+       * server rejects the request instead of risking a replay.
+       * 
+ * + * string expected_service_instance_id = 4; + * @return The expectedServiceInstanceId. + */ + java.lang.String getExpectedServiceInstanceId(); + /** + *
+       * Required instance epoch obtained from GetSystemInfo. A mismatch
+       * means the process-local deduplication ledger was recreated, so the
+       * server rejects the request instead of risking a replay.
+       * 
+ * + * string expected_service_instance_id = 4; + * @return The bytes for expectedServiceInstanceId. + */ + com.google.protobuf.ByteString + getExpectedServiceInstanceIdBytes(); + } + /** + * Protobuf type {@code cmvr.api.ActionQueueCommand.Request} + */ + public static final class Request extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cmvr.api.ActionQueueCommand.Request) + RequestOrBuilder { + private static final long serialVersionUID = 0L; + // Use Request.newBuilder() to construct. + private Request(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Request() { + actionId_ = ""; + steps_ = java.util.Collections.emptyList(); + expectedServiceInstanceId_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new Request(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionQueueCommand_Request_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionQueueCommand_Request_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cmvr.api.SystemCommand.ActionQueueCommand.Request.class, cmvr.api.SystemCommand.ActionQueueCommand.Request.Builder.class); + } + + public static final int ACTION_ID_FIELD_NUMBER = 1; + private volatile java.lang.Object actionId_; + /** + *
+       * Client-generated globally unique idempotency key. During one Action
+       * service instance, retrying an identical accepted request with the
+       * same action_id does not dispatch its steps a second time. Recent
+       * terminal results can be returned; older accepted IDs are rejected
+       * fail-closed after their result is evicted. Deduplication is not
+       * persisted across an edge-service restart; the required instance
+       * epoch below prevents an old retry from being replayed after restart.
+       * 
+ * + * string action_id = 1; + * @return The actionId. + */ + @java.lang.Override + public java.lang.String getActionId() { + java.lang.Object ref = actionId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + actionId_ = s; + return s; + } + } + /** + *
+       * Client-generated globally unique idempotency key. During one Action
+       * service instance, retrying an identical accepted request with the
+       * same action_id does not dispatch its steps a second time. Recent
+       * terminal results can be returned; older accepted IDs are rejected
+       * fail-closed after their result is evicted. Deduplication is not
+       * persisted across an edge-service restart; the required instance
+       * epoch below prevents an old retry from being replayed after restart.
+       * 
+ * + * string action_id = 1; + * @return The bytes for actionId. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getActionIdBytes() { + java.lang.Object ref = actionId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + actionId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int STEPS_FIELD_NUMBER = 2; + private java.util.List steps_; + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + @java.lang.Override + public java.util.List getStepsList() { + return steps_; + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + @java.lang.Override + public java.util.List + getStepsOrBuilderList() { + return steps_; + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + @java.lang.Override + public int getStepsCount() { + return steps_.size(); + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + @java.lang.Override + public cmvr.api.SystemCommand.ActionStep getSteps(int index) { + return steps_.get(index); + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + @java.lang.Override + public cmvr.api.SystemCommand.ActionStepOrBuilder getStepsOrBuilder( + int index) { + return steps_.get(index); + } + + public static final int TOTAL_TIMEOUT_MS_FIELD_NUMBER = 3; + private int totalTimeoutMs_; + /** + *
+       * Total queue-wait plus execution timeout in milliseconds. Zero uses a
+       * bounded server default.
+       * 
+ * + * uint32 total_timeout_ms = 3; + * @return The totalTimeoutMs. + */ + @java.lang.Override + public int getTotalTimeoutMs() { + return totalTimeoutMs_; + } + + public static final int EXPECTED_SERVICE_INSTANCE_ID_FIELD_NUMBER = 4; + private volatile java.lang.Object expectedServiceInstanceId_; + /** + *
+       * Required instance epoch obtained from GetSystemInfo. A mismatch
+       * means the process-local deduplication ledger was recreated, so the
+       * server rejects the request instead of risking a replay.
+       * 
+ * + * string expected_service_instance_id = 4; + * @return The expectedServiceInstanceId. + */ + @java.lang.Override + public java.lang.String getExpectedServiceInstanceId() { + java.lang.Object ref = expectedServiceInstanceId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + expectedServiceInstanceId_ = s; + return s; + } + } + /** + *
+       * Required instance epoch obtained from GetSystemInfo. A mismatch
+       * means the process-local deduplication ledger was recreated, so the
+       * server rejects the request instead of risking a replay.
+       * 
+ * + * string expected_service_instance_id = 4; + * @return The bytes for expectedServiceInstanceId. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getExpectedServiceInstanceIdBytes() { + java.lang.Object ref = expectedServiceInstanceId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + expectedServiceInstanceId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(actionId_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, actionId_); + } + for (int i = 0; i < steps_.size(); i++) { + output.writeMessage(2, steps_.get(i)); + } + if (totalTimeoutMs_ != 0) { + output.writeUInt32(3, totalTimeoutMs_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(expectedServiceInstanceId_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 4, expectedServiceInstanceId_); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(actionId_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, actionId_); + } + for (int i = 0; i < steps_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, steps_.get(i)); + } + if (totalTimeoutMs_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeUInt32Size(3, totalTimeoutMs_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(expectedServiceInstanceId_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, expectedServiceInstanceId_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cmvr.api.SystemCommand.ActionQueueCommand.Request)) { + return super.equals(obj); + } + cmvr.api.SystemCommand.ActionQueueCommand.Request other = (cmvr.api.SystemCommand.ActionQueueCommand.Request) obj; + + if (!getActionId() + .equals(other.getActionId())) return false; + if (!getStepsList() + .equals(other.getStepsList())) return false; + if (getTotalTimeoutMs() + != other.getTotalTimeoutMs()) return false; + if (!getExpectedServiceInstanceId() + .equals(other.getExpectedServiceInstanceId())) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + ACTION_ID_FIELD_NUMBER; + hash = (53 * hash) + getActionId().hashCode(); + if (getStepsCount() > 0) { + hash = (37 * hash) + STEPS_FIELD_NUMBER; + hash = (53 * hash) + getStepsList().hashCode(); + } + hash = (37 * hash) + TOTAL_TIMEOUT_MS_FIELD_NUMBER; + hash = (53 * hash) + getTotalTimeoutMs(); + hash = (37 * hash) + EXPECTED_SERVICE_INSTANCE_ID_FIELD_NUMBER; + hash = (53 * hash) + getExpectedServiceInstanceId().hashCode(); + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cmvr.api.SystemCommand.ActionQueueCommand.Request parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Request parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Request parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Request parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Request parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Request parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Request parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Request parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Request parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Request parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Request parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Request parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cmvr.api.SystemCommand.ActionQueueCommand.Request prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code cmvr.api.ActionQueueCommand.Request} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cmvr.api.ActionQueueCommand.Request) + cmvr.api.SystemCommand.ActionQueueCommand.RequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionQueueCommand_Request_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionQueueCommand_Request_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cmvr.api.SystemCommand.ActionQueueCommand.Request.class, cmvr.api.SystemCommand.ActionQueueCommand.Request.Builder.class); + } + + // Construct using cmvr.api.SystemCommand.ActionQueueCommand.Request.newBuilder() + private Builder() { + + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + actionId_ = ""; + + if (stepsBuilder_ == null) { + steps_ = java.util.Collections.emptyList(); + } else { + steps_ = null; + stepsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + totalTimeoutMs_ = 0; + + expectedServiceInstanceId_ = ""; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionQueueCommand_Request_descriptor; + } + + @java.lang.Override + public cmvr.api.SystemCommand.ActionQueueCommand.Request getDefaultInstanceForType() { + return cmvr.api.SystemCommand.ActionQueueCommand.Request.getDefaultInstance(); + } + + @java.lang.Override + public cmvr.api.SystemCommand.ActionQueueCommand.Request build() { + cmvr.api.SystemCommand.ActionQueueCommand.Request result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cmvr.api.SystemCommand.ActionQueueCommand.Request buildPartial() { + cmvr.api.SystemCommand.ActionQueueCommand.Request result = new cmvr.api.SystemCommand.ActionQueueCommand.Request(this); + int from_bitField0_ = bitField0_; + result.actionId_ = actionId_; + if (stepsBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0)) { + steps_ = java.util.Collections.unmodifiableList(steps_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.steps_ = steps_; + } else { + result.steps_ = stepsBuilder_.build(); + } + result.totalTimeoutMs_ = totalTimeoutMs_; + result.expectedServiceInstanceId_ = expectedServiceInstanceId_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cmvr.api.SystemCommand.ActionQueueCommand.Request) { + return mergeFrom((cmvr.api.SystemCommand.ActionQueueCommand.Request)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cmvr.api.SystemCommand.ActionQueueCommand.Request other) { + if (other == cmvr.api.SystemCommand.ActionQueueCommand.Request.getDefaultInstance()) return this; + if (!other.getActionId().isEmpty()) { + actionId_ = other.actionId_; + onChanged(); + } + if (stepsBuilder_ == null) { + if (!other.steps_.isEmpty()) { + if (steps_.isEmpty()) { + steps_ = other.steps_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureStepsIsMutable(); + steps_.addAll(other.steps_); + } + onChanged(); + } + } else { + if (!other.steps_.isEmpty()) { + if (stepsBuilder_.isEmpty()) { + stepsBuilder_.dispose(); + stepsBuilder_ = null; + steps_ = other.steps_; + bitField0_ = (bitField0_ & ~0x00000001); + stepsBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? + getStepsFieldBuilder() : null; + } else { + stepsBuilder_.addAllMessages(other.steps_); + } + } + } + if (other.getTotalTimeoutMs() != 0) { + setTotalTimeoutMs(other.getTotalTimeoutMs()); + } + if (!other.getExpectedServiceInstanceId().isEmpty()) { + expectedServiceInstanceId_ = other.expectedServiceInstanceId_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + actionId_ = input.readStringRequireUtf8(); + + break; + } // case 10 + case 18: { + cmvr.api.SystemCommand.ActionStep m = + input.readMessage( + cmvr.api.SystemCommand.ActionStep.parser(), + extensionRegistry); + if (stepsBuilder_ == null) { + ensureStepsIsMutable(); + steps_.add(m); + } else { + stepsBuilder_.addMessage(m); + } + break; + } // case 18 + case 24: { + totalTimeoutMs_ = input.readUInt32(); + + break; + } // case 24 + case 34: { + expectedServiceInstanceId_ = input.readStringRequireUtf8(); + + break; + } // case 34 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private java.lang.Object actionId_ = ""; + /** + *
+         * Client-generated globally unique idempotency key. During one Action
+         * service instance, retrying an identical accepted request with the
+         * same action_id does not dispatch its steps a second time. Recent
+         * terminal results can be returned; older accepted IDs are rejected
+         * fail-closed after their result is evicted. Deduplication is not
+         * persisted across an edge-service restart; the required instance
+         * epoch below prevents an old retry from being replayed after restart.
+         * 
+ * + * string action_id = 1; + * @return The actionId. + */ + public java.lang.String getActionId() { + java.lang.Object ref = actionId_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + actionId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + *
+         * Client-generated globally unique idempotency key. During one Action
+         * service instance, retrying an identical accepted request with the
+         * same action_id does not dispatch its steps a second time. Recent
+         * terminal results can be returned; older accepted IDs are rejected
+         * fail-closed after their result is evicted. Deduplication is not
+         * persisted across an edge-service restart; the required instance
+         * epoch below prevents an old retry from being replayed after restart.
+         * 
+ * + * string action_id = 1; + * @return The bytes for actionId. + */ + public com.google.protobuf.ByteString + getActionIdBytes() { + java.lang.Object ref = actionId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + actionId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
+         * Client-generated globally unique idempotency key. During one Action
+         * service instance, retrying an identical accepted request with the
+         * same action_id does not dispatch its steps a second time. Recent
+         * terminal results can be returned; older accepted IDs are rejected
+         * fail-closed after their result is evicted. Deduplication is not
+         * persisted across an edge-service restart; the required instance
+         * epoch below prevents an old retry from being replayed after restart.
+         * 
+ * + * string action_id = 1; + * @param value The actionId to set. + * @return This builder for chaining. + */ + public Builder setActionId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + actionId_ = value; + onChanged(); + return this; + } + /** + *
+         * Client-generated globally unique idempotency key. During one Action
+         * service instance, retrying an identical accepted request with the
+         * same action_id does not dispatch its steps a second time. Recent
+         * terminal results can be returned; older accepted IDs are rejected
+         * fail-closed after their result is evicted. Deduplication is not
+         * persisted across an edge-service restart; the required instance
+         * epoch below prevents an old retry from being replayed after restart.
+         * 
+ * + * string action_id = 1; + * @return This builder for chaining. + */ + public Builder clearActionId() { + + actionId_ = getDefaultInstance().getActionId(); + onChanged(); + return this; + } + /** + *
+         * Client-generated globally unique idempotency key. During one Action
+         * service instance, retrying an identical accepted request with the
+         * same action_id does not dispatch its steps a second time. Recent
+         * terminal results can be returned; older accepted IDs are rejected
+         * fail-closed after their result is evicted. Deduplication is not
+         * persisted across an edge-service restart; the required instance
+         * epoch below prevents an old retry from being replayed after restart.
+         * 
+ * + * string action_id = 1; + * @param value The bytes for actionId to set. + * @return This builder for chaining. + */ + public Builder setActionIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + actionId_ = value; + onChanged(); + return this; + } + + private java.util.List steps_ = + java.util.Collections.emptyList(); + private void ensureStepsIsMutable() { + if (!((bitField0_ & 0x00000001) != 0)) { + steps_ = new java.util.ArrayList(steps_); + bitField0_ |= 0x00000001; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + cmvr.api.SystemCommand.ActionStep, cmvr.api.SystemCommand.ActionStep.Builder, cmvr.api.SystemCommand.ActionStepOrBuilder> stepsBuilder_; + + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + public java.util.List getStepsList() { + if (stepsBuilder_ == null) { + return java.util.Collections.unmodifiableList(steps_); + } else { + return stepsBuilder_.getMessageList(); + } + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + public int getStepsCount() { + if (stepsBuilder_ == null) { + return steps_.size(); + } else { + return stepsBuilder_.getCount(); + } + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + public cmvr.api.SystemCommand.ActionStep getSteps(int index) { + if (stepsBuilder_ == null) { + return steps_.get(index); + } else { + return stepsBuilder_.getMessage(index); + } + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + public Builder setSteps( + int index, cmvr.api.SystemCommand.ActionStep value) { + if (stepsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureStepsIsMutable(); + steps_.set(index, value); + onChanged(); + } else { + stepsBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + public Builder setSteps( + int index, cmvr.api.SystemCommand.ActionStep.Builder builderForValue) { + if (stepsBuilder_ == null) { + ensureStepsIsMutable(); + steps_.set(index, builderForValue.build()); + onChanged(); + } else { + stepsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + public Builder addSteps(cmvr.api.SystemCommand.ActionStep value) { + if (stepsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureStepsIsMutable(); + steps_.add(value); + onChanged(); + } else { + stepsBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + public Builder addSteps( + int index, cmvr.api.SystemCommand.ActionStep value) { + if (stepsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureStepsIsMutable(); + steps_.add(index, value); + onChanged(); + } else { + stepsBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + public Builder addSteps( + cmvr.api.SystemCommand.ActionStep.Builder builderForValue) { + if (stepsBuilder_ == null) { + ensureStepsIsMutable(); + steps_.add(builderForValue.build()); + onChanged(); + } else { + stepsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + public Builder addSteps( + int index, cmvr.api.SystemCommand.ActionStep.Builder builderForValue) { + if (stepsBuilder_ == null) { + ensureStepsIsMutable(); + steps_.add(index, builderForValue.build()); + onChanged(); + } else { + stepsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + public Builder addAllSteps( + java.lang.Iterable values) { + if (stepsBuilder_ == null) { + ensureStepsIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, steps_); + onChanged(); + } else { + stepsBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + public Builder clearSteps() { + if (stepsBuilder_ == null) { + steps_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + stepsBuilder_.clear(); + } + return this; + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + public Builder removeSteps(int index) { + if (stepsBuilder_ == null) { + ensureStepsIsMutable(); + steps_.remove(index); + onChanged(); + } else { + stepsBuilder_.remove(index); + } + return this; + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + public cmvr.api.SystemCommand.ActionStep.Builder getStepsBuilder( + int index) { + return getStepsFieldBuilder().getBuilder(index); + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + public cmvr.api.SystemCommand.ActionStepOrBuilder getStepsOrBuilder( + int index) { + if (stepsBuilder_ == null) { + return steps_.get(index); } else { + return stepsBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + public java.util.List + getStepsOrBuilderList() { + if (stepsBuilder_ != null) { + return stepsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(steps_); + } + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + public cmvr.api.SystemCommand.ActionStep.Builder addStepsBuilder() { + return getStepsFieldBuilder().addBuilder( + cmvr.api.SystemCommand.ActionStep.getDefaultInstance()); + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + public cmvr.api.SystemCommand.ActionStep.Builder addStepsBuilder( + int index) { + return getStepsFieldBuilder().addBuilder( + index, cmvr.api.SystemCommand.ActionStep.getDefaultInstance()); + } + /** + * repeated .cmvr.api.ActionStep steps = 2; + */ + public java.util.List + getStepsBuilderList() { + return getStepsFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + cmvr.api.SystemCommand.ActionStep, cmvr.api.SystemCommand.ActionStep.Builder, cmvr.api.SystemCommand.ActionStepOrBuilder> + getStepsFieldBuilder() { + if (stepsBuilder_ == null) { + stepsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + cmvr.api.SystemCommand.ActionStep, cmvr.api.SystemCommand.ActionStep.Builder, cmvr.api.SystemCommand.ActionStepOrBuilder>( + steps_, + ((bitField0_ & 0x00000001) != 0), + getParentForChildren(), + isClean()); + steps_ = null; + } + return stepsBuilder_; + } + + private int totalTimeoutMs_ ; + /** + *
+         * Total queue-wait plus execution timeout in milliseconds. Zero uses a
+         * bounded server default.
+         * 
+ * + * uint32 total_timeout_ms = 3; + * @return The totalTimeoutMs. + */ + @java.lang.Override + public int getTotalTimeoutMs() { + return totalTimeoutMs_; + } + /** + *
+         * Total queue-wait plus execution timeout in milliseconds. Zero uses a
+         * bounded server default.
+         * 
+ * + * uint32 total_timeout_ms = 3; + * @param value The totalTimeoutMs to set. + * @return This builder for chaining. + */ + public Builder setTotalTimeoutMs(int value) { + + totalTimeoutMs_ = value; + onChanged(); + return this; + } + /** + *
+         * Total queue-wait plus execution timeout in milliseconds. Zero uses a
+         * bounded server default.
+         * 
+ * + * uint32 total_timeout_ms = 3; + * @return This builder for chaining. + */ + public Builder clearTotalTimeoutMs() { + + totalTimeoutMs_ = 0; + onChanged(); + return this; + } + + private java.lang.Object expectedServiceInstanceId_ = ""; + /** + *
+         * Required instance epoch obtained from GetSystemInfo. A mismatch
+         * means the process-local deduplication ledger was recreated, so the
+         * server rejects the request instead of risking a replay.
+         * 
+ * + * string expected_service_instance_id = 4; + * @return The expectedServiceInstanceId. + */ + public java.lang.String getExpectedServiceInstanceId() { + java.lang.Object ref = expectedServiceInstanceId_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + expectedServiceInstanceId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + *
+         * Required instance epoch obtained from GetSystemInfo. A mismatch
+         * means the process-local deduplication ledger was recreated, so the
+         * server rejects the request instead of risking a replay.
+         * 
+ * + * string expected_service_instance_id = 4; + * @return The bytes for expectedServiceInstanceId. + */ + public com.google.protobuf.ByteString + getExpectedServiceInstanceIdBytes() { + java.lang.Object ref = expectedServiceInstanceId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + expectedServiceInstanceId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
+         * Required instance epoch obtained from GetSystemInfo. A mismatch
+         * means the process-local deduplication ledger was recreated, so the
+         * server rejects the request instead of risking a replay.
+         * 
+ * + * string expected_service_instance_id = 4; + * @param value The expectedServiceInstanceId to set. + * @return This builder for chaining. + */ + public Builder setExpectedServiceInstanceId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + expectedServiceInstanceId_ = value; + onChanged(); + return this; + } + /** + *
+         * Required instance epoch obtained from GetSystemInfo. A mismatch
+         * means the process-local deduplication ledger was recreated, so the
+         * server rejects the request instead of risking a replay.
+         * 
+ * + * string expected_service_instance_id = 4; + * @return This builder for chaining. + */ + public Builder clearExpectedServiceInstanceId() { + + expectedServiceInstanceId_ = getDefaultInstance().getExpectedServiceInstanceId(); + onChanged(); + return this; + } + /** + *
+         * Required instance epoch obtained from GetSystemInfo. A mismatch
+         * means the process-local deduplication ledger was recreated, so the
+         * server rejects the request instead of risking a replay.
+         * 
+ * + * string expected_service_instance_id = 4; + * @param value The bytes for expectedServiceInstanceId to set. + * @return This builder for chaining. + */ + public Builder setExpectedServiceInstanceIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + expectedServiceInstanceId_ = value; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cmvr.api.ActionQueueCommand.Request) + } + + // @@protoc_insertion_point(class_scope:cmvr.api.ActionQueueCommand.Request) + private static final cmvr.api.SystemCommand.ActionQueueCommand.Request DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cmvr.api.SystemCommand.ActionQueueCommand.Request(); + } + + public static cmvr.api.SystemCommand.ActionQueueCommand.Request getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Request parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cmvr.api.SystemCommand.ActionQueueCommand.Request getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface FeedbackOrBuilder extends + // @@protoc_insertion_point(interface_extends:cmvr.api.ActionQueueCommand.Feedback) + com.google.protobuf.MessageOrBuilder { + + /** + * .cmvr.api.CommandHeader.Feedback header = 1; + * @return Whether the header field is set. + */ + boolean hasHeader(); + /** + * .cmvr.api.CommandHeader.Feedback header = 1; + * @return The header. + */ + cmvr.api.Common.CommandHeader.Feedback getHeader(); + /** + * .cmvr.api.CommandHeader.Feedback header = 1; + */ + cmvr.api.Common.CommandHeader.FeedbackOrBuilder getHeaderOrBuilder(); + + /** + * string action_id = 2; + * @return The actionId. + */ + java.lang.String getActionId(); + /** + * string action_id = 2; + * @return The bytes for actionId. + */ + com.google.protobuf.ByteString + getActionIdBytes(); + + /** + *
+       * Number of steps which completed successfully before the final result.
+       * 
+ * + * uint32 completed_steps = 3; + * @return The completedSteps. + */ + int getCompletedSteps(); + + /** + *
+       * Present only when a particular step caused failure, cancellation,
+       * timeout, or rejection. Presence distinguishes index zero from no
+       * failed step.
+       * 
+ * + * optional uint32 failed_step_index = 4; + * @return Whether the failedStepIndex field is set. + */ + boolean hasFailedStepIndex(); + /** + *
+       * Present only when a particular step caused failure, cancellation,
+       * timeout, or rejection. Presence distinguishes index zero from no
+       * failed step.
+       * 
+ * + * optional uint32 failed_step_index = 4; + * @return The failedStepIndex. + */ + int getFailedStepIndex(); + + /** + * .cmvr.api.ActionResultCode result = 5; + * @return The enum numeric value on the wire for result. + */ + int getResultValue(); + /** + * .cmvr.api.ActionResultCode result = 5; + * @return The result. + */ + cmvr.api.SystemCommand.ActionResultCode getResult(); + + /** + * string service_instance_id = 6; + * @return The serviceInstanceId. + */ + java.lang.String getServiceInstanceId(); + /** + * string service_instance_id = 6; + * @return The bytes for serviceInstanceId. + */ + com.google.protobuf.ByteString + getServiceInstanceIdBytes(); + + /** + * .cmvr.api.ActionDeduplicationStatus deduplication_status = 7; + * @return The enum numeric value on the wire for deduplicationStatus. + */ + int getDeduplicationStatusValue(); + /** + * .cmvr.api.ActionDeduplicationStatus deduplication_status = 7; + * @return The deduplicationStatus. + */ + cmvr.api.SystemCommand.ActionDeduplicationStatus getDeduplicationStatus(); + } + /** + * Protobuf type {@code cmvr.api.ActionQueueCommand.Feedback} + */ + public static final class Feedback extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cmvr.api.ActionQueueCommand.Feedback) + FeedbackOrBuilder { + private static final long serialVersionUID = 0L; + // Use Feedback.newBuilder() to construct. + private Feedback(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Feedback() { + actionId_ = ""; + result_ = 0; + serviceInstanceId_ = ""; + deduplicationStatus_ = 0; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new Feedback(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionQueueCommand_Feedback_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionQueueCommand_Feedback_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cmvr.api.SystemCommand.ActionQueueCommand.Feedback.class, cmvr.api.SystemCommand.ActionQueueCommand.Feedback.Builder.class); + } + + private int bitField0_; + public static final int HEADER_FIELD_NUMBER = 1; + private cmvr.api.Common.CommandHeader.Feedback header_; + /** + * .cmvr.api.CommandHeader.Feedback header = 1; + * @return Whether the header field is set. + */ + @java.lang.Override + public boolean hasHeader() { + return header_ != null; + } + /** + * .cmvr.api.CommandHeader.Feedback header = 1; + * @return The header. + */ + @java.lang.Override + public cmvr.api.Common.CommandHeader.Feedback getHeader() { + return header_ == null ? cmvr.api.Common.CommandHeader.Feedback.getDefaultInstance() : header_; + } + /** + * .cmvr.api.CommandHeader.Feedback header = 1; + */ + @java.lang.Override + public cmvr.api.Common.CommandHeader.FeedbackOrBuilder getHeaderOrBuilder() { + return getHeader(); + } + + public static final int ACTION_ID_FIELD_NUMBER = 2; + private volatile java.lang.Object actionId_; + /** + * string action_id = 2; + * @return The actionId. + */ + @java.lang.Override + public java.lang.String getActionId() { + java.lang.Object ref = actionId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + actionId_ = s; + return s; + } + } + /** + * string action_id = 2; + * @return The bytes for actionId. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getActionIdBytes() { + java.lang.Object ref = actionId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + actionId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int COMPLETED_STEPS_FIELD_NUMBER = 3; + private int completedSteps_; + /** + *
+       * Number of steps which completed successfully before the final result.
+       * 
+ * + * uint32 completed_steps = 3; + * @return The completedSteps. + */ + @java.lang.Override + public int getCompletedSteps() { + return completedSteps_; + } + + public static final int FAILED_STEP_INDEX_FIELD_NUMBER = 4; + private int failedStepIndex_; + /** + *
+       * Present only when a particular step caused failure, cancellation,
+       * timeout, or rejection. Presence distinguishes index zero from no
+       * failed step.
+       * 
+ * + * optional uint32 failed_step_index = 4; + * @return Whether the failedStepIndex field is set. + */ + @java.lang.Override + public boolean hasFailedStepIndex() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + *
+       * Present only when a particular step caused failure, cancellation,
+       * timeout, or rejection. Presence distinguishes index zero from no
+       * failed step.
+       * 
+ * + * optional uint32 failed_step_index = 4; + * @return The failedStepIndex. + */ + @java.lang.Override + public int getFailedStepIndex() { + return failedStepIndex_; + } + + public static final int RESULT_FIELD_NUMBER = 5; + private int result_; + /** + * .cmvr.api.ActionResultCode result = 5; + * @return The enum numeric value on the wire for result. + */ + @java.lang.Override public int getResultValue() { + return result_; + } + /** + * .cmvr.api.ActionResultCode result = 5; + * @return The result. + */ + @java.lang.Override public cmvr.api.SystemCommand.ActionResultCode getResult() { + @SuppressWarnings("deprecation") + cmvr.api.SystemCommand.ActionResultCode result = cmvr.api.SystemCommand.ActionResultCode.valueOf(result_); + return result == null ? cmvr.api.SystemCommand.ActionResultCode.UNRECOGNIZED : result; + } + + public static final int SERVICE_INSTANCE_ID_FIELD_NUMBER = 6; + private volatile java.lang.Object serviceInstanceId_; + /** + * string service_instance_id = 6; + * @return The serviceInstanceId. + */ + @java.lang.Override + public java.lang.String getServiceInstanceId() { + java.lang.Object ref = serviceInstanceId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + serviceInstanceId_ = s; + return s; + } + } + /** + * string service_instance_id = 6; + * @return The bytes for serviceInstanceId. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getServiceInstanceIdBytes() { + java.lang.Object ref = serviceInstanceId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + serviceInstanceId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int DEDUPLICATION_STATUS_FIELD_NUMBER = 7; + private int deduplicationStatus_; + /** + * .cmvr.api.ActionDeduplicationStatus deduplication_status = 7; + * @return The enum numeric value on the wire for deduplicationStatus. + */ + @java.lang.Override public int getDeduplicationStatusValue() { + return deduplicationStatus_; + } + /** + * .cmvr.api.ActionDeduplicationStatus deduplication_status = 7; + * @return The deduplicationStatus. + */ + @java.lang.Override public cmvr.api.SystemCommand.ActionDeduplicationStatus getDeduplicationStatus() { + @SuppressWarnings("deprecation") + cmvr.api.SystemCommand.ActionDeduplicationStatus result = cmvr.api.SystemCommand.ActionDeduplicationStatus.valueOf(deduplicationStatus_); + return result == null ? cmvr.api.SystemCommand.ActionDeduplicationStatus.UNRECOGNIZED : result; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (header_ != null) { + output.writeMessage(1, getHeader()); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(actionId_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, actionId_); + } + if (completedSteps_ != 0) { + output.writeUInt32(3, completedSteps_); + } + if (((bitField0_ & 0x00000001) != 0)) { + output.writeUInt32(4, failedStepIndex_); + } + if (result_ != cmvr.api.SystemCommand.ActionResultCode.ACTION_RESULT_CODE_UNSPECIFIED.getNumber()) { + output.writeEnum(5, result_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(serviceInstanceId_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 6, serviceInstanceId_); + } + if (deduplicationStatus_ != cmvr.api.SystemCommand.ActionDeduplicationStatus.ACTION_DEDUPLICATION_STATUS_UNSPECIFIED.getNumber()) { + output.writeEnum(7, deduplicationStatus_); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (header_ != null) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getHeader()); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(actionId_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, actionId_); + } + if (completedSteps_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeUInt32Size(3, completedSteps_); + } + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeUInt32Size(4, failedStepIndex_); + } + if (result_ != cmvr.api.SystemCommand.ActionResultCode.ACTION_RESULT_CODE_UNSPECIFIED.getNumber()) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(5, result_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(serviceInstanceId_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, serviceInstanceId_); + } + if (deduplicationStatus_ != cmvr.api.SystemCommand.ActionDeduplicationStatus.ACTION_DEDUPLICATION_STATUS_UNSPECIFIED.getNumber()) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(7, deduplicationStatus_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cmvr.api.SystemCommand.ActionQueueCommand.Feedback)) { + return super.equals(obj); + } + cmvr.api.SystemCommand.ActionQueueCommand.Feedback other = (cmvr.api.SystemCommand.ActionQueueCommand.Feedback) obj; + + if (hasHeader() != other.hasHeader()) return false; + if (hasHeader()) { + if (!getHeader() + .equals(other.getHeader())) return false; + } + if (!getActionId() + .equals(other.getActionId())) return false; + if (getCompletedSteps() + != other.getCompletedSteps()) return false; + if (hasFailedStepIndex() != other.hasFailedStepIndex()) return false; + if (hasFailedStepIndex()) { + if (getFailedStepIndex() + != other.getFailedStepIndex()) return false; + } + if (result_ != other.result_) return false; + if (!getServiceInstanceId() + .equals(other.getServiceInstanceId())) return false; + if (deduplicationStatus_ != other.deduplicationStatus_) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasHeader()) { + hash = (37 * hash) + HEADER_FIELD_NUMBER; + hash = (53 * hash) + getHeader().hashCode(); + } + hash = (37 * hash) + ACTION_ID_FIELD_NUMBER; + hash = (53 * hash) + getActionId().hashCode(); + hash = (37 * hash) + COMPLETED_STEPS_FIELD_NUMBER; + hash = (53 * hash) + getCompletedSteps(); + if (hasFailedStepIndex()) { + hash = (37 * hash) + FAILED_STEP_INDEX_FIELD_NUMBER; + hash = (53 * hash) + getFailedStepIndex(); + } + hash = (37 * hash) + RESULT_FIELD_NUMBER; + hash = (53 * hash) + result_; + hash = (37 * hash) + SERVICE_INSTANCE_ID_FIELD_NUMBER; + hash = (53 * hash) + getServiceInstanceId().hashCode(); + hash = (37 * hash) + DEDUPLICATION_STATUS_FIELD_NUMBER; + hash = (53 * hash) + deduplicationStatus_; + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cmvr.api.SystemCommand.ActionQueueCommand.Feedback parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Feedback parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Feedback parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Feedback parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Feedback parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Feedback parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Feedback parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Feedback parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Feedback parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Feedback parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Feedback parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cmvr.api.SystemCommand.ActionQueueCommand.Feedback parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cmvr.api.SystemCommand.ActionQueueCommand.Feedback prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code cmvr.api.ActionQueueCommand.Feedback} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cmvr.api.ActionQueueCommand.Feedback) + cmvr.api.SystemCommand.ActionQueueCommand.FeedbackOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionQueueCommand_Feedback_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionQueueCommand_Feedback_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cmvr.api.SystemCommand.ActionQueueCommand.Feedback.class, cmvr.api.SystemCommand.ActionQueueCommand.Feedback.Builder.class); + } + + // Construct using cmvr.api.SystemCommand.ActionQueueCommand.Feedback.newBuilder() + private Builder() { + + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + if (headerBuilder_ == null) { + header_ = null; + } else { + header_ = null; + headerBuilder_ = null; + } + actionId_ = ""; + + completedSteps_ = 0; + + failedStepIndex_ = 0; + bitField0_ = (bitField0_ & ~0x00000001); + result_ = 0; + + serviceInstanceId_ = ""; + + deduplicationStatus_ = 0; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionQueueCommand_Feedback_descriptor; + } + + @java.lang.Override + public cmvr.api.SystemCommand.ActionQueueCommand.Feedback getDefaultInstanceForType() { + return cmvr.api.SystemCommand.ActionQueueCommand.Feedback.getDefaultInstance(); + } + + @java.lang.Override + public cmvr.api.SystemCommand.ActionQueueCommand.Feedback build() { + cmvr.api.SystemCommand.ActionQueueCommand.Feedback result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cmvr.api.SystemCommand.ActionQueueCommand.Feedback buildPartial() { + cmvr.api.SystemCommand.ActionQueueCommand.Feedback result = new cmvr.api.SystemCommand.ActionQueueCommand.Feedback(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (headerBuilder_ == null) { + result.header_ = header_; + } else { + result.header_ = headerBuilder_.build(); + } + result.actionId_ = actionId_; + result.completedSteps_ = completedSteps_; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.failedStepIndex_ = failedStepIndex_; + to_bitField0_ |= 0x00000001; + } + result.result_ = result_; + result.serviceInstanceId_ = serviceInstanceId_; + result.deduplicationStatus_ = deduplicationStatus_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cmvr.api.SystemCommand.ActionQueueCommand.Feedback) { + return mergeFrom((cmvr.api.SystemCommand.ActionQueueCommand.Feedback)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cmvr.api.SystemCommand.ActionQueueCommand.Feedback other) { + if (other == cmvr.api.SystemCommand.ActionQueueCommand.Feedback.getDefaultInstance()) return this; + if (other.hasHeader()) { + mergeHeader(other.getHeader()); + } + if (!other.getActionId().isEmpty()) { + actionId_ = other.actionId_; + onChanged(); + } + if (other.getCompletedSteps() != 0) { + setCompletedSteps(other.getCompletedSteps()); + } + if (other.hasFailedStepIndex()) { + setFailedStepIndex(other.getFailedStepIndex()); + } + if (other.result_ != 0) { + setResultValue(other.getResultValue()); + } + if (!other.getServiceInstanceId().isEmpty()) { + serviceInstanceId_ = other.serviceInstanceId_; + onChanged(); + } + if (other.deduplicationStatus_ != 0) { + setDeduplicationStatusValue(other.getDeduplicationStatusValue()); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + input.readMessage( + getHeaderFieldBuilder().getBuilder(), + extensionRegistry); + + break; + } // case 10 + case 18: { + actionId_ = input.readStringRequireUtf8(); + + break; + } // case 18 + case 24: { + completedSteps_ = input.readUInt32(); + + break; + } // case 24 + case 32: { + failedStepIndex_ = input.readUInt32(); + bitField0_ |= 0x00000001; + break; + } // case 32 + case 40: { + result_ = input.readEnum(); + + break; + } // case 40 + case 50: { + serviceInstanceId_ = input.readStringRequireUtf8(); + + break; + } // case 50 + case 56: { + deduplicationStatus_ = input.readEnum(); + + break; + } // case 56 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private cmvr.api.Common.CommandHeader.Feedback header_; + private com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.Common.CommandHeader.Feedback, cmvr.api.Common.CommandHeader.Feedback.Builder, cmvr.api.Common.CommandHeader.FeedbackOrBuilder> headerBuilder_; + /** + * .cmvr.api.CommandHeader.Feedback header = 1; + * @return Whether the header field is set. + */ + public boolean hasHeader() { + return headerBuilder_ != null || header_ != null; + } + /** + * .cmvr.api.CommandHeader.Feedback header = 1; + * @return The header. + */ + public cmvr.api.Common.CommandHeader.Feedback getHeader() { + if (headerBuilder_ == null) { + return header_ == null ? cmvr.api.Common.CommandHeader.Feedback.getDefaultInstance() : header_; + } else { + return headerBuilder_.getMessage(); + } + } + /** + * .cmvr.api.CommandHeader.Feedback header = 1; + */ + public Builder setHeader(cmvr.api.Common.CommandHeader.Feedback value) { + if (headerBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + header_ = value; + onChanged(); + } else { + headerBuilder_.setMessage(value); + } + + return this; + } + /** + * .cmvr.api.CommandHeader.Feedback header = 1; + */ + public Builder setHeader( + cmvr.api.Common.CommandHeader.Feedback.Builder builderForValue) { + if (headerBuilder_ == null) { + header_ = builderForValue.build(); + onChanged(); + } else { + headerBuilder_.setMessage(builderForValue.build()); + } + + return this; + } + /** + * .cmvr.api.CommandHeader.Feedback header = 1; + */ + public Builder mergeHeader(cmvr.api.Common.CommandHeader.Feedback value) { + if (headerBuilder_ == null) { + if (header_ != null) { + header_ = + cmvr.api.Common.CommandHeader.Feedback.newBuilder(header_).mergeFrom(value).buildPartial(); + } else { + header_ = value; + } + onChanged(); + } else { + headerBuilder_.mergeFrom(value); + } + + return this; + } + /** + * .cmvr.api.CommandHeader.Feedback header = 1; + */ + public Builder clearHeader() { + if (headerBuilder_ == null) { + header_ = null; + onChanged(); + } else { + header_ = null; + headerBuilder_ = null; + } + + return this; + } + /** + * .cmvr.api.CommandHeader.Feedback header = 1; + */ + public cmvr.api.Common.CommandHeader.Feedback.Builder getHeaderBuilder() { + + onChanged(); + return getHeaderFieldBuilder().getBuilder(); + } + /** + * .cmvr.api.CommandHeader.Feedback header = 1; + */ + public cmvr.api.Common.CommandHeader.FeedbackOrBuilder getHeaderOrBuilder() { + if (headerBuilder_ != null) { + return headerBuilder_.getMessageOrBuilder(); + } else { + return header_ == null ? + cmvr.api.Common.CommandHeader.Feedback.getDefaultInstance() : header_; + } + } + /** + * .cmvr.api.CommandHeader.Feedback header = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.Common.CommandHeader.Feedback, cmvr.api.Common.CommandHeader.Feedback.Builder, cmvr.api.Common.CommandHeader.FeedbackOrBuilder> + getHeaderFieldBuilder() { + if (headerBuilder_ == null) { + headerBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + cmvr.api.Common.CommandHeader.Feedback, cmvr.api.Common.CommandHeader.Feedback.Builder, cmvr.api.Common.CommandHeader.FeedbackOrBuilder>( + getHeader(), + getParentForChildren(), + isClean()); + header_ = null; + } + return headerBuilder_; + } + + private java.lang.Object actionId_ = ""; + /** + * string action_id = 2; + * @return The actionId. + */ + public java.lang.String getActionId() { + java.lang.Object ref = actionId_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + actionId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string action_id = 2; + * @return The bytes for actionId. + */ + public com.google.protobuf.ByteString + getActionIdBytes() { + java.lang.Object ref = actionId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + actionId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string action_id = 2; + * @param value The actionId to set. + * @return This builder for chaining. + */ + public Builder setActionId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + actionId_ = value; + onChanged(); + return this; + } + /** + * string action_id = 2; + * @return This builder for chaining. + */ + public Builder clearActionId() { + + actionId_ = getDefaultInstance().getActionId(); + onChanged(); + return this; + } + /** + * string action_id = 2; + * @param value The bytes for actionId to set. + * @return This builder for chaining. + */ + public Builder setActionIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + actionId_ = value; + onChanged(); + return this; + } + + private int completedSteps_ ; + /** + *
+         * Number of steps which completed successfully before the final result.
+         * 
+ * + * uint32 completed_steps = 3; + * @return The completedSteps. + */ + @java.lang.Override + public int getCompletedSteps() { + return completedSteps_; + } + /** + *
+         * Number of steps which completed successfully before the final result.
+         * 
+ * + * uint32 completed_steps = 3; + * @param value The completedSteps to set. + * @return This builder for chaining. + */ + public Builder setCompletedSteps(int value) { + + completedSteps_ = value; + onChanged(); + return this; + } + /** + *
+         * Number of steps which completed successfully before the final result.
+         * 
+ * + * uint32 completed_steps = 3; + * @return This builder for chaining. + */ + public Builder clearCompletedSteps() { + + completedSteps_ = 0; + onChanged(); + return this; + } + + private int failedStepIndex_ ; + /** + *
+         * Present only when a particular step caused failure, cancellation,
+         * timeout, or rejection. Presence distinguishes index zero from no
+         * failed step.
+         * 
+ * + * optional uint32 failed_step_index = 4; + * @return Whether the failedStepIndex field is set. + */ + @java.lang.Override + public boolean hasFailedStepIndex() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + *
+         * Present only when a particular step caused failure, cancellation,
+         * timeout, or rejection. Presence distinguishes index zero from no
+         * failed step.
+         * 
+ * + * optional uint32 failed_step_index = 4; + * @return The failedStepIndex. + */ + @java.lang.Override + public int getFailedStepIndex() { + return failedStepIndex_; + } + /** + *
+         * Present only when a particular step caused failure, cancellation,
+         * timeout, or rejection. Presence distinguishes index zero from no
+         * failed step.
+         * 
+ * + * optional uint32 failed_step_index = 4; + * @param value The failedStepIndex to set. + * @return This builder for chaining. + */ + public Builder setFailedStepIndex(int value) { + bitField0_ |= 0x00000001; + failedStepIndex_ = value; + onChanged(); + return this; + } + /** + *
+         * Present only when a particular step caused failure, cancellation,
+         * timeout, or rejection. Presence distinguishes index zero from no
+         * failed step.
+         * 
+ * + * optional uint32 failed_step_index = 4; + * @return This builder for chaining. + */ + public Builder clearFailedStepIndex() { + bitField0_ = (bitField0_ & ~0x00000001); + failedStepIndex_ = 0; + onChanged(); + return this; + } + + private int result_ = 0; + /** + * .cmvr.api.ActionResultCode result = 5; + * @return The enum numeric value on the wire for result. + */ + @java.lang.Override public int getResultValue() { + return result_; + } + /** + * .cmvr.api.ActionResultCode result = 5; + * @param value The enum numeric value on the wire for result to set. + * @return This builder for chaining. + */ + public Builder setResultValue(int value) { + + result_ = value; + onChanged(); + return this; + } + /** + * .cmvr.api.ActionResultCode result = 5; + * @return The result. + */ + @java.lang.Override + public cmvr.api.SystemCommand.ActionResultCode getResult() { + @SuppressWarnings("deprecation") + cmvr.api.SystemCommand.ActionResultCode result = cmvr.api.SystemCommand.ActionResultCode.valueOf(result_); + return result == null ? cmvr.api.SystemCommand.ActionResultCode.UNRECOGNIZED : result; + } + /** + * .cmvr.api.ActionResultCode result = 5; + * @param value The result to set. + * @return This builder for chaining. + */ + public Builder setResult(cmvr.api.SystemCommand.ActionResultCode value) { + if (value == null) { + throw new NullPointerException(); + } + + result_ = value.getNumber(); + onChanged(); + return this; + } + /** + * .cmvr.api.ActionResultCode result = 5; + * @return This builder for chaining. + */ + public Builder clearResult() { + + result_ = 0; + onChanged(); + return this; + } + + private java.lang.Object serviceInstanceId_ = ""; + /** + * string service_instance_id = 6; + * @return The serviceInstanceId. + */ + public java.lang.String getServiceInstanceId() { + java.lang.Object ref = serviceInstanceId_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + serviceInstanceId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string service_instance_id = 6; + * @return The bytes for serviceInstanceId. + */ + public com.google.protobuf.ByteString + getServiceInstanceIdBytes() { + java.lang.Object ref = serviceInstanceId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + serviceInstanceId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string service_instance_id = 6; + * @param value The serviceInstanceId to set. + * @return This builder for chaining. + */ + public Builder setServiceInstanceId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + serviceInstanceId_ = value; + onChanged(); + return this; + } + /** + * string service_instance_id = 6; + * @return This builder for chaining. + */ + public Builder clearServiceInstanceId() { + + serviceInstanceId_ = getDefaultInstance().getServiceInstanceId(); + onChanged(); + return this; + } + /** + * string service_instance_id = 6; + * @param value The bytes for serviceInstanceId to set. + * @return This builder for chaining. + */ + public Builder setServiceInstanceIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + serviceInstanceId_ = value; + onChanged(); + return this; + } + + private int deduplicationStatus_ = 0; + /** + * .cmvr.api.ActionDeduplicationStatus deduplication_status = 7; + * @return The enum numeric value on the wire for deduplicationStatus. + */ + @java.lang.Override public int getDeduplicationStatusValue() { + return deduplicationStatus_; + } + /** + * .cmvr.api.ActionDeduplicationStatus deduplication_status = 7; + * @param value The enum numeric value on the wire for deduplicationStatus to set. + * @return This builder for chaining. + */ + public Builder setDeduplicationStatusValue(int value) { + + deduplicationStatus_ = value; + onChanged(); + return this; + } + /** + * .cmvr.api.ActionDeduplicationStatus deduplication_status = 7; + * @return The deduplicationStatus. + */ + @java.lang.Override + public cmvr.api.SystemCommand.ActionDeduplicationStatus getDeduplicationStatus() { + @SuppressWarnings("deprecation") + cmvr.api.SystemCommand.ActionDeduplicationStatus result = cmvr.api.SystemCommand.ActionDeduplicationStatus.valueOf(deduplicationStatus_); + return result == null ? cmvr.api.SystemCommand.ActionDeduplicationStatus.UNRECOGNIZED : result; + } + /** + * .cmvr.api.ActionDeduplicationStatus deduplication_status = 7; + * @param value The deduplicationStatus to set. + * @return This builder for chaining. + */ + public Builder setDeduplicationStatus(cmvr.api.SystemCommand.ActionDeduplicationStatus value) { + if (value == null) { + throw new NullPointerException(); + } + + deduplicationStatus_ = value.getNumber(); + onChanged(); + return this; + } + /** + * .cmvr.api.ActionDeduplicationStatus deduplication_status = 7; + * @return This builder for chaining. + */ + public Builder clearDeduplicationStatus() { + + deduplicationStatus_ = 0; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cmvr.api.ActionQueueCommand.Feedback) + } + + // @@protoc_insertion_point(class_scope:cmvr.api.ActionQueueCommand.Feedback) + private static final cmvr.api.SystemCommand.ActionQueueCommand.Feedback DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cmvr.api.SystemCommand.ActionQueueCommand.Feedback(); + } + + public static cmvr.api.SystemCommand.ActionQueueCommand.Feedback getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Feedback parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cmvr.api.SystemCommand.ActionQueueCommand.Feedback getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cmvr.api.SystemCommand.ActionQueueCommand)) { + return super.equals(obj); + } + cmvr.api.SystemCommand.ActionQueueCommand other = (cmvr.api.SystemCommand.ActionQueueCommand) obj; + + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cmvr.api.SystemCommand.ActionQueueCommand parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cmvr.api.SystemCommand.ActionQueueCommand parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionQueueCommand parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cmvr.api.SystemCommand.ActionQueueCommand parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionQueueCommand parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cmvr.api.SystemCommand.ActionQueueCommand parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionQueueCommand parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cmvr.api.SystemCommand.ActionQueueCommand parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionQueueCommand parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cmvr.api.SystemCommand.ActionQueueCommand parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cmvr.api.SystemCommand.ActionQueueCommand parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cmvr.api.SystemCommand.ActionQueueCommand parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cmvr.api.SystemCommand.ActionQueueCommand prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Atomically submits a complete command sequence for edge-local serial
+     * execution. Device motion alternatives must use synchronous execution.
+     * 
+ * + * Protobuf type {@code cmvr.api.ActionQueueCommand} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cmvr.api.ActionQueueCommand) + cmvr.api.SystemCommand.ActionQueueCommandOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionQueueCommand_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionQueueCommand_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cmvr.api.SystemCommand.ActionQueueCommand.class, cmvr.api.SystemCommand.ActionQueueCommand.Builder.class); + } + + // Construct using cmvr.api.SystemCommand.ActionQueueCommand.newBuilder() + private Builder() { + + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cmvr.api.SystemCommand.internal_static_cmvr_api_ActionQueueCommand_descriptor; + } + + @java.lang.Override + public cmvr.api.SystemCommand.ActionQueueCommand getDefaultInstanceForType() { + return cmvr.api.SystemCommand.ActionQueueCommand.getDefaultInstance(); + } + + @java.lang.Override + public cmvr.api.SystemCommand.ActionQueueCommand build() { + cmvr.api.SystemCommand.ActionQueueCommand result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cmvr.api.SystemCommand.ActionQueueCommand buildPartial() { + cmvr.api.SystemCommand.ActionQueueCommand result = new cmvr.api.SystemCommand.ActionQueueCommand(this); + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cmvr.api.SystemCommand.ActionQueueCommand) { + return mergeFrom((cmvr.api.SystemCommand.ActionQueueCommand)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cmvr.api.SystemCommand.ActionQueueCommand other) { + if (other == cmvr.api.SystemCommand.ActionQueueCommand.getDefaultInstance()) return this; + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cmvr.api.ActionQueueCommand) + } + + // @@protoc_insertion_point(class_scope:cmvr.api.ActionQueueCommand) + private static final cmvr.api.SystemCommand.ActionQueueCommand DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cmvr.api.SystemCommand.ActionQueueCommand(); + } + + public static cmvr.api.SystemCommand.ActionQueueCommand getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public ActionQueueCommand parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cmvr.api.SystemCommand.ActionQueueCommand getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + private static final com.google.protobuf.Descriptors.Descriptor internal_static_cmvr_api_DeviceList_descriptor; private static final @@ -13177,6 +19379,31 @@ public final class SystemCommand { private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_cmvr_api_StopAllCommand_Feedback_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cmvr_api_DelayAction_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cmvr_api_DelayAction_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cmvr_api_ActionStep_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cmvr_api_ActionStep_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cmvr_api_ActionQueueCommand_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cmvr_api_ActionQueueCommand_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cmvr_api_ActionQueueCommand_Request_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cmvr_api_ActionQueueCommand_Request_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cmvr_api_ActionQueueCommand_Feedback_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cmvr_api_ActionQueueCommand_Feedback_fieldAccessorTable; public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { @@ -13187,75 +19414,118 @@ public final class SystemCommand { static { java.lang.String[] descriptorData = { "\n\035cmvr/api/system_command.proto\022\010cmvr.ap" + - "i\032\025cmvr/api/common.proto\"J\n\nDeviceList\022\021" + - "\n\tdevice_id\030\001 \001(\t\022)\n\013device_type\030\002 \001(\0162\024" + - ".cmvr.api.DeviceType\"\251\002\n\020SystemDeviceInf" + - "o\022\021\n\tdevice_id\030\001 \001(\t\022/\n\013device_type\030\002 \001(" + - "\0162\032.cmvr.api.SystemDeviceType\022\021\n\ttype_na" + - "me\030\003 \001(\t\022\017\n\007enabled\030\004 \001(\010\0222\n\rmanager_sta" + - "te\030\005 \001(\0162\033.cmvr.api.SystemDeviceState\022,\n" + - "\006health\030\006 \001(\0162\034.cmvr.api.SystemDeviceHea" + - "lth\022\021\n\thas_error\030\007 \001(\010\022\025\n\rerror_message\030" + - "\010 \001(\t\022!\n\031status_updated_at_unix_ms\030\t \001(\004" + - "\"\371\001\n\024GetDeviceListCommand\032\t\n\007Request\032\325\001\n" + - "\010Feedback\0220\n\006header\030\001 \001(\0132 .cmvr.api.Com" + - "mandHeader.Feedback\022\024\n\014manager_name\030\002 \001(" + - "\t\022\027\n\017manager_version\030\003 \001(\t\022\033\n\023manager_de" + - "scription\030\004 \001(\t\022/\n\013device_list\030\005 \003(\0132\032.c" + - "mvr.api.SystemDeviceInfo\022\032\n\022sampled_at_u" + - "nix_ms\030\006 \001(\004\"\325\001\n\024GetSystemInfoCommand\032\t\n" + - "\007Request\032\261\001\n\010Feedback\0220\n\006header\030\001 \001(\0132 ." + - "cmvr.api.CommandHeader.Feedback\022\023\n\013syste" + - "m_name\030\002 \001(\t\022\017\n\007version\030\003 \001(\t\022\023\n\013descrip" + - "tion\030\004 \001(\t\022\n\n\002os\030\005 \001(\t\022\026\n\016kernel_version" + - "\030\006 \001(\t\022\024\n\014architecture\030\007 \001(\t\"\370\001\n\026GetSyst" + - "emStatusCommand\032\t\n\007Request\032\322\001\n\010Feedback\022" + - "0\n\006header\030\001 \001(\0132 .cmvr.api.CommandHeader" + - ".Feedback\022\021\n\tcpu_usage\030\002 \001(\002\022\024\n\014mem_tota" + - "l_mb\030\003 \001(\002\022\023\n\013mem_used_mb\030\004 \001(\002\022\025\n\rdisk_" + - "total_gb\030\005 \001(\002\022\024\n\014disk_used_gb\030\006 \001(\002\022)\n\013" + - "device_list\030\007 \003(\0132\024.cmvr.api.DeviceList\"" + - "\266\001\n\023UpdateParamsCommand\032a\n\007Request\022/\n\006he" + - "ader\030\001 \001(\0132\037.cmvr.api.CommandHeader.Requ" + - "est\022%\n\006params\030\002 \003(\0132\025.cmvr.api.ConfigPar" + - "am\032<\n\010Feedback\0220\n\006header\030\001 \001(\0132 .cmvr.ap" + - "i.CommandHeader.Feedback\"\212\001\n\016StopAllComm" + - "and\032:\n\007Request\022/\n\006header\030\001 \001(\0132\037.cmvr.ap" + - "i.CommandHeader.Request\032<\n\010Feedback\0220\n\006h" + - "eader\030\001 \001(\0132 .cmvr.api.CommandHeader.Fee" + - "dback*}\n\nDeviceType\022\007\n\003AGV\020\000\022\013\n\007Battery\020" + - "\001\022\n\n\006Camera\020\002\022\013\n\007DexHand\020\003\022\013\n\007Gripper\020\004\022" + - "\016\n\nMicrophone\020\005\022\t\n\005Robot\020\006\022\013\n\007Speaker\020\007\022" + - "\013\n\007Unknown\020\024*\236\004\n\020SystemDeviceType\022\"\n\036SYS" + - "TEM_DEVICE_TYPE_UNSPECIFIED\020\000\022\032\n\026SYSTEM_" + - "DEVICE_TYPE_AGV\020\001\022\032\n\026SYSTEM_DEVICE_TYPE_" + - "ARM\020\002\022\036\n\032SYSTEM_DEVICE_TYPE_BATTERY\020\003\022\037\n" + - "\033SYSTEM_DEVICE_TYPE_BIO_HEAD\020\004\022\035\n\031SYSTEM" + - "_DEVICE_TYPE_CAMERA\020\005\022\036\n\032SYSTEM_DEVICE_T" + - "YPE_CAN_BUS\020\006\022\037\n\033SYSTEM_DEVICE_TYPE_DEX_" + - "HAND\020\007\022\036\n\032SYSTEM_DEVICE_TYPE_GRIPPER\020\010\022!" + - "\n\035SYSTEM_DEVICE_TYPE_MICROPHONE\020\t\022\034\n\030SYS" + - "TEM_DEVICE_TYPE_MOTOR\020\n\022#\n\037SYSTEM_DEVICE" + - "_TYPE_MOTOR_SYSTEM\020\013\022$\n SYSTEM_DEVICE_TY" + - "PE_MUJOCO_VIEWER\020\014\022#\n\037SYSTEM_DEVICE_TYPE" + - "_MUJOCO_WORLD\020\r\022\034\n\030SYSTEM_DEVICE_TYPE_RO" + - "BOT\020\016\022\036\n\032SYSTEM_DEVICE_TYPE_SPEAKER\020\017*\244\002" + - "\n\021SystemDeviceState\022#\n\037SYSTEM_DEVICE_STA" + - "TE_UNSPECIFIED\020\000\022 \n\034SYSTEM_DEVICE_STATE_" + - "DISABLED\020\001\022$\n SYSTEM_DEVICE_STATE_INITIA" + - "LIZING\020\002\022\"\n\036SYSTEM_DEVICE_STATE_REGISTER" + - "ED\020\003\022\035\n\031SYSTEM_DEVICE_STATE_READY\020\004\022\037\n\033S" + - "YSTEM_DEVICE_STATE_RUNNING\020\005\022\037\n\033SYSTEM_D" + - "EVICE_STATE_STOPPED\020\006\022\035\n\031SYSTEM_DEVICE_S" + - "TATE_ERROR\020\007*\237\001\n\022SystemDeviceHealth\022$\n S" + - "YSTEM_DEVICE_HEALTH_UNSPECIFIED\020\000\022 \n\034SYS" + - "TEM_DEVICE_HEALTH_HEALTHY\020\001\022!\n\035SYSTEM_DE" + - "VICE_HEALTH_DEGRADED\020\002\022\036\n\032SYSTEM_DEVICE_" + - "HEALTH_FAULT\020\003b\006proto3" + "i\032\032cmvr/api/agv_command.proto\032\032cmvr/api/" + + "arm_command.proto\032\025cmvr/api/common.proto" + + "\"J\n\nDeviceList\022\021\n\tdevice_id\030\001 \001(\t\022)\n\013dev" + + "ice_type\030\002 \001(\0162\024.cmvr.api.DeviceType\"\251\002\n" + + "\020SystemDeviceInfo\022\021\n\tdevice_id\030\001 \001(\t\022/\n\013" + + "device_type\030\002 \001(\0162\032.cmvr.api.SystemDevic" + + "eType\022\021\n\ttype_name\030\003 \001(\t\022\017\n\007enabled\030\004 \001(" + + "\010\0222\n\rmanager_state\030\005 \001(\0162\033.cmvr.api.Syst" + + "emDeviceState\022,\n\006health\030\006 \001(\0162\034.cmvr.api" + + ".SystemDeviceHealth\022\021\n\thas_error\030\007 \001(\010\022\025" + + "\n\rerror_message\030\010 \001(\t\022!\n\031status_updated_" + + "at_unix_ms\030\t \001(\004\"\371\001\n\024GetDeviceListComman" + + "d\032\t\n\007Request\032\325\001\n\010Feedback\0220\n\006header\030\001 \001(" + + "\0132 .cmvr.api.CommandHeader.Feedback\022\024\n\014m" + + "anager_name\030\002 \001(\t\022\027\n\017manager_version\030\003 \001" + + "(\t\022\033\n\023manager_description\030\004 \001(\t\022/\n\013devic" + + "e_list\030\005 \003(\0132\032.cmvr.api.SystemDeviceInfo" + + "\022\032\n\022sampled_at_unix_ms\030\006 \001(\004\"\371\001\n\024GetSyst" + + "emInfoCommand\032\t\n\007Request\032\325\001\n\010Feedback\0220\n" + + "\006header\030\001 \001(\0132 .cmvr.api.CommandHeader.F" + + "eedback\022\023\n\013system_name\030\002 \001(\t\022\017\n\007version\030" + + "\003 \001(\t\022\023\n\013description\030\004 \001(\t\022\n\n\002os\030\005 \001(\t\022\026" + + "\n\016kernel_version\030\006 \001(\t\022\024\n\014architecture\030\007" + + " \001(\t\022\"\n\032action_service_instance_id\030\010 \001(\t" + + "\"\370\001\n\026GetSystemStatusCommand\032\t\n\007Request\032\322" + + "\001\n\010Feedback\0220\n\006header\030\001 \001(\0132 .cmvr.api.C" + + "ommandHeader.Feedback\022\021\n\tcpu_usage\030\002 \001(\002" + + "\022\024\n\014mem_total_mb\030\003 \001(\002\022\023\n\013mem_used_mb\030\004 " + + "\001(\002\022\025\n\rdisk_total_gb\030\005 \001(\002\022\024\n\014disk_used_" + + "gb\030\006 \001(\002\022)\n\013device_list\030\007 \003(\0132\024.cmvr.api" + + ".DeviceList\"\266\001\n\023UpdateParamsCommand\032a\n\007R" + + "equest\022/\n\006header\030\001 \001(\0132\037.cmvr.api.Comman" + + "dHeader.Request\022%\n\006params\030\002 \003(\0132\025.cmvr.a" + + "pi.ConfigParam\032<\n\010Feedback\0220\n\006header\030\001 \001" + + "(\0132 .cmvr.api.CommandHeader.Feedback\"\212\001\n" + + "\016StopAllCommand\032:\n\007Request\022/\n\006header\030\001 \001" + + "(\0132\037.cmvr.api.CommandHeader.Request\032<\n\010F" + + "eedback\0220\n\006header\030\001 \001(\0132 .cmvr.api.Comma" + + "ndHeader.Feedback\"\"\n\013DelayAction\022\023\n\013dura" + + "tion_ms\030\001 \001(\r\"\243\003\n\nActionStep\022\017\n\007step_id\030" + + "\001 \001(\t\022\022\n\ntimeout_ms\030\002 \001(\r\022-\n\narm_move_j\030" + + "\n \001(\0132\027.cmvr.api.MoveJ.RequestH\000\022-\n\narm_" + + "move_l\030\013 \001(\0132\027.cmvr.api.MoveL.RequestH\000\022" + + "J\n\024agv_navigate_to_pose\030\024 \001(\0132*.cmvr.api" + + ".AgvNavigateToPoseCommand.RequestH\000\022P\n\027a" + + "gv_navigate_to_station\030\025 \001(\0132-.cmvr.api." + + "AgvNavigateToStationCommand.RequestH\000\022A\n" + + "\017agv_follow_path\030\026 \001(\0132&.cmvr.api.AgvFol" + + "lowPathCommand.RequestH\000\022&\n\005delay\030Z \001(\0132" + + "\025.cmvr.api.DelayActionH\000B\t\n\007command\"\305\003\n\022" + + "ActionQueueCommand\032\201\001\n\007Request\022\021\n\taction" + + "_id\030\001 \001(\t\022#\n\005steps\030\002 \003(\0132\024.cmvr.api.Acti" + + "onStep\022\030\n\020total_timeout_ms\030\003 \001(\r\022$\n\034expe" + + "cted_service_instance_id\030\004 \001(\t\032\252\002\n\010Feedb" + + "ack\0220\n\006header\030\001 \001(\0132 .cmvr.api.CommandHe" + + "ader.Feedback\022\021\n\taction_id\030\002 \001(\t\022\027\n\017comp" + + "leted_steps\030\003 \001(\r\022\036\n\021failed_step_index\030\004" + + " \001(\rH\000\210\001\001\022*\n\006result\030\005 \001(\0162\032.cmvr.api.Act" + + "ionResultCode\022\033\n\023service_instance_id\030\006 \001" + + "(\t\022A\n\024deduplication_status\030\007 \001(\0162#.cmvr." + + "api.ActionDeduplicationStatusB\024\n\022_failed" + + "_step_index*}\n\nDeviceType\022\007\n\003AGV\020\000\022\013\n\007Ba" + + "ttery\020\001\022\n\n\006Camera\020\002\022\013\n\007DexHand\020\003\022\013\n\007Grip" + + "per\020\004\022\016\n\nMicrophone\020\005\022\t\n\005Robot\020\006\022\013\n\007Spea" + + "ker\020\007\022\013\n\007Unknown\020\024*\236\004\n\020SystemDeviceType\022" + + "\"\n\036SYSTEM_DEVICE_TYPE_UNSPECIFIED\020\000\022\032\n\026S" + + "YSTEM_DEVICE_TYPE_AGV\020\001\022\032\n\026SYSTEM_DEVICE" + + "_TYPE_ARM\020\002\022\036\n\032SYSTEM_DEVICE_TYPE_BATTER" + + "Y\020\003\022\037\n\033SYSTEM_DEVICE_TYPE_BIO_HEAD\020\004\022\035\n\031" + + "SYSTEM_DEVICE_TYPE_CAMERA\020\005\022\036\n\032SYSTEM_DE" + + "VICE_TYPE_CAN_BUS\020\006\022\037\n\033SYSTEM_DEVICE_TYP" + + "E_DEX_HAND\020\007\022\036\n\032SYSTEM_DEVICE_TYPE_GRIPP" + + "ER\020\010\022!\n\035SYSTEM_DEVICE_TYPE_MICROPHONE\020\t\022" + + "\034\n\030SYSTEM_DEVICE_TYPE_MOTOR\020\n\022#\n\037SYSTEM_" + + "DEVICE_TYPE_MOTOR_SYSTEM\020\013\022$\n SYSTEM_DEV" + + "ICE_TYPE_MUJOCO_VIEWER\020\014\022#\n\037SYSTEM_DEVIC" + + "E_TYPE_MUJOCO_WORLD\020\r\022\034\n\030SYSTEM_DEVICE_T" + + "YPE_ROBOT\020\016\022\036\n\032SYSTEM_DEVICE_TYPE_SPEAKE" + + "R\020\017*\244\002\n\021SystemDeviceState\022#\n\037SYSTEM_DEVI" + + "CE_STATE_UNSPECIFIED\020\000\022 \n\034SYSTEM_DEVICE_" + + "STATE_DISABLED\020\001\022$\n SYSTEM_DEVICE_STATE_" + + "INITIALIZING\020\002\022\"\n\036SYSTEM_DEVICE_STATE_RE" + + "GISTERED\020\003\022\035\n\031SYSTEM_DEVICE_STATE_READY\020" + + "\004\022\037\n\033SYSTEM_DEVICE_STATE_RUNNING\020\005\022\037\n\033SY" + + "STEM_DEVICE_STATE_STOPPED\020\006\022\035\n\031SYSTEM_DE" + + "VICE_STATE_ERROR\020\007*\237\001\n\022SystemDeviceHealt" + + "h\022$\n SYSTEM_DEVICE_HEALTH_UNSPECIFIED\020\000\022" + + " \n\034SYSTEM_DEVICE_HEALTH_HEALTHY\020\001\022!\n\035SYS" + + "TEM_DEVICE_HEALTH_DEGRADED\020\002\022\036\n\032SYSTEM_D" + + "EVICE_HEALTH_FAULT\020\003*\333\001\n\020ActionResultCod" + + "e\022\"\n\036ACTION_RESULT_CODE_UNSPECIFIED\020\000\022 \n" + + "\034ACTION_RESULT_CODE_COMPLETED\020\001\022\035\n\031ACTIO" + + "N_RESULT_CODE_FAILED\020\002\022\037\n\033ACTION_RESULT_" + + "CODE_CANCELED\020\003\022 \n\034ACTION_RESULT_CODE_TI" + + "MED_OUT\020\004\022\037\n\033ACTION_RESULT_CODE_REJECTED" + + "\020\005*\250\003\n\031ActionDeduplicationStatus\022+\n\'ACTI" + + "ON_DEDUPLICATION_STATUS_UNSPECIFIED\020\000\022,\n" + + "(ACTION_DEDUPLICATION_STATUS_ACCEPTED_NE" + + "W\020\001\0220\n,ACTION_DEDUPLICATION_STATUS_JOINE" + + "D_IN_FLIGHT\020\002\022-\n)ACTION_DEDUPLICATION_ST" + + "ATUS_CACHED_RESULT\020\003\022.\n*ACTION_DEDUPLICA" + + "TION_STATUS_RESULT_EVICTED\020\004\0220\n,ACTION_D" + + "EDUPLICATION_STATUS_LEDGER_EXHAUSTED\020\005\0222" + + "\n.ACTION_DEDUPLICATION_STATUS_ACTION_ID_" + + "CONFLICT\020\006\0229\n5ACTION_DEDUPLICATION_STATU" + + "S_SERVICE_INSTANCE_MISMATCH\020\007b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, new com.google.protobuf.Descriptors.FileDescriptor[] { + cmvr.api.AgvCommand.getDescriptor(), + cmvr.api.ArmCommand.getDescriptor(), cmvr.api.Common.getDescriptor(), }); internal_static_cmvr_api_DeviceList_descriptor = @@ -13305,7 +19575,7 @@ public final class SystemCommand { internal_static_cmvr_api_GetSystemInfoCommand_Feedback_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_cmvr_api_GetSystemInfoCommand_Feedback_descriptor, - new java.lang.String[] { "Header", "SystemName", "Version", "Description", "Os", "KernelVersion", "Architecture", }); + new java.lang.String[] { "Header", "SystemName", "Version", "Description", "Os", "KernelVersion", "Architecture", "ActionServiceInstanceId", }); internal_static_cmvr_api_GetSystemStatusCommand_descriptor = getDescriptor().getMessageTypes().get(4); internal_static_cmvr_api_GetSystemStatusCommand_fieldAccessorTable = new @@ -13360,6 +19630,38 @@ public final class SystemCommand { com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_cmvr_api_StopAllCommand_Feedback_descriptor, new java.lang.String[] { "Header", }); + internal_static_cmvr_api_DelayAction_descriptor = + getDescriptor().getMessageTypes().get(7); + internal_static_cmvr_api_DelayAction_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cmvr_api_DelayAction_descriptor, + new java.lang.String[] { "DurationMs", }); + internal_static_cmvr_api_ActionStep_descriptor = + getDescriptor().getMessageTypes().get(8); + internal_static_cmvr_api_ActionStep_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cmvr_api_ActionStep_descriptor, + new java.lang.String[] { "StepId", "TimeoutMs", "ArmMoveJ", "ArmMoveL", "AgvNavigateToPose", "AgvNavigateToStation", "AgvFollowPath", "Delay", "Command", }); + internal_static_cmvr_api_ActionQueueCommand_descriptor = + getDescriptor().getMessageTypes().get(9); + internal_static_cmvr_api_ActionQueueCommand_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cmvr_api_ActionQueueCommand_descriptor, + new java.lang.String[] { }); + internal_static_cmvr_api_ActionQueueCommand_Request_descriptor = + internal_static_cmvr_api_ActionQueueCommand_descriptor.getNestedTypes().get(0); + internal_static_cmvr_api_ActionQueueCommand_Request_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cmvr_api_ActionQueueCommand_Request_descriptor, + new java.lang.String[] { "ActionId", "Steps", "TotalTimeoutMs", "ExpectedServiceInstanceId", }); + internal_static_cmvr_api_ActionQueueCommand_Feedback_descriptor = + internal_static_cmvr_api_ActionQueueCommand_descriptor.getNestedTypes().get(1); + internal_static_cmvr_api_ActionQueueCommand_Feedback_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cmvr_api_ActionQueueCommand_Feedback_descriptor, + new java.lang.String[] { "Header", "ActionId", "CompletedSteps", "FailedStepIndex", "Result", "ServiceInstanceId", "DeduplicationStatus", "FailedStepIndex", }); + cmvr.api.AgvCommand.getDescriptor(); + cmvr.api.ArmCommand.getDescriptor(); cmvr.api.Common.getDescriptor(); } diff --git a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/java/cmvr/api/SystemServiceGrpc.java b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/java/cmvr/api/SystemServiceGrpc.java index 8b5e7c9..3a0707a 100644 --- a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/java/cmvr/api/SystemServiceGrpc.java +++ b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/java/cmvr/api/SystemServiceGrpc.java @@ -170,6 +170,37 @@ public final class SystemServiceGrpc { return getStopAllMethod; } + private static volatile io.grpc.MethodDescriptor getExecuteActionQueueMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "ExecuteActionQueue", + requestType = cmvr.api.SystemCommand.ActionQueueCommand.Request.class, + responseType = cmvr.api.SystemCommand.ActionQueueCommand.Feedback.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getExecuteActionQueueMethod() { + io.grpc.MethodDescriptor getExecuteActionQueueMethod; + if ((getExecuteActionQueueMethod = SystemServiceGrpc.getExecuteActionQueueMethod) == null) { + synchronized (SystemServiceGrpc.class) { + if ((getExecuteActionQueueMethod = SystemServiceGrpc.getExecuteActionQueueMethod) == null) { + SystemServiceGrpc.getExecuteActionQueueMethod = getExecuteActionQueueMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "ExecuteActionQueue")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cmvr.api.SystemCommand.ActionQueueCommand.Request.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cmvr.api.SystemCommand.ActionQueueCommand.Feedback.getDefaultInstance())) + .setSchemaDescriptor(new SystemServiceMethodDescriptorSupplier("ExecuteActionQueue")) + .build(); + } + } + } + return getExecuteActionQueueMethod; + } + /** * Creates a new async stub that supports all call types for the service */ @@ -253,6 +284,13 @@ public final class SystemServiceGrpc { io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getStopAllMethod(), responseObserver); } + /** + */ + public void executeActionQueue(cmvr.api.SystemCommand.ActionQueueCommand.Request request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getExecuteActionQueueMethod(), responseObserver); + } + @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) .addMethod( @@ -290,6 +328,13 @@ public final class SystemServiceGrpc { cmvr.api.SystemCommand.StopAllCommand.Request, cmvr.api.SystemCommand.StopAllCommand.Feedback>( this, METHODID_STOP_ALL))) + .addMethod( + getExecuteActionQueueMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + cmvr.api.SystemCommand.ActionQueueCommand.Request, + cmvr.api.SystemCommand.ActionQueueCommand.Feedback>( + this, METHODID_EXECUTE_ACTION_QUEUE))) .build(); } } @@ -347,6 +392,14 @@ public final class SystemServiceGrpc { io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getStopAllMethod(), getCallOptions()), request, responseObserver); } + + /** + */ + public void executeActionQueue(cmvr.api.SystemCommand.ActionQueueCommand.Request request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getExecuteActionQueueMethod(), getCallOptions()), request, responseObserver); + } } /** @@ -397,6 +450,13 @@ public final class SystemServiceGrpc { return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getStopAllMethod(), getCallOptions(), request); } + + /** + */ + public cmvr.api.SystemCommand.ActionQueueCommand.Feedback executeActionQueue(cmvr.api.SystemCommand.ActionQueueCommand.Request request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getExecuteActionQueueMethod(), getCallOptions(), request); + } } /** @@ -452,6 +512,14 @@ public final class SystemServiceGrpc { return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getStopAllMethod(), getCallOptions()), request); } + + /** + */ + public com.google.common.util.concurrent.ListenableFuture executeActionQueue( + cmvr.api.SystemCommand.ActionQueueCommand.Request request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getExecuteActionQueueMethod(), getCallOptions()), request); + } } private static final int METHODID_GET_SYSTEM_INFO = 0; @@ -459,6 +527,7 @@ public final class SystemServiceGrpc { private static final int METHODID_GET_DEVICE_LIST = 2; private static final int METHODID_UPDATE_PARAMS = 3; private static final int METHODID_STOP_ALL = 4; + private static final int METHODID_EXECUTE_ACTION_QUEUE = 5; private static final class MethodHandlers implements io.grpc.stub.ServerCalls.UnaryMethod, @@ -497,6 +566,10 @@ public final class SystemServiceGrpc { serviceImpl.stopAll((cmvr.api.SystemCommand.StopAllCommand.Request) request, (io.grpc.stub.StreamObserver) responseObserver); break; + case METHODID_EXECUTE_ACTION_QUEUE: + serviceImpl.executeActionQueue((cmvr.api.SystemCommand.ActionQueueCommand.Request) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; default: throw new AssertionError(); } @@ -563,6 +636,7 @@ public final class SystemServiceGrpc { .addMethod(getGetDeviceListMethod()) .addMethod(getUpdateParamsMethod()) .addMethod(getStopAllMethod()) + .addMethod(getExecuteActionQueueMethod()) .build(); } } diff --git a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/java/cmvr/api/SystemServiceOuterClass.java b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/java/cmvr/api/SystemServiceOuterClass.java index 5c27447..e4a1a26 100644 --- a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/java/cmvr/api/SystemServiceOuterClass.java +++ b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/java/cmvr/api/SystemServiceOuterClass.java @@ -24,7 +24,7 @@ public final class SystemServiceOuterClass { static { java.lang.String[] descriptorData = { "\n\035cmvr/api/system_service.proto\022\010cmvr.ap" + - "i\032\035cmvr/api/system_command.proto2\364\003\n\rSys" + + "i\032\035cmvr/api/system_command.proto2\331\004\n\rSys" + "temService\022b\n\rGetSystemInfo\022&.cmvr.api.G" + "etSystemInfoCommand.Request\032\'.cmvr.api.G" + "etSystemInfoCommand.Feedback\"\000\022h\n\017GetSys" + @@ -37,7 +37,10 @@ public final class SystemServiceOuterClass { "and.Request\032&.cmvr.api.UpdateParamsComma" + "nd.Feedback\"\000\022P\n\007StopAll\022 .cmvr.api.Stop" + "AllCommand.Request\032!.cmvr.api.StopAllCom" + - "mand.Feedback\"\000b\006proto3" + "mand.Feedback\"\000\022c\n\022ExecuteActionQueue\022$." + + "cmvr.api.ActionQueueCommand.Request\032%.cm" + + "vr.api.ActionQueueCommand.Feedback\"\000b\006pr" + + "oto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, diff --git a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/proto/cmvr/api/system_command.proto b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/proto/cmvr/api/system_command.proto index c61fa36..b572d23 100644 --- a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/proto/cmvr/api/system_command.proto +++ b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/proto/cmvr/api/system_command.proto @@ -1,5 +1,7 @@ syntax = "proto3"; +import "cmvr/api/agv_command.proto"; +import "cmvr/api/arm_command.proto"; import "cmvr/api/common.proto"; package cmvr.api; @@ -103,6 +105,10 @@ message GetSystemInfoCommand { string os = 5; string kernel_version = 6; string architecture = 7; + + // Changes whenever the in-process ActionQueue idempotency ledger is + // recreated. Clients bind submissions and retries to this value. + string action_service_instance_id = 8; } } @@ -141,3 +147,97 @@ message StopAllCommand { CommandHeader.Feedback header = 1; } } + +// Final outcome of one ActionQueue execution. +enum ActionResultCode { + ACTION_RESULT_CODE_UNSPECIFIED = 0; + ACTION_RESULT_CODE_COMPLETED = 1; + ACTION_RESULT_CODE_FAILED = 2; + ACTION_RESULT_CODE_CANCELED = 3; + ACTION_RESULT_CODE_TIMED_OUT = 4; + ACTION_RESULT_CODE_REJECTED = 5; +} + +// Describes whether this RPC admitted a new action or observed an existing +// idempotency record. Clients must not infer this from an error string. +enum ActionDeduplicationStatus { + ACTION_DEDUPLICATION_STATUS_UNSPECIFIED = 0; + ACTION_DEDUPLICATION_STATUS_ACCEPTED_NEW = 1; + ACTION_DEDUPLICATION_STATUS_JOINED_IN_FLIGHT = 2; + ACTION_DEDUPLICATION_STATUS_CACHED_RESULT = 3; + ACTION_DEDUPLICATION_STATUS_RESULT_EVICTED = 4; + ACTION_DEDUPLICATION_STATUS_LEDGER_EXHAUSTED = 5; + ACTION_DEDUPLICATION_STATUS_ACTION_ID_CONFLICT = 6; + ACTION_DEDUPLICATION_STATUS_SERVICE_INSTANCE_MISMATCH = 7; +} + +// Edge-local delay between two device commands. +message DelayAction { + // Delay duration in milliseconds. The server applies a bounded maximum. + uint32 duration_ms = 1; +} + +// One finite, synchronous command in an ActionQueue request. +message ActionStep { + // Client-provided identifier used for diagnostics. It must be unique within + // one ActionQueue request. + string step_id = 1; + + // Per-step timeout in milliseconds. Zero inherits the remaining action + // timeout or the server default. + uint32 timeout_ms = 2; + + // Tags are grouped by domain so compatible commands can be added without + // renumbering existing alternatives: Arm 10-19, AGV 20-29, built-ins 90+. + oneof command { + MoveJ.Request arm_move_j = 10; + MoveL.Request arm_move_l = 11; + + AgvNavigateToPoseCommand.Request agv_navigate_to_pose = 20; + AgvNavigateToStationCommand.Request agv_navigate_to_station = 21; + AgvFollowPathCommand.Request agv_follow_path = 22; + + DelayAction delay = 90; + } +} + +// Atomically submits a complete command sequence for edge-local serial +// execution. Device motion alternatives must use synchronous execution. +message ActionQueueCommand { + message Request { + // Client-generated globally unique idempotency key. During one Action + // service instance, retrying an identical accepted request with the + // same action_id does not dispatch its steps a second time. Recent + // terminal results can be returned; older accepted IDs are rejected + // fail-closed after their result is evicted. Deduplication is not + // persisted across an edge-service restart; the required instance + // epoch below prevents an old retry from being replayed after restart. + string action_id = 1; + repeated ActionStep steps = 2; + + // Total queue-wait plus execution timeout in milliseconds. Zero uses a + // bounded server default. + uint32 total_timeout_ms = 3; + + // Required instance epoch obtained from GetSystemInfo. A mismatch + // means the process-local deduplication ledger was recreated, so the + // server rejects the request instead of risking a replay. + string expected_service_instance_id = 4; + } + + message Feedback { + CommandHeader.Feedback header = 1; + string action_id = 2; + + // Number of steps which completed successfully before the final result. + uint32 completed_steps = 3; + + // Present only when a particular step caused failure, cancellation, + // timeout, or rejection. Presence distinguishes index zero from no + // failed step. + optional uint32 failed_step_index = 4; + ActionResultCode result = 5; + string service_instance_id = 6; + ActionDeduplicationStatus deduplication_status = 7; + } +} diff --git a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/proto/cmvr/api/system_service.proto b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/proto/cmvr/api/system_service.proto index 83f19af..bb6dc4b 100644 --- a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/proto/cmvr/api/system_service.proto +++ b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-lib/src/main/proto/cmvr/api/system_service.proto @@ -13,4 +13,6 @@ service SystemService { rpc UpdateParams(UpdateParamsCommand.Request) returns (UpdateParamsCommand.Feedback) {} rpc StopAll(StopAllCommand.Request) returns (StopAllCommand.Feedback) {} + + rpc ExecuteActionQueue(ActionQueueCommand.Request) returns (ActionQueueCommand.Feedback) {} } diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/core/minio/MinioService.java b/cmvr-iot-common/src/main/java/com/cmvr/common/core/minio/MinioService.java index 28a3a7c..bd560f9 100644 --- a/cmvr-iot-common/src/main/java/com/cmvr/common/core/minio/MinioService.java +++ b/cmvr-iot-common/src/main/java/com/cmvr/common/core/minio/MinioService.java @@ -23,6 +23,7 @@ import java.io.InputStream; import java.nio.file.Files; import java.util.Date; import java.util.HashMap; +import java.util.Locale; import java.util.Map; @Slf4j @@ -134,7 +135,7 @@ public class MinioService { .bucket(bucketName) .object(path + "/" + objectName) .stream(stream, file.length(), -1) // 传入文件流 - .contentType("application/octet-stream") // 可以根据需要修改文件类型 + .contentType(resolveContentType(file)) .build(); // 上传文件到 MinIO @@ -147,6 +148,24 @@ public class MinioService { return objectName; } + private String resolveContentType(File file) { + try { + String detected = Files.probeContentType(file.toPath()); + if (StringUtils.isNotBlank(detected)) { + return detected; + } + } catch (Exception exception) { + log.debug("无法自动识别文件媒体类型: {}", file.getName(), exception); + } + String name = file.getName().toLowerCase(Locale.ROOT); + if (name.endsWith(".wav")) return "audio/wav"; + if (name.endsWith(".mp3")) return "audio/mpeg"; + if (name.endsWith(".mp4")) return "video/mp4"; + if (name.endsWith(".jpg") || name.endsWith(".jpeg")) return "image/jpeg"; + if (name.endsWith(".png")) return "image/png"; + return "application/octet-stream"; + } + /** * 文件上传 * diff --git a/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/domain/InspectionTaskLog.java b/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/domain/InspectionTaskLog.java index 979fb11..7ce65d7 100644 --- a/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/domain/InspectionTaskLog.java +++ b/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/domain/InspectionTaskLog.java @@ -2,6 +2,7 @@ package com.cmvr.inspection.domain; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; @@ -46,6 +47,14 @@ public class InspectionTaskLog extends BaseEntity @ApiModelProperty("检查项id") private String itemId; + /** 当前绑定项的执行位置,从 1 开始。 */ + @TableField(exist = false) + private Integer itemOrder; + + /** 同一检测项在任务中第几次出现。 */ + @TableField(exist = false) + private Integer itemOccurrence; + @Excel(name = "节点ID") @ApiModelProperty("节点ID") private String nodeId; diff --git a/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/domain/vo/InspectionTaskInstanceVo.java b/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/domain/vo/InspectionTaskInstanceVo.java index 510f331..31fa623 100644 --- a/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/domain/vo/InspectionTaskInstanceVo.java +++ b/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/domain/vo/InspectionTaskInstanceVo.java @@ -55,6 +55,10 @@ public class InspectionTaskInstanceVo extends BaseEntity @ApiModelProperty("机器人名称") private String robotName; + /** 主要机器人的永久身份,用于兼容旧任务的执行默认值 */ + @ApiModelProperty("主要机器人的永久身份ID") + private String robotIdentity; + /** 地图ID */ @Excel(name = "地图ID") @ApiModelProperty("地图ID") diff --git a/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/domain/vo/InspectionTaskStartVO.java b/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/domain/vo/InspectionTaskStartVO.java index c08f47b..fc59c34 100644 --- a/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/domain/vo/InspectionTaskStartVO.java +++ b/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/domain/vo/InspectionTaskStartVO.java @@ -1,5 +1,6 @@ package com.cmvr.inspection.domain.vo; +import com.alibaba.fastjson2.JSONObject; import com.cmvr.test.model.vo.ResourceRuntimeAssignmentVO; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -17,4 +18,7 @@ public class InspectionTaskStartVO { @ApiModelProperty("机器人角色运行分配") private List runtimeAssignments = new ArrayList<>(); + + @ApiModelProperty("按检测项和出现序号组织的本次运行参数") + private JSONObject runParams = new JSONObject(); } diff --git a/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/listener/InspectionFlowExecutionListener.java b/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/listener/InspectionFlowExecutionListener.java index 3cf2d7b..f2d08b0 100644 --- a/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/listener/InspectionFlowExecutionListener.java +++ b/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/listener/InspectionFlowExecutionListener.java @@ -2,6 +2,7 @@ package com.cmvr.inspection.listener; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSONObject; import com.cmvr.common.utils.DateUtils; import com.cmvr.framework.websocket.service.MessagePushService; import com.cmvr.device.service.InspectionAlertListenService; @@ -15,6 +16,7 @@ import com.cmvr.inspection.service.IInspectionResultService; import com.cmvr.test.flow.runtime.event.FlowExecutionEvent; import com.cmvr.test.flow.runtime.event.FlowExecutionListener; import com.cmvr.test.flow.runtime.event.FlowExecutionModuleCodes; +import com.cmvr.test.flow.runtime.operator.FlowMediaParamResolver; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -71,13 +73,14 @@ public class InspectionFlowExecutionListener implements FlowExecutionListener { // 1.节点完成才记录当前item下node if (StrUtil.isNotBlank(itemId) && StrUtil.isNotBlank(nodeId) && FlowExecutionEvent.EventType.NODE_COMPLETED == event.getEventType()) { - itemNodeExecutMap.computeIfAbsent(itemExecutionKey(instId, itemId), + itemNodeExecutMap.computeIfAbsent(itemExecutionKey(instId, itemId, event.getItemOrder()), k -> java.util.concurrent.ConcurrentHashMap.newKeySet()).add(nodeId); } // 任意事件:当前任务绑定item(item一启动就入Map,所以统计已完成item要-1) if (StrUtil.isNotBlank(instId) && StrUtil.isNotBlank(itemId)) { taskItemExecutMap.computeIfAbsent(instId, - k -> java.util.concurrent.ConcurrentHashMap.newKeySet()).add(itemId); + k -> java.util.concurrent.ConcurrentHashMap.newKeySet()) + .add(itemExecutionKey(instId, itemId, event.getItemOrder())); } InspectionTaskInstance taskInstance = findTaskInstance(instId); @@ -133,11 +136,14 @@ public class InspectionFlowExecutionListener implements FlowExecutionListener { // 当前item已完成节点数 Set finishedNodeSet = itemNodeExecutMap.getOrDefault( - itemExecutionKey(instId, itemId), new HashSet<>()); + itemExecutionKey(instId, itemId, event.getItemOrder()), new HashSet<>()); int finishedNode = finishedNodeSet.size(); int totalNode = event.getNodeCount() == 0 ? 1 : event.getNodeCount(); // 已完整跑完点位占比 + if (event.getItemOrder() != null && event.getItemOrder() > 0) { + finishedItemNum = event.getItemOrder() - 1; + } double itemTotalRatio = finishedItemNum / (double) waypointCount; // 当前运行item内部节点占比 double innerRatio = finishedNode / (double) totalNode / waypointCount; @@ -153,16 +159,37 @@ public class InspectionFlowExecutionListener implements FlowExecutionListener { String logId = UUID.randomUUID().toString().replace("-", ""); // 四舍五入保留2位小数 progress = Math.round(progress * 100) / 100.0; + JSONObject outputParams = event.getOutputParams(); + String imageUrl = FlowMediaParamResolver.lastUrl(outputParams, "imageUrl"); + String videoUrl = FlowMediaParamResolver.lastUrl(outputParams, "videoUrl"); + String audioUrl = FlowMediaParamResolver.lastUrl(outputParams, "audioUrl"); + int logType = InspectionLogTypeEnum.TEXT.getCode(); + String mediaUrl = null; + if (StrUtil.isNotBlank(imageUrl)) { + logType = InspectionLogTypeEnum.IMAGE.getCode(); + mediaUrl = imageUrl; + } else if (StrUtil.isNotBlank(videoUrl)) { + logType = InspectionLogTypeEnum.VIDEO.getCode(); + mediaUrl = videoUrl; + } else if (StrUtil.isNotBlank(audioUrl)) { + logType = InspectionLogTypeEnum.AUDIO.getCode(); + mediaUrl = audioUrl; + } // 保存日志到数据库 InspectionTaskLog taskLog = InspectionTaskLog.builder() .id(logId) .taskInstanceId(taskInstance.getId()) .taskId(taskInstance.getTaskId()) .itemId(itemId) + .itemOrder(event.getItemOrder()) + .itemOccurrence(event.getItemOccurrence()) .nodeId(nodeId) .nodeName(event.getNodeName()) - .logType(InspectionLogTypeEnum.TEXT.getCode()) + .logType(logType) .logContent("节点【" + event.getNodeName() + "】" + info) + .mediaUrl(mediaUrl) + .extraInfo(outputParams == null || outputParams.isEmpty() + ? null : outputParams.toJSONString()) .status(targetStatus) .progress(progress) .logTime(now) @@ -185,7 +212,7 @@ public class InspectionFlowExecutionListener implements FlowExecutionListener { /** 任务结束统一清理缓存 */ private void clearCache(String taskInsId) { Set itemList = taskItemExecutMap.getOrDefault(taskInsId, new HashSet<>()); - itemList.forEach(itemId -> itemNodeExecutMap.remove(itemExecutionKey(taskInsId, itemId))); + itemList.forEach(itemNodeExecutMap::remove); taskItemExecutMap.remove(taskInsId); } @@ -193,6 +220,11 @@ public class InspectionFlowExecutionListener implements FlowExecutionListener { return taskInsId + "|" + itemId; } + private String itemExecutionKey(String taskInsId, String itemId, Integer itemOrder) { + return itemOrder != null && itemOrder > 0 ? taskInsId + "|" + itemOrder + : itemExecutionKey(taskInsId, itemId); + } + /** * 工作流是异步启动的,首个节点事件可能略早于巡检实例写入task_ins_id,短暂重试消除该竞态。 */ diff --git a/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/service/InspectionRobotDeviceAssignmentValidator.java b/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/service/InspectionRobotDeviceAssignmentValidator.java index 4c3fd39..7cc3bfc 100644 --- a/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/service/InspectionRobotDeviceAssignmentValidator.java +++ b/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/service/InspectionRobotDeviceAssignmentValidator.java @@ -6,10 +6,16 @@ import com.cmvr.test.flow.runtime.engine.RobotDeviceAssignmentValidator; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.util.Locale; + @Service @RequiredArgsConstructor public class InspectionRobotDeviceAssignmentValidator implements RobotDeviceAssignmentValidator { + private static final int MICROPHONE_DEVICE_KIND = 9; + private static final String RECORDING_STREAM_CONFLICT = + "cannot start streaming while microphone recording is active"; + private final InspectionRobotDeviceMapper deviceMapper; @Override @@ -18,9 +24,28 @@ public class InspectionRobotDeviceAssignmentValidator implements RobotDeviceAssi if (devices.isEmpty()) { throw new GlobalException("设备[" + deviceId + "]不属于机器人[" + robotId + "]"); } - Integer actualKind = devices.get(0).getDeviceKind(); + var device = devices.get(0); + Integer actualKind = device.getDeviceKind(); if (expectedDeviceKind != null && !expectedDeviceKind.equals(actualKind)) { throw new GlobalException("设备[" + deviceId + "]的类型与流程设备用途不匹配"); } + if (!"1".equals(device.getOnlineStatus())) { + throw new GlobalException("设备[" + deviceId + "]当前离线,请重新选择在线设备"); + } + if (!"1".equals(device.getEnabled())) { + throw new GlobalException("设备[" + deviceId + "]当前未启用"); + } + boolean recoverableMicrophoneConflict = Integer.valueOf(MICROPHONE_DEVICE_KIND).equals(actualKind) + && device.getErrorMessage() != null + && device.getErrorMessage().toLowerCase(Locale.ROOT).contains(RECORDING_STREAM_CONFLICT); + if ("1".equals(device.getHasError()) && !recoverableMicrophoneConflict) { + String detail = device.getErrorMessage() == null || device.getErrorMessage().isBlank() + ? "设备上报异常" + : device.getErrorMessage(); + throw new GlobalException("设备[" + deviceId + "]当前异常: " + detail); + } + if (Integer.valueOf(3).equals(device.getHealthStatus()) && !recoverableMicrophoneConflict) { + throw new GlobalException("设备[" + deviceId + "]当前处于故障状态"); + } } } diff --git a/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/service/impl/InspectionTaskInstanceServiceImpl.java b/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/service/impl/InspectionTaskInstanceServiceImpl.java index 767dabc..fed15ce 100644 --- a/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/service/impl/InspectionTaskInstanceServiceImpl.java +++ b/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/service/impl/InspectionTaskInstanceServiceImpl.java @@ -2,9 +2,12 @@ package com.cmvr.inspection.service.impl; import java.util.List; import java.util.UUID; +import java.util.HashMap; +import java.util.Map; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.spring.service.impl.ServiceImpl; +import cn.hutool.core.util.StrUtil; import com.cmvr.common.exception.ServiceException; import com.cmvr.common.utils.SecurityUtils; import com.cmvr.inspection.domain.InspectionRobot; @@ -18,6 +21,9 @@ import com.cmvr.test.flow.control.FlowControlService; import com.cmvr.test.flow.runtime.engine.FlowTaskRuntimeService; import com.cmvr.test.flow.runtime.event.FlowExecutionModuleCodes; import com.cmvr.test.model.vo.TeTaskExecuteNormalVO; +import com.cmvr.test.model.vo.TeTaskOrchestraVO; +import com.cmvr.test.model.vo.ResourceRuntimeAssignmentVO; +import com.cmvr.test.model.vo.RobotRuntimeMemberVO; import com.cmvr.test.service.ITeTaskOrchestrationService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; @@ -27,6 +33,7 @@ import com.cmvr.inspection.mapper.InspectionTaskInstanceMapper; import com.cmvr.inspection.domain.InspectionTaskInstance; import com.cmvr.inspection.domain.vo.InspectionTaskStartVO; import com.cmvr.inspection.service.IInspectionTaskInstanceService; +import java.util.stream.Collectors; /** * 巡检任务执行实例Service业务层处理 @@ -160,18 +167,60 @@ public class InspectionTaskInstanceServiceImpl extends ServiceImpl runtimeAssignments = startVO == null + ? null : startVO.getRuntimeAssignments(); + normalizeRuntimeRobotIdentities(runtimeAssignments); + String robotId = normalizeRobotIdentity(startVO == null ? null : startVO.getRobotId()); + if (StrUtil.isBlank(robotId)) { + robotId = firstAssignedRobotId(runtimeAssignments); + } + if (StrUtil.isBlank(robotId) && StrUtil.isNotBlank(instance.getRobotId())) { + InspectionRobot legacyRobot = inspectionRobotMapper.selectInspectionRobotById(instance.getRobotId()); + if (legacyRobot == null || StrUtil.isBlank(legacyRobot.getRobotId())) { + throw new ServiceException("巡检任务实例关联的旧机器人不存在"); + } + robotId = legacyRobot.getRobotId(); + } + InspectionRobot primaryRobot = findRobotByIdentity(robotId); + if (primaryRobot != null) { + update.setRobotId(primaryRobot.getId()); + } + List orderedItemIds = inspectionTaskService.selectWaypointsByTaskId(instance.getTaskId()).stream() + .map(com.cmvr.inspection.domain.InspectionWaypoint::getDetectItemId) + .filter(StrUtil::isNotBlank) + .collect(Collectors.toList()); + if (orderedItemIds.isEmpty()) { + throw new ServiceException("巡检任务没有绑定可执行的巡检点位"); + } + teTaskOrchestrationService.insertTeTaskOrchestration(TeTaskOrchestraVO.builder() + .taskId(inspectionTask.getTaskConfigId()) + .itemIds(orderedItemIds) + .build()); JSONObject runParams = new JSONObject(); + JSONObject requestedRunParams = startVO == null ? null : startVO.getRunParams(); + Map itemOccurrences = new HashMap<>(); // 获取所有的检测项id - teTaskOrchestrationService.queryByTaskId(inspectionTask.getTaskConfigId()).forEach(item -> runParams.put(item.getItemId(), new JSONObject())); + teTaskOrchestrationService.queryByTaskId(inspectionTask.getTaskConfigId()).forEach(item -> { + int occurrence = itemOccurrences.merge(item.getItemId(), 1, Integer::sum); + JSONObject submitted = requestedRunParams == null ? null + : requestedRunParams.getJSONObject(item.getItemId() + ":" + occurrence); + if (submitted == null && requestedRunParams != null) { + submitted = requestedRunParams.getJSONObject(item.getItemId()); + } + JSONObject itemParams = submitted == null ? new JSONObject() : new JSONObject(submitted); + itemParams.put("taskInstanceId", instance.getId()); + itemParams.put("inspectionTaskId", inspectionTask.getId()); + itemParams.put("mapId", inspectionTask.getMapId()); + runParams.put(item.getItemId() + ":" + occurrence, itemParams); + }); // 调用真正的执行 String insId = flowTaskRuntimeService.executeTask(TeTaskExecuteNormalVO.builder() .taskId(inspectionTask.getTaskConfigId()) - .robotId(startVO != null && startVO.getRobotId() != null ? startVO.getRobotId() : robot.getRobotId()) - .runtimeAssignments(startVO == null ? null : startVO.getRuntimeAssignments()) + .robotId(robotId) + .runtimeAssignments(runtimeAssignments) .moduleCode(FlowExecutionModuleCodes.INSPECTION) .runParams(runParams) .build()); @@ -179,6 +228,55 @@ public class InspectionTaskInstanceServiceImpl extends ServiceImpl assignments) { + if (assignments == null) { + return; + } + for (ResourceRuntimeAssignmentVO assignment : assignments) { + if (assignment == null || assignment.getMembers() == null) { + continue; + } + for (RobotRuntimeMemberVO member : assignment.getMembers()) { + if (member != null) { + member.setRobotId(normalizeRobotIdentity(member.getRobotId())); + } + } + } + } + + private String normalizeRobotIdentity(String value) { + if (StrUtil.isBlank(value)) { + return value; + } + InspectionRobot robot = inspectionRobotMapper.selectInspectionRobotById(value); + return robot != null && StrUtil.isNotBlank(robot.getRobotId()) ? robot.getRobotId() : value; + } + + private String firstAssignedRobotId(List assignments) { + if (assignments == null) { + return null; + } + for (ResourceRuntimeAssignmentVO assignment : assignments) { + if (assignment == null || assignment.getMembers() == null) { + continue; + } + for (RobotRuntimeMemberVO member : assignment.getMembers()) { + if (member != null && StrUtil.isNotBlank(member.getRobotId())) { + return member.getRobotId(); + } + } + } + return null; + } + + private InspectionRobot findRobotByIdentity(String robotId) { + if (StrUtil.isBlank(robotId)) { + return null; + } + List robots = inspectionRobotMapper.selectByRobotId(robotId); + return robots == null || robots.isEmpty() ? null : robots.get(0); + } + /** * 暂停任务实例 */ diff --git a/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/service/impl/InspectionTaskServiceImpl.java b/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/service/impl/InspectionTaskServiceImpl.java index 4a0d71a..614807f 100644 --- a/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/service/impl/InspectionTaskServiceImpl.java +++ b/cmvr-iot-inspection/src/main/java/com/cmvr/inspection/service/impl/InspectionTaskServiceImpl.java @@ -16,6 +16,7 @@ import com.cmvr.test.service.ITeTaskConfigInfoService; import com.cmvr.test.service.ITeTaskOrchestrationService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import com.cmvr.common.utils.DateUtils; import com.cmvr.common.utils.SecurityUtils; import com.cmvr.inspection.mapper.InspectionTaskMapper; @@ -144,11 +145,22 @@ public class InspectionTaskServiceImpl extends ServiceImpl waypoints = inspectionTaskWaypointMapper.selectWaypointsByTaskId(taskId); // 同步任务编排 - TeTaskOrchestraVO teTaskOrchestraVO = TeTaskOrchestraVO.builder().taskId(inspectionTask.getTaskConfigId()).itemIds(waypoints.stream().map(InspectionWaypoint::getDetectItemId).collect(Collectors.toList())).build(); - teTaskOrchestrationService.insertTeTaskOrchestration(teTaskOrchestraVO); + List detectItemIds = waypoints.stream() + .map(InspectionWaypoint::getDetectItemId) + .filter(itemId -> itemId != null && !itemId.isEmpty()) + .collect(Collectors.toList()); + if (!detectItemIds.isEmpty() && inspectionTask.getTaskConfigId() != null) { + TeTaskOrchestraVO teTaskOrchestraVO = TeTaskOrchestraVO.builder() + .taskId(inspectionTask.getTaskConfigId()) + .itemIds(detectItemIds) + .build(); + teTaskOrchestrationService.insertTeTaskOrchestration(teTaskOrchestraVO); + } else if (inspectionTask.getTaskConfigId() != null) { + teTaskOrchestrationService.deleteByTaskId(inspectionTask.getTaskConfigId()); + } return 1; } @@ -180,8 +202,18 @@ public class InspectionTaskServiceImpl extends ServiceImpl + @@ -129,7 +130,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select ti.id, ti.create_by, ti.create_time, ti.update_by, ti.update_time, ti.remark, ti.task_id, t.task_name, t.task_code, - ti.robot_id, r.robot_name, + ti.robot_id, r.robot_name, r.robot_id as robot_identity, r.current_map_id as robot_current_map_id, m.map_name, ti.status, ti.start_time, ti.end_time, ti.task_ins_id from inspection_task_instance ti diff --git a/cmvr-iot-inspection/src/main/resources/mapper/inspection/InspectionTaskWaypointMapper.xml b/cmvr-iot-inspection/src/main/resources/mapper/inspection/InspectionTaskWaypointMapper.xml index 5c2c809..d5c64d6 100644 --- a/cmvr-iot-inspection/src/main/resources/mapper/inspection/InspectionTaskWaypointMapper.xml +++ b/cmvr-iot-inspection/src/main/resources/mapper/inspection/InspectionTaskWaypointMapper.xml @@ -12,11 +12,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"