diff --git a/src/main/java/a8k/BoditechA800Application.java b/src/main/java/a8k/BoditechA800Application.java index cd33002..aea0cc4 100644 --- a/src/main/java/a8k/BoditechA800Application.java +++ b/src/main/java/a8k/BoditechA800Application.java @@ -10,6 +10,9 @@ import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.core.env.Environment; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + @Slf4j @SpringBootApplication public class BoditechA800Application implements ApplicationListener { @@ -19,8 +22,6 @@ public class BoditechA800Application implements ApplicationListener inetAddresses = networkInterface.getInetAddresses(); + while (inetAddresses.hasMoreElements()) { + InetAddress inetAddress = inetAddresses.nextElement(); + if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) { + return inetAddress.getHostAddress(); + } + } + log.warn("网卡 {} 没有找到有效的IPv4地址", getEthName()); + return ""; + } + + public static void main(String[] args) { + System.out.println("LOCAL IP: " + OS.getLocalIp()); + } + } diff --git a/src/main/java/a8k/app/channel/iflytophald/type/protocol/A8kEcode.java b/src/main/java/a8k/app/channel/iflytophald/type/protocol/A8kEcode.java index cb2aa08..d6414d7 100644 --- a/src/main/java/a8k/app/channel/iflytophald/type/protocol/A8kEcode.java +++ b/src/main/java/a8k/app/channel/iflytophald/type/protocol/A8kEcode.java @@ -32,6 +32,9 @@ public enum A8kEcode { APPE_PAUSE_OPERATION_NOT_SUPPORT_IN_ENGINEER_TASK(20), // APPE_CONTINUE_OPERATION_NOT_SUPPORT_IN_ENGINEER_TASK(21), // APPE_WAST_BIN_IS_FULL(22), //废料箱已满 + SYS_CMD_EXEC_OVERTIME(23), //Linux命令执行超时 + NETWORK_PARAMETER_ERROR(24), //网络参数错误 + // // 参数错误 diff --git a/src/main/java/a8k/app/controler/api/v1/app/setting/DeviceInfoControler.java b/src/main/java/a8k/app/controler/api/v1/app/setting/DeviceInfoControler.java index 5b7ff58..2d68728 100644 --- a/src/main/java/a8k/app/controler/api/v1/app/setting/DeviceInfoControler.java +++ b/src/main/java/a8k/app/controler/api/v1/app/setting/DeviceInfoControler.java @@ -37,7 +37,7 @@ public class DeviceInfoControler { info.mcuVersion = gstate.getMcuVersion(); info.sn = gstate.getSn(); info.factorySN = gstate.getFactorySn(); - info.ip = "192.168.8.10"; + info.ip = gstate.getLocalIp(); return ApiRet.success(info); } @@ -57,7 +57,7 @@ public class DeviceInfoControler { @PostMapping("/getIp") public ApiRet readdeviceip() { //TODO: - return ApiRet.success("192.168.8.10"); + return ApiRet.success(gstate.getLocalIp()); } } diff --git a/src/main/java/a8k/app/controler/api/v1/app/setting/DeviceSettingController.java b/src/main/java/a8k/app/controler/api/v1/app/setting/DeviceSettingController.java index 98eb401..adacbc4 100644 --- a/src/main/java/a8k/app/controler/api/v1/app/setting/DeviceSettingController.java +++ b/src/main/java/a8k/app/controler/api/v1/app/setting/DeviceSettingController.java @@ -1,6 +1,6 @@ package a8k.app.controler.api.v1.app.setting; -import a8k.app.service.os.OSSettingService; +import a8k.app.service.os.OSTimeMgrService; import a8k.app.type.exception.AppException; import a8k.app.type.ui.ApiRet; import a8k.app.dao.type.db.DeviceSetting; @@ -26,7 +26,7 @@ import java.util.List; @RequiredArgsConstructor public class DeviceSettingController { private final AppSettingsMgrService appSettingsMgrService; - private final OSSettingService osSettingService; + private final OSTimeMgrService osTimeMgrService; // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // EXT FUNC @@ -119,7 +119,7 @@ public class DeviceSettingController { @Operation(summary = "设置时间") @PostMapping("/setDateAndTime") public void setDateAndTime(String datetime) { - osSettingService.setDateAndTime(datetime); + osTimeMgrService.setDateAndTime(datetime); } } diff --git a/src/main/java/a8k/app/controler/api/v1/app/setting/NetworkSettingController.java b/src/main/java/a8k/app/controler/api/v1/app/setting/NetworkSettingController.java index 7339328..8f787c5 100644 --- a/src/main/java/a8k/app/controler/api/v1/app/setting/NetworkSettingController.java +++ b/src/main/java/a8k/app/controler/api/v1/app/setting/NetworkSettingController.java @@ -1,7 +1,8 @@ package a8k.app.controler.api.v1.app.setting; import a8k.app.dao.type.db.NetworkSetting; -import a8k.app.service.setting.AppNetworkSettingService; +import a8k.app.service.os.OSNetworkMgrService; +import a8k.app.type.exception.AppException; import a8k.app.type.ui.ApiRet; import a8k.app.utils.ZJsonHelper; import io.swagger.v3.oas.annotations.Operation; @@ -22,7 +23,7 @@ import org.springframework.web.bind.annotation.ResponseBody; @ResponseBody public class NetworkSettingController { @Resource - AppNetworkSettingService appNetworkService; + OSNetworkMgrService appNetworkService; // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // EXT FUNC // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -36,7 +37,7 @@ public class NetworkSettingController { @Operation(summary = "设置系统设置") @PostMapping("/setNetworkSetting") - public ApiRet setNetworkSetting(@RequestBody NetworkSetting setting) { + public ApiRet setNetworkSetting(@RequestBody NetworkSetting setting) throws AppException { log.info("设置LIS配置 {}", ZJsonHelper.objToPrettyJson(setting)); appNetworkService.setNetworkSetting(setting); return ApiRet.success(); 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 a024683..8cc4395 100644 --- a/src/main/java/a8k/app/dao/type/db/NetworkSetting.java +++ b/src/main/java/a8k/app/dao/type/db/NetworkSetting.java @@ -15,7 +15,7 @@ public class NetworkSetting implements Serializable { public String ip = "192.168.8.10"; public String netmask = "255.255.255.0"; public String gateway = "192.168.8.1"; - public List dnsList = ZList.of("223.5.5.5", "223.6.6.6"); + public List dnsList = ZList.of("192.168.8.1"); } static public class DynamicIpConfig { @@ -23,6 +23,7 @@ public class NetworkSetting implements Serializable { public List dnsList = ZList.of("223.5.5.5", "223.6.6.6"); } + public Boolean firstRun = true; // 是否第一次运行,第一次运行需要初始化网络配置 public NetworkMode networkMode = NetworkMode.STATIC_IP; public StaticIPConfig staticIPConfig = new StaticIPConfig(); public DynamicIpConfig dynamicIpConfig = new DynamicIpConfig(); diff --git a/src/main/java/a8k/app/i18n/Internationalization.java b/src/main/java/a8k/app/i18n/Internationalization.java index 99da145..b89cd05 100644 --- a/src/main/java/a8k/app/i18n/Internationalization.java +++ b/src/main/java/a8k/app/i18n/Internationalization.java @@ -81,6 +81,8 @@ public class Internationalization { case APPE_PAUSE_OPERATION_NOT_SUPPORT_IN_ENGINEER_TASK -> "工程师任务,不支持暂停操作"; case APPE_CONTINUE_OPERATION_NOT_SUPPORT_IN_ENGINEER_TASK -> "工程师任务,不支持继续操作"; case APPE_WAST_BIN_IS_FULL -> "废料箱已满"; + case SYS_CMD_EXEC_OVERTIME -> "系统指令超时"; + case NETWORK_PARAMETER_ERROR -> "网络参数错误"; default -> ecode.toString(); }; } diff --git a/src/main/java/a8k/app/service/os/OSNetworkMgrService.java b/src/main/java/a8k/app/service/os/OSNetworkMgrService.java new file mode 100644 index 0000000..e532138 --- /dev/null +++ b/src/main/java/a8k/app/service/os/OSNetworkMgrService.java @@ -0,0 +1,103 @@ +package a8k.app.service.os; + +import a8k.OS; +import a8k.app.channel.iflytophald.type.protocol.A8kEcode; +import a8k.app.dao.NetworkSettingDao; +import a8k.app.dao.type.db.NetworkSetting; +import a8k.app.service.statemgr.GStateMgrService; +import a8k.app.type.exception.AppException; +import a8k.iflyutils.netplan.NetplanConfigFactory; +import a8k.iflyutils.netplan.exception.NetSettingIllegalException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.io.FileWriter; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +@Component +@Slf4j +@RequiredArgsConstructor +@EnableScheduling +public class OSNetworkMgrService implements ApplicationListener { + private final NetworkSettingDao networkSettingDao; + private final GStateMgrService gStateMgrService; + + public NetworkSetting getNetworkSetting() { + return networkSettingDao.get(); + } + + + public void setNetworkSetting(NetworkSetting setting) throws AppException { + try { + doSetNetworkSetting(setting); + } catch (NetSettingIllegalException e) { + throw AppException.of(A8kEcode.NETWORK_PARAMETER_ERROR, e.getMessage()); + } catch (IOException e) { + throw AppException.of(A8kEcode.CODEERROR, e.getMessage()); + } + networkSettingDao.update(setting); + log.info("Network configuration updated: {}", setting); + } + + public void doSetNetworkSetting(NetworkSetting setting) throws NetSettingIllegalException, IOException, AppException { + if (OS.isRunOnWindows()) { + return; + } + NetplanConfigFactory netplanConfigFactory = new NetplanConfigFactory(); + String netplanConfigContent = ""; + switch (setting.networkMode) { + case STATIC_IP -> netplanConfigContent = netplanConfigFactory.newStaticEthernetConfig( + OS.getEthName(), + setting.staticIPConfig.ip, + setting.staticIPConfig.netmask, + setting.staticIPConfig.gateway, + setting.staticIPConfig.dnsList); + + case DYNAMIC_IP -> netplanConfigContent = netplanConfigFactory.newDynamicEthernetConfig( + OS.getEthName(), setting.dynamicIpConfig.autoDns, setting.dynamicIpConfig.dnsList); + } + + //参考规范 https://iflytop1.feishu.cn/wiki/I2v5whcqEitWeRkFZtKcuC08nxe + try (FileWriter writer = new FileWriter("/etc/netplan/00_netplan_config.yaml")) { + //向/etc/netplan/00_netplan_config.yaml写入配置文件 + writer.write(netplanConfigContent); + } + + try { + OS.executeLinuxCommand("netplan apply", 5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + throw new AppException(A8kEcode.SYS_CMD_EXEC_OVERTIME); + } + log.info("Network configuration applied successfully: {}", setting); + } + + @Scheduled(fixedDelay = 1000) + void updateLocalIp() { + gStateMgrService.updateLocalIp(OS.getLocalIp()); + } + + /** + * 在应用启动时设置网络配置 + */ + @Override public void onApplicationEvent(ContextRefreshedEvent event) { + if (OS.isRunOnWindows()) { + return; + } + + NetworkSetting setting = networkSettingDao.get(); + try { + doSetNetworkSetting(setting); + setting.firstRun = false; + networkSettingDao.update(setting); + log.info("Network setting applied on startup: {}", setting); + } catch (Exception e) { + log.error("setting network failed: {}", e.getMessage()); + } + } +} diff --git a/src/main/java/a8k/app/service/os/OSSettingService.java b/src/main/java/a8k/app/service/os/OSTimeMgrService.java similarity index 98% rename from src/main/java/a8k/app/service/os/OSSettingService.java rename to src/main/java/a8k/app/service/os/OSTimeMgrService.java index 8d49cdc..4dbbbd0 100644 --- a/src/main/java/a8k/app/service/os/OSSettingService.java +++ b/src/main/java/a8k/app/service/os/OSTimeMgrService.java @@ -10,7 +10,7 @@ import java.io.InputStreamReader; @Component @Slf4j @RequiredArgsConstructor -public class OSSettingService { +public class OSTimeMgrService { /** * Set the system date and time. diff --git a/src/main/java/a8k/app/service/setting/AppNetworkSettingService.java b/src/main/java/a8k/app/service/setting/AppNetworkSettingService.java deleted file mode 100644 index 686ace0..0000000 --- a/src/main/java/a8k/app/service/setting/AppNetworkSettingService.java +++ /dev/null @@ -1,33 +0,0 @@ -package a8k.app.service.setting; - -import a8k.app.dao.NetworkSettingDao; -import a8k.app.dao.type.db.NetworkSetting; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - -@Component -@Slf4j -@RequiredArgsConstructor -public class AppNetworkSettingService { - - private final NetworkSettingDao networkSettingDao; - - public NetworkSetting getNetworkSetting() { - return networkSettingDao.get(); - } - - public void setNetworkSetting(NetworkSetting setting) { - networkSettingDao.update(setting); - log.info("Network configuration updated: {}", setting); - } - - - - - - - - - -} diff --git a/src/main/java/a8k/app/service/statemgr/GStateMgrService.java b/src/main/java/a8k/app/service/statemgr/GStateMgrService.java index c6b416b..52e7a7e 100644 --- a/src/main/java/a8k/app/service/statemgr/GStateMgrService.java +++ b/src/main/java/a8k/app/service/statemgr/GStateMgrService.java @@ -132,6 +132,15 @@ public class GStateMgrService { this.gState.fatalErrorInfo = null; } + synchronized public void updateLocalIp(String localIp) { + this.gState.localIP = localIp; + } + + synchronized public String getLocalIp() { + return this.gState.localIP; + } + + @PostConstruct public void init() { log.info("GStateMgrService init {}", this.gState.deviceRunMode); diff --git a/src/main/java/a8k/app/type/GState.java b/src/main/java/a8k/app/type/GState.java index 620fbd6..3459506 100644 --- a/src/main/java/a8k/app/type/GState.java +++ b/src/main/java/a8k/app/type/GState.java @@ -30,6 +30,8 @@ public class GState { public Boolean fatalError = false; // public AppError fatalErrorInfo = null; + // + public String localIP = "";//设备IP public SensorState sensorState = new SensorState(); } diff --git a/src/main/java/a8k/iflyutils/netplan/NetplanConfigFactory.java b/src/main/java/a8k/iflyutils/netplan/NetplanConfigFactory.java index 3265bb3..f6fd1cd 100644 --- a/src/main/java/a8k/iflyutils/netplan/NetplanConfigFactory.java +++ b/src/main/java/a8k/iflyutils/netplan/NetplanConfigFactory.java @@ -25,8 +25,8 @@ public class NetplanConfigFactory { * cat /run/systemd/resolve/resolv.conf * 应用配置 * netplan apply - * - * + * 配置说明参考: + * https://wiki.t-firefly.com/zh_CN/Firefly-Linux-Guide/first_use.html#shi-yong-netplan-guan-li-wang-luo */ RendererType renderer = RendererType.NetworkManager;