Files
FT546-WCS/ruoyi-ft546-protocol/src/main/java/com/ruoyi/ft546/protocol/Ft546SrgvCommandEncoder.java

154 lines
6.5 KiB
Java

package com.ruoyi.ft546.protocol;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public final class Ft546SrgvCommandEncoder {
public Ft546EncodedCommand encode(Ft546SrgvCommandIntent intent,
Ft546DeviceProfile profile,
Set<String> capabilities) {
if (intent == null) {
throw new IllegalArgumentException("intent must not be null");
}
if (profile == null) {
throw new IllegalArgumentException("profile must not be null");
}
if (capabilities == null) {
throw new IllegalArgumentException(
"capabilities must not be null");
}
int[] route = route(intent.getPathPoints());
Integer stage = intent.getTwoStageNumber();
if (stage == null) {
if (!capabilities.contains("POINT_TO_POINT_COMMAND")) {
throw new IllegalStateException(
"POINT_TO_POINT_COMMAND is not enabled");
}
return main(intent, profile, route);
}
if (!capabilities.contains("TWO_STAGE_ATOMIC_TASK")) {
throw new IllegalStateException(
"TWO_STAGE_ATOMIC_TASK is not enabled");
}
if (stage.intValue() == 1) {
return secondStageOne(intent, profile, route);
}
if (stage.intValue() == 2) {
return secondStageTwo(intent, profile, route);
}
throw new IllegalArgumentException("stage must be 1 or 2");
}
private static Ft546EncodedCommand main(Ft546SrgvCommandIntent intent,
Ft546DeviceProfile profile,
int[] route) {
List<Ft546RegisterWrite> writes =
new ArrayList<Ft546RegisterWrite>();
add(writes, profile, "path", Ft546RegisterWrite.DataType.INT32,
false, route);
add(writes, profile, "taskNo", Ft546RegisterWrite.DataType.INT32,
false, intent.getTaskNo());
add(writes, profile, "taskType", Ft546RegisterWrite.DataType.INT16,
false, intent.getTaskType());
add(writes, profile, "trigger", Ft546RegisterWrite.DataType.INT16,
true, 1);
if (intent.getTaskType() == 8) {
if (intent.getCrossFloorTarget() == null) {
throw new IllegalArgumentException(
"crossFloorTarget is required");
}
add(writes, profile, "crossFloorFlag",
Ft546RegisterWrite.DataType.INT16, false, 1);
add(writes, profile, "crossFloorTarget",
Ft546RegisterWrite.DataType.INT16, false,
intent.getCrossFloorTarget());
}
return new Ft546EncodedCommand(intent, writes, 1);
}
private static Ft546EncodedCommand secondStageOne(
Ft546SrgvCommandIntent intent, Ft546DeviceProfile profile,
int[] route) {
List<Ft546RegisterWrite> writes =
new ArrayList<Ft546RegisterWrite>();
add(writes, profile, "secondPath",
Ft546RegisterWrite.DataType.INT32, false, route);
add(writes, profile, "secondStageFlag",
Ft546RegisterWrite.DataType.INT16, true, 1);
add(writes, profile, "secondTaskType",
Ft546RegisterWrite.DataType.INT16, false,
intent.getTaskType());
add(writes, profile, "secondTaskNo",
Ft546RegisterWrite.DataType.INT32, false,
intent.getTaskNo());
return new Ft546EncodedCommand(intent, writes, 1);
}
private static Ft546EncodedCommand secondStageTwo(
Ft546SrgvCommandIntent intent, Ft546DeviceProfile profile,
int[] route) {
List<Ft546RegisterWrite> writes =
new ArrayList<Ft546RegisterWrite>();
add(writes, profile, "secondPath",
Ft546RegisterWrite.DataType.INT32, false, route);
add(writes, profile, "secondStageFlag",
Ft546RegisterWrite.DataType.INT16, true, 2);
add(writes, profile, "secondComplete",
Ft546RegisterWrite.DataType.INT16, false, 99);
add(writes, profile, "secondTaskType",
Ft546RegisterWrite.DataType.INT16, false, 9);
add(writes, profile, "secondTaskNo",
Ft546RegisterWrite.DataType.INT32, false,
intent.getTaskNo());
return new Ft546EncodedCommand(intent, writes, 2);
}
private static void add(List<Ft546RegisterWrite> writes,
Ft546DeviceProfile profile, String register,
Ft546RegisterWrite.DataType dataType,
boolean trigger, int... values) {
List<Integer> boxed = new ArrayList<Integer>(values.length);
for (int value : values) {
if (dataType == Ft546RegisterWrite.DataType.INT16
&& (value < Short.MIN_VALUE || value > Short.MAX_VALUE)) {
throw new IllegalArgumentException(
register + " value is not an int16");
}
boxed.add(value);
}
writes.add(new Ft546RegisterWrite(register(profile, register),
dataType, boxed, writes.size() + 1, trigger));
}
private static int[] route(List<Integer> points) {
if (points.size() < 2 || points.size() > 8) {
throw new IllegalArgumentException(
"legacy route must contain between 2 and 8 command points");
}
int[] result = new int[8];
for (int index = 0; index < points.size(); index++) {
Integer point = points.get(index);
if (point == null || point.intValue() <= 0) {
throw new IllegalArgumentException(
"route node must be positive");
}
if (point.intValue() > 999999) {
throw new IllegalArgumentException(
"route node exceeds six digits");
}
result[index] = point.intValue();
}
return result;
}
private static String register(Ft546DeviceProfile profile, String name) {
String address = profile.getRegisters().get(name);
if (address == null || address.trim().isEmpty()) {
throw new IllegalArgumentException(
"profile register is missing: " + name);
}
return address.trim();
}
}