diff --git a/pom.xml b/pom.xml index bc6f326..560817f 100644 --- a/pom.xml +++ b/pom.xml @@ -121,6 +121,14 @@ 4.1.94.Final + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + 2.12.4 + + + diff --git a/src/main/java/a8k/BoditechA800Application.java b/src/main/java/a8k/BoditechA800Application.java index 5ceffc2..cd33002 100644 --- a/src/main/java/a8k/BoditechA800Application.java +++ b/src/main/java/a8k/BoditechA800Application.java @@ -25,15 +25,16 @@ public class BoditechA800Application implements ApplicationListener receiptQueue = new LinkedBlockingQueue<>(); // - A8kPacket cmdPacket; - Map txcmdcache = new HashMap<>(); + A8kPacket cmdPacket; + Map txcmdcache = new HashMap<>(); public A8kPacket getReceipt(long overtime) { @@ -181,7 +181,7 @@ public class A8kCanBusConnection extends WebSocketClient { // @Scheduled(fixedRate = 10000) private void autoConnect() { - if (!enableCanBus) + if (!iflytophaldEnable) return; if (!isOpen()) { diff --git a/src/main/java/a8k/app/channel/iflytophald/channel/A8kCanBusService.java b/src/main/java/a8k/app/channel/iflytophald/channel/A8kCanBusService.java index 9ee95d4..0ae21ef 100644 --- a/src/main/java/a8k/app/channel/iflytophald/channel/A8kCanBusService.java +++ b/src/main/java/a8k/app/channel/iflytophald/channel/A8kCanBusService.java @@ -19,12 +19,13 @@ public class A8kCanBusService { @Resource A8kCanBusConnection connection; - @Value("${device.enableCanBus}") - Boolean enableCanBus; + + @Value("${iflytophald.enable}") + Boolean iflytophaldEnable; @PostConstruct public void init() throws URISyntaxException { - if (enableCanBus) { + if (iflytophaldEnable) { connection.connect(); } else { log.warn("canBus is disabled"); diff --git a/src/main/java/a8k/app/channel/iflytophald/channel/LisUartChannel.java b/src/main/java/a8k/app/channel/iflytophald/channel/LisUartChannel.java index c7a6ad3..8d0ef20 100644 --- a/src/main/java/a8k/app/channel/iflytophald/channel/LisUartChannel.java +++ b/src/main/java/a8k/app/channel/iflytophald/channel/LisUartChannel.java @@ -2,12 +2,14 @@ package a8k.app.channel.iflytophald.channel; import a8k.app.config.IflytophaldConnectionConfig; import a8k.app.channel.iflytophald.channelctrl.IflytophaldChannelCtrl; +import a8k.app.utils.ByteArrayUtils; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.java_websocket.client.WebSocketClient; import org.java_websocket.enums.ReadyState; import org.java_websocket.handshake.ServerHandshake; +import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @@ -20,6 +22,11 @@ import java.nio.ByteBuffer; @Component @RequiredArgsConstructor public class LisUartChannel { + + @Value("${iflytophald.enable}") + Boolean iflytophaldEnable; + + private final String channelName = "lis"; private final String charsetName = "UTF-8"; @@ -32,6 +39,7 @@ public class LisUartChannel { private Integer baudRate = 115200; private Boolean syncBaudRateSuc = false; private final Object baudRateLock = new Object(); + private Boolean loopbackMode = false; synchronized public void tx(byte[] toSend) { @@ -53,6 +61,10 @@ public class LisUartChannel { this.onMessageListener = listener; } + synchronized public boolean isConnected() { + return conn != null && conn.isOpen(); + } + public synchronized Boolean setBaudRate(Integer baudRate) { if (baudRate == null) { log.warn("setBaudRate: baudRate is null or empty"); @@ -63,14 +75,33 @@ public class LisUartChannel { return true; } + public synchronized void setInLoopbackMode(boolean inLoopback) { + synchronized (this.baudRateLock) { + loopbackMode = inLoopback; + } + } + + public Boolean isInLoopbackMode() { + synchronized (this.baudRateLock) { + return loopbackMode; + } + } + public Integer getBaudRateDirect() { synchronized (this.baudRateLock) { + if (!isConnected()) { + return this.baudRate; + } + + if (syncBaudRateSuc) { + return this.baudRate; + } + var receipt = cmdSender.callCmd(channelName, "getBaudrate", GetBaudrateResponse.class); if (receipt == null || receipt.status != 0 || receipt.data == null) { log.error("getBaudRateDirect: callCmd returned null or error"); return null; } - log.info("getBaudRateDirect: current baudrate is {}", receipt.data.baudrate); syncBaudRateSuc = receipt.data.baudrate != null && receipt.data.baudrate.equals(this.baudRate); return receipt.data.baudrate; } @@ -83,32 +114,24 @@ public class LisUartChannel { @FunctionalInterface public interface OnMessageListener { - void onMessage(String message); + void onMessage(byte[] bytes); } static public class GetBaudrateResponse { public Integer baudrate; } - private void onMessage(String s) { - // String - log.info("1onMessage: {}", s); - } private void onMessage(ByteBuffer bytes) { byte[] byteArray = new byte[bytes.remaining()]; bytes.get(byteArray); - //log.info("rx: {}", ByteArray.toByteString(byteArray)); - - String message; - try { - message = new String(byteArray, charsetName); - log.info("onMessage: {}", message); - if (onMessageListener != null) { - onMessageListener.onMessage(message); - } - } catch (UnsupportedEncodingException e) { - log.error("onMessage error", e); + log.debug("onMessage: {}", ByteArrayUtils.toByteString(byteArray)); + if (onMessageListener != null) { + onMessageListener.onMessage(byteArray); + } + if (loopbackMode) { + // 如果是环回模式,则直接发送回去 + tx(byteArray); } } @@ -125,7 +148,7 @@ public class LisUartChannel { @Override public void onMessage(String s) { - LisUartChannel.this.onMessage(s); + log.error("onMessage: received string message {}, this should not happen in LisUartChannel", s); } @Override @@ -165,6 +188,11 @@ public class LisUartChannel { if (baudRate != null) { this.baudRate = baudRate; } + if (!isConnected()) { + log.warn("lis channel is not connected, sync later"); + return; + } + if (syncBaudRateSuc) { return; } @@ -179,8 +207,13 @@ public class LisUartChannel { syncBaudRateSuc = true; } } + @Scheduled(fixedRate = 1000) private void autoConnect() { + if (!iflytophaldEnable) { + return; + } + if (!conn.isOpen()) { if (conn.getReadyState().equals(ReadyState.NOT_YET_CONNECTED)) { try { diff --git a/src/main/java/a8k/app/channel/iflytophald/channel/PrinterUartChannel.java b/src/main/java/a8k/app/channel/iflytophald/channel/PrinterUartChannel.java index 97ccd4b..439c6a8 100644 --- a/src/main/java/a8k/app/channel/iflytophald/channel/PrinterUartChannel.java +++ b/src/main/java/a8k/app/channel/iflytophald/channel/PrinterUartChannel.java @@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j; import org.java_websocket.client.WebSocketClient; import org.java_websocket.enums.ReadyState; import org.java_websocket.handshake.ServerHandshake; +import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @@ -20,6 +21,9 @@ import java.util.Queue; @Component @RequiredArgsConstructor public class PrinterUartChannel { + @Value("${iflytophald.enable}") + Boolean iflytophaldEnable; + WebSocketClient conn; private final IflytophaldConnectionConfig config; @@ -141,6 +145,9 @@ public class PrinterUartChannel { @Scheduled(fixedRate = 10000) private void autoConnect() { + if (!iflytophaldEnable) { + return; + } if (!conn.isOpen()) { if (conn.getReadyState().equals(ReadyState.NOT_YET_CONNECTED)) { try { diff --git a/src/main/java/a8k/app/channel/net/BoditechLisSingleTrackTcpClient.java b/src/main/java/a8k/app/channel/net/BoditechLisSingleTrackTcpClient.java index 8693e56..7349ab1 100644 --- a/src/main/java/a8k/app/channel/net/BoditechLisSingleTrackTcpClient.java +++ b/src/main/java/a8k/app/channel/net/BoditechLisSingleTrackTcpClient.java @@ -9,6 +9,7 @@ import io.netty.handler.codec.LineBasedFrameDecoder; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import lombok.extern.slf4j.Slf4j; + import java.util.concurrent.TimeUnit; @Slf4j @@ -55,6 +56,10 @@ public class BoditechLisSingleTrackTcpClient extends SimpleChannelInboundHandler group.shutdownGracefully(); } + public synchronized boolean isConnected() { + return channel != null && channel.isActive(); + } + public synchronized void tx(String data) { if (channel != null && channel.isActive()) { channel.writeAndFlush(data).addListener(future -> { @@ -100,7 +105,7 @@ public class BoditechLisSingleTrackTcpClient extends SimpleChannelInboundHandler // 处理接收到的消息 @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { - log.info("Received message from server: {}({})", msg,msg.length()); + log.info("Received message from server: {}({})", msg, msg.length()); } public static void main(String[] args) { diff --git a/src/main/java/a8k/app/constant/AppConstant.java b/src/main/java/a8k/app/constant/AppConstant.java index b81593c..70629d6 100644 --- a/src/main/java/a8k/app/constant/AppConstant.java +++ b/src/main/java/a8k/app/constant/AppConstant.java @@ -6,7 +6,6 @@ public class AppConstant { public static final int CONSUMABLE_COL_NUM = 5; public static final int CONSUMABLE_ROW_NUM = 5; public static final int TIP_NUM = 120; - public static final String APP_VERSION = "3.0"; public static final int CONSUMABLE_CHANNEL_NUM = 6; } diff --git a/src/main/java/a8k/app/constant/AppVersion.java b/src/main/java/a8k/app/constant/AppVersion.java new file mode 100644 index 0000000..2ce2257 --- /dev/null +++ b/src/main/java/a8k/app/constant/AppVersion.java @@ -0,0 +1,5 @@ +package a8k.app.constant; + +public class AppVersion { + public static final String APP_VERSION = "1.0.1"; +} diff --git a/src/main/java/a8k/app/controler/api/v1/app/setting/LISSettingController.java b/src/main/java/a8k/app/controler/api/v1/app/setting/LISSettingController.java index c23cca5..6491e3d 100644 --- a/src/main/java/a8k/app/controler/api/v1/app/setting/LISSettingController.java +++ b/src/main/java/a8k/app/controler/api/v1/app/setting/LISSettingController.java @@ -1,6 +1,7 @@ package a8k.app.controler.api.v1.app.setting; import a8k.app.dao.type.db.LISSetting; +import a8k.app.service.lis.LisCommunicationService; import a8k.app.service.setting.AppSettingsMgrService; import a8k.app.type.lis.LISDirectionTypeEnum; import a8k.app.type.lis.LISIFType; @@ -30,6 +31,9 @@ public class LISSettingController { AppSettingsMgrService appSettingsMgrService; @Resource + LisCommunicationService lisCommunicationService; + + @Resource GStateMgrService gstate; // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -49,6 +53,7 @@ public class LISSettingController { public ApiRet setAppSettings(@RequestBody LISSetting setting) { log.info("设置LIS配置 {}", ZJsonHelper.objToPrettyJson(setting)); appSettingsMgrService.setLISSetting(setting); + lisCommunicationService.updateLisSetting(setting); return ApiRet.success(); } diff --git a/src/main/java/a8k/app/dao/ProjOptInfoDao.java b/src/main/java/a8k/app/dao/ProjOptInfoDao.java index ccb39df..8d03870 100644 --- a/src/main/java/a8k/app/dao/ProjOptInfoDao.java +++ b/src/main/java/a8k/app/dao/ProjOptInfoDao.java @@ -34,33 +34,33 @@ public class ProjOptInfoDao extends ZSqlite { } } - public void add(OptCfg val) { -// checkVal(val); - super.add(val); + public OptCfg add(OptCfg val) { + // checkVal(val); + return super.add(val); } -// public void removeAll() { -// super.deleteAll(); -// } -// -// private void checkVal(ProjOptInfo val) { -// for (var field : val.getClass().getDeclaredFields()) { -// if (field.getName().equals("id")) { -// continue; -// } -// -// try { -// field.setAccessible(true); -// if (field.get(val) == null) { -// log.error("field {} is null,{}", field.getName(), ZJsonHelper.objectToJson(val)); -// System.exit(1); -// } -// } catch (IllegalAccessException e) { -// log.error("", e); -// System.exit(1); -// } -// } -// -// } + // public void removeAll() { + // super.deleteAll(); + // } + // + // private void checkVal(ProjOptInfo val) { + // for (var field : val.getClass().getDeclaredFields()) { + // if (field.getName().equals("id")) { + // continue; + // } + // + // try { + // field.setAccessible(true); + // if (field.get(val) == null) { + // log.error("field {} is null,{}", field.getName(), ZJsonHelper.objectToJson(val)); + // System.exit(1); + // } + // } catch (IllegalAccessException e) { + // log.error("", e); + // System.exit(1); + // } + // } + // + // } } diff --git a/src/main/java/a8k/app/dao/ProjectBaseInfoDao.java b/src/main/java/a8k/app/dao/ProjectBaseInfoDao.java index 7c2c17b..8add410 100644 --- a/src/main/java/a8k/app/dao/ProjectBaseInfoDao.java +++ b/src/main/java/a8k/app/dao/ProjectBaseInfoDao.java @@ -27,9 +27,9 @@ public class ProjectBaseInfoDao extends ZSqlite { return queryOne("select * from " + tableName + " where projId = ?;", projId); } - public void add(ProjectBaseInfo val) { + public ProjectBaseInfo add(ProjectBaseInfo val) { val.color = UtilsProjectColorAllocer.getProjColor(val.projId); - super.add(val); + return super.add(val); } diff --git a/src/main/java/a8k/app/dao/type/db/NetworkSetting.java b/src/main/java/a8k/app/dao/type/db/NetworkSetting.java index d82b5d9..a024683 100644 --- a/src/main/java/a8k/app/dao/type/db/NetworkSetting.java +++ b/src/main/java/a8k/app/dao/type/db/NetworkSetting.java @@ -19,12 +19,12 @@ public class NetworkSetting implements Serializable { } static public class DynamicIpConfig { + public Boolean autoDns = true; public List dnsList = ZList.of("223.5.5.5", "223.6.6.6"); } - public NetworkMode networkMode = NetworkMode.STATIC_IP; + public NetworkMode networkMode = NetworkMode.STATIC_IP; public StaticIPConfig staticIPConfig = new StaticIPConfig(); public DynamicIpConfig dynamicIpConfig = new DynamicIpConfig(); - } diff --git a/src/main/java/a8k/app/factory/BoditechLisSingleTrackFrameFactory.java b/src/main/java/a8k/app/factory/BoditechLisSingleTrackFrameFactory.java index c6472d1..ebbf713 100644 --- a/src/main/java/a8k/app/factory/BoditechLisSingleTrackFrameFactory.java +++ b/src/main/java/a8k/app/factory/BoditechLisSingleTrackFrameFactory.java @@ -91,7 +91,7 @@ public class BoditechLisSingleTrackFrameFactory { FakeProjBuildInInfoFactory.buildFakeProjBuildInInfo()); List frames = BoditechLisSingleTrackFrameFactory.buildBoditechLisSingleTrackFrame(record); for (BoditechLisSingleTrackFrame frame : frames) { - System.out.println(frame.toFrame()); + System.out.println(frame.serialization()); } } diff --git a/src/main/java/a8k/app/service/background/AppEventBusService.java b/src/main/java/a8k/app/service/background/AppEventBusService.java index 00a69b0..6e69e8d 100644 --- a/src/main/java/a8k/app/service/background/AppEventBusService.java +++ b/src/main/java/a8k/app/service/background/AppEventBusService.java @@ -43,7 +43,7 @@ public class AppEventBusService implements ApplicationListener { + boditechLisSingleTrackTcpClient.start(hostip, port); + } + case UART -> { + + } + } + } + + public boolean isConnected() { + switch (channelType) { + case UART -> { + if (lisUartChannel != null) { + return lisUartChannel.isConnected(); + } + } + case TCP -> { + if (boditechLisSingleTrackTcpClient != null) { + return boditechLisSingleTrackTcpClient.isConnected(); + } + } + } + return false; + } + + public void shotdown() { + switch (channelType) { + case UART -> { + } + case TCP -> { + if (boditechLisSingleTrackTcpClient != null) { + boditechLisSingleTrackTcpClient.shutdown(); + } + } + } + } + + public void reportReactionReport(ReactionRecord reactionRecord) { + if (reactionRecord == null) { + return; + } + List frames = BoditechLisSingleTrackFrameFactory.buildBoditechLisSingleTrackFrame(reactionRecord); + for (BoditechLisSingleTrackFrame frame : frames) { + tx(frame); + } + } + + public void tx(BoditechLisSingleTrackFrame frame) { + if (frame == null) { + return; + } + String frameStr = frame.serialization(); + switch (channelType) { + case UART -> { + if (lisUartChannel != null) { + log.debug("BoditechLisSingleTrackChannel tx frame by uart: {}", frameStr); + lisUartChannel.tx(frameStr); + } + } + case TCP -> { + if (boditechLisSingleTrackTcpClient != null) { + log.debug("BoditechLisSingleTrackChannel tx frame by tcp: {}", frameStr); + boditechLisSingleTrackTcpClient.tx(frameStr); + } + } + } + } +} diff --git a/src/main/java/a8k/app/service/lis/LisCommunicationService.java b/src/main/java/a8k/app/service/lis/LisCommunicationService.java new file mode 100644 index 0000000..3b26e0d --- /dev/null +++ b/src/main/java/a8k/app/service/lis/LisCommunicationService.java @@ -0,0 +1,119 @@ +package a8k.app.service.lis; + +import a8k.app.channel.iflytophald.channel.LisUartChannel; +import a8k.app.dao.type.db.LISSetting; +import a8k.app.dao.type.db.ReactionRecord; +import a8k.app.service.setting.AppSettingsMgrService; +import a8k.app.type.lis.LISDirectionTypeEnum; +import a8k.app.type.lis.LISIFType; +import a8k.app.type.lis.LISProtocolEnum; +import a8k.app.utils.ZJsonHelper; +import jakarta.annotation.PostConstruct; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +@Slf4j +public class LisCommunicationService { + private final AppSettingsMgrService appSettingsMgrService; + private final LisUartChannel lisUartChannel; + private LISSetting setting; + + BoditechLisSingleTrackChannel boditechLisSingleTrackChannel; + + public void updateLisSetting(LISSetting lisSetting) { + log.info("updateLisSetting: {}", ZJsonHelper.objToPrettyJson(lisSetting)); + setting = lisSetting; + doUpdateLisSetting(); + } + + public String getProtocolDetail() { + + if (isChannelEq(LISProtocolEnum.Boditech, LISDirectionTypeEnum.SINGLE_TRACK, LISIFType.SERIAL)) { + return String.format("%s.%s.%s,baudrate:%s", setting.lisProtocol, setting.lisType, setting.lisIf, setting.lisSerialBaudrate.baudrate); + } + else if (isChannelEq(LISProtocolEnum.Boditech, LISDirectionTypeEnum.SINGLE_TRACK, LISIFType.NETWORK)) { + return String.format("%s.%s.%s,ip:%s,port:%d", setting.lisProtocol, setting.lisType, setting.lisIf, setting.lisNetIp, setting.lisNetPort); + } else { + return String.format("%s.%s.%s", setting.lisProtocol, setting.lisType, setting.lisIf); + } + + + } + + public Boolean getConnectionState() { + //巴迪泰串口单向 && 巴迪泰网口单向 + if (isChannelEq(LISProtocolEnum.Boditech, LISDirectionTypeEnum.SINGLE_TRACK, null)) { + return boditechLisSingleTrackChannel.isConnected(); + } + return false; + } + + public void reportReactionRecord(ReactionRecord reactionRecord) { + //巴迪泰串口单向 && 巴迪泰网口单向 + if (isChannelEq(LISProtocolEnum.Boditech, LISDirectionTypeEnum.SINGLE_TRACK, null)) { + boditechLisSingleTrackChannel.reportReactionReport(reactionRecord); + } else { + log.warn("LIS Type is not support, ignore report"); + } + } + + + @PostConstruct + public void init() { + log.info("LisCommunicationService init"); + setting = appSettingsMgrService.getLISSetting(); + doUpdateLisSetting(); + } + + // + // Channel builder + // + + private void doUpdateLisSetting() { + shutdownAllChannel(); + //巴迪泰串口单向 + if (isChannelEq(LISProtocolEnum.Boditech, LISDirectionTypeEnum.SINGLE_TRACK, LISIFType.SERIAL)) { + log.info("new BoditechLisSingleTrackChannel with SERIAL , baudrate: {}", setting.lisSerialBaudrate.baudrate); + lisUartChannel.setBaudRate(setting.lisSerialBaudrate.baudrate); + boditechLisSingleTrackChannel = new BoditechLisSingleTrackChannel(lisUartChannel); + boditechLisSingleTrackChannel.start(); + } + //巴迪泰网口单向 + else if (isChannelEq(LISProtocolEnum.Boditech, LISDirectionTypeEnum.SINGLE_TRACK, LISIFType.NETWORK)) { + log.info("new BoditechLisSingleTrackChannel with NETWORK, ip: {}, port: {}", setting.lisNetIp, setting.lisNetPort); + boditechLisSingleTrackChannel = new BoditechLisSingleTrackChannel(setting.lisNetIp, setting.lisNetPort); + boditechLisSingleTrackChannel.start(); + } else { + log.warn("Unsupported LIS channel configuration: protocol={}, direction={}, ifType={}", + setting.lisProtocol, setting.lisType, setting.lisIf); + } + + } + + boolean isChannelEq(LISProtocolEnum protocol, LISDirectionTypeEnum direction, LISIFType ifType) { + if (setting == null) { + return false; + } + + boolean protocolIsEq = protocol == null || setting.lisProtocol.equals(protocol); + boolean ifTypeIsEq = ifType == null || setting.lisIf.equals(ifType); + boolean directionIsEq = direction == null || setting.lisType.equals(direction); + + return protocolIsEq && + ifTypeIsEq && + directionIsEq; + } + + + private void shutdownAllChannel() { + if (boditechLisSingleTrackChannel != null) { + boditechLisSingleTrackChannel.shotdown(); + boditechLisSingleTrackChannel = null; + } + log.info("shutdownAllChannel done"); + } + +} diff --git a/src/main/java/a8k/app/service/mainctrl/AppDeviceInitCtrlService.java b/src/main/java/a8k/app/service/mainctrl/AppDeviceInitCtrlService.java index ebf1c23..caef3a3 100644 --- a/src/main/java/a8k/app/service/mainctrl/AppDeviceInitCtrlService.java +++ b/src/main/java/a8k/app/service/mainctrl/AppDeviceInitCtrlService.java @@ -3,11 +3,13 @@ package a8k.app.service.mainctrl; import a8k.app.channel.iflytophald.driver.*; import a8k.app.channel.iflytophald.type.protocol.*; import a8k.app.service.appsetup.A8kSubModuleRegInitService; +import a8k.app.service.background.AppEventBusService; import a8k.app.service.lowerctrl.HbotMoveCtrlService; import a8k.app.service.lowerctrl.HbotMoveExCtrlService; import a8k.app.service.lowerctrl.TubeFeedingCtrlService; import a8k.app.service.lowerctrl.TubePreProcessModuleCtrlService; import a8k.app.service.statemgr.DeviceWorkStateMgrService; +import a8k.app.type.appevent.AppDeviceInitSucEvent; import a8k.app.type.exception.AppException; import a8k.app.type.ui.ZAppPromopt; import a8k.app.type.ui.ZAppPromoptFormsItem; @@ -28,6 +30,8 @@ import java.util.List; @Slf4j @RequiredArgsConstructor public class AppDeviceInitCtrlService { + private final AppEventBusService appEventBusService; + public static class Checkpoint { public enum Type { CHECK_TUBE_X_CHANNEL_IS_EMPTY,//入料通道是否为空 @@ -264,6 +268,9 @@ public class AppDeviceInitCtrlService { gstate.clearFatalError(); deviceWorkStateMgrService.clearFatalErrorFlag(); + log.info("设备初始化完成"); + appEventBusService.pushEvent(new AppDeviceInitSucEvent()); + return results; } diff --git a/src/main/java/a8k/app/service/module/OptScanCtrlModule.java b/src/main/java/a8k/app/service/module/OptScanCtrlModule.java index 5b845ba..2dc8fe1 100644 --- a/src/main/java/a8k/app/service/module/OptScanCtrlModule.java +++ b/src/main/java/a8k/app/service/module/OptScanCtrlModule.java @@ -7,6 +7,7 @@ import a8k.app.factory.AppErrorFactory; import a8k.app.factory.FakeReactionRecordFactory; import a8k.app.optalgo.A8kPeakAnalyzer; import a8k.app.service.data.ReactionRecordMgrService; +import a8k.app.service.lis.LisCommunicationService; import a8k.app.service.lowerctrl.OptScanModuleLowerCtrlService; import a8k.app.service.statemgr.GStateMgrService; import a8k.app.service.statemgr.OptScanModuleStateMgr; @@ -66,6 +67,7 @@ public class OptScanCtrlModule { // 数据库 // private final ReactionRecordMgrService reactionRecordMgrService; + private final LisCommunicationService lisCommunicationService; // // 控制 // @@ -191,6 +193,7 @@ public class OptScanCtrlModule { List reactionResults = FakeReactionRecordFactory.buildReactionResult(projInfo); List optScanResults = new ArrayList<>(); reactionRecordMgrService.addRecord(sampleInfo, projInfo, optScanResults, reactionResults); +// lisCommunicationService.reportReactionRecord(); } diff --git a/src/main/java/a8k/app/service/setting/AppNetworkSettingService.java b/src/main/java/a8k/app/service/setting/AppNetworkSettingService.java index 79b91b6..686ace0 100644 --- a/src/main/java/a8k/app/service/setting/AppNetworkSettingService.java +++ b/src/main/java/a8k/app/service/setting/AppNetworkSettingService.java @@ -21,4 +21,13 @@ public class AppNetworkSettingService { networkSettingDao.update(setting); log.info("Network configuration updated: {}", setting); } + + + + + + + + + } diff --git a/src/main/java/a8k/app/type/GState.java b/src/main/java/a8k/app/type/GState.java index 49361d0..620fbd6 100644 --- a/src/main/java/a8k/app/type/GState.java +++ b/src/main/java/a8k/app/type/GState.java @@ -1,6 +1,7 @@ package a8k.app.type; import a8k.app.constant.AppConstant; +import a8k.app.constant.AppVersion; import a8k.app.i18n.Internationalization; import a8k.app.type.a8k.state.SensorState; import a8k.app.type.error.AppError; @@ -18,7 +19,7 @@ public class GState { @Value("${device.runmode}") public DeviceRunMode deviceRunMode = null; //软件版本 - public String appVersion = AppConstant.APP_VERSION; + public String appVersion = AppVersion.APP_VERSION; //MCU版本 public String mcuVersion = ""; //设备SN diff --git a/src/main/java/a8k/app/type/a8k/proj/A8kResultUnit.java b/src/main/java/a8k/app/type/a8k/proj/A8kResultUnit.java index c1c2c29..b762d20 100644 --- a/src/main/java/a8k/app/type/a8k/proj/A8kResultUnit.java +++ b/src/main/java/a8k/app/type/a8k/proj/A8kResultUnit.java @@ -16,20 +16,20 @@ public enum A8kResultUnit { ugPdl(12, "ug/dL"), mgPdl(13, "mg/dL"), gPdl(14, "g/dL"), - pmolPl(15, "pmol/L"), - nmolPl(16, "nmol/L"), - umolPl(17, "umol/L"), - mmolPl(18, "mmol/L"), - uiuPml(19, "uIU/mL"), - miuPml(20, "mIU/mL"), - iuPml(21, "IU/mL"), - uuPml(22, "uU/mL"), - muPml(23, "mU/mL"), - uPml(24, "U/mL"), - muPl(25, "mU/L"), + pmolPl(15, "pmol/l"), + nmolPl(16, "nmol/l"), + umolPl(17, "umol/l"), + mmolPl(18, "mmol/l"), + uiuPml(19, "uiu/mL"), + miuPml(20, "miu/mL"), + iuPml(21, "iu/mL"), + uuPml(22, "uu/mL"), + muPml(23, "mu/mL"), + uPml(24, "u/mL"), + muPl(25, "mu/l"), uPl(26, "U/L"), - kiuPl(27, "kIU/L"), - kuPl(28, "kU/L"), + kiuPl(27, "kiu/L"), + kuPl(28, "ku/L"), percent(29, "%"), mmolPmol(30, "mmol/mol"), milPul(31, "mil/uL"), @@ -40,10 +40,10 @@ public enum A8kResultUnit { mptPl(36, "mpt/L"), tptPl(37, "tpt/L"), gptPl(38, "gpt/L"), - pfuPml(39, "PFU/mL"), - cfuPml(40, "CFU/mL"), - sPco(41, "S/CO"), - coi(42, "COI"), + pfuPml(39, "pfu/mL"), + cfuPml(40, "cfu/mL"), + sPco(41, "s/co"), + coi(42, "coi"), index(43, ""), UNSUPPORT(-1, "UNSUPPORT"), ; diff --git a/src/main/java/a8k/app/type/appevent/AppDeviceInitSucEvent.java b/src/main/java/a8k/app/type/appevent/AppDeviceInitSucEvent.java new file mode 100644 index 0000000..532addb --- /dev/null +++ b/src/main/java/a8k/app/type/appevent/AppDeviceInitSucEvent.java @@ -0,0 +1,7 @@ +package a8k.app.type.appevent; + +public class AppDeviceInitSucEvent extends AppEvent { + public AppDeviceInitSucEvent() { + super(AppDeviceInitSucEvent.class.getSimpleName()); + } +} diff --git a/src/main/java/a8k/app/type/lis/LISSerialBaudrateType.java b/src/main/java/a8k/app/type/lis/LISSerialBaudrateType.java index 22bcaa6..91d1abe 100644 --- a/src/main/java/a8k/app/type/lis/LISSerialBaudrateType.java +++ b/src/main/java/a8k/app/type/lis/LISSerialBaudrateType.java @@ -1,8 +1,16 @@ package a8k.app.type.lis; public enum LISSerialBaudrateType { - B9600, - B115200, - B12800, - B19200; + B9600(9600), + B19200(19200), + B38400(38400), + B115200(115200), + B460800(460800), + ; + + final public Integer baudrate; + + LISSerialBaudrateType(Integer baudrate) { + this.baudrate = baudrate; + } } diff --git a/src/main/java/a8k/app/type/lisprotocol/BoditechLisSingleTrackFrame.java b/src/main/java/a8k/app/type/lisprotocol/BoditechLisSingleTrackFrame.java index 721dd72..63b6996 100644 --- a/src/main/java/a8k/app/type/lisprotocol/BoditechLisSingleTrackFrame.java +++ b/src/main/java/a8k/app/type/lisprotocol/BoditechLisSingleTrackFrame.java @@ -56,7 +56,7 @@ public class BoditechLisSingleTrackFrame { public String reserved4; // public String reserved5; // - public String toFrame() { + public String serialization() { StringBuffer strBuffer = new StringBuffer(); strBuffer.append(HEADER); Field[] fields = this.getClass().getDeclaredFields(); diff --git a/src/main/java/a8k/app/utils/ZSqlite.java b/src/main/java/a8k/app/utils/ZSqlite.java index 84d2131..1bb008e 100644 --- a/src/main/java/a8k/app/utils/ZSqlite.java +++ b/src/main/java/a8k/app/utils/ZSqlite.java @@ -115,13 +115,15 @@ public class ZSqlite { ZSqliteJdbcHelper.delete(jdbcTemplate, tableName, id); } - public void add(T obj) { + public T add(T obj) { if (obj == null) { - return; + return null; } ZSqliteJdbcHelper.addObj(jdbcTemplate, tableName, tClass, obj); + return queryOne("SELECT * FROM " + tableName + " ORDER BY id DESC LIMIT 1;"); // 获取最新插入的对象 } + public void addAll(List list) { for (var val : list) { add(val); diff --git a/src/main/java/a8k/app/utils/ZSqliteJdbcHelper.java b/src/main/java/a8k/app/utils/ZSqliteJdbcHelper.java index f1f8ea0..3db6206 100644 --- a/src/main/java/a8k/app/utils/ZSqliteJdbcHelper.java +++ b/src/main/java/a8k/app/utils/ZSqliteJdbcHelper.java @@ -9,7 +9,10 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.node.ObjectNode; import org.slf4j.Logger; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.PreparedStatementCreatorFactory; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import javax.lang.model.element.TypeElement; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; @@ -222,6 +225,7 @@ public class ZSqliteJdbcHelper { jdbcTemplate.update("delete from " + tableName + " where id = ?", id); } + public static void addObj(JdbcTemplate jdbcTemplate, String tableName, Class tClass, Object obj) { StringBuilder sql = new StringBuilder("insert into " + tableName + "("); StringBuilder values = new StringBuilder(" values("); @@ -257,6 +261,8 @@ public class ZSqliteJdbcHelper { args.add(idval); jdbcTemplate.update(sql.toString(), args.toArray()); + + } public static void updateObj(JdbcTemplate jdbcTemplate, String tableName, Class tClass, Object obj) { diff --git a/src/main/java/a8k/extui/mgr/ExtApiPageGroupCfgMgr.java b/src/main/java/a8k/extui/mgr/ExtApiPageGroupCfgMgr.java index 358aab3..57e33fb 100644 --- a/src/main/java/a8k/extui/mgr/ExtApiPageGroupCfgMgr.java +++ b/src/main/java/a8k/extui/mgr/ExtApiPageGroupCfgMgr.java @@ -1,6 +1,8 @@ package a8k.extui.mgr; import a8k.app.utils.ZList; +import a8k.extui.page.apptest.LisTestPage; +import a8k.extui.page.apptest.PrinterDebugPage; import a8k.extui.page.debug.*; import a8k.extui.page.driver.*; import a8k.extui.page.driver.pipette_module.*; @@ -160,7 +162,14 @@ public class ExtApiPageGroupCfgMgr { new Menu(WaterTempControllerTestPage.class, "控温系统测试"), new Menu(PipetteGunHardwareTestPage.class, "移液枪硬件测试"), new Menu(CodeScannerDriverCtrlPage.class, "扫码枪测试"), - new Menu(ICCardReaderTestPage.class, "ID卡测试") + new Menu(ICCardReaderTestPage.class, "ID卡测试"), + new Menu(LISUartTestPage.class, "LIS串口测试"), + new Menu(PrinterDebugPage.class, "打印机测试") + )), + + new Menu("APP测试", ZList.of( + new Menu(LisTestPage.class, "LIS测试"), + new Menu(PrinterDebugPage.class, "打印机测试") )), new Menu("光学标定与验证", ZList.of( diff --git a/src/main/java/a8k/extui/page/apptest/LisTestPage.java b/src/main/java/a8k/extui/page/apptest/LisTestPage.java new file mode 100644 index 0000000..5463bad --- /dev/null +++ b/src/main/java/a8k/extui/page/apptest/LisTestPage.java @@ -0,0 +1,50 @@ +package a8k.extui.page.apptest; + +import a8k.app.dao.type.db.ReactionRecord; +import a8k.app.factory.FakeReactionRecordFactory; +import a8k.app.service.data.ProjInfoMgrService; +import a8k.app.service.lis.LisCommunicationService; +import a8k.app.type.exception.AppException; +import a8k.extui.mgr.ExtApiPageMgr; +import a8k.extui.type.ExtApiStatu; +import a8k.extui.type.ExtUIPageCfg; +import jakarta.annotation.PostConstruct; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.stream.Stream; + +@Component +@Slf4j +@RequiredArgsConstructor +public class LisTestPage { + private final LisCommunicationService lisCommunicationService; + private final ProjInfoMgrService projInfoMgrService; + private final ExtApiPageMgr extApiPageMgr; + + + @ExtApiStatu(name = "", group = "LIS协议", order = 1) + public String getLisProtocol() { + return lisCommunicationService.getProtocolDetail(); + } + + @ExtApiStatu(name = "", group = "LIS连接状态", order = 2) + public Boolean getLisConnection() { + return lisCommunicationService.getConnectionState(); + } + + public void reportFakeData() throws AppException { + ReactionRecord record = FakeReactionRecordFactory.buildRecord(projInfoMgrService.getProjBuildInInfo(1)); + lisCommunicationService.reportReactionRecord(record); + } + + + + @PostConstruct + void init() { + ExtUIPageCfg page = new ExtUIPageCfg(this); + page.addFunction("上报记录", this::reportFakeData); + extApiPageMgr.addPage(page); + } +} diff --git a/src/main/java/a8k/extui/page/driver/PrinterDebugPage.java b/src/main/java/a8k/extui/page/apptest/PrinterDebugPage.java similarity index 98% rename from src/main/java/a8k/extui/page/driver/PrinterDebugPage.java rename to src/main/java/a8k/extui/page/apptest/PrinterDebugPage.java index bcb1107..d30b384 100644 --- a/src/main/java/a8k/extui/page/driver/PrinterDebugPage.java +++ b/src/main/java/a8k/extui/page/apptest/PrinterDebugPage.java @@ -1,4 +1,4 @@ -package a8k.extui.page.driver; +package a8k.extui.page.apptest; import a8k.OS; import a8k.app.channel.iflytophald.channel.PrinterUartChannel; diff --git a/src/main/java/a8k/extui/page/extapp/debug_assistant/FakeReactionRecordGeneratorPage.java b/src/main/java/a8k/extui/page/extapp/debug_assistant/FakeReactionRecordGeneratorPage.java index 8b111f3..82d1f9c 100644 --- a/src/main/java/a8k/extui/page/extapp/debug_assistant/FakeReactionRecordGeneratorPage.java +++ b/src/main/java/a8k/extui/page/extapp/debug_assistant/FakeReactionRecordGeneratorPage.java @@ -76,11 +76,11 @@ public class FakeReactionRecordGeneratorPage { if (!error) { for (int i = 0; i < projInfo.buildIn.getSubProjNum(); i++) { if (i == 0) - reactionResults.add(new ReactionRecord.ReactionResult("Tn-I", "Tn-I", A8kOptType.FOPT,1.0, resultBuilder0.toResultUnitConverters())); + reactionResults.add(new ReactionRecord.ReactionResult("Tn-I", "Tn-I", A8kOptType.FOPT,9999.99, resultBuilder0.toResultUnitConverters())); if (i == 1) - reactionResults.add(new ReactionRecord.ReactionResult("CK-MB", "CK-MB", A8kOptType.FOPT,2.0, resultBuilder1.toResultUnitConverters())); + reactionResults.add(new ReactionRecord.ReactionResult("CK-MB", "CK-MB", A8kOptType.FOPT,9999.99, resultBuilder1.toResultUnitConverters())); if (i == 2) - reactionResults.add(new ReactionRecord.ReactionResult("Myoglobin", "MG", A8kOptType.FOPT,3.0, resultBuilder2.toResultUnitConverters())); + reactionResults.add(new ReactionRecord.ReactionResult("Myoglobin", "MG", A8kOptType.FOPT,9999.99, resultBuilder2.toResultUnitConverters())); } } else { for (int i = 0; i < projInfo.buildIn.getSubProjNum(); i++) { diff --git a/src/main/java/a8k/extui/page/hardwaretest/LISUartTestPage.java b/src/main/java/a8k/extui/page/hardwaretest/LISUartTestPage.java new file mode 100644 index 0000000..f4e2b9d --- /dev/null +++ b/src/main/java/a8k/extui/page/hardwaretest/LISUartTestPage.java @@ -0,0 +1,49 @@ +package a8k.extui.page.hardwaretest; + +import a8k.app.channel.iflytophald.channel.LisUartChannel; +import a8k.app.type.lis.LISSerialBaudrateType; +import a8k.extui.mgr.ExtApiPageMgr; +import a8k.extui.type.ExtApiStatu; +import jakarta.annotation.PostConstruct; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class LISUartTestPage { + final private LisUartChannel lisUartChannel; + private final ExtApiPageMgr extApiPageMgr; + + @ExtApiStatu(name = "", group = "波特率", order = 1) + public Integer getBaudRate() { + return lisUartChannel.getBaudRateDirect(); + } + + @ExtApiStatu(name = "", group = "回环模式", order = 1) + public Boolean getLoopbackMode() { + return lisUartChannel.isInLoopbackMode(); + } + + public void setBaudRate(LISSerialBaudrateType baudRate) { + lisUartChannel.setBaudRate(baudRate.baudrate); + } + + + public void setInLoopbackMode(Boolean val) { + lisUartChannel.setInLoopbackMode(val); + } + + public void sendCommand(String msg) { + lisUartChannel.tx(msg); + } + + @PostConstruct + public void init() { + var page = extApiPageMgr.newPage(this); + page.addFunction("设置波特率", this::setBaudRate); + page.addFunction("设置环回模式", this::setInLoopbackMode); + page.addFunction("发送命令", this::sendCommand); + extApiPageMgr.addPage(page); + } + +} diff --git a/src/main/java/a8k/iflyutils/IftIpUtils.java b/src/main/java/a8k/iflyutils/IftIpUtils.java new file mode 100644 index 0000000..79cd2b7 --- /dev/null +++ b/src/main/java/a8k/iflyutils/IftIpUtils.java @@ -0,0 +1,57 @@ +package a8k.iflyutils; + +import a8k.iflyutils.netplan.exception.NetSettingIllegalException; + +public class IftIpUtils { + + /** + * 将IP地址和子网掩码转换为CIDR表示法 + * @param ipAddress IP地址 + * @param netmask 子网掩码 + * @return ipAddress/netmask的CIDR表示法 + *

+ * demo: + * String ip = IftIpUtils.toCIDR("192.168.8.1", "255.255.255.0"); + * ip == 192.168.8.1/24 + * + */ + public static String toCIDR(String ipAddress, String netmask) throws NetSettingIllegalException { + // 验证IP和子网掩码格式 + if (!isValidIp(ipAddress) || !isValidIp(netmask)) { + throw new NetSettingIllegalException("无效的IP地址或子网掩码格式"); + } + // 计算子网掩码对应的前缀长度 + int prefixLength = netmaskToPrefixLength(netmask); + return ipAddress + "/" + prefixLength; + } + + public static boolean isValidIp(String ip) { + return ip.matches("^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"); + } + + public static boolean isValidNetmask(String netmask) { + return netmask.matches("^((255|254|252|248|240|224|192|128|0)\\.){3}(255|254|252|248|240|224|192|128|0)$"); + } + + private static int netmaskToPrefixLength(String netmask) throws NetSettingIllegalException { + String[] octets = netmask.split("\\."); + int prefixLength = 0; + + for (String octet : octets) { + int value = Integer.parseInt(octet); + // 检查是否为有效的子网掩码值 + if (value != 0 && value != 128 && value != 192 && value != 224 && + value != 240 && value != 248 && value != 252 && value != 254 && value != 255) { + throw new NetSettingIllegalException("无效的子网掩码"); + } + // 计算前缀长度 + prefixLength += Integer.bitCount(value); + } + + return prefixLength; + } + + public static void main(String[] args) { + } + +} diff --git a/src/main/java/a8k/iflyutils/netplan/NetplanConfigFactory.java b/src/main/java/a8k/iflyutils/netplan/NetplanConfigFactory.java new file mode 100644 index 0000000..3265bb3 --- /dev/null +++ b/src/main/java/a8k/iflyutils/netplan/NetplanConfigFactory.java @@ -0,0 +1,122 @@ +package a8k.iflyutils.netplan; + +import a8k.iflyutils.IftIpUtils; +import a8k.iflyutils.netplan.exception.NetSettingIllegalException; +import a8k.iflyutils.netplan.type.EthernetConfig; +import a8k.iflyutils.netplan.type.NetplanConfig; +import a8k.iflyutils.netplan.type.RendererType; +import a8k.iflyutils.netplan.type.Route; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + + +public class NetplanConfigFactory { + /** + * + * 调试常用指令 + * 查看当前dns + * cat /run/systemd/resolve/resolv.conf + * 应用配置 + * netplan apply + * + * + */ + + RendererType renderer = RendererType.NetworkManager; + + + public String newDynamicEthernetConfig(String ethName, Boolean autoDns, List dnsList) throws NetSettingIllegalException, JsonProcessingException { + + var mapper = createMapper(); + Map top = new LinkedHashMap<>(); + + NetplanConfig config = new NetplanConfig(); + config.version = 2; + config.renderer = renderer; + config.ethernets = new LinkedHashMap<>(); + { + EthernetConfig ethConfig = new EthernetConfig(); + ethConfig.addresses = null; + ethConfig.routes = null; + if (autoDns || dnsList == null || dnsList.isEmpty()) { + ethConfig.nameservers = null; + // ethConfig.accept_ra = true; + } else { + // ethConfig.accept_ra = false; + ethConfig.nameservers.addresses.addAll(dnsList); + } + ethConfig.dhcp4 = "yes"; + config.ethernets.put(ethName, ethConfig); + } + + top.put("network", config); + return mapper.writeValueAsString(top); + } + + public String newStaticEthernetConfig(String ethName, + String ip, + String netmask, + String gateway, + List dnsList) throws NetSettingIllegalException, JsonProcessingException { + + var mapper = createMapper(); + Map top = new LinkedHashMap<>(); + + NetplanConfig config = new NetplanConfig(); + config.version = 2; + config.renderer = renderer; + config.ethernets = new LinkedHashMap<>(); + { + EthernetConfig ethConfig = new EthernetConfig(); + ethConfig.addresses.add(IftIpUtils.toCIDR(ip, netmask)); + ethConfig.nameservers.addresses.addAll(dnsList); + ethConfig.routes.add(new Route("0.0.0.0/0", gateway)); + ethConfig.dhcp4 = "no"; + config.ethernets.put(ethName, ethConfig); + } + + top.put("network", config); + return mapper.writeValueAsString(top); + } + + // + // PRIVATE + // + static private ObjectMapper createMapper() { + YAMLFactory yamlFactory = new YAMLFactory() + .enable(YAMLGenerator.Feature.MINIMIZE_QUOTES) + .enable(YAMLGenerator.Feature.LITERAL_BLOCK_STYLE) + .enable(YAMLGenerator.Feature.INDENT_ARRAYS_WITH_INDICATOR) + .disable(YAMLGenerator.Feature.INDENT_ARRAYS); + ObjectMapper mapper = new ObjectMapper(yamlFactory); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + return mapper; + } + + + public static void main(String[] args) throws NetSettingIllegalException, JsonProcessingException { + // 创建YAML映射工厂,配置输出选项 + // 写入YAML文件 + NetplanConfigFactory factory = new NetplanConfigFactory(); + var netplanConfig = factory.newStaticEthernetConfig( + "eth1", + "192.168.8.10", + "255.255.255.0", + "192.168.8.1", + List.of("192.168.8.1") + ); + System.out.println(netplanConfig); + System.out.println("==============================================================="); + var netDConfig = factory.newDynamicEthernetConfig("eth1", false, List.of("8.8.8.8")); + System.out.println(netDConfig); + + + } +} diff --git a/src/main/java/a8k/iflyutils/netplan/exception/NetSettingIllegalException.java b/src/main/java/a8k/iflyutils/netplan/exception/NetSettingIllegalException.java new file mode 100644 index 0000000..64b4fc7 --- /dev/null +++ b/src/main/java/a8k/iflyutils/netplan/exception/NetSettingIllegalException.java @@ -0,0 +1,7 @@ +package a8k.iflyutils.netplan.exception; + +public class NetSettingIllegalException extends Exception { + public NetSettingIllegalException(String message) { + super(message); + } +} diff --git a/src/main/java/a8k/iflyutils/netplan/type/EthernetConfig.java b/src/main/java/a8k/iflyutils/netplan/type/EthernetConfig.java new file mode 100644 index 0000000..c82cc01 --- /dev/null +++ b/src/main/java/a8k/iflyutils/netplan/type/EthernetConfig.java @@ -0,0 +1,15 @@ +package a8k.iflyutils.netplan.type; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.ArrayList; +import java.util.List; + +public class EthernetConfig { + public List addresses = new ArrayList<>(); + public Nameservers nameservers = new Nameservers(); + public List routes = new ArrayList<>(); + public String dhcp4 = "no"; +// @JsonProperty("accept-ra") +// public Boolean accept_ra = true; +} diff --git a/src/main/java/a8k/iflyutils/netplan/type/Nameservers.java b/src/main/java/a8k/iflyutils/netplan/type/Nameservers.java new file mode 100644 index 0000000..d063a08 --- /dev/null +++ b/src/main/java/a8k/iflyutils/netplan/type/Nameservers.java @@ -0,0 +1,8 @@ +package a8k.iflyutils.netplan.type; + +import java.util.ArrayList; +import java.util.List; + +public class Nameservers { + public List addresses = new ArrayList<>(); +} diff --git a/src/main/java/a8k/iflyutils/netplan/type/NetplanConfig.java b/src/main/java/a8k/iflyutils/netplan/type/NetplanConfig.java new file mode 100644 index 0000000..702b9be --- /dev/null +++ b/src/main/java/a8k/iflyutils/netplan/type/NetplanConfig.java @@ -0,0 +1,10 @@ +package a8k.iflyutils.netplan.type; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class NetplanConfig { + public int version = 2; + public RendererType renderer = RendererType.NetworkManager; + public Map ethernets = new LinkedHashMap<>(); +} diff --git a/src/main/java/a8k/iflyutils/netplan/type/RendererType.java b/src/main/java/a8k/iflyutils/netplan/type/RendererType.java new file mode 100644 index 0000000..07283dc --- /dev/null +++ b/src/main/java/a8k/iflyutils/netplan/type/RendererType.java @@ -0,0 +1,6 @@ +package a8k.iflyutils.netplan.type; + +public enum RendererType { + networkd, + NetworkManager; +} diff --git a/src/main/java/a8k/iflyutils/netplan/type/Route.java b/src/main/java/a8k/iflyutils/netplan/type/Route.java new file mode 100644 index 0000000..fb851be --- /dev/null +++ b/src/main/java/a8k/iflyutils/netplan/type/Route.java @@ -0,0 +1,12 @@ +package a8k.iflyutils.netplan.type; + +public class Route { + public String to; + public String via; + public Integer metric = null; + + public Route(String to, String via) { + this.to = to; + this.via = via; + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 709c708..e5cd703 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,17 +1,27 @@ -#server.port: 8082 +#WEB虚拟后端 +#server.port: 80 #iflytophald.ip: 127.0.0.1 +#iflytophald.enable: false #device.runmode: "VirtualStateGenerateMode" -#device.enableCanBus: false +#PC调试 server.port: 80 device.runmode: "RealMode" iflytophald.ip: 192.168.8.10 -device.enableCanBus: true +iflytophald.enable: true + +#硬件测试 +#server.port: 8082 +#iflytophald.ip: 192.168.8.10 +#device.runmode: "RealMode" +#iflytophald.enable: true #server.port: 80 #device.runmode: "RealMode" #iflytophald.ip: 127.0.0.1 +#iflytophald.enable: true + a8k.enableTemperatureCtrl: false