Browse Source

update

master
zhaohe 1 month ago
parent
commit
94f3a83417
  1. 8
      pom.xml
  2. 7
      src/main/java/a8k/BoditechA800Application.java
  3. 7
      src/main/java/a8k/OS.java
  4. 10
      src/main/java/a8k/app/channel/iflytophald/channel/A8kCanBusConnection.java
  5. 7
      src/main/java/a8k/app/channel/iflytophald/channel/A8kCanBusService.java
  6. 69
      src/main/java/a8k/app/channel/iflytophald/channel/LisUartChannel.java
  7. 7
      src/main/java/a8k/app/channel/iflytophald/channel/PrinterUartChannel.java
  8. 7
      src/main/java/a8k/app/channel/net/BoditechLisSingleTrackTcpClient.java
  9. 1
      src/main/java/a8k/app/constant/AppConstant.java
  10. 5
      src/main/java/a8k/app/constant/AppVersion.java
  11. 5
      src/main/java/a8k/app/controler/api/v1/app/setting/LISSettingController.java
  12. 52
      src/main/java/a8k/app/dao/ProjOptInfoDao.java
  13. 4
      src/main/java/a8k/app/dao/ProjectBaseInfoDao.java
  14. 4
      src/main/java/a8k/app/dao/type/db/NetworkSetting.java
  15. 2
      src/main/java/a8k/app/factory/BoditechLisSingleTrackFrameFactory.java
  16. 2
      src/main/java/a8k/app/service/background/AppEventBusService.java
  17. 14
      src/main/java/a8k/app/service/background/LisCommunicationService.java
  18. 2
      src/main/java/a8k/app/service/background/ProjIDCardCtrlAndMonitorService.java
  19. 2
      src/main/java/a8k/app/service/data/ReactionRecordMgrService.java
  20. 109
      src/main/java/a8k/app/service/lis/BoditechLisSingleTrackChannel.java
  21. 119
      src/main/java/a8k/app/service/lis/LisCommunicationService.java
  22. 7
      src/main/java/a8k/app/service/mainctrl/AppDeviceInitCtrlService.java
  23. 3
      src/main/java/a8k/app/service/module/OptScanCtrlModule.java
  24. 9
      src/main/java/a8k/app/service/setting/AppNetworkSettingService.java
  25. 3
      src/main/java/a8k/app/type/GState.java
  26. 34
      src/main/java/a8k/app/type/a8k/proj/A8kResultUnit.java
  27. 7
      src/main/java/a8k/app/type/appevent/AppDeviceInitSucEvent.java
  28. 16
      src/main/java/a8k/app/type/lis/LISSerialBaudrateType.java
  29. 2
      src/main/java/a8k/app/type/lisprotocol/BoditechLisSingleTrackFrame.java
  30. 6
      src/main/java/a8k/app/utils/ZSqlite.java
  31. 6
      src/main/java/a8k/app/utils/ZSqliteJdbcHelper.java
  32. 11
      src/main/java/a8k/extui/mgr/ExtApiPageGroupCfgMgr.java
  33. 50
      src/main/java/a8k/extui/page/apptest/LisTestPage.java
  34. 2
      src/main/java/a8k/extui/page/apptest/PrinterDebugPage.java
  35. 6
      src/main/java/a8k/extui/page/extapp/debug_assistant/FakeReactionRecordGeneratorPage.java
  36. 49
      src/main/java/a8k/extui/page/hardwaretest/LISUartTestPage.java
  37. 57
      src/main/java/a8k/iflyutils/IftIpUtils.java
  38. 122
      src/main/java/a8k/iflyutils/netplan/NetplanConfigFactory.java
  39. 7
      src/main/java/a8k/iflyutils/netplan/exception/NetSettingIllegalException.java
  40. 15
      src/main/java/a8k/iflyutils/netplan/type/EthernetConfig.java
  41. 8
      src/main/java/a8k/iflyutils/netplan/type/Nameservers.java
  42. 10
      src/main/java/a8k/iflyutils/netplan/type/NetplanConfig.java
  43. 6
      src/main/java/a8k/iflyutils/netplan/type/RendererType.java
  44. 12
      src/main/java/a8k/iflyutils/netplan/type/Route.java
  45. 16
      src/main/resources/application.yml

8
pom.xml

@ -121,6 +121,14 @@
<version>4.1.94.Final</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>2.12.4</version>
</dependency>
</dependencies>
<build>

7
src/main/java/a8k/BoditechA800Application.java

@ -25,15 +25,16 @@ public class BoditechA800Application implements ApplicationListener<ContextRefre
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
DeviceRunMode runmode = env.getProperty("device.runmode", DeviceRunMode.class);
if (!runmode.equals(DeviceRunMode.RealMode)) {
log.info("Springboot加载完成");
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("windows")) {
if (null == event.getApplicationContext().getParent()) {
log.info("Springboot加载完成");
try {
Runtime.getRuntime().exec(String.format("cmd /c start http://127.0.0.1:%s/exui/index.html", env.getProperty("server.port")));
} catch (Exception ignored) {
}
}
}
}
}

7
src/main/java/a8k/OS.java

@ -15,10 +15,15 @@ public class OS {
}
}
public static void threadSleep(Integer mills) {
public static void threadSleep(Integer mills) {
try {
Thread.sleep(mills);
} catch (InterruptedException ignored) {
}
}
public static boolean isRunOnWindows() {
String os = System.getProperty("os.name").toLowerCase();
return os.contains("windows");
}
}

10
src/main/java/a8k/app/channel/iflytophald/channel/A8kCanBusConnection.java

@ -39,14 +39,14 @@ public class A8kCanBusConnection extends WebSocketClient {
String cmdchurl = null;
Boolean firstCall = true;
@Value("${device.enableCanBus}")
Boolean enableCanBus;
@Value("${iflytophald.enable}")
Boolean iflytophaldEnable;
static class ProcessContext {
BlockingQueue<A8kPacket> receiptQueue = new LinkedBlockingQueue<>(); //
A8kPacket cmdPacket;
Map<MId, CmdId> txcmdcache = new HashMap<>();
A8kPacket cmdPacket;
Map<MId, CmdId> 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()) {

7
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");

69
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 {

7
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 {

7
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) {

1
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;
}

5
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";
}

5
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<Void> setAppSettings(@RequestBody LISSetting setting) {
log.info("设置LIS配置 {}", ZJsonHelper.objToPrettyJson(setting));
appSettingsMgrService.setLISSetting(setting);
lisCommunicationService.updateLisSetting(setting);
return ApiRet.success();
}

52
src/main/java/a8k/app/dao/ProjOptInfoDao.java

@ -34,33 +34,33 @@ public class ProjOptInfoDao extends ZSqlite<OptCfg> {
}
}
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);
// }
// }
//
// }
}

4
src/main/java/a8k/app/dao/ProjectBaseInfoDao.java

@ -27,9 +27,9 @@ public class ProjectBaseInfoDao extends ZSqlite<ProjectBaseInfo> {
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);
}

4
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<String> 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();
}

2
src/main/java/a8k/app/factory/BoditechLisSingleTrackFrameFactory.java

@ -91,7 +91,7 @@ public class BoditechLisSingleTrackFrameFactory {
FakeProjBuildInInfoFactory.buildFakeProjBuildInInfo());
List<BoditechLisSingleTrackFrame> frames = BoditechLisSingleTrackFrameFactory.buildBoditechLisSingleTrackFrame(record);
for (BoditechLisSingleTrackFrame frame : frames) {
System.out.println(frame.toFrame());
System.out.println(frame.serialization());
}
}

2
src/main/java/a8k/app/service/background/AppEventBusService.java

@ -43,7 +43,7 @@ public class AppEventBusService implements ApplicationListener<ContextRefreshedE
public void pushEvent(AppEvent event) {
logger.info("pushEvent: {} {}", event.getClass().getSimpleName(), event);
logger.info("pushEvent: {}", event.getClass().getSimpleName());
eventQueue.add(event);
}

14
src/main/java/a8k/app/service/background/LisCommunicationService.java

@ -1,14 +0,0 @@
package a8k.app.service.background;
import a8k.app.channel.iflytophald.channel.LisUartChannel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
@Slf4j
public class LisCommunicationService {
private final LisUartChannel lisUartChannel;
}

2
src/main/java/a8k/app/service/background/ProjIDCardCtrlAndMonitorService.java

@ -89,7 +89,7 @@ public class ProjIDCardCtrlAndMonitorService {
eventBus.pushEvent(new AppIDCardUnmountEvent());
log.info("拔出ID卡");
}
} else if (event instanceof A8kCanBusOnConnectEvent canPacket) {
} else if (event instanceof AppDeviceInitSucEvent appDeviceInitializeSuc) {
if (idCardStatus()) {
log.info("ID卡读卡器在线");
workQueue.addTask(this::readIDCard);

2
src/main/java/a8k/app/service/data/ReactionRecordMgrService.java

@ -70,8 +70,8 @@ public class ReactionRecordMgrService {
record.results = reactionResults;
record.detailOptData = optScanResults;
record = reactionReportDao.add(record);
logger.info("addRecord: {}", ZJsonHelper.objectToJson(record));
reactionReportDao.add(record);
appEventBusService.pushEvent(new AppNewReactionRecordEvent(record));
}

109
src/main/java/a8k/app/service/lis/BoditechLisSingleTrackChannel.java

@ -0,0 +1,109 @@
package a8k.app.service.lis;
import a8k.app.channel.iflytophald.channel.LisUartChannel;
import a8k.app.channel.net.BoditechLisSingleTrackTcpClient;
import a8k.app.dao.type.db.ReactionRecord;
import a8k.app.factory.BoditechLisSingleTrackFrameFactory;
import a8k.app.type.lisprotocol.BoditechLisSingleTrackFrame;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
public class BoditechLisSingleTrackChannel {
private static final Logger log = LoggerFactory.getLogger(BoditechLisSingleTrackChannel.class);
enum ChannelType {
UART,
TCP,
}
BoditechLisSingleTrackTcpClient boditechLisSingleTrackTcpClient;
LisUartChannel lisUartChannel;
ChannelType channelType;
String hostip;
Integer port;
public BoditechLisSingleTrackChannel(String hostip, Integer port) {
boditechLisSingleTrackTcpClient = new BoditechLisSingleTrackTcpClient();
this.hostip = hostip;
this.port = port;
channelType = ChannelType.TCP;
}
public BoditechLisSingleTrackChannel(LisUartChannel lisUartChannel) {
this.lisUartChannel = lisUartChannel;
channelType = ChannelType.UART;
}
public void start() {
switch (channelType) {
case TCP -> {
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<BoditechLisSingleTrackFrame> 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);
}
}
}
}
}

119
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");
}
}

7
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;
}

3
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<ReactionRecord.ReactionResult> reactionResults = FakeReactionRecordFactory.buildReactionResult(projInfo);
List<OptScanResult> optScanResults = new ArrayList<>();
reactionRecordMgrService.addRecord(sampleInfo, projInfo, optScanResults, reactionResults);
// lisCommunicationService.reportReactionRecord();
}

9
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);
}
}

3
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

34
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"),
;

7
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());
}
}

16
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;
}
}

2
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();

6
src/main/java/a8k/app/utils/ZSqlite.java

@ -115,13 +115,15 @@ public class ZSqlite<T> {
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<T> list) {
for (var val : list) {
add(val);

6
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) {

11
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(

50
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);
}
}

2
src/main/java/a8k/extui/page/driver/PrinterDebugPage.java → 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;

6
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++) {

49
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);
}
}

57
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表示法
* <p>
* 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) {
}
}

122
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<String> dnsList) throws NetSettingIllegalException, JsonProcessingException {
var mapper = createMapper();
Map<String, Object> 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<String> dnsList) throws NetSettingIllegalException, JsonProcessingException {
var mapper = createMapper();
Map<String, Object> 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);
}
}

7
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);
}
}

15
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<String> addresses = new ArrayList<>();
public Nameservers nameservers = new Nameservers();
public List<Route> routes = new ArrayList<>();
public String dhcp4 = "no";
// @JsonProperty("accept-ra")
// public Boolean accept_ra = true;
}

8
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<String> addresses = new ArrayList<>();
}

10
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<String, EthernetConfig> ethernets = new LinkedHashMap<>();
}

6
src/main/java/a8k/iflyutils/netplan/type/RendererType.java

@ -0,0 +1,6 @@
package a8k.iflyutils.netplan.type;
public enum RendererType {
networkd,
NetworkManager;
}

12
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;
}
}

16
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

Loading…
Cancel
Save