From 078fa4871015314defcafb97dcdd7bc2c8b27625 Mon Sep 17 00:00:00 2001 From: "USER-20220102CG\\noblelift" <546428999@qq.com> Date: Fri, 20 May 2022 15:20:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../acs/agv/server/impl/AgvServiceImpl.java | 26 +- .../device/device_driver/DriverTypeEnum.java | 66 ++- .../nl/acs/device/rest/DeviceController.java | 9 + .../impl/DeviceAssignedServiceImpl.java | 39 +- .../java/org/nl/acs/device/wql/task_inst.xls | Bin 154624 -> 156160 bytes .../lnsh_fold_disc_site/ItemProtocol.java | 123 ++++ .../LnshFoldDiscSiteDefination.java | 75 +++ .../LnshFoldDiscSiteDeviceDriver.java | 336 +++++++++++ .../lnsh/lnsh_kiln_lane/ItemProtocol.java | 123 ++++ .../LnshKilnLaneDefination.java | 76 +++ .../LnshKilnLaneDeviceDriver.java | 334 +++++++++++ .../lnsh/lnsh_kiln_truss/ItemProtocol.java | 141 +++++ .../LnshKilnTrussDefination.java | 78 +++ .../LnshKilnTrussDeviceDriver.java | 347 +++++++++++ .../lnsh_labeling_machine/ItemProtocol.java | 117 ++++ .../LnshLabelingMachineDefination.java | 75 +++ .../LnshLabelingMachineDeviceDriver.java | 348 +++++++++++ .../lnsh/lnsh_mixing_mill/ItemProtocol.java | 151 +++++ .../LnshMixingMillDefination.java | 80 +++ .../LnshMixingMillDeviceDriver.java | 325 +++++++++++ .../lnsh_out_kiln_truss/ItemProtocol.java | 129 +++++ .../LnshOutKilnTrussDefination.java | 76 +++ .../LnshOutKilnTrussDeviceDriver.java | 346 +++++++++++ .../lnsh/lnsh_package_line/ItemProtocol.java | 129 +++++ .../LnshPackageLineDefination.java | 74 +++ .../LnshPackageLineDeviceDriver.java | 346 +++++++++++ .../ItemProtocol.java | 179 ++++++ ...nshPackagePalletManipulatorDefination.java | 81 +++ ...hPackagePalletManipulatorDeviceDriver.java | 267 +++++++++ .../lnsh_pallet_storage/ItemProtocol.java | 129 +++++ .../LnshPalletStorageDefination.java | 76 +++ .../LnshPalletStorageDeviceDriver.java | 346 +++++++++++ .../ItemProtocol.java | 162 ++++++ .../LnshPalletizingManipulatorDefination.java | 81 +++ ...nshPalletizingManipulatorDeviceDriver.java | 313 ++++++++++ .../lnsh/lnsh_press/ItemProtocol.java | 167 ++++++ .../lnsh/lnsh_press/LnshPressDefination.java | 82 +++ .../lnsh_press/LnshPressDeviceDriver.java | 313 ++++++++++ .../lnsh/lnsh_rgv/ItemProtocol.java | 178 ++++++ .../lnsh/lnsh_rgv/LnshRGVDefination.java | 83 +++ .../lnsh/lnsh_rgv/LnshRGVDeviceDriver.java | 305 ++++++++++ .../lnsh_split_manipulator/ItemProtocol.java | 143 +++++ .../LnshSplitManipulatorDefination.java | 79 +++ .../LnshSplitManipulatorDeviceDriver.java | 305 ++++++++++ .../lnsh/lnsh_station/ItemProtocol.java | 131 +++++ .../lnsh_station/LnshStationDefination.java | 78 +++ .../lnsh_station/LnshStationDeviceDriver.java | 538 ++++++++++++++++++ ...eyorControlWithPlcScannerDeviceDriver.java | 12 +- ...CoveyorControlWithScannerDeviceDriver.java | 12 +- .../wms/service/impl/WmsToAcsServiceImpl.java | 11 +- .../rest/InstructionController.java | 9 + .../service/InstructionService.java | 5 + .../org/nl/acs/log/rest/LogsController.java | 6 +- .../org/nl/acs/log/service/LogServer.java | 22 +- .../acs/log/service/impl/LogServerImpl.java | 61 +- .../order/rest/CustomerbaseController.java | 75 +++ .../order/rest/MaterialbaseController.java | 76 +++ .../rest/ProduceshiftorderController.java | 95 ++++ .../order/service/CustomerbaseService.java | 73 +++ .../order/service/MaterialbaseService.java | 75 +++ .../service/ProduceshiftorderService.java | 101 ++++ .../order/service/dto/CustomerbaseDto.java | 65 +++ .../order/service/dto/MaterialbaseDto.java | 87 +++ .../service/dto/ProduceshiftorderDto.java | 60 ++ .../dto/ProduceshiftorderdetailDto.java | 99 ++++ .../service/impl/CustomerbaseServiceImpl.java | 140 +++++ .../service/impl/MaterialbaseServiceImpl.java | 158 +++++ .../impl/ProduceshiftorderServiceImpl.java | 234 ++++++++ .../order/service/wql/QPRODUCESHIFTORDER.wql | 52 ++ .../org/nl/acs/order/service/wql/order.xls | Bin 0 -> 221696 bytes .../acs/route/rest/RouteLineController.java | 9 + .../service/impl/RouteLineServiceImpl.java | 2 +- .../acs/stage/rest/StageActorController.java | 3 +- .../org/nl/acs/task/rest/TaskController.java | 9 + .../org/nl/acs/task/service/TaskService.java | 5 + .../org/nl/acs/task/service/dto/TaskDto.java | 5 + .../task/service/impl/TaskServiceImpl.java | 36 +- .../org/nl/modules/log/MongoDBAppender.java | 3 + .../nl/modules/log/MongoDBAppenderBase.java | 2 +- .../modules/log/rest/RootLogController.java | 25 +- .../modules/log/service/RootLogService.java | 17 +- .../log/service/impl/RootLogServiceImpl.java | 48 +- .../modules/quartz/task/AutoCreateInst.java | 322 ----------- .../nl/modules/quartz/task/ToAgvDevice.java | 2 +- .../quartz/task/queryAOrderDterail.java | 90 +++ .../main/resources/config/application-dev.yml | 8 +- .../src/main/resources/log/AcsToErp.xml | 2 +- .../src/main/resources/logback-spring.xml | 8 +- 88 files changed, 9649 insertions(+), 480 deletions(-) create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_fold_disc_site/ItemProtocol.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_fold_disc_site/LnshFoldDiscSiteDefination.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_fold_disc_site/LnshFoldDiscSiteDeviceDriver.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_lane/ItemProtocol.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_lane/LnshKilnLaneDefination.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_lane/LnshKilnLaneDeviceDriver.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_truss/ItemProtocol.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_truss/LnshKilnTrussDefination.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_truss/LnshKilnTrussDeviceDriver.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_labeling_machine/ItemProtocol.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_labeling_machine/LnshLabelingMachineDefination.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_labeling_machine/LnshLabelingMachineDeviceDriver.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_mixing_mill/ItemProtocol.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_mixing_mill/LnshMixingMillDefination.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_mixing_mill/LnshMixingMillDeviceDriver.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_out_kiln_truss/ItemProtocol.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_out_kiln_truss/LnshOutKilnTrussDefination.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_out_kiln_truss/LnshOutKilnTrussDeviceDriver.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_line/ItemProtocol.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_line/LnshPackageLineDefination.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_line/LnshPackageLineDeviceDriver.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_pallet_manipulator/ItemProtocol.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_pallet_manipulator/LnshPackagePalletManipulatorDefination.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_pallet_manipulator/LnshPackagePalletManipulatorDeviceDriver.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_pallet_storage/ItemProtocol.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_pallet_storage/LnshPalletStorageDefination.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_pallet_storage/LnshPalletStorageDeviceDriver.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_palletizing_manipulator/ItemProtocol.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_palletizing_manipulator/LnshPalletizingManipulatorDefination.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_palletizing_manipulator/LnshPalletizingManipulatorDeviceDriver.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_press/ItemProtocol.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_press/LnshPressDefination.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_press/LnshPressDeviceDriver.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_rgv/ItemProtocol.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_rgv/LnshRGVDefination.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_rgv/LnshRGVDeviceDriver.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_split_manipulator/ItemProtocol.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_split_manipulator/LnshSplitManipulatorDefination.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_split_manipulator/LnshSplitManipulatorDeviceDriver.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_station/ItemProtocol.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_station/LnshStationDefination.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_station/LnshStationDeviceDriver.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/order/rest/CustomerbaseController.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/order/rest/MaterialbaseController.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/order/rest/ProduceshiftorderController.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/order/service/CustomerbaseService.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/order/service/MaterialbaseService.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/order/service/ProduceshiftorderService.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/order/service/dto/CustomerbaseDto.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/order/service/dto/MaterialbaseDto.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/order/service/dto/ProduceshiftorderDto.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/order/service/dto/ProduceshiftorderdetailDto.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/order/service/impl/CustomerbaseServiceImpl.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/order/service/impl/MaterialbaseServiceImpl.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/order/service/impl/ProduceshiftorderServiceImpl.java create mode 100644 nladmin-system/src/main/java/org/nl/acs/order/service/wql/QPRODUCESHIFTORDER.wql create mode 100644 nladmin-system/src/main/java/org/nl/acs/order/service/wql/order.xls create mode 100644 nladmin-system/src/main/java/org/nl/modules/quartz/task/queryAOrderDterail.java diff --git a/nladmin-system/src/main/java/org/nl/acs/agv/server/impl/AgvServiceImpl.java b/nladmin-system/src/main/java/org/nl/acs/agv/server/impl/AgvServiceImpl.java index 14f915e..d846ff5 100644 --- a/nladmin-system/src/main/java/org/nl/acs/agv/server/impl/AgvServiceImpl.java +++ b/nladmin-system/src/main/java/org/nl/acs/agv/server/impl/AgvServiceImpl.java @@ -328,10 +328,15 @@ public class AgvServiceImpl implements AgvService { log.info("下发agv指令参数:{}", orderjo.toString()); - HttpResponse result = HttpRequest.post(agvurl) - .body(String.valueOf(orderjo))//表单内容 - .timeout(20000)//超时,毫秒 - .execute(); + HttpResponse result = null; + try { + result = HttpRequest.post(agvurl) + .body(String.valueOf(orderjo))//表单内容 + .timeout(20000)//超时,毫秒 + .execute(); + } catch (Exception e) { + throw new RuntimeException("下发agv失败!"); + } return result; } else { return null; @@ -610,10 +615,15 @@ public class AgvServiceImpl implements AgvService { agvurl = agvurl + ":" + agvport + "/v1/transportOrders/" + instCode + "/withdrawal"; log.info("删除agv指令请求agvurl:{}", agvurl); - HttpResponse result = HttpRequest.post(agvurl) - .timeout(20000)//超时,毫秒 - .execute(); - log.info("删除agv指令请求反馈:{}", result); + HttpResponse result = null; + try { + result = HttpRequest.post(agvurl) + .timeout(20000)//超时,毫秒 + .execute(); + log.info("删除agv指令请求反馈:{}", result); + } catch (Exception e) { + throw new RuntimeException("下发agv失败!"); + } return result; diff --git a/nladmin-system/src/main/java/org/nl/acs/device/device_driver/DriverTypeEnum.java b/nladmin-system/src/main/java/org/nl/acs/device/device_driver/DriverTypeEnum.java index 0085f62..df33776 100644 --- a/nladmin-system/src/main/java/org/nl/acs/device/device_driver/DriverTypeEnum.java +++ b/nladmin-system/src/main/java/org/nl/acs/device/device_driver/DriverTypeEnum.java @@ -9,47 +9,47 @@ import com.alibaba.fastjson.JSONObject; * https://blog.csdn.net/moneyshi/article/details/82978073 */ public enum DriverTypeEnum { - ORDINARY_SITE(1, "standard_ordinary_site", "普通站点", "conveyor"), + ORDINARY_SITE(1, "standard_ordinary_site", "普通站点", "station"), - WEIGHING_SITE(2, "weighing_site", "称重站点", "conveyor"), + WEIGHING_SITE(2, "weighing_site", "称重站点", "station"), - INSPECT_SITE(3, "standard_inspect_site", "检测站点", "conveyor"), + INSPECT_SITE(3, "standard_inspect_site", "检测站点", "station"), - NON_LINE_INSPECT_SITE(4, "non_line_inspect_site", "检测站点-无PLC", "conveyor"), + NON_LINE_INSPECT_SITE(4, "non_line_inspect_site", "检测站点-无PLC", "station"), - MACHINES_SITE(5, "machines_site", "机台设备-无光电", "conveyor"), + MACHINES_SITE(5, "machines_site", "机台设备-无光电", "station"), - SPECIAL_SITE(6, "standard_special_inspect_site", "专机设备交互站点", "conveyor"), + SPECIAL_SITE(6, "standard_special_inspect_site", "专机设备交互站点", "station"), - MANIPULATOR_SITE(7, "standard_manipulator_inspect_site", "区域管制设备交互站点", "conveyor"), + MANIPULATOR_SITE(7, "standard_manipulator_inspect_site", "区域管制设备交互站点", "station"), - NON_LINE_MANIPULATOR_SITE(8, "non_line_manipulator_inspect_site", "区域管制设备交互站点-无PLC", "conveyor"), + NON_LINE_MANIPULATOR_SITE(8, "non_line_manipulator_inspect_site", "区域管制设备交互站点-无PLC", "station"), AUTODOOR(9, "standard_autodoor", "标准版-自动门", "autodoor"), - STACK_EMPUYPALLET_SITE(10, "standard_emptypallet_site", "标准版-空盘叠盘站点", "conveyor"), + STACK_EMPUYPALLET_SITE(10, "standard_emptypallet_site", "标准版-空盘叠盘站点", "station"), - LAMP_THREE_COLOR(11, "lamp_three_color", "标准版-三色灯", "三色灯"), + LAMP_THREE_COLOR(11, "lamp_three_color", "标准版-三色灯", "alarmLamp"), - SPECIAL_ORDINARY_SITE(12, "special_ordinary_site", "特殊版-普通站点-关联锁定", "conveyor"), + SPECIAL_ORDINARY_SITE(12, "special_ordinary_site", "特殊版-普通站点-关联锁定", "station"), STORAGE(13, "standard_storage", "标准版-货架", "storage"), SCANNER(14, "standard_scanner", "标准版-扫码器", "scanner"), - INSPECT_CONVEYOR_CONTROL_WITH_SCANNER(15, "standard_conveyor_control_with_scanner", "标准版-输送机-控制点-关联扫码", "conveyor"), + INSPECT_CONVEYOR_CONTROL_WITH_SCANNER(15, "standard_conveyor_control_with_scanner", "标准版-输送机-控制点-关联扫码", "station"), INSPECT_CONVEYOR_CONTROL(16, "standard_conveyor_control", "标准版-输送机-控制点", "conveyor"), INSPECT_CONVEYOR_MONITOR(17, "standard_conveyor_monitor", "标准版-输送机-监控点", "conveyor"), - MANIPULATOR_INSPECT_SITE_NDC(18, "manipulator_inspect_site_NDC", "区域管制设备交互站点-NDC", "conveyor"), + MANIPULATOR_INSPECT_SITE_NDC(18, "manipulator_inspect_site_NDC", "区域管制设备交互站点-NDC", "station"), - FEEDBACK_AGV_STATUS_SITE(19, "feedback_agv_status_site", "上报AGV状态站点", "conveyor"), + FEEDBACK_AGV_STATUS_SITE(19, "feedback_agv_status_site", "上报AGV状态站点", "station"), MANIPULATOR_STACKING_SITE(20, "standard_manipulator_stacking_site", "机械手码垛驱动(区分托盘类型)", "conveyor"), - PHOTOELECTRIC_INSPECT_SITE(21, "standard_photoelectric_inspect_site", "光电检测站点(优先出库)", "conveyor"), + PHOTOELECTRIC_INSPECT_SITE(21, "standard_photoelectric_inspect_site", "光电检测站点(优先出库)", "station"), HAILIANG_PACKING(22, "hailiang_packing", "海亮项目-包装机", "conveyor"), @@ -57,9 +57,9 @@ public enum DriverTypeEnum { HAILIANG_COATING(24, "hailiang_coating", "海亮项目-裹膜机", "conveyor"), - NDXY_SPECIAL(25, "ndxy_special", "纽迪希亚专用", "conveyor"), + NDXY_SPECIAL(25, "ndxy_special", "纽迪希亚专用", "station"), - NDXY_SPECIAL_TWO(26, "ndxy_special_two", "纽迪希亚专用2", "conveyor"), + NDXY_SPECIAL_TWO(26, "ndxy_special_two", "纽迪希亚专用2", "station"), INSPECT_CONVEYOR_CONTROL_WITH_PLCSCANNER(27, "standard_conveyor_control_with_plcscanner", "标准版-输送机-控制点-PLC扫码", "conveyor"), @@ -75,11 +75,39 @@ public enum DriverTypeEnum { OUMULONGPLC(33, "oumulong_plc", "标准版-自动门-欧姆龙plc", "autodoor"), - TRAFFIC_LIGHT(34, "traffic_light", "标准版-交通灯-欧姆龙plc", "三色灯"), + TRAFFIC_LIGHT(34, "traffic_light", "标准版-交通灯-欧姆龙plc", "alarmLamp"), STANDARD_RGV(35, "standard_rgv", "标准版-RGV", "rgv"), - YKBK_SPECIAL(36, "ykbk_special", "伊科拜克默认物料", "conveyor"); + YKBK_SPECIAL(36, "ykbk_special", "伊科拜克默认物料", "station"), + + LNSH_MIXING_MILL(37, "lnsh_mixing_mill", "晟华-混碾机", "station"), + + LNSH_PRESS(38, "lnsh_press", "晟华-压力机", "station"), + + LNSH_PALLETIZING_MANIPULATOR(39, "lnsh_palletizing_manipulator", "晟华-码垛机械手", "station"), + + LNSH_KILN_TRUSS(40, "lnsh_kiln_truss", "晟华-入窑桁架", "station"), + + LNSH_OUT_KILN_TRUSS(41, "lnsh_out_kiln_truss", "晟华-出窑桁架", "station"), + + LNSH_KILN_LANE(42, "lnsh_kiln_lane", "晟华-窑车道", "station"), + + LNSH_FOLD_DISC_SITE(43, "lnsh_fold_disc_site", "晟华-叠盘工位", "station"), + + LNSH_PALLET_STORAGE(44, "lnsh_pallet_storage", "晟华-托盘存储线", "station"), + + LNSH_PACKAGE_PALLET_MANIPULATOR(45, "lnsh_package_pallet_manipulator", "晟华-包装码垛机械手", "station"), + + LNSH_LABELING_MACHINE(46, "lnsh_labeling_machine", "晟华-贴标机", "station"), + + LNSH_SPLIT_MANIPULATOR(47, "lnsh_split_manipulator", "晟华-拆垛机械手", "station"), + + LNSH_RGV(48, "lnsh_rgv", "晟华-RGV", "station"), + + LNSH_PACKAGE_LINE(49, "lnsh_package_line", "晟华-包装线", "station"), + + LNSH_STATION(50, "lnsh_station", "晟华-工位(交互模板)", "station"); //驱动索引 diff --git a/nladmin-system/src/main/java/org/nl/acs/device/rest/DeviceController.java b/nladmin-system/src/main/java/org/nl/acs/device/rest/DeviceController.java index dfdb620..ff6b4f1 100644 --- a/nladmin-system/src/main/java/org/nl/acs/device/rest/DeviceController.java +++ b/nladmin-system/src/main/java/org/nl/acs/device/rest/DeviceController.java @@ -49,6 +49,15 @@ public class DeviceController { return new ResponseEntity<>(deviceService.queryAll(whereJson, page), HttpStatus.OK); } + @GetMapping("/reload") + @Log("数据同步") + @ApiOperation("数据同步") + //@PreAuthorize("@el.check('task:list')") + public ResponseEntity reload() { + deviceService.reload(); + return new ResponseEntity<>(HttpStatus.OK); + } + @GetMapping("/protocol") @Log("查询设备协议") @ApiOperation("查询设备协议") diff --git a/nladmin-system/src/main/java/org/nl/acs/device/service/impl/DeviceAssignedServiceImpl.java b/nladmin-system/src/main/java/org/nl/acs/device/service/impl/DeviceAssignedServiceImpl.java index b089232..7bcd791 100644 --- a/nladmin-system/src/main/java/org/nl/acs/device/service/impl/DeviceAssignedServiceImpl.java +++ b/nladmin-system/src/main/java/org/nl/acs/device/service/impl/DeviceAssignedServiceImpl.java @@ -4,6 +4,7 @@ package org.nl.acs.device.service.impl; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import lombok.RequiredArgsConstructor; @@ -167,19 +168,39 @@ public class DeviceAssignedServiceImpl implements DeviceAssignedService { } @Override - public List queryAssignedBydevice(String device_code, String task_nextdeice_code) { + public List queryAssignedBydevice(String device_code, String old_task_nextdevice_code) { WQLObject wo = WQLObject.getWQLObject("acs_device_assigned"); - JSONArray arr = wo.query("device_code ='" + device_code + "' and task_nextDevice_code= '" + task_nextdeice_code + "'").getResultJSONArray(0); + JSONArray arr = wo.query("device_code ='" + device_code + "'").getResultJSONArray(0); List list = new ArrayList(); for (int i = 0; i < arr.size(); i++) { JSONObject jo = arr.getJSONObject(i); - DeviceAssignedDto dto = new DeviceAssignedDto(); - dto.setAssigned_id(jo.getString("assigned_id")); - dto.setDevice_code(jo.getString("device_code")); - dto.setInst_nextdevice_code(jo.getString("inst_nextdevice_code")); - dto.setTask_nextdevice_code(jo.getString("task_nextdevice_code")); - dto.setParam(jo.getString("param")); - list.add(dto); + if(jo.getString("task_nextdevice_code").indexOf(",") != -1){ + String task_nextdevice_code[] = jo.getString("task_nextdevice_code").split(","); + for(int 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 delta 12455 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 CQYmi$ diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_fold_disc_site/ItemProtocol.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_fold_disc_site/ItemProtocol.java new file mode 100644 index 0000000..62c1e19 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_fold_disc_site/ItemProtocol.java @@ -0,0 +1,123 @@ +package org.nl.acs.device_driver.lnsh.lnsh_fold_disc_site; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Data +public class ItemProtocol { + public static String item_heartbeat = "heartbeat"; + public static String item_mode = "mode"; + public static String item_status = "status"; + public static String item_open_time = "open_time"; + public static String item_close_time = "close_time"; + public static String item_standby_time = "standby_time "; + public static String item_production_time = "production_time"; + public static String item_error_time = "error_time"; + public static String item_container_qty = "container_qty"; + public static String item_to_command = "to_command"; + public static String item_to_target = "to_target"; + public static String item_to_task = "to_task"; + Boolean isonline; + + private LnshFoldDiscSiteDeviceDriver driver; + + public ItemProtocol(LnshFoldDiscSiteDeviceDriver driver) { + this.driver = driver; + } + + public int getHeartbeat() { + return this.getOpcIntegerValue(item_heartbeat); + } + + public int getMode() { + return this.getOpcIntegerValue(item_mode); + } + + public int getStatus() { + return this.getOpcIntegerValue(item_status); + } + + public int getOpen_time() { + return this.getOpcIntegerValue(item_open_time); + } + + public int getClose_time() { + return this.getOpcIntegerValue(item_close_time); + } + + public int getStandby_time() { + return this.getOpcIntegerValue(item_standby_time); + } + + public int getProduction_time() { + return this.getOpcIntegerValue(item_production_time); + } + + public int getError_time() { + return this.getOpcIntegerValue(item_error_time); + } + + public int getContainer_qty() { + return this.getOpcIntegerValue(item_container_qty); + } + + public int getToCommand() { + return this.getOpcIntegerValue(item_to_command); + } + + public int getToTarget() { + return this.getOpcIntegerValue(item_to_target); + } + + public int getToTask() { + return this.getOpcIntegerValue(item_to_task); + } + + //是否有货 + public int hasGoods(int move) { + return move; + } + + + public int getOpcIntegerValue(String protocol) { + Integer value = this.driver.getIntegeregerValue(protocol); + if (value == null) { + log.error(this.getDriver().getDeviceCode() + ":protocol " + protocol + " 信号同步异常!"); + setIsonline(false); + } else { + setIsonline(true); + return value; + } + return 0; + + } + + public static List getReadableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(item_mode, "工作状态", "DB600.B1", Boolean.valueOf(true))); + list.add(new ItemDto(item_status, "设备状态", "DB600.B2")); + list.add(new ItemDto(item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(item_close_time, "关机时间", "DB600.D5")); + list.add(new ItemDto(item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(item_error_time, "故障时间", "DB600.D8")); + list.add(new ItemDto(item_container_qty, "托盘数", "DB600.D8")); + return list; + } + + public static List getWriteableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_to_command, "下发命令反馈", "DB601.W2", Boolean.valueOf(true))); + list.add(new ItemDto(item_to_target, "下发目标站", "DB601.W4")); + list.add(new ItemDto(item_to_task, "下发任务号", "DB601.D8")); + return list; + } + +} + diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_fold_disc_site/LnshFoldDiscSiteDefination.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_fold_disc_site/LnshFoldDiscSiteDefination.java new file mode 100644 index 0000000..e7c7d55 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_fold_disc_site/LnshFoldDiscSiteDefination.java @@ -0,0 +1,75 @@ +package org.nl.acs.device_driver.lnsh.lnsh_fold_disc_site; + +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.defination.OpcDeviceDriverDefination; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceType; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * 晟华叠盘工位 + */ +@Service +public class LnshFoldDiscSiteDefination implements OpcDeviceDriverDefination { + @Override + public String getDriverCode() { + return "lnsh_fold_disc_site"; + } + + @Override + public String getDriverName() { + return "晟华-叠盘工位"; + } + + @Override + public String getDriverDescription() { + return "晟华-叠盘工位"; + } + + @Override + public DeviceDriver getDriverInstance(Device device) { + return (new LnshFoldDiscSiteDeviceDriver()).setDevice(device).setDriverDefination(this); + } + + @Override + public Class getDeviceDriverType() { + return LnshFoldDiscSiteDeviceDriver.class; + } + + @Override + public List getFitDeviceTypes() { + List types = new LinkedList(); + types.add(DeviceType.conveyor); + return types; + } + + @Override + public List getReadableItemDtos() { + return getReadableItemDtos2(); + } + + public static List getReadableItemDtos2() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(ItemProtocol.item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(ItemProtocol.item_mode, "工作状态", "DB600.B1", Boolean.valueOf(true))); + list.add(new ItemDto(ItemProtocol.item_status, "设备状态", "DB600.B2")); + list.add(new ItemDto(ItemProtocol.item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(ItemProtocol.item_close_time, "关机时间", "DB600.D5")); + list.add(new ItemDto(ItemProtocol.item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(ItemProtocol.item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(ItemProtocol.item_error_time, "故障时间", "DB600.D8")); + list.add(new ItemDto(ItemProtocol.item_container_qty, "托盘数", "DB600.D8")); + return list; + } + + @Override + public List getWriteableItemDtos() { + return ItemProtocol.getWriteableItemDtos(); + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_fold_disc_site/LnshFoldDiscSiteDeviceDriver.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_fold_disc_site/LnshFoldDiscSiteDeviceDriver.java new file mode 100644 index 0000000..06eb47a --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_fold_disc_site/LnshFoldDiscSiteDeviceDriver.java @@ -0,0 +1,336 @@ +package org.nl.acs.device_driver.lnsh.lnsh_fold_disc_site; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ReadUtil; +import org.nl.acs.device.service.DeviceService; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.RouteableDeviceDriver; +import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; +import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.instruction.service.dto.Instruction; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.WcsConfig; +import org.nl.acs.route.service.RouteLineService; +import org.nl.acs.route.service.dto.RouteLineDto; +import org.nl.acs.task.service.TaskService; +import org.nl.acs.task.service.dto.TaskDto; +import org.nl.modules.system.util.CodeUtil; +import org.nl.utils.SpringContextHolder; +import org.nl.wql.core.bean.WQLObject; +import org.openscada.opc.lib.da.Server; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.*; + +/** + * 晟华叠盘工位 + */ +@Slf4j +@Data +@RequiredArgsConstructor +public class LnshFoldDiscSiteDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver { + protected ItemProtocol itemProtocol = new ItemProtocol(this); + @Autowired + InstructionService instructionService = SpringContextHolder.getBean("instructionServiceImpl"); + @Autowired + DeviceService deviceservice = SpringContextHolder.getBean("deviceServiceImpl"); + @Autowired + RouteLineService routelineserver = SpringContextHolder.getBean("routeLineServiceImpl"); + @Autowired + TaskService taskserver = SpringContextHolder.getBean("taskServiceImpl"); + + + String container; + String container_type_desc; + String last_container_type_desc; + String last_container; + //放货准备锁 + String putReadyLock = null; + //有货标记 + protected boolean has_goods_tag = false; + + + String device_code; + int mode = 0; + int error = 0; + int move = 0; + int action; + int io_action; + int task = 0; + int container_type = 0; + int last_mode = 0; + int last_error = 0; + int last_move = 0; + int last_task = 0; + int last_container_type; + Boolean isonline = true; + int hasGoods = 0; + Boolean iserror = false; + + boolean hasVehicle = false; + boolean isReady = false; + protected int instruction_num = 0; + protected int instruction_num_truth = 0; + boolean isFold = false; + private String assemble_check_tag; + private Boolean sampleMode0; + private Boolean sampleMode3; + private Integer sampleError; + private Boolean sampleOnline; + protected String displayMessage = null; + public int display_message_time_out = 30000; + public Date display_message_time; + protected String current_stage_instruction_message; + protected String last_stage_instruction_message; + Integer heartbeat_tag; + private Date instruction_require_time = new Date(); + private Date instruction_finished_time = new Date(); + + private int instruction_require_time_out = 3000; + boolean requireSucess = false; + + private int instruction_finished_time_out; + + int heartbeat; + int last_heartbeat; + private Date checkHeartbeattime = new Date(); + private Date last_checkHeartbeattime = new Date(); + + int branchProtocol = 0; + //当前指令 + Instruction inst = null; + //上次指令 + Instruction last_inst = null; + + //触摸屏手动触发任务 + private Boolean is_has_task = false; + + String message; + + @Override + public Device getDevice() { + return this.device; + } + + + @Override + public void execute() { + String message = null; + try { + device_code = this.getDeviceCode(); + + mode = this.itemProtocol.getMode(); + + } catch (Exception var17) { + return; + } + + //急停 + if (this.isStop()) { + + //未在线无心跳 + } else if (!this.itemProtocol.getIsonline()) { + this.setIsonline(false); + this.setIserror(true); + message = "信号量同步异常"; + //未联机 + } else if (mode == 0) { + this.setIsonline(false); + this.setIserror(true); + message = "未联机"; + //有报警 + } else if (error != 0) { + this.setIsonline(false); + this.setIserror(true); + message = "有报警"; + //无报警 + } else { + this.setIsonline(true); + this.setIserror(false); + message = ""; + Instruction instruction = null; + List toInstructions; + switch (mode) { + case 1: + log.debug("设备运转模式:等待工作"); + break; + case 2: + + break; + case 3: + + break; + case 4: + break; + } + } + + last_mode = mode; + last_error = error; + last_move = move; + last_task = task; + last_container_type = container_type; + } + + + protected void thingToNothing() throws Exception { + this.setRequireSucess(false); + } + + public void finish_instruction(Instruction instruction) throws Exception { + instruction_finished(instruction); + } + + /** + * 完成指令 + * + * @param instruction + * @return + */ + public boolean instruction_finished(Instruction instruction) throws Exception { + Date date = new Date(); + if (date.getTime() - this.instruction_finished_time.getTime() < (long) this.instruction_finished_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_finished_time_out); + return false; + } else { + instructionService.finish(instruction.getInstruction_id()); + this.instruction_finished_time = date; + return true; + } + } + + /** + * 完成并创建下一条指令 + * + * @param instruction + * @param needCreateNext + * @return + */ + public boolean instruction_finished(Instruction instruction, boolean needCreateNext) { + Date date = new Date(); + if (date.getTime() - this.instruction_finished_time.getTime() < (long) this.instruction_finished_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_finished_time_out); + return false; + } else { + this.instruction_finished_time = date; + return true; + } + } + + + private Instruction findInstruction() { + Instruction instruction = null; + if (this.instruction_num != 0) { + instruction = (Instruction) instructionService.findByCodeFromCache(String.valueOf(instruction_num)); + } + if (instruction != null) { + //可进行校验 + + + } else { + List container_instructions = new ArrayList(); + String barcode = this.getLast_container(); + + if (!StrUtil.isEmpty(barcode)) { + Map map = new HashMap(); + map.put("vehicle_code", barcode); + container_instructions = instructionService.queryAll(map); + } + + if (((List) container_instructions).size() > 1) { + log.debug("容器存在多个指令"); + } else { + if (((List) container_instructions).size() > 0) { + instruction = (Instruction) ((List) container_instructions).get(0); + } + } + } + return instruction; + } + + + public boolean exe_error() { + if (this.error == 0) { + return true; + } else { + log.debug("设备报警"); + return false; + } + } + + public void set_last_container(String barcode, String type_desc) { + this.set_last_container(barcode); + this.set_last_container_type_desc(type_desc); + } + + public void set_last_container(String barcode) { + } + + public void set_last_container_type_desc(String type) { + } + + public boolean exe_business() { + return true; + } + + public void executing(Server server, Map itemMap) { + ReadUtil.write(itemMap, server); + } + + + public boolean instruction_require(String container_code) { + return instruction_require(container_code, WcsConfig.task_container_type_default_desc); + } + + /** + * 请求指令 + * + * @param container_code + * @param container_type + */ + public synchronized boolean instruction_require(String container_code, String container_type) { + Date date = new Date(); + if (date.getTime() - this.instruction_require_time.getTime() < (long) this.instruction_require_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_require_time_out); + return false; + } else { + this.instruction_require_time = date; + TaskDto dto = new TaskDto(); + String now = DateUtil.now(); + dto.setTask_id(IdUtil.simpleUUID()); + dto.setCreate_by(this.getDevice().getDevice_code()); + dto.setUpdate_by(this.getDevice().getDevice_code()); + dto.setStart_point_code(this.getDevice().getDevice_code()); + dto.setVehicle_code(container_code); + dto.setVehicle_type(container_type); + + String taskcode = CodeUtil.getNewCode("TASK_NO"); + dto.setTask_code("-" + taskcode); + dto.setTask_status("0"); + dto.setPriority("101"); + RouteLineDto jo = routelineserver.findByCode(this.getDevice().getDevice_code()); + String next_device_codecode = jo.getNext_device_code(); + if (StrUtil.isEmpty(next_device_codecode)) { + throw new RuntimeException("该设备未找到对应路由"); + } + dto.setNext_point_code(next_device_codecode); + dto.setUpdate_time(now); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("acs_task"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + + wo.insert(json); + requireSucess = false; + return true; + } + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_lane/ItemProtocol.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_lane/ItemProtocol.java new file mode 100644 index 0000000..38d2a95 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_lane/ItemProtocol.java @@ -0,0 +1,123 @@ +package org.nl.acs.device_driver.lnsh.lnsh_kiln_lane; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Data +public class ItemProtocol { + public static String item_heartbeat = "heartbeat"; + public static String item_mode = "mode"; + public static String item_status = "status"; + public static String item_open_time = "open_time"; + public static String item_standby_time = "standby_time "; + public static String item_production_time = "production_time"; + public static String item_error_time = "error_time"; + public static String item_car_sum = "car_sum"; + public static String item_nullCar_qty = "nullCar_qty"; + public static String item_burning_car_qty = "burning_car_qty"; + public static String item_to_command = "to_command"; + public static String item_to_material_code = "to_material_code"; + Boolean isonline; + + private LnshKilnLaneDeviceDriver driver; + + public ItemProtocol(LnshKilnLaneDeviceDriver driver) { + this.driver = driver; + } + + public int getHeartbeat() { + return this.getOpcIntegerValue(item_heartbeat); + } + + public int getMode() { + return this.getOpcIntegerValue(item_mode); + } + + public int getStatus() { + return this.getOpcIntegerValue(item_status); + } + + public int getOpen_time() { + return this.getOpcIntegerValue(item_open_time); + } + + public int getStandby_time() { + return this.getOpcIntegerValue(item_standby_time); + } + + public int getProduction_time() { + return this.getOpcIntegerValue(item_production_time); + } + + public int getError_time() { + return this.getOpcIntegerValue(item_error_time); + } + + public int getCar_sum() { + return this.getOpcIntegerValue(item_car_sum); + } + + public int getNullCar_qty() { + return this.getOpcIntegerValue(item_nullCar_qty); + } + + public int getBurning_car_qty() { + return this.getOpcIntegerValue(item_burning_car_qty); + } + + public int getToCommand() { + return this.getOpcIntegerValue(item_to_command); + } + + public int getTo_material_code() { + return this.getOpcIntegerValue(item_to_material_code); + } + + //是否有货 + public int hasGoods(int move) { + return move; + } + + + public int getOpcIntegerValue(String protocol) { + Integer value = this.driver.getIntegeregerValue(protocol); + if (value == null) { + log.error(this.getDriver().getDeviceCode() + ":protocol " + protocol + " 信号同步异常!"); + setIsonline(false); + } else { + setIsonline(true); + return value; + } + return 0; + + } + + public static List getReadableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(item_mode, "工作状态", "DB600.B1", Boolean.valueOf(true))); + list.add(new ItemDto(item_status, "设备状态", "DB600.B3")); + list.add(new ItemDto(item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(item_error_time, "故障时间", "DB600.D8")); + list.add(new ItemDto(item_car_sum, "窑车总数", "DB600.B4")); + list.add(new ItemDto(item_nullCar_qty, "空窑车数", "DB600.B6")); + list.add(new ItemDto(item_burning_car_qty, "在烧窑车数", "DB600.D8")); + return list; + } + + public static List getWriteableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_to_command, "下发命令", "DB601.W2", Boolean.valueOf(true))); + list.add(new ItemDto(item_to_material_code, "下发物料编号", "DB601.W4")); + return list; + } + +} + diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_lane/LnshKilnLaneDefination.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_lane/LnshKilnLaneDefination.java new file mode 100644 index 0000000..e803a0c --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_lane/LnshKilnLaneDefination.java @@ -0,0 +1,76 @@ +package org.nl.acs.device_driver.lnsh.lnsh_kiln_lane; + +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.defination.OpcDeviceDriverDefination; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceType; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * 晟华窑车道 + */ +@Service +public class LnshKilnLaneDefination implements OpcDeviceDriverDefination { + @Override + public String getDriverCode() { + return "lnsh_kiln_lane"; + } + + @Override + public String getDriverName() { + return "晟华-窑车道"; + } + + @Override + public String getDriverDescription() { + return "晟华-窑车道"; + } + + @Override + public DeviceDriver getDriverInstance(Device device) { + return (new LnshKilnLaneDeviceDriver()).setDevice(device).setDriverDefination(this); + } + + @Override + public Class getDeviceDriverType() { + return LnshKilnLaneDeviceDriver.class; + } + + @Override + public List getFitDeviceTypes() { + List types = new LinkedList(); + types.add(DeviceType.conveyor); + return types; + } + + @Override + public List getReadableItemDtos() { + return getReadableItemDtos2(); + } + + public static List getReadableItemDtos2() { + List list = new ArrayList(); + list.add(new ItemDto(ItemProtocol.item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(ItemProtocol.item_mode, "工作状态", "DB600.B1", Boolean.valueOf(true))); + list.add(new ItemDto(ItemProtocol.item_status, "设备状态", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(ItemProtocol.item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(ItemProtocol.item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(ItemProtocol.item_error_time, "故障时间", "DB600.D8")); + list.add(new ItemDto(ItemProtocol.item_car_sum, "窑车总数", "DB600.B4")); + list.add(new ItemDto(ItemProtocol.item_nullCar_qty, "空窑车数", "DB600.B6")); + list.add(new ItemDto(ItemProtocol.item_burning_car_qty, "在烧窑车数", "DB600.D8")); + return list; + } + + @Override + public List getWriteableItemDtos() { + return ItemProtocol.getWriteableItemDtos(); + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_lane/LnshKilnLaneDeviceDriver.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_lane/LnshKilnLaneDeviceDriver.java new file mode 100644 index 0000000..8e8c6d3 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_lane/LnshKilnLaneDeviceDriver.java @@ -0,0 +1,334 @@ +package org.nl.acs.device_driver.lnsh.lnsh_kiln_lane; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ReadUtil; +import org.nl.acs.device.service.DeviceService; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.RouteableDeviceDriver; +import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; +import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.instruction.service.dto.Instruction; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.WcsConfig; +import org.nl.acs.route.service.RouteLineService; +import org.nl.acs.route.service.dto.RouteLineDto; +import org.nl.acs.task.service.TaskService; +import org.nl.acs.task.service.dto.TaskDto; +import org.nl.modules.system.util.CodeUtil; +import org.nl.utils.SpringContextHolder; +import org.nl.wql.core.bean.WQLObject; +import org.openscada.opc.lib.da.Server; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.*; + +/** + * 晟华窑车道 + */ +@Slf4j +@Data +@RequiredArgsConstructor +public class LnshKilnLaneDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver { + protected ItemProtocol itemProtocol = new ItemProtocol(this); + @Autowired + InstructionService instructionService = SpringContextHolder.getBean("instructionServiceImpl"); + @Autowired + DeviceService deviceservice = SpringContextHolder.getBean("deviceServiceImpl"); + @Autowired + RouteLineService routelineserver = SpringContextHolder.getBean("routeLineServiceImpl"); + @Autowired + TaskService taskserver = SpringContextHolder.getBean("taskServiceImpl"); + + + String container; + String container_type_desc; + String last_container_type_desc; + String last_container; + //放货准备锁 + String putReadyLock = null; + //有货标记 + protected boolean has_goods_tag = false; + + + String device_code; + int mode = 0; + int error = 0; + int move = 0; + int action; + int io_action; + int task = 0; + int container_type = 0; + int last_mode = 0; + int last_error = 0; + int last_move = 0; + int last_task = 0; + int last_container_type; + Boolean isonline = true; + int hasGoods = 0; + Boolean iserror = false; + + boolean hasVehicle = false; + boolean isReady = false; + protected int instruction_num = 0; + protected int instruction_num_truth = 0; + boolean isFold = false; + private String assemble_check_tag; + private Boolean sampleMode0; + private Boolean sampleMode3; + private Integer sampleError; + private Boolean sampleOnline; + protected String displayMessage = null; + public int display_message_time_out = 30000; + public Date display_message_time; + protected String current_stage_instruction_message; + protected String last_stage_instruction_message; + Integer heartbeat_tag; + private Date instruction_require_time = new Date(); + private Date instruction_finished_time = new Date(); + + private int instruction_require_time_out = 3000; + boolean requireSucess = false; + + private int instruction_finished_time_out; + + int heartbeat; + int last_heartbeat; + private Date checkHeartbeattime = new Date(); + private Date last_checkHeartbeattime = new Date(); + + int branchProtocol = 0; + //当前指令 + Instruction inst = null; + //上次指令 + Instruction last_inst = null; + + //触摸屏手动触发任务 + private Boolean is_has_task = false; + + String message; + + @Override + public Device getDevice() { + return this.device; + } + + + @Override + public void execute() { + String message = null; + try { + device_code = this.getDeviceCode(); + + } catch (Exception var17) { + return; + } + + //急停 + if (this.isStop()) { + + //未在线无心跳 + } else if (!this.itemProtocol.getIsonline()) { + this.setIsonline(false); + this.setIserror(true); + message = "信号量同步异常"; + //未联机 + } else if (mode == 0) { + this.setIsonline(false); + this.setIserror(true); + message = "未联机"; + //有报警 + } else if (error != 0) { + this.setIsonline(false); + this.setIserror(true); + message = "有报警"; + //无报警 + } else { + this.setIsonline(true); + this.setIserror(false); + message = ""; + Instruction instruction = null; + List toInstructions; + switch (mode) { + case 1: + log.debug("设备运转模式:等待工作"); + break; + case 2: + + break; + case 3: + + break; + case 4: + break; + } + } + + last_mode = mode; + last_error = error; + last_move = move; + last_task = task; + last_container_type = container_type; + } + + + protected void thingToNothing() throws Exception { + this.setRequireSucess(false); + } + + public void finish_instruction(Instruction instruction) throws Exception { + instruction_finished(instruction); + } + + /** + * 完成指令 + * + * @param instruction + * @return + */ + public boolean instruction_finished(Instruction instruction) throws Exception { + Date date = new Date(); + if (date.getTime() - this.instruction_finished_time.getTime() < (long) this.instruction_finished_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_finished_time_out); + return false; + } else { + instructionService.finish(instruction.getInstruction_id()); + this.instruction_finished_time = date; + return true; + } + } + + /** + * 完成并创建下一条指令 + * + * @param instruction + * @param needCreateNext + * @return + */ + public boolean instruction_finished(Instruction instruction, boolean needCreateNext) { + Date date = new Date(); + if (date.getTime() - this.instruction_finished_time.getTime() < (long) this.instruction_finished_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_finished_time_out); + return false; + } else { + this.instruction_finished_time = date; + return true; + } + } + + + private Instruction findInstruction() { + Instruction instruction = null; + if (this.instruction_num != 0) { + instruction = (Instruction) instructionService.findByCodeFromCache(String.valueOf(instruction_num)); + } + if (instruction != null) { + //可进行校验 + + + } else { + List container_instructions = new ArrayList(); + String barcode = this.getLast_container(); + + if (!StrUtil.isEmpty(barcode)) { + Map map = new HashMap(); + map.put("vehicle_code", barcode); + container_instructions = instructionService.queryAll(map); + } + + if (((List) container_instructions).size() > 1) { + log.debug("容器存在多个指令"); + } else { + if (((List) container_instructions).size() > 0) { + instruction = (Instruction) ((List) container_instructions).get(0); + } + } + } + return instruction; + } + + + public boolean exe_error() { + if (this.error == 0) { + return true; + } else { + log.debug("设备报警"); + return false; + } + } + + public void set_last_container(String barcode, String type_desc) { + this.set_last_container(barcode); + this.set_last_container_type_desc(type_desc); + } + + public void set_last_container(String barcode) { + } + + public void set_last_container_type_desc(String type) { + } + + public boolean exe_business() { + return true; + } + + public void executing(Server server, Map itemMap) { + ReadUtil.write(itemMap, server); + } + + + public boolean instruction_require(String container_code) { + return instruction_require(container_code, WcsConfig.task_container_type_default_desc); + } + + /** + * 请求指令 + * + * @param container_code + * @param container_type + */ + public synchronized boolean instruction_require(String container_code, String container_type) { + Date date = new Date(); + if (date.getTime() - this.instruction_require_time.getTime() < (long) this.instruction_require_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_require_time_out); + return false; + } else { + this.instruction_require_time = date; + TaskDto dto = new TaskDto(); + String now = DateUtil.now(); + dto.setTask_id(IdUtil.simpleUUID()); + dto.setCreate_by(this.getDevice().getDevice_code()); + dto.setUpdate_by(this.getDevice().getDevice_code()); + dto.setStart_point_code(this.getDevice().getDevice_code()); + dto.setVehicle_code(container_code); + dto.setVehicle_type(container_type); + + String taskcode = CodeUtil.getNewCode("TASK_NO"); + dto.setTask_code("-" + taskcode); + dto.setTask_status("0"); + dto.setPriority("101"); + RouteLineDto jo = routelineserver.findByCode(this.getDevice().getDevice_code()); + String next_device_codecode = jo.getNext_device_code(); + if (StrUtil.isEmpty(next_device_codecode)) { + throw new RuntimeException("该设备未找到对应路由"); + } + dto.setNext_point_code(next_device_codecode); + dto.setUpdate_time(now); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("acs_task"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + + wo.insert(json); + requireSucess = false; + return true; + } + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_truss/ItemProtocol.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_truss/ItemProtocol.java new file mode 100644 index 0000000..b16c777 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_truss/ItemProtocol.java @@ -0,0 +1,141 @@ +package org.nl.acs.device_driver.lnsh.lnsh_kiln_truss; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Data +public class ItemProtocol { + public static String item_heartbeat = "heartbeat"; + public static String item_mode = "mode"; + public static String item_status = "status"; + public static String item_outKiln_move = "outKiln_move"; + public static String item_inKiln_move = "inKiln_move"; + public static String item_inKiln_barcode = "inKiln_barcode"; + public static String item_outKiln_barcode = "outKiln_barcode"; + public static String item_inKiln_device = "inKiln_device"; + public static String item_open_time = "open_time"; + public static String item_standby_time = "standby_time "; + public static String item_production_time = "production_time"; + public static String item_error_time = "error_time"; + public static String item_to_command = "to_command"; + public static String item_to_target = "to_target"; + public static String item_to_task = "to_task"; + Boolean isonline; + + private LnshKilnTrussDeviceDriver driver; + + public ItemProtocol(LnshKilnTrussDeviceDriver driver) { + this.driver = driver; + } + + public int getHeartbeat() { + return this.getOpcIntegerValue(item_heartbeat); + } + + public int getMode() { + return this.getOpcIntegerValue(item_mode); + } + + public int getStatus() { + return this.getOpcIntegerValue(item_status); + } + + public int getOutKiln_move() { + return this.getOpcIntegerValue(item_outKiln_move); + } + + public int getInKiln_move() { + return this.getOpcIntegerValue(item_inKiln_move); + } + + public int getInKiln_barcode() { + return this.getOpcIntegerValue(item_inKiln_barcode); + } + + public int getOutKiln_barcode() { + return this.getOpcIntegerValue(item_outKiln_barcode); + } + + public int getInKiln_device() { + return this.getOpcIntegerValue(item_inKiln_device); + } + + public int getOpen_time() { + return this.getOpcIntegerValue(item_open_time); + } + + public int getStandby_time() { + return this.getOpcIntegerValue(item_standby_time); + } + + public int getProduction_time() { + return this.getOpcIntegerValue(item_production_time); + } + + public int getError_time() { + return this.getOpcIntegerValue(item_error_time); + } + + public int getTo_command() { + return this.getOpcIntegerValue(item_to_command); + } + + public int getTo_target() { + return this.getOpcIntegerValue(item_to_target); + } + + public int getTo_task() { + return this.getOpcIntegerValue(item_to_task); + } + + //是否有货 + public int hasGoods(int move) { + return move; + } + + + public int getOpcIntegerValue(String protocol) { + Integer value = this.driver.getIntegeregerValue(protocol); + if (value == null) { + log.error(this.getDriver().getDeviceCode() + ":protocol " + protocol + " 信号同步异常!"); + setIsonline(false); + } else { + setIsonline(true); + return value; + } + return 0; + + } + + public static List getReadableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(item_mode, "工作状态", "DB600.B1", Boolean.valueOf(true))); + list.add(new ItemDto(item_status, "设备状态", "DB600.B2")); + list.add(new ItemDto(item_outKiln_move, "出窑光电", "DB600.B2")); + list.add(new ItemDto(item_inKiln_move, "入窑光电", "DB600.B2")); + list.add(new ItemDto(item_inKiln_barcode, "入窑条码", "DB600.B2")); + list.add(new ItemDto(item_outKiln_barcode, "出窑条码", "DB600.B2")); + list.add(new ItemDto(item_inKiln_device, "入窑设备号", "DB600.B2")); + list.add(new ItemDto(item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(item_error_time, "故障时间", "DB600.D8")); + return list; + } + + public static List getWriteableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_to_command, "下发命令反馈", "DB601.W2", Boolean.valueOf(true))); + list.add(new ItemDto(item_to_target, "下发目标站", "DB601.D8")); + list.add(new ItemDto(item_to_task, "下发任务号", "DB601.D8")); + return list; + } + +} + diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_truss/LnshKilnTrussDefination.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_truss/LnshKilnTrussDefination.java new file mode 100644 index 0000000..1ea802c --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_truss/LnshKilnTrussDefination.java @@ -0,0 +1,78 @@ +package org.nl.acs.device_driver.lnsh.lnsh_kiln_truss; + +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.defination.OpcDeviceDriverDefination; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceType; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * 晟华入窑桁架 + */ +@Service +public class LnshKilnTrussDefination implements OpcDeviceDriverDefination { + @Override + public String getDriverCode() { + return "lnsh_kiln_truss"; + } + + @Override + public String getDriverName() { + return "晟华-入窑桁架"; + } + + @Override + public String getDriverDescription() { + return "晟华-入窑桁架"; + } + + @Override + public DeviceDriver getDriverInstance(Device device) { + return (new LnshKilnTrussDeviceDriver()).setDevice(device).setDriverDefination(this); + } + + @Override + public Class getDeviceDriverType() { + return LnshKilnTrussDeviceDriver.class; + } + + @Override + public List getFitDeviceTypes() { + List types = new LinkedList(); + types.add(DeviceType.conveyor); + return types; + } + + @Override + public List getReadableItemDtos() { + return getReadableItemDtos2(); + } + + public static List getReadableItemDtos2() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(ItemProtocol.item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(ItemProtocol.item_mode, "工作状态", "DB600.B1", Boolean.valueOf(true))); + list.add(new ItemDto(ItemProtocol.item_status, "设备状态", "DB600.B2")); + list.add(new ItemDto(ItemProtocol.item_outKiln_move, "出窑光电", "DB600.B2")); + list.add(new ItemDto(ItemProtocol.item_inKiln_move, "入窑光电", "DB600.B2")); + list.add(new ItemDto(ItemProtocol.item_inKiln_barcode, "入窑条码", "DB600.B2")); + list.add(new ItemDto(ItemProtocol.item_outKiln_barcode, "出窑条码", "DB600.B2")); + list.add(new ItemDto(ItemProtocol.item_inKiln_device, "入窑设备号", "DB600.B2")); + list.add(new ItemDto(ItemProtocol.item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(ItemProtocol.item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(ItemProtocol.item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(ItemProtocol.item_error_time, "故障时间", "DB600.D8")); + return list; + } + + @Override + public List getWriteableItemDtos() { + return ItemProtocol.getWriteableItemDtos(); + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_truss/LnshKilnTrussDeviceDriver.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_truss/LnshKilnTrussDeviceDriver.java new file mode 100644 index 0000000..be61aa2 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_kiln_truss/LnshKilnTrussDeviceDriver.java @@ -0,0 +1,347 @@ +package org.nl.acs.device_driver.lnsh.lnsh_kiln_truss; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ReadUtil; +import org.nl.acs.device.service.DeviceService; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.RouteableDeviceDriver; +import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; +import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.instruction.service.dto.Instruction; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.WcsConfig; +import org.nl.acs.route.service.RouteLineService; +import org.nl.acs.route.service.dto.RouteLineDto; +import org.nl.acs.task.service.TaskService; +import org.nl.acs.task.service.dto.TaskDto; +import org.nl.modules.system.util.CodeUtil; +import org.nl.utils.SpringContextHolder; +import org.nl.wql.core.bean.WQLObject; +import org.openscada.opc.lib.da.Server; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.*; + +/** + * 晟华入窑桁架 + */ +@Slf4j +@Data +@RequiredArgsConstructor +public class LnshKilnTrussDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver { + protected ItemProtocol itemProtocol = new ItemProtocol(this); + @Autowired + InstructionService instructionService = SpringContextHolder.getBean("instructionServiceImpl"); + @Autowired + DeviceService deviceservice = SpringContextHolder.getBean("deviceServiceImpl"); + @Autowired + RouteLineService routelineserver = SpringContextHolder.getBean("routeLineServiceImpl"); + @Autowired + TaskService taskserver = SpringContextHolder.getBean("taskServiceImpl"); + + + String container; + String container_type_desc; + String last_container_type_desc; + String last_container; + //放货准备锁 + String putReadyLock = null; + //有货标记 + protected boolean has_goods_tag = false; + + + String device_code; + int mode = 0; + int error = 0; + int move = 0; + int action; + int io_action; + int task = 0; + int container_type = 0; + int last_mode = 0; + int last_error = 0; + int last_move = 0; + int last_task = 0; + int last_container_type; + Boolean isonline = true; + int hasGoods = 0; + Boolean iserror = false; + + boolean hasVehicle = false; + boolean isReady = false; + protected int instruction_num = 0; + protected int instruction_num_truth = 0; + boolean isFold = false; + private String assemble_check_tag; + private Boolean sampleMode0; + private Boolean sampleMode3; + private Integer sampleError; + private Boolean sampleOnline; + protected String displayMessage = null; + public int display_message_time_out = 30000; + public Date display_message_time; + protected String current_stage_instruction_message; + protected String last_stage_instruction_message; + Integer heartbeat_tag; + private Date instruction_require_time = new Date(); + private Date instruction_finished_time = new Date(); + + private int instruction_require_time_out = 3000; + boolean requireSucess = false; + + private int instruction_finished_time_out; + + int heartbeat; + int last_heartbeat; + private Date checkHeartbeattime = new Date(); + private Date last_checkHeartbeattime = new Date(); + + int branchProtocol = 0; + //当前指令 + Instruction inst = null; + //上次指令 + Instruction last_inst = null; + + //触摸屏手动触发任务 + private Boolean is_has_task = false; + + String message; + + @Override + public Device getDevice() { + return this.device; + } + + + @Override + public void execute() { + String message = null; + try { + device_code = this.getDeviceCode(); + + mode = this.itemProtocol.getMode(); + + if (mode != last_mode) { + this.setRequireSucess(false); + } + if (move != last_move) { + thingToNothing(); + } + if (error != last_error) { + } + if (container_type != last_container_type) { + } + + } catch (Exception var17) { + return; + } + + //急停 + if (this.isStop()) { + + //未在线无心跳 + } else if (!this.itemProtocol.getIsonline()) { + this.setIsonline(false); + this.setIserror(true); + message = "信号量同步异常"; + //未联机 + } else if (mode == 0) { + this.setIsonline(false); + this.setIserror(true); + message = "未联机"; + //有报警 + } else if (error != 0) { + this.setIsonline(false); + this.setIserror(true); + message = "有报警"; + //无报警 + } else { + this.setIsonline(true); + this.setIserror(false); + message = ""; + Instruction instruction = null; + List toInstructions; + switch (mode) { + case 1: + log.debug("设备运转模式:等待工作"); + break; + case 2: + + break; + case 3: + + break; + case 4: + break; + } + } + + last_mode = mode; + last_error = error; + last_move = move; + last_task = task; + last_container_type = container_type; + } + + + protected void thingToNothing() throws Exception { + this.setRequireSucess(false); + } + + public void finish_instruction(Instruction instruction) throws Exception { + instruction_finished(instruction); + } + + /** + * 完成指令 + * + * @param instruction + * @return + */ + public boolean instruction_finished(Instruction instruction) throws Exception { + Date date = new Date(); + if (date.getTime() - this.instruction_finished_time.getTime() < (long) this.instruction_finished_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_finished_time_out); + return false; + } else { + instructionService.finish(instruction.getInstruction_id()); + this.instruction_finished_time = date; + return true; + } + } + + /** + * 完成并创建下一条指令 + * + * @param instruction + * @param needCreateNext + * @return + */ + public boolean instruction_finished(Instruction instruction, boolean needCreateNext) { + Date date = new Date(); + if (date.getTime() - this.instruction_finished_time.getTime() < (long) this.instruction_finished_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_finished_time_out); + return false; + } else { + this.instruction_finished_time = date; + return true; + } + } + + + private Instruction findInstruction() { + Instruction instruction = null; + if (this.instruction_num != 0) { + instruction = (Instruction) instructionService.findByCodeFromCache(String.valueOf(instruction_num)); + } + if (instruction != null) { + //可进行校验 + + + } else { + List container_instructions = new ArrayList(); + String barcode = this.getLast_container(); + + if (!StrUtil.isEmpty(barcode)) { + Map map = new HashMap(); + map.put("vehicle_code", barcode); + container_instructions = instructionService.queryAll(map); + } + + if (((List) container_instructions).size() > 1) { + log.debug("容器存在多个指令"); + } else { + if (((List) container_instructions).size() > 0) { + instruction = (Instruction) ((List) container_instructions).get(0); + } + } + } + return instruction; + } + + + public boolean exe_error() { + if (this.error == 0) { + return true; + } else { + log.debug("设备报警"); + return false; + } + } + + public void set_last_container(String barcode, String type_desc) { + this.set_last_container(barcode); + this.set_last_container_type_desc(type_desc); + } + + public void set_last_container(String barcode) { + } + + public void set_last_container_type_desc(String type) { + } + + public boolean exe_business() { + return true; + } + + public void executing(Server server, Map itemMap) { + ReadUtil.write(itemMap, server); + } + + + public boolean instruction_require(String container_code) { + return instruction_require(container_code, WcsConfig.task_container_type_default_desc); + } + + /** + * 请求指令 + * + * @param container_code + * @param container_type + */ + public synchronized boolean instruction_require(String container_code, String container_type) { + Date date = new Date(); + if (date.getTime() - this.instruction_require_time.getTime() < (long) this.instruction_require_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_require_time_out); + return false; + } else { + this.instruction_require_time = date; + TaskDto dto = new TaskDto(); + String now = DateUtil.now(); + dto.setTask_id(IdUtil.simpleUUID()); + dto.setCreate_by(this.getDevice().getDevice_code()); + dto.setUpdate_by(this.getDevice().getDevice_code()); + dto.setStart_point_code(this.getDevice().getDevice_code()); + dto.setVehicle_code(container_code); + dto.setVehicle_type(container_type); + + String taskcode = CodeUtil.getNewCode("TASK_NO"); + dto.setTask_code("-" + taskcode); + dto.setTask_status("0"); + dto.setPriority("101"); + RouteLineDto jo = routelineserver.findByCode(this.getDevice().getDevice_code()); + String next_device_codecode = jo.getNext_device_code(); + if (StrUtil.isEmpty(next_device_codecode)) { + throw new RuntimeException("该设备未找到对应路由"); + } + dto.setNext_point_code(next_device_codecode); + dto.setUpdate_time(now); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("acs_task"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + + wo.insert(json); + requireSucess = false; + return true; + } + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_labeling_machine/ItemProtocol.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_labeling_machine/ItemProtocol.java new file mode 100644 index 0000000..5f766e6 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_labeling_machine/ItemProtocol.java @@ -0,0 +1,117 @@ +package org.nl.acs.device_driver.lnsh.lnsh_labeling_machine; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Data +public class ItemProtocol { + public static String item_heartbeat = "heartbeat"; + public static String item_mode = "mode"; + public static String item_status = "status"; + public static String item_open_time = "open_time"; + public static String item_close_time = "close_time"; + public static String item_standby_time = "standby_time "; + public static String item_production_time = "production_time"; + public static String item_error_time = "error_time"; + public static String item_labeling_qty = "labeling_qty"; + public static String item_to_command = "to_command"; + public static String item_to_material_code = "to_material_code"; + Boolean isonline; + + private LnshLabelingMachineDeviceDriver driver; + + public ItemProtocol(LnshLabelingMachineDeviceDriver driver) { + this.driver = driver; + } + + public int getHeartbeat() { + return this.getOpcIntegerValue(item_heartbeat); + } + + public int getMode() { + return this.getOpcIntegerValue(item_mode); + } + + public int getStatus() { + return this.getOpcIntegerValue(item_status); + } + + public int getOpen_time() { + return this.getOpcIntegerValue(item_open_time); + } + + public int getClose_time() { + return this.getOpcIntegerValue(item_close_time); + } + + public int getStandby_time() { + return this.getOpcIntegerValue(item_standby_time); + } + + public int getProduction_time() { + return this.getOpcIntegerValue(item_production_time); + } + + public int getError_time() { + return this.getOpcIntegerValue(item_error_time); + } + + public int getLabeling_qty() { + return this.getOpcIntegerValue(item_labeling_qty); + } + + public int getToCommand() { + return this.getOpcIntegerValue(item_to_command); + } + + public int getTo_material_code() { + return this.getOpcIntegerValue(item_to_material_code); + } + + //是否有货 + public int hasGoods(int move) { + return move; + } + + + public int getOpcIntegerValue(String protocol) { + Integer value = this.driver.getIntegeregerValue(protocol); + if (value == null) { + log.error(this.getDriver().getDeviceCode() + ":protocol " + protocol + " 信号同步异常!"); + setIsonline(false); + } else { + setIsonline(true); + return value; + } + return 0; + + } + + public static List getReadableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(item_mode, "工作状态", "DB600.B1", Boolean.valueOf(true))); + list.add(new ItemDto(item_status, "设备状态", "DB600.B2")); + list.add(new ItemDto(item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(item_close_time, "关机时间", "DB600.D5")); + list.add(new ItemDto(item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(item_error_time, "故障时间", "DB600.D8")); + list.add(new ItemDto(item_labeling_qty, "贴标数量", "DB600.D8")); + return list; + } + + public static List getWriteableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_to_command, "下发命令", "DB601.W2", Boolean.valueOf(true))); + list.add(new ItemDto(item_to_material_code, "下发物料编号", "DB601.D8")); + return list; + } + +} + diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_labeling_machine/LnshLabelingMachineDefination.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_labeling_machine/LnshLabelingMachineDefination.java new file mode 100644 index 0000000..dd72655 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_labeling_machine/LnshLabelingMachineDefination.java @@ -0,0 +1,75 @@ +package org.nl.acs.device_driver.lnsh.lnsh_labeling_machine; + +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.defination.OpcDeviceDriverDefination; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceType; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * 晟华贴标机 + */ +@Service +public class LnshLabelingMachineDefination implements OpcDeviceDriverDefination { + @Override + public String getDriverCode() { + return "lnsh_labeling_machine"; + } + + @Override + public String getDriverName() { + return "晟华-贴标机"; + } + + @Override + public String getDriverDescription() { + return "晟华-贴标机"; + } + + @Override + public DeviceDriver getDriverInstance(Device device) { + return (new LnshLabelingMachineDeviceDriver()).setDevice(device).setDriverDefination(this); + } + + @Override + public Class getDeviceDriverType() { + return LnshLabelingMachineDeviceDriver.class; + } + + @Override + public List getFitDeviceTypes() { + List types = new LinkedList(); + types.add(DeviceType.conveyor); + return types; + } + + @Override + public List getReadableItemDtos() { + return getReadableItemDtos2(); + } + + public static List getReadableItemDtos2() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(ItemProtocol.item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(ItemProtocol.item_mode, "工作状态", "DB600.B1", Boolean.valueOf(true))); + list.add(new ItemDto(ItemProtocol.item_status, "设备状态", "DB600.B2")); + list.add(new ItemDto(ItemProtocol.item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(ItemProtocol.item_close_time, "关机时间", "DB600.D5")); + list.add(new ItemDto(ItemProtocol.item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(ItemProtocol.item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(ItemProtocol.item_error_time, "故障时间", "DB600.D8")); + list.add(new ItemDto(ItemProtocol.item_labeling_qty, "贴标数量", "DB600.D8")); + return list; + } + + @Override + public List getWriteableItemDtos() { + return ItemProtocol.getWriteableItemDtos(); + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_labeling_machine/LnshLabelingMachineDeviceDriver.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_labeling_machine/LnshLabelingMachineDeviceDriver.java new file mode 100644 index 0000000..5e32ea4 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_labeling_machine/LnshLabelingMachineDeviceDriver.java @@ -0,0 +1,348 @@ +package org.nl.acs.device_driver.lnsh.lnsh_labeling_machine; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ReadUtil; +import org.nl.acs.device.service.DeviceService; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.RouteableDeviceDriver; +import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; +import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.instruction.service.dto.Instruction; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.WcsConfig; +import org.nl.acs.route.service.RouteLineService; +import org.nl.acs.route.service.dto.RouteLineDto; +import org.nl.acs.task.service.TaskService; +import org.nl.acs.task.service.dto.TaskDto; +import org.nl.modules.system.util.CodeUtil; +import org.nl.utils.SpringContextHolder; +import org.nl.wql.core.bean.WQLObject; +import org.openscada.opc.lib.da.Server; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.*; + +/** + * 晟华贴标机 + */ +@Slf4j +@Data +@RequiredArgsConstructor +public class LnshLabelingMachineDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver { + protected ItemProtocol itemProtocol = new ItemProtocol(this); + @Autowired + InstructionService instructionService = SpringContextHolder.getBean("instructionServiceImpl"); + @Autowired + DeviceService deviceservice = SpringContextHolder.getBean("deviceServiceImpl"); + @Autowired + RouteLineService routelineserver = SpringContextHolder.getBean("routeLineServiceImpl"); + @Autowired + TaskService taskserver = SpringContextHolder.getBean("taskServiceImpl"); + + + String container; + String container_type_desc; + String last_container_type_desc; + String last_container; + //放货准备锁 + String putReadyLock = null; + //有货标记 + protected boolean has_goods_tag = false; + + + String device_code; + int mode = 0; + int error = 0; + int move = 0; + int action; + int io_action; + int task = 0; + int container_type = 0; + int last_mode = 0; + int last_error = 0; + int last_move = 0; + int last_task = 0; + int last_container_type; + Boolean isonline = true; + int hasGoods = 0; + Boolean iserror = false; + + boolean hasVehicle = false; + boolean isReady = false; + protected int instruction_num = 0; + protected int instruction_num_truth = 0; + boolean isFold = false; + private String assemble_check_tag; + private Boolean sampleMode0; + private Boolean sampleMode3; + private Integer sampleError; + private Boolean sampleOnline; + protected String displayMessage = null; + public int display_message_time_out = 30000; + public Date display_message_time; + protected String current_stage_instruction_message; + protected String last_stage_instruction_message; + Integer heartbeat_tag; + private Date instruction_require_time = new Date(); + private Date instruction_finished_time = new Date(); + + private int instruction_require_time_out = 3000; + boolean requireSucess = false; + + private int instruction_finished_time_out; + + int heartbeat; + int last_heartbeat; + private Date checkHeartbeattime = new Date(); + private Date last_checkHeartbeattime = new Date(); + + int branchProtocol = 0; + //当前指令 + Instruction inst = null; + //上次指令 + Instruction last_inst = null; + + //触摸屏手动触发任务 + private Boolean is_has_task = false; + + String message; + + @Override + public Device getDevice() { + return this.device; + } + + + @Override + public void execute() { + String message = null; + try { + device_code = this.getDeviceCode(); + + mode = this.itemProtocol.getMode(); + + if (mode != last_mode) { + this.setRequireSucess(false); + } + if (move != last_move) { + thingToNothing(); + } + if (error != last_error) { + } + if (container_type != last_container_type) { + } + + } catch (Exception var17) { + return; + } + + //急停 + if (this.isStop()) { + + //未在线无心跳 + } else if (!this.itemProtocol.getIsonline()) { + this.setIsonline(false); + this.setIserror(true); + message = "信号量同步异常"; + //未联机 + } else if (mode == 0) { + this.setIsonline(false); + this.setIserror(true); + message = "未联机"; + //有报警 + } else if (error != 0) { + this.setIsonline(false); + this.setIserror(true); + message = "有报警"; + //无报警 + } else { + this.setIsonline(true); + this.setIserror(false); + message = ""; + Instruction instruction = null; + List toInstructions; + switch (mode) { + case 1: + log.debug("设备运转模式:等待工作"); + break; + case 2: + + break; + case 3: + + break; + case 4: + break; + } + } + + last_mode = mode; + last_error = error; + last_move = move; + last_task = task; + last_container_type = container_type; + } + + + protected void thingToNothing() throws Exception { + this.setRequireSucess(false); + } + + public void finish_instruction(Instruction instruction) throws Exception { + instruction_finished(instruction); + } + + /** + * 完成指令 + * + * @param instruction + * @return + */ + public boolean instruction_finished(Instruction instruction) throws Exception { + Date date = new Date(); + if (date.getTime() - this.instruction_finished_time.getTime() < (long) this.instruction_finished_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_finished_time_out); + return false; + } else { + instructionService.finish(instruction.getInstruction_id()); + this.instruction_finished_time = date; + return true; + } + } + + /** + * 完成并创建下一条指令 + * + * @param instruction + * @param needCreateNext + * @return + */ + public boolean instruction_finished(Instruction instruction, boolean needCreateNext) { + Date date = new Date(); + if (date.getTime() - this.instruction_finished_time.getTime() < (long) this.instruction_finished_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_finished_time_out); + return false; + } else { + this.instruction_finished_time = date; + return true; + } + } + + + private Instruction findInstruction() { + Instruction instruction = null; + if (this.instruction_num != 0) { + instruction = (Instruction) instructionService.findByCodeFromCache(String.valueOf(instruction_num)); + } + if (instruction != null) { + //可进行校验 + + + } else { + List container_instructions = new ArrayList(); + String barcode = this.getLast_container(); + + if (!StrUtil.isEmpty(barcode)) { + Map map = new HashMap(); + map.put("vehicle_code", barcode); + container_instructions = instructionService.queryAll(map); + } + + if (((List) container_instructions).size() > 1) { + log.debug("容器存在多个指令"); + } else { + if (((List) container_instructions).size() > 0) { + instruction = (Instruction) ((List) container_instructions).get(0); + } + } + } + return instruction; + } + + + public boolean exe_error() { + if (this.error == 0) { + return true; + } else { + log.debug("设备报警"); + return false; + } + } + + public void set_last_container(String barcode, String type_desc) { + this.set_last_container(barcode); + this.set_last_container_type_desc(type_desc); + } + + public void set_last_container(String barcode) { + } + + public void set_last_container_type_desc(String type) { + } + + public boolean exe_business() { + return true; + } + + public void executing(Server server, Map itemMap) { + ReadUtil.write(itemMap, server); + } + + public boolean instruction_require(String container_code) { + return instruction_require(container_code, WcsConfig.task_container_type_default_desc); + } + + + + /** + * 请求指令 + * + * @param container_code + * @param container_type + */ + public synchronized boolean instruction_require(String container_code, String container_type) { + Date date = new Date(); + if (date.getTime() - this.instruction_require_time.getTime() < (long) this.instruction_require_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_require_time_out); + return false; + } else { + this.instruction_require_time = date; + TaskDto dto = new TaskDto(); + String now = DateUtil.now(); + dto.setTask_id(IdUtil.simpleUUID()); + dto.setCreate_by(this.getDevice().getDevice_code()); + dto.setUpdate_by(this.getDevice().getDevice_code()); + dto.setStart_point_code(this.getDevice().getDevice_code()); + dto.setVehicle_code(container_code); + dto.setVehicle_type(container_type); + + String taskcode = CodeUtil.getNewCode("TASK_NO"); + dto.setTask_code("-" + taskcode); + dto.setTask_status("0"); + dto.setPriority("101"); + RouteLineDto jo = routelineserver.findByCode(this.getDevice().getDevice_code()); + String next_device_codecode = jo.getNext_device_code(); + if (StrUtil.isEmpty(next_device_codecode)) { + throw new RuntimeException("该设备未找到对应路由"); + } + dto.setNext_point_code(next_device_codecode); + dto.setUpdate_time(now); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("acs_task"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + + wo.insert(json); + requireSucess = false; + return true; + } + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_mixing_mill/ItemProtocol.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_mixing_mill/ItemProtocol.java new file mode 100644 index 0000000..887a705 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_mixing_mill/ItemProtocol.java @@ -0,0 +1,151 @@ +package org.nl.acs.device_driver.lnsh.lnsh_mixing_mill; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Data +public class ItemProtocol { + + public static String item_heartbeat = "heartbeat"; + public static String item_mode = "mode"; + public static String item_status = "status"; + public static String item_error = "error"; + public static String item_open_time = "open_time"; + public static String item_standby_time = "standby_time "; + public static String item_production_time = "production_time"; + public static String item_error_time = "error_time"; + public static String item_weight = "weight"; + public static String item_order_No = "order_No"; + public static String item_mix_num = "mix_num"; + public static String item_material = "material"; + public static String item_to_command = "to_command"; + public static String item_to_error = "to_error"; + public static String item_to_task = "to_task"; + public static String item_to_weight = "to_weight"; + public static String item_to_material_code = "to_material_code"; + + + private LnshMixingMillDeviceDriver driver; + + public ItemProtocol(LnshMixingMillDeviceDriver driver) { + this.driver = driver; + } + + public int getMode() { + return this.getOpcIntegerValue(item_heartbeat); + } + + public int getStatus() { + return this.getOpcIntegerValue(item_status); + } + + public int getError() { + return this.getOpcIntegerValue(item_error); + } + + public int getOpen_time() { + return this.getOpcIntegerValue(item_open_time); + } + + public int getWeight() { + return this.getOpcIntegerValue(item_weight); + } + + public int getStandby_time() { + return this.getOpcIntegerValue(item_standby_time); + } + + public int getProduction_time() { + return this.getOpcIntegerValue(item_production_time); + } + + public int getError_time() { + return this.getOpcIntegerValue(item_error_time); + } + + public int getMaterial() { + return this.getOpcIntegerValue(item_material); + } + + public int getOrder_No() { + return this.getOpcIntegerValue(item_order_No); + } + + public int getMix_num() { + return this.getOpcIntegerValue(item_mix_num); + } + + public int getTo_error() { + return this.getOpcIntegerValue(item_to_error); + } + + public int getTo_task() { + return this.getOpcIntegerValue(item_to_task); + } + + public int getTo_command() { + return this.getOpcIntegerValue(item_to_command); + } + + public int getTo_weight() { + return this.getOpcIntegerValue(item_to_weight); + } + + public int getTo_material_code() { + return this.getOpcIntegerValue(item_to_material_code); + } + + //是否有货 + public int hasGoods(int move) { + return move; + } + + Boolean isonline; + + public int getOpcIntegerValue(String protocol) { + Integer value = this.driver.getIntegeregerValue(protocol); + if (value == null) { + log.error(this.getDriver().getDeviceCode() + ":protocol " + protocol + " 信号同步异常!"); + setIsonline(false); + } else { + setIsonline(true); + return value; + } + return 0; + + } + + public static List getReadableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(item_mode, "工作状态", "DB600.B2", Boolean.valueOf(true))); + list.add(new ItemDto(item_status, "设备状态", "DB600.B3")); + list.add(new ItemDto(item_error, "故障代码", "DB600.B3")); + list.add(new ItemDto(item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(item_error_time, "故障时间", "DB600.D8")); + list.add(new ItemDto(item_weight, "当前生产重量", "DB600.D8")); + list.add(new ItemDto(item_order_No, "工单号", "DB600.D8"));; + list.add(new ItemDto(item_mix_num, "碾次", "DB600.D8"));; + list.add(new ItemDto(item_material, "当前生产物料", "DB600.D9")); + return list; + } + + public static List getWriteableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_to_command, "反馈", "DB601.W2", Boolean.valueOf(true))); + list.add(new ItemDto(item_to_error, "error", "DB601.W2")); + list.add(new ItemDto(item_to_task, "工单号", "DB601.W2")); + list.add(new ItemDto(item_to_weight, "生产重量", "DB601.W2")); + list.add(new ItemDto(item_to_material_code, "下发物料编号", "DB601.W10")); + return list; + } + +} + diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_mixing_mill/LnshMixingMillDefination.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_mixing_mill/LnshMixingMillDefination.java new file mode 100644 index 0000000..e99b3b9 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_mixing_mill/LnshMixingMillDefination.java @@ -0,0 +1,80 @@ +package org.nl.acs.device_driver.lnsh.lnsh_mixing_mill; + +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.defination.OpcDeviceDriverDefination; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceType; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * 晟华混碾机 + * + */ +@Service +public class LnshMixingMillDefination implements OpcDeviceDriverDefination { + @Override + public String getDriverCode() { + return "lnsh_mixing_mill"; + } + + @Override + public String getDriverName() { + return "晟华-混碾机"; + } + + @Override + public String getDriverDescription() { + return "晟华-混碾机"; + } + + @Override + public DeviceDriver getDriverInstance(Device device) { + return (new LnshMixingMillDeviceDriver()).setDevice(device).setDriverDefination(this); + + } + + @Override + public Class getDeviceDriverType() { + return LnshMixingMillDeviceDriver.class; + } + + @Override + public List getFitDeviceTypes() { + List types = new LinkedList(); + types.add(DeviceType.conveyor); + return types; + } + + @Override + public List getReadableItemDtos() { + return getReadableItemDtos2(); + } + + public static List getReadableItemDtos2() { + List list = new ArrayList(); + list.add(new ItemDto(ItemProtocol.item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(ItemProtocol.item_mode, "工作状态", "DB600.B2", Boolean.valueOf(true))); + list.add(new ItemDto(ItemProtocol.item_status, "设备状态", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_error, "故障代码", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(ItemProtocol.item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(ItemProtocol.item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(ItemProtocol.item_error_time, "故障时间", "DB600.D8")); + list.add(new ItemDto(ItemProtocol.item_weight, "当前生产重量", "DB600.D8")); + list.add(new ItemDto(ItemProtocol.item_order_No, "工单号", "DB600.D8"));; + list.add(new ItemDto(ItemProtocol.item_mix_num, "碾次", "DB600.D8"));; + list.add(new ItemDto(ItemProtocol.item_material, "当前生产物料", "DB600.D9")); + return list; + } + + @Override + public List getWriteableItemDtos() { + return ItemProtocol.getWriteableItemDtos(); + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_mixing_mill/LnshMixingMillDeviceDriver.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_mixing_mill/LnshMixingMillDeviceDriver.java new file mode 100644 index 0000000..8bc820b --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_mixing_mill/LnshMixingMillDeviceDriver.java @@ -0,0 +1,325 @@ +package org.nl.acs.device_driver.lnsh.lnsh_mixing_mill; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ReadUtil; +import org.nl.acs.device.service.DeviceService; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.RouteableDeviceDriver; +import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; +import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.instruction.service.dto.Instruction; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceAppService; +import org.nl.acs.opc.DeviceAppServiceImpl; +import org.nl.acs.opc.WcsConfig; +import org.nl.acs.route.service.RouteLineService; +import org.nl.acs.route.service.dto.RouteLineDto; +import org.nl.acs.task.service.TaskService; +import org.nl.acs.task.service.dto.TaskDto; +import org.nl.modules.system.util.CodeUtil; +import org.nl.utils.SpringContextHolder; +import org.nl.wql.core.bean.WQLObject; +import org.openscada.opc.lib.da.Server; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 晟华混碾机 + */ +@Slf4j +@Data +@RequiredArgsConstructor +public class LnshMixingMillDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver { + protected ItemProtocol itemProtocol = new ItemProtocol(this); + @Autowired + InstructionService instructionService = SpringContextHolder.getBean("instructionServiceImpl"); + @Autowired + DeviceService deviceservice = SpringContextHolder.getBean("deviceServiceImpl"); + @Autowired + RouteLineService routelineserver = SpringContextHolder.getBean("routeLineServiceImpl"); + @Autowired + TaskService taskserver = SpringContextHolder.getBean("taskServiceImpl"); + String container; + String container_type_desc; + String last_container_type_desc; + String last_container; + //放货准备锁 + String putReadyLock = null; + //有货标记 + protected boolean has_goods_tag = false; + + int mode = 0; + int error = 0; + int last_mode = 0; + int last_error = 0; + Boolean isonline = true; + int hasGoods = 0; + String message = null; + Boolean iserror = false; + + + boolean hasVehicle = false; + boolean isReady = false; + protected int instruction_num = 0; + protected int instruction_num_truth = 0; + boolean isFold = false; + private String assemble_check_tag; + + protected String current_stage_instruction_message; + protected String last_stage_instruction_message; + Integer heartbeat_tag; + private Date instruction_require_time = new Date(); + private Date instruction_finished_time = new Date(); + + private int instruction_require_time_out; + boolean requireSucess = false; + + private int instruction_finished_time_out; + + int branchProtocol = 0; + //备注 + String remark; + //数量 + String qty; + //物料 + String material; + //批次 + String batch; + //当前指令 + Instruction inst = null; + //上次指令 + Instruction last_inst = null; + + //触摸屏手动触发任务 + private Boolean is_has_task = false; + + //申请搬运任务 + private Boolean apply_handling = false; + //申请物料 + private Boolean apply_material = false; + + //暂定 0就绪 1请求取货 2取货完成 3请求放货 4放货完成 5取货完成离开 6放货完成离开 7请求进入区域 8请求离开区域 + int flag; + + String devicecode; + + @Override + public Device getDevice() { + return this.device; + } + + + @Override + public void execute() { + String message = null; + try { + String device_code = this.getDeviceCode(); + mode = this.itemProtocol.getMode(); + + if (mode != last_mode) { + this.setRequireSucess(false); + } + if (error != last_error) { + } + + } catch (Exception var17) { + return; + } + + if (!this.itemProtocol.getIsonline()) { + this.setIsonline(false); + this.setIserror(true); + message = "信号量同步异常"; + //未联机 + } else if (mode == 0) { + this.setIsonline(false); + this.setIserror(true); + message = "未联机"; + //有报警 + } else if (error != 0) { + this.setIsonline(false); + this.setIserror(true); + message = "有报警"; + //无报警 + } else { + this.setIsonline(true); + this.setIserror(false); + message = ""; + Instruction instruction = null; + List toInstructions; + switch (mode) { + case 1: + log.debug("设备运转模式:等待工作"); + return; + case 2: + if (material.length() > 0 && qty.length() > 0 && !requireSucess) { + this.instruction_require(container); + } + } + + switch (flag) { + //取货完成 + case 1: + writing(2); + return; + //放货完成 + case 2: + writing(3); + return; + + } + + } + last_mode = mode; + last_error = error; + + } + + + public boolean exe_error() { + if (this.error == 0) { + return true; + } else { + log.debug("设备报警"); + return false; + } + } + + protected void thingToNothing() { + log.debug("从有货到无货 清理数据"); + this.set_last_container(container, container_type_desc); + } + + public void set_last_container(String barcode, String type_desc) { + this.set_last_container(barcode); + this.set_last_container_type_desc(type_desc); + } + + public void set_last_container(String barcode) { + } + + public void set_last_container_type_desc(String type) { + } + + public boolean exe_business() { + return true; + } + + protected void executing(Instruction instruction) { + this.executing(1, instruction, ""); + } + + public void executing(int command, Instruction instruction, String appendMessage) { + String to_command = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code() + + "." + ItemProtocol.item_to_command; + String to_material_code = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code() + + "." + ItemProtocol.item_to_material_code; + if (appendMessage == null) { + appendMessage = ""; + } + if (instruction != null) { + instruction_num = Integer.parseInt(instruction.getInstruction_code()); + } + String opcservcerid = this.getDevice().getOpc_server_id(); + Server server = ReadUtil.getServer(opcservcerid); + Map itemMap = new HashMap(); + itemMap.put(to_command, 1); + ReadUtil.write(itemMap, server); + + } + + public void executing(Server server, Map itemMap) { + ReadUtil.write(itemMap, server); + } + + public void writing(int command) { + String to_command = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code() + + "." + ItemProtocol.item_to_command; + + String opcservcerid = this.getDevice().getOpc_server_id(); + Server server = ReadUtil.getServer(opcservcerid); + Map itemMap = new HashMap(); + itemMap.put(to_command, command); + ReadUtil.write(itemMap, server); + + } + + public void writing(int type, int command) { + String to_command = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code() + + "." + ItemProtocol.item_to_command; + String to_material_code = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code() + + "." + ItemProtocol.item_to_material_code; + String opcservcerid = this.getDevice().getOpc_server_id(); + Server server = ReadUtil.getServer(opcservcerid); + Map itemMap = new HashMap(); + if (type == 1) { + itemMap.put(to_command, command); + } else if (type == 2) { + itemMap.put(to_material_code, command); + + } + ReadUtil.write(itemMap, server); + + } + + public boolean instruction_require(String container_code) { + return instruction_require(container_code, WcsConfig.task_container_type_default_desc); + } + + /** + * 请求指令 + * + * @param container_code + * @param container_type + */ + public synchronized boolean instruction_require(String container_code, String container_type) { + Date date = new Date(); + if (date.getTime() - this.instruction_require_time.getTime() < (long) this.instruction_require_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_require_time_out); + return false; + } else { + this.instruction_require_time = date; + TaskDto dto = new TaskDto(); + String now = DateUtil.now(); + dto.setTask_id(IdUtil.simpleUUID()); + dto.setCreate_by(this.getDevice().getDevice_code()); + dto.setUpdate_by(this.getDevice().getDevice_code()); + dto.setStart_point_code(this.getDevice().getDevice_code()); + dto.setVehicle_code(container_code); + dto.setVehicle_type(container_type); + + String taskcode = CodeUtil.getNewCode("TASK_NO"); + dto.setTask_code("-" + taskcode); + dto.setTask_status("0"); + dto.setPriority("101"); + RouteLineDto jo = routelineserver.findByCode(this.getDevice().getDevice_code()); + String next_device_codecode = jo.getNext_device_code(); + if (StrUtil.isEmpty(next_device_codecode)) { + throw new RuntimeException("该设备未找到对应路由"); + } + dto.setNext_point_code(next_device_codecode); + dto.setUpdate_time(now); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("acs_task"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + + wo.insert(json); + requireSucess = false; + return true; + } + } + + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_out_kiln_truss/ItemProtocol.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_out_kiln_truss/ItemProtocol.java new file mode 100644 index 0000000..0f8dd14 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_out_kiln_truss/ItemProtocol.java @@ -0,0 +1,129 @@ +package org.nl.acs.device_driver.lnsh.lnsh_out_kiln_truss; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Data +public class ItemProtocol { + public static String item_heartbeat = "heartbeat"; + public static String item_mode = "mode"; + public static String item_status = "status"; + public static String item_outKiln_move = "outKiln_move"; + public static String item_outKiln_barcode = "outKiln_barcode"; + public static String item_outKiln_device = "outKiln_device"; + public static String item_open_time = "open_time"; + public static String item_standby_time = "standby_time "; + public static String item_production_time = "production_time"; + public static String item_error_time = "error_time"; + public static String item_to_command = "to_command"; + public static String item_to_target = "to_target"; + public static String item_to_task = "to_task"; + Boolean isonline; + + private LnshOutKilnTrussDeviceDriver driver; + + public ItemProtocol(LnshOutKilnTrussDeviceDriver driver) { + this.driver = driver; + } + + public int getHeartbeat() { + return this.getOpcIntegerValue(item_heartbeat); + } + + public int getMode() { + return this.getOpcIntegerValue(item_mode); + } + + public int getStatus() { + return this.getOpcIntegerValue(item_status); + } + + public int getOutKiln_move() { + return this.getOpcIntegerValue(item_outKiln_move); + } + + public int getOutKiln_barcode() { + return this.getOpcIntegerValue(item_outKiln_barcode); + } + + public int getOutKiln_device() { + return this.getOpcIntegerValue(item_outKiln_device); + } + + public int getOpen_time() { + return this.getOpcIntegerValue(item_open_time); + } + + public int getStandby_time() { + return this.getOpcIntegerValue(item_standby_time); + } + + public int getProduction_time() { + return this.getOpcIntegerValue(item_production_time); + } + + public int getError_time() { + return this.getOpcIntegerValue(item_error_time); + } + + public int getToCommand() { + return this.getOpcIntegerValue(item_to_command); + } + + public int getToTarget() { + return this.getOpcIntegerValue(item_to_target); + } + + public int getToTask() { + return this.getOpcIntegerValue(item_to_task); + } + + //是否有货 + public int hasGoods(int move) { + return move; + } + + + public int getOpcIntegerValue(String protocol) { + Integer value = this.driver.getIntegeregerValue(protocol); + if (value == null) { + log.error(this.getDriver().getDeviceCode() + ":protocol " + protocol + " 信号同步异常!"); + setIsonline(false); + } else { + setIsonline(true); + return value; + } + return 0; + + } + + public static List getReadableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(item_mode, "工作状态", "DB600.B1", Boolean.valueOf(true))); + list.add(new ItemDto(item_status, "设备状态", "DB600.B2")); + list.add(new ItemDto(item_outKiln_move, "出窑光电", "DB600.B2")); + list.add(new ItemDto(item_outKiln_barcode, "出窑条码", "DB600.B2")); + list.add(new ItemDto(item_outKiln_device, "出窑设备", "DB600.B2")); + list.add(new ItemDto(item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(item_error_time, "故障时间", "DB600.D8")); + return list; + } + + public static List getWriteableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_to_command, "下发命令反馈", "DB601.W2", Boolean.valueOf(true))); + list.add(new ItemDto(item_to_target, "下发目标站", "DB601.W4")); + list.add(new ItemDto(item_to_task, "下发任务号", "DB601.D8")); + return list; + } + +} + diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_out_kiln_truss/LnshOutKilnTrussDefination.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_out_kiln_truss/LnshOutKilnTrussDefination.java new file mode 100644 index 0000000..0ac8356 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_out_kiln_truss/LnshOutKilnTrussDefination.java @@ -0,0 +1,76 @@ +package org.nl.acs.device_driver.lnsh.lnsh_out_kiln_truss; + +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.defination.OpcDeviceDriverDefination; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceType; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * 晟华出窑桁架 + */ +@Service +public class LnshOutKilnTrussDefination implements OpcDeviceDriverDefination { + @Override + public String getDriverCode() { + return "lnsh_out_kiln_truss"; + } + + @Override + public String getDriverName() { + return "晟华-出窑桁架"; + } + + @Override + public String getDriverDescription() { + return "晟华-出窑桁架"; + } + + @Override + public DeviceDriver getDriverInstance(Device device) { + return (new LnshOutKilnTrussDeviceDriver()).setDevice(device).setDriverDefination(this); + } + + @Override + public Class getDeviceDriverType() { + return LnshOutKilnTrussDeviceDriver.class; + } + + @Override + public List getFitDeviceTypes() { + List types = new LinkedList(); + types.add(DeviceType.conveyor); + return types; + } + + @Override + public List getReadableItemDtos() { + return getReadableItemDtos2(); + } + + public static List getReadableItemDtos2() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(ItemProtocol.item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(ItemProtocol.item_mode, "工作状态", "DB600.B1", Boolean.valueOf(true))); + list.add(new ItemDto(ItemProtocol.item_status, "设备状态", "DB600.B2")); + list.add(new ItemDto(ItemProtocol.item_outKiln_move, "出窑光电", "DB600.B2")); + list.add(new ItemDto(ItemProtocol.item_outKiln_barcode, "出窑条码", "DB600.B2")); + list.add(new ItemDto(ItemProtocol.item_outKiln_device, "出窑设备", "DB600.B2")); + list.add(new ItemDto(ItemProtocol.item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(ItemProtocol.item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(ItemProtocol.item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(ItemProtocol.item_error_time, "故障时间", "DB600.D8")); + return list; + } + + @Override + public List getWriteableItemDtos() { + return ItemProtocol.getWriteableItemDtos(); + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_out_kiln_truss/LnshOutKilnTrussDeviceDriver.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_out_kiln_truss/LnshOutKilnTrussDeviceDriver.java new file mode 100644 index 0000000..8a9c7fc --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_out_kiln_truss/LnshOutKilnTrussDeviceDriver.java @@ -0,0 +1,346 @@ +package org.nl.acs.device_driver.lnsh.lnsh_out_kiln_truss; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ReadUtil; +import org.nl.acs.device.service.DeviceService; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.RouteableDeviceDriver; +import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; +import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.instruction.service.dto.Instruction; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.WcsConfig; +import org.nl.acs.route.service.RouteLineService; +import org.nl.acs.route.service.dto.RouteLineDto; +import org.nl.acs.task.service.TaskService; +import org.nl.acs.task.service.dto.TaskDto; +import org.nl.modules.system.util.CodeUtil; +import org.nl.utils.SpringContextHolder; +import org.nl.wql.core.bean.WQLObject; +import org.openscada.opc.lib.da.Server; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.*; + +/** + * 晟华出窑桁架 + */ +@Slf4j +@Data +@RequiredArgsConstructor +public class LnshOutKilnTrussDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver { + protected ItemProtocol itemProtocol = new ItemProtocol(this); + @Autowired + InstructionService instructionService = SpringContextHolder.getBean("instructionServiceImpl"); + @Autowired + DeviceService deviceservice = SpringContextHolder.getBean("deviceServiceImpl"); + @Autowired + RouteLineService routelineserver = SpringContextHolder.getBean("routeLineServiceImpl"); + @Autowired + TaskService taskserver = SpringContextHolder.getBean("taskServiceImpl"); + + + String container; + String container_type_desc; + String last_container_type_desc; + String last_container; + //放货准备锁 + String putReadyLock = null; + //有货标记 + protected boolean has_goods_tag = false; + + + String device_code; + int mode = 0; + int error = 0; + int move = 0; + int action; + int io_action; + int task = 0; + int container_type = 0; + int last_mode = 0; + int last_error = 0; + int last_move = 0; + int last_task = 0; + int last_container_type; + Boolean isonline = true; + int hasGoods = 0; + Boolean iserror = false; + + boolean hasVehicle = false; + boolean isReady = false; + protected int instruction_num = 0; + protected int instruction_num_truth = 0; + boolean isFold = false; + private String assemble_check_tag; + private Boolean sampleMode0; + private Boolean sampleMode3; + private Integer sampleError; + private Boolean sampleOnline; + protected String displayMessage = null; + public int display_message_time_out = 30000; + public Date display_message_time; + protected String current_stage_instruction_message; + protected String last_stage_instruction_message; + Integer heartbeat_tag; + private Date instruction_require_time = new Date(); + private Date instruction_finished_time = new Date(); + + private int instruction_require_time_out = 3000; + boolean requireSucess = false; + + private int instruction_finished_time_out; + + int heartbeat; + int last_heartbeat; + private Date checkHeartbeattime = new Date(); + private Date last_checkHeartbeattime = new Date(); + + int branchProtocol = 0; + //当前指令 + Instruction inst = null; + //上次指令 + Instruction last_inst = null; + + //触摸屏手动触发任务 + private Boolean is_has_task = false; + + String message; + + @Override + public Device getDevice() { + return this.device; + } + + + @Override + public void execute() { + String message = null; + try { + device_code = this.getDeviceCode(); + + mode = this.itemProtocol.getMode(); + + if (mode != last_mode) { + this.setRequireSucess(false); + } + if (move != last_move) { + thingToNothing(); + } + if (error != last_error) { + } + if (container_type != last_container_type) { + } + + } catch (Exception var17) { + return; + } + + //急停 + if (this.isStop()) { + + //未在线无心跳 + } else if (!this.itemProtocol.getIsonline()) { + this.setIsonline(false); + this.setIserror(true); + message = "信号量同步异常"; + //未联机 + } else if (mode == 0) { + this.setIsonline(false); + this.setIserror(true); + message = "未联机"; + //有报警 + } else if (error != 0) { + this.setIsonline(false); + this.setIserror(true); + message = "有报警"; + //无报警 + } else { + this.setIsonline(true); + this.setIserror(false); + message = ""; + Instruction instruction = null; + List toInstructions; + switch (mode) { + case 1: + log.debug("设备运转模式:等待工作"); + break; + case 2: + + break; + case 3: + + break; + case 4: + break; + } + } + + last_mode = mode; + last_error = error; + last_move = move; + last_task = task; + last_container_type = container_type; + } + + + protected void thingToNothing() throws Exception { + this.setRequireSucess(false); + } + + public void finish_instruction(Instruction instruction) throws Exception { + instruction_finished(instruction); + } + + /** + * 完成指令 + * + * @param instruction + * @return + */ + public boolean instruction_finished(Instruction instruction) throws Exception { + Date date = new Date(); + if (date.getTime() - this.instruction_finished_time.getTime() < (long) this.instruction_finished_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_finished_time_out); + return false; + } else { + instructionService.finish(instruction.getInstruction_id()); + this.instruction_finished_time = date; + return true; + } + } + + /** + * 完成并创建下一条指令 + * + * @param instruction + * @param needCreateNext + * @return + */ + public boolean instruction_finished(Instruction instruction, boolean needCreateNext) { + Date date = new Date(); + if (date.getTime() - this.instruction_finished_time.getTime() < (long) this.instruction_finished_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_finished_time_out); + return false; + } else { + this.instruction_finished_time = date; + return true; + } + } + + + private Instruction findInstruction() { + Instruction instruction = null; + if (this.instruction_num != 0) { + instruction = (Instruction) instructionService.findByCodeFromCache(String.valueOf(instruction_num)); + } + if (instruction != null) { + //可进行校验 + + + } else { + List container_instructions = new ArrayList(); + String barcode = this.getLast_container(); + + if (!StrUtil.isEmpty(barcode)) { + Map map = new HashMap(); + map.put("vehicle_code", barcode); + container_instructions = instructionService.queryAll(map); + } + + if (((List) container_instructions).size() > 1) { + log.debug("容器存在多个指令"); + } else { + if (((List) container_instructions).size() > 0) { + instruction = (Instruction) ((List) container_instructions).get(0); + } + } + } + return instruction; + } + + + public boolean exe_error() { + if (this.error == 0) { + return true; + } else { + log.debug("设备报警"); + return false; + } + } + + public void set_last_container(String barcode, String type_desc) { + this.set_last_container(barcode); + this.set_last_container_type_desc(type_desc); + } + + public void set_last_container(String barcode) { + } + + public void set_last_container_type_desc(String type) { + } + + public boolean exe_business() { + return true; + } + + public void executing(Server server, Map itemMap) { + ReadUtil.write(itemMap, server); + } + + public boolean instruction_require(String container_code) { + return instruction_require(container_code, WcsConfig.task_container_type_default_desc); + } + + /** + * 请求指令 + * + * @param container_code + * @param container_type + */ + public synchronized boolean instruction_require(String container_code, String container_type) { + Date date = new Date(); + if (date.getTime() - this.instruction_require_time.getTime() < (long) this.instruction_require_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_require_time_out); + return false; + } else { + this.instruction_require_time = date; + TaskDto dto = new TaskDto(); + String now = DateUtil.now(); + dto.setTask_id(IdUtil.simpleUUID()); + dto.setCreate_by(this.getDevice().getDevice_code()); + dto.setUpdate_by(this.getDevice().getDevice_code()); + dto.setStart_point_code(this.getDevice().getDevice_code()); + dto.setVehicle_code(container_code); + dto.setVehicle_type(container_type); + + String taskcode = CodeUtil.getNewCode("TASK_NO"); + dto.setTask_code("-" + taskcode); + dto.setTask_status("0"); + dto.setPriority("101"); + RouteLineDto jo = routelineserver.findByCode(this.getDevice().getDevice_code()); + String next_device_codecode = jo.getNext_device_code(); + if (StrUtil.isEmpty(next_device_codecode)) { + throw new RuntimeException("该设备未找到对应路由"); + } + dto.setNext_point_code(next_device_codecode); + dto.setUpdate_time(now); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("acs_task"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + + wo.insert(json); + requireSucess = false; + return true; + } + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_line/ItemProtocol.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_line/ItemProtocol.java new file mode 100644 index 0000000..882a915 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_line/ItemProtocol.java @@ -0,0 +1,129 @@ +package org.nl.acs.device_driver.lnsh.lnsh_package_line; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Data +public class ItemProtocol { + public static String item_heartbeat = "heartbeat"; + public static String item_mode = "mode"; + public static String item_status = "status"; + public static String item_open_time = "open_time"; + public static String item_standby_time = "standby_time "; + public static String item_production_time = "production_time"; + public static String item_error_time = "error_time"; + public static String item_barcode = "barcode"; + public static String item_to_command = "to_command"; + public static String item_to_target = "to_target"; + public static String item_to_task = "to_task"; + public static String item_to_code_message = "to_code_message"; + public static String item_to_isPackage = "to_isPackage"; + Boolean isonline; + + private LnshPackageLineDeviceDriver driver; + + public ItemProtocol(LnshPackageLineDeviceDriver driver) { + this.driver = driver; + } + + public int getHeartbeat() { + return this.getOpcIntegerValue(item_heartbeat); + } + + public int getMode() { + return this.getOpcIntegerValue(item_mode); + } + + public int getStatus() { + return this.getOpcIntegerValue(item_status); + } + + public int getOpen_time() { + return this.getOpcIntegerValue(item_open_time); + } + + public int getStandby_time() { + return this.getOpcIntegerValue(item_standby_time); + } + + public int getProduction_time() { + return this.getOpcIntegerValue(item_production_time); + } + + public int getError_time() { + return this.getOpcIntegerValue(item_error_time); + } + + public int getBarcode() { + return this.getOpcIntegerValue(item_barcode); + } + + public int getTo_command() { + return this.getOpcIntegerValue(item_to_command); + } + + public int getTo_target() { + return this.getOpcIntegerValue(item_to_target); + } + + public int getTo_task() { + return this.getOpcIntegerValue(item_to_task); + } + + public int getTo_code_message() { + return this.getOpcIntegerValue(item_to_code_message); + } + + public int getTo_isPackage() { + return this.getOpcIntegerValue(item_to_isPackage); + } + + //是否有货 + public int hasGoods(int move) { + return move; + } + + + public int getOpcIntegerValue(String protocol) { + Integer value = this.driver.getIntegeregerValue(protocol); + if (value == null) { + log.error(this.getDriver().getDeviceCode() + ":protocol " + protocol + " 信号同步异常!"); + setIsonline(false); + } else { + setIsonline(true); + return value; + } + return 0; + + } + + public static List getReadableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(item_mode, "工作状态", "DB600.B1", Boolean.valueOf(true))); + list.add(new ItemDto(item_status, "设备状态", "DB600.B2")); + list.add(new ItemDto(item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(item_error_time, "故障时间", "DB600.D8")); + list.add(new ItemDto(item_barcode, "条码", "DB600.D8")); + return list; + } + + public static List getWriteableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_to_command, "下发命令", "DB601.W2", Boolean.valueOf(true))); + list.add(new ItemDto(item_to_target, "下发目标站", "DB601.W4")); + list.add(new ItemDto(item_to_task, "下发任务号", "DB601.D8")); + list.add(new ItemDto(item_to_code_message, "打码信息", "DB601.D8")); + list.add(new ItemDto(item_to_isPackage, "是否包装", "DB601.D8")); + return list; + } + +} + diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_line/LnshPackageLineDefination.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_line/LnshPackageLineDefination.java new file mode 100644 index 0000000..ac7ba54 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_line/LnshPackageLineDefination.java @@ -0,0 +1,74 @@ +package org.nl.acs.device_driver.lnsh.lnsh_package_line; + +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.defination.OpcDeviceDriverDefination; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceType; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * 晟华包装线 + */ +@Service +public class LnshPackageLineDefination implements OpcDeviceDriverDefination { + @Override + public String getDriverCode() { + return "lnsh_package_line"; + } + + @Override + public String getDriverName() { + return "晟华-包装线"; + } + + @Override + public String getDriverDescription() { + return "晟华-包装线"; + } + + @Override + public DeviceDriver getDriverInstance(Device device) { + return (new LnshPackageLineDeviceDriver()).setDevice(device).setDriverDefination(this); + } + + @Override + public Class getDeviceDriverType() { + return LnshPackageLineDeviceDriver.class; + } + + @Override + public List getFitDeviceTypes() { + List types = new LinkedList(); + types.add(DeviceType.conveyor); + return types; + } + + @Override + public List getReadableItemDtos() { + return getReadableItemDtos2(); + } + + public static List getReadableItemDtos2() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(ItemProtocol.item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(ItemProtocol.item_mode, "工作状态", "DB600.B1", Boolean.valueOf(true))); + list.add(new ItemDto(ItemProtocol.item_status, "设备状态", "DB600.B2")); + list.add(new ItemDto(ItemProtocol.item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(ItemProtocol.item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(ItemProtocol.item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(ItemProtocol.item_error_time, "故障时间", "DB600.D8")); + list.add(new ItemDto(ItemProtocol.item_barcode, "条码", "DB600.D8")); + return list; + } + + @Override + public List getWriteableItemDtos() { + return ItemProtocol.getWriteableItemDtos(); + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_line/LnshPackageLineDeviceDriver.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_line/LnshPackageLineDeviceDriver.java new file mode 100644 index 0000000..62ec7e6 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_line/LnshPackageLineDeviceDriver.java @@ -0,0 +1,346 @@ +package org.nl.acs.device_driver.lnsh.lnsh_package_line; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ReadUtil; +import org.nl.acs.device.service.DeviceService; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.RouteableDeviceDriver; +import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; +import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.instruction.service.dto.Instruction; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.WcsConfig; +import org.nl.acs.route.service.RouteLineService; +import org.nl.acs.route.service.dto.RouteLineDto; +import org.nl.acs.task.service.TaskService; +import org.nl.acs.task.service.dto.TaskDto; +import org.nl.modules.system.util.CodeUtil; +import org.nl.utils.SpringContextHolder; +import org.nl.wql.core.bean.WQLObject; +import org.openscada.opc.lib.da.Server; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.*; + +/** + * 晟华包装线 + */ +@Slf4j +@Data +@RequiredArgsConstructor +public class LnshPackageLineDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver { + protected ItemProtocol itemProtocol = new ItemProtocol(this); + @Autowired + InstructionService instructionService = SpringContextHolder.getBean("instructionServiceImpl"); + @Autowired + DeviceService deviceservice = SpringContextHolder.getBean("deviceServiceImpl"); + @Autowired + RouteLineService routelineserver = SpringContextHolder.getBean("routeLineServiceImpl"); + @Autowired + TaskService taskserver = SpringContextHolder.getBean("taskServiceImpl"); + + + String container; + String container_type_desc; + String last_container_type_desc; + String last_container; + //放货准备锁 + String putReadyLock = null; + //有货标记 + protected boolean has_goods_tag = false; + + + String device_code; + int mode = 0; + int error = 0; + int move = 0; + int action; + int io_action; + int task = 0; + int container_type = 0; + int last_mode = 0; + int last_error = 0; + int last_move = 0; + int last_task = 0; + int last_container_type; + Boolean isonline = true; + int hasGoods = 0; + Boolean iserror = false; + + boolean hasVehicle = false; + boolean isReady = false; + protected int instruction_num = 0; + protected int instruction_num_truth = 0; + boolean isFold = false; + private String assemble_check_tag; + private Boolean sampleMode0; + private Boolean sampleMode3; + private Integer sampleError; + private Boolean sampleOnline; + protected String displayMessage = null; + public int display_message_time_out = 30000; + public Date display_message_time; + protected String current_stage_instruction_message; + protected String last_stage_instruction_message; + Integer heartbeat_tag; + private Date instruction_require_time = new Date(); + private Date instruction_finished_time = new Date(); + + private int instruction_require_time_out = 3000; + boolean requireSucess = false; + + private int instruction_finished_time_out; + + int heartbeat; + int last_heartbeat; + private Date checkHeartbeattime = new Date(); + private Date last_checkHeartbeattime = new Date(); + + int branchProtocol = 0; + //当前指令 + Instruction inst = null; + //上次指令 + Instruction last_inst = null; + + //触摸屏手动触发任务 + private Boolean is_has_task = false; + + String message; + + @Override + public Device getDevice() { + return this.device; + } + + + @Override + public void execute() { + String message = null; + try { + device_code = this.getDeviceCode(); + + mode = this.itemProtocol.getMode(); + + if (mode != last_mode) { + this.setRequireSucess(false); + } + if (move != last_move) { + thingToNothing(); + } + if (error != last_error) { + } + if (container_type != last_container_type) { + } + + } catch (Exception var17) { + return; + } + + //急停 + if (this.isStop()) { + + //未在线无心跳 + } else if (!this.itemProtocol.getIsonline()) { + this.setIsonline(false); + this.setIserror(true); + message = "信号量同步异常"; + //未联机 + } else if (mode == 0) { + this.setIsonline(false); + this.setIserror(true); + message = "未联机"; + //有报警 + } else if (error != 0) { + this.setIsonline(false); + this.setIserror(true); + message = "有报警"; + //无报警 + } else { + this.setIsonline(true); + this.setIserror(false); + message = ""; + Instruction instruction = null; + List toInstructions; + switch (mode) { + case 1: + log.debug("设备运转模式:等待工作"); + break; + case 2: + + break; + case 3: + + break; + case 4: + break; + } + } + + last_mode = mode; + last_error = error; + last_move = move; + last_task = task; + last_container_type = container_type; + } + + + protected void thingToNothing() throws Exception { + this.setRequireSucess(false); + } + + public void finish_instruction(Instruction instruction) throws Exception { + instruction_finished(instruction); + } + + /** + * 完成指令 + * + * @param instruction + * @return + */ + public boolean instruction_finished(Instruction instruction) throws Exception { + Date date = new Date(); + if (date.getTime() - this.instruction_finished_time.getTime() < (long) this.instruction_finished_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_finished_time_out); + return false; + } else { + instructionService.finish(instruction.getInstruction_id()); + this.instruction_finished_time = date; + return true; + } + } + + /** + * 完成并创建下一条指令 + * + * @param instruction + * @param needCreateNext + * @return + */ + public boolean instruction_finished(Instruction instruction, boolean needCreateNext) { + Date date = new Date(); + if (date.getTime() - this.instruction_finished_time.getTime() < (long) this.instruction_finished_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_finished_time_out); + return false; + } else { + this.instruction_finished_time = date; + return true; + } + } + + + private Instruction findInstruction() { + Instruction instruction = null; + if (this.instruction_num != 0) { + instruction = (Instruction) instructionService.findByCodeFromCache(String.valueOf(instruction_num)); + } + if (instruction != null) { + //可进行校验 + + + } else { + List container_instructions = new ArrayList(); + String barcode = this.getLast_container(); + + if (!StrUtil.isEmpty(barcode)) { + Map map = new HashMap(); + map.put("vehicle_code", barcode); + container_instructions = instructionService.queryAll(map); + } + + if (((List) container_instructions).size() > 1) { + log.debug("容器存在多个指令"); + } else { + if (((List) container_instructions).size() > 0) { + instruction = (Instruction) ((List) container_instructions).get(0); + } + } + } + return instruction; + } + + + public boolean exe_error() { + if (this.error == 0) { + return true; + } else { + log.debug("设备报警"); + return false; + } + } + + public void set_last_container(String barcode, String type_desc) { + this.set_last_container(barcode); + this.set_last_container_type_desc(type_desc); + } + + public void set_last_container(String barcode) { + } + + public void set_last_container_type_desc(String type) { + } + + public boolean exe_business() { + return true; + } + + public void executing(Server server, Map itemMap) { + ReadUtil.write(itemMap, server); + } + + public boolean instruction_require(String container_code) { + return instruction_require(container_code, WcsConfig.task_container_type_default_desc); + } + + /** + * 请求指令 + * + * @param container_code + * @param container_type + */ + public synchronized boolean instruction_require(String container_code, String container_type) { + Date date = new Date(); + if (date.getTime() - this.instruction_require_time.getTime() < (long) this.instruction_require_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_require_time_out); + return false; + } else { + this.instruction_require_time = date; + TaskDto dto = new TaskDto(); + String now = DateUtil.now(); + dto.setTask_id(IdUtil.simpleUUID()); + dto.setCreate_by(this.getDevice().getDevice_code()); + dto.setUpdate_by(this.getDevice().getDevice_code()); + dto.setStart_point_code(this.getDevice().getDevice_code()); + dto.setVehicle_code(container_code); + dto.setVehicle_type(container_type); + + String taskcode = CodeUtil.getNewCode("TASK_NO"); + dto.setTask_code("-" + taskcode); + dto.setTask_status("0"); + dto.setPriority("101"); + RouteLineDto jo = routelineserver.findByCode(this.getDevice().getDevice_code()); + String next_device_codecode = jo.getNext_device_code(); + if (StrUtil.isEmpty(next_device_codecode)) { + throw new RuntimeException("该设备未找到对应路由"); + } + dto.setNext_point_code(next_device_codecode); + dto.setUpdate_time(now); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("acs_task"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + + wo.insert(json); + requireSucess = false; + return true; + } + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_pallet_manipulator/ItemProtocol.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_pallet_manipulator/ItemProtocol.java new file mode 100644 index 0000000..cfb0c87 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_pallet_manipulator/ItemProtocol.java @@ -0,0 +1,179 @@ +package org.nl.acs.device_driver.lnsh.lnsh_package_pallet_manipulator; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Data +public class ItemProtocol { + + public static String item_heartbeat = "heartbeat"; + public static String item_mode = "mode"; + public static String item_status = "status"; + public static String item_error = "error"; + public static String item_putStation = "putStation"; + public static String item_barcode = "barcode"; + public static String item_material = "material"; + public static String item_qty = "qty"; + public static String item_open_time = "open_time"; + public static String item_standby_time = "standby_time "; + public static String item_production_time = "production_time"; + public static String item_error_time = "error_time"; + public static String item_order_No = "order_No"; + public static String item_to_heartbeat = "to_heartbeat"; + public static String item_to_feedback = "to_feedback"; + public static String item_to_error = "to_error"; + public static String item_to_material_qty = "to_material_qty"; + public static String item_to_allow_pallet_qty = "to_allow_pallet_qty"; + public static String item_to_material_type = "to_material_type"; + public static String item_to_material_code = "to_material_code"; + public static String item_to_order_No = "to_order_No"; + + + private LnshPackagePalletManipulatorDeviceDriver driver; + + public ItemProtocol(LnshPackagePalletManipulatorDeviceDriver driver) { + this.driver = driver; + } + + public int getHeartbeat() { + return this.getOpcIntegerValue(item_heartbeat); + } + + public int getMode() { + return this.getOpcIntegerValue(item_mode); + } + + public int getStatus() { + return this.getOpcIntegerValue(item_status); + } + + public int getError() { + return this.getOpcIntegerValue(item_error); + } + + public int getPutStation() { + return this.getOpcIntegerValue(item_putStation); + } + + public int getBarcode() { + return this.getOpcIntegerValue(item_barcode); + } + + public int getMaterial() { + return this.getOpcIntegerValue(item_material); + } + + public int getQty() { + return this.getOpcIntegerValue(item_qty); + } + + public int getOpen_time() { + return this.getOpcIntegerValue(item_open_time); + } + + public int getStandby_time() { + return this.getOpcIntegerValue(item_standby_time); + } + + public int getProduction_time() { + return this.getOpcIntegerValue(item_production_time); + } + + public int getError_time() { + return this.getOpcIntegerValue(item_error_time); + } + + public int getOrder_No() { + return this.getOpcIntegerValue(item_order_No); + } + + public int getTo_heartbeat() { + return this.getOpcIntegerValue(item_to_heartbeat); + } + + public int getTo_feedback() { + return this.getOpcIntegerValue(item_to_feedback); + } + + public int getTo_error() { + return this.getOpcIntegerValue(item_to_error); + } + + public int getTo_material_qty() { + return this.getOpcIntegerValue(item_to_material_qty); + } + + public int getTo_allow_pallet_qty() { + return this.getOpcIntegerValue(item_to_allow_pallet_qty); + } + + public int getTo_material_type() { + return this.getOpcIntegerValue(item_to_material_type); + } + + public int getTo_material_code() { + return this.getOpcIntegerValue(item_to_material_code); + } + + public int getTo_order_No() { + return this.getOpcIntegerValue(item_to_order_No); + } + + //是否有货 + public int hasGoods(int move) { + return move; + } + + Boolean isonline; + + public int getOpcIntegerValue(String protocol) { + Integer value = this.driver.getIntegeregerValue(protocol); + if (value == null) { + log.error(this.getDriver().getDeviceCode() + ":protocol " + protocol + " 信号同步异常!"); + setIsonline(false); + } else { + setIsonline(true); + return value; + } + return 0; + + } + + public static List getReadableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(item_mode, "工作状态", "DB600.B2", Boolean.valueOf(true))); + list.add(new ItemDto(item_status, "设备状态", "DB600.B3")); + list.add(new ItemDto(item_error, "故障代码", "DB600.B3")); + list.add(new ItemDto(item_putStation, "当前码盘工位", "DB600.B3")); + list.add(new ItemDto(item_barcode, "当前码盘工位条码", "DB600.B3")); + list.add(new ItemDto(item_material, "码盘工位当前物料", "DB600.B3")); + list.add(new ItemDto(item_qty, "数量", "DB600.B3")); + list.add(new ItemDto(item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(item_error_time, "故障时间", "DB600.D8")); + list.add(new ItemDto(item_order_No, "工单号", "DB600.D9")); + return list; + } + + public static List getWriteableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_to_heartbeat, "心跳", "DB601.W0")); + list.add(new ItemDto(item_to_feedback, "机器人动作反馈", "DB601.W0")); + list.add(new ItemDto(item_to_error, "故障代码", "DB601.W0")); + list.add(new ItemDto(item_to_material_qty, "托盘上数量", "DB601.W0")); + list.add(new ItemDto(item_to_allow_pallet_qty, "允许码垛数量", "DB601.W0")); + list.add(new ItemDto(item_to_material_type, "托盘类型", "DB601.W0")); + list.add(new ItemDto(item_to_material_code, "下发物料编号", "DB601.W10")); + list.add(new ItemDto(item_to_order_No, "工单号", "DB601.W10")); + return list; + } + +} + diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_pallet_manipulator/LnshPackagePalletManipulatorDefination.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_pallet_manipulator/LnshPackagePalletManipulatorDefination.java new file mode 100644 index 0000000..1840b0a --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_pallet_manipulator/LnshPackagePalletManipulatorDefination.java @@ -0,0 +1,81 @@ +package org.nl.acs.device_driver.lnsh.lnsh_package_pallet_manipulator; + +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.defination.OpcDeviceDriverDefination; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceType; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * 晟华包装码垛机械手 + * + */ +@Service +public class LnshPackagePalletManipulatorDefination implements OpcDeviceDriverDefination { + @Override + public String getDriverCode() { + return "lnsh_package_pallet_manipulator"; + } + + @Override + public String getDriverName() { + return "晟华-包装码垛机械手"; + } + + @Override + public String getDriverDescription() { + return "晟华-包装码垛机械手"; + } + + @Override + public DeviceDriver getDriverInstance(Device device) { + return (new LnshPackagePalletManipulatorDeviceDriver()).setDevice(device).setDriverDefination(this); + + } + + @Override + public Class getDeviceDriverType() { + return LnshPackagePalletManipulatorDeviceDriver.class; + } + + @Override + public List getFitDeviceTypes() { + List types = new LinkedList(); + types.add(DeviceType.conveyor); + return types; + } + + @Override + public List getReadableItemDtos() { + return getReadableItemDtos2(); + } + + public static List getReadableItemDtos2() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(ItemProtocol.item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(ItemProtocol.item_mode, "工作状态", "DB600.B2", Boolean.valueOf(true))); + list.add(new ItemDto(ItemProtocol.item_status, "设备状态", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_error, "故障代码", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_putStation, "当前码盘工位", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_barcode, "当前码盘工位条码", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_material, "码盘工位当前物料", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_qty, "数量", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(ItemProtocol.item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(ItemProtocol.item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(ItemProtocol.item_error_time, "故障时间", "DB600.D8")); + list.add(new ItemDto(ItemProtocol.item_order_No, "工单号", "DB600.D9")); + return list; + } + + @Override + public List getWriteableItemDtos() { + return ItemProtocol.getWriteableItemDtos(); + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_pallet_manipulator/LnshPackagePalletManipulatorDeviceDriver.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_pallet_manipulator/LnshPackagePalletManipulatorDeviceDriver.java new file mode 100644 index 0000000..2b387fb --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_package_pallet_manipulator/LnshPackagePalletManipulatorDeviceDriver.java @@ -0,0 +1,267 @@ +package org.nl.acs.device_driver.lnsh.lnsh_package_pallet_manipulator; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ReadUtil; +import org.nl.acs.device.service.DeviceService; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.RouteableDeviceDriver; +import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; +import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.instruction.service.dto.Instruction; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.WcsConfig; +import org.nl.acs.route.service.RouteLineService; +import org.nl.acs.route.service.dto.RouteLineDto; +import org.nl.acs.task.service.TaskService; +import org.nl.acs.task.service.dto.TaskDto; +import org.nl.modules.system.util.CodeUtil; +import org.nl.utils.SpringContextHolder; +import org.nl.wql.core.bean.WQLObject; +import org.openscada.opc.lib.da.Server; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 晟华干燥窑 + */ +@Slf4j +@Data +@RequiredArgsConstructor +public class LnshPackagePalletManipulatorDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver { + protected ItemProtocol itemProtocol = new ItemProtocol(this); + @Autowired + InstructionService instructionService = SpringContextHolder.getBean("instructionServiceImpl"); + @Autowired + DeviceService deviceservice = SpringContextHolder.getBean("deviceServiceImpl"); + @Autowired + RouteLineService routelineserver = SpringContextHolder.getBean("routeLineServiceImpl"); + @Autowired + TaskService taskserver = SpringContextHolder.getBean("taskServiceImpl"); + String container; + String container_type_desc; + String last_container_type_desc; + String last_container; + //放货准备锁 + String putReadyLock = null; + //有货标记 + protected boolean has_goods_tag = false; + + int mode = 0; + int error = 0; + int last_mode = 0; + int last_error = 0; + Boolean isonline = true; + int hasGoods = 0; + String message = null; + Boolean iserror = false; + + + boolean hasVehicle = false; + boolean isReady = false; + protected int instruction_num = 0; + protected int instruction_num_truth = 0; + boolean isFold = false; + private String assemble_check_tag; + + protected String current_stage_instruction_message; + protected String last_stage_instruction_message; + Integer heartbeat_tag; + private Date instruction_require_time = new Date(); + private Date instruction_finished_time = new Date(); + + private int instruction_require_time_out; + boolean requireSucess = false; + + private int instruction_finished_time_out; + + int branchProtocol = 0; + //备注 + String remark; + //数量 + String qty; + //物料 + String material; + //批次 + String batch; + //当前指令 + Instruction inst = null; + //上次指令 + Instruction last_inst = null; + + //触摸屏手动触发任务 + private Boolean is_has_task = false; + + //申请搬运任务 + private Boolean apply_handling = false; + //申请物料 + private Boolean apply_material = false; + + //暂定 0就绪 1请求取货 2取货完成 3请求放货 4放货完成 5取货完成离开 6放货完成离开 7请求进入区域 8请求离开区域 + int flag; + + String devicecode; + + @Override + public Device getDevice() { + return this.device; + } + + + @Override + public void execute() { + String message = null; + try { + String device_code = this.getDeviceCode(); + mode = this.itemProtocol.getMode(); + + if (mode != last_mode) { + this.setRequireSucess(false); + } + if (error != last_error) { + } + + } catch (Exception var17) { + return; + } + + if (!this.itemProtocol.getIsonline()) { + this.setIsonline(false); + this.setIserror(true); + message = "信号量同步异常"; + //未联机 + } else if (mode == 0) { + this.setIsonline(false); + this.setIserror(true); + message = "未联机"; + //有报警 + } else if (error != 0) { + this.setIsonline(false); + this.setIserror(true); + message = "有报警"; + //无报警 + } else { + this.setIsonline(true); + this.setIserror(false); + message = ""; + Instruction instruction = null; + List toInstructions; + switch (mode) { + case 1: + log.debug("设备运转模式:等待工作"); + return; + case 2: + if (material.length() > 0 && qty.length() > 0 && !requireSucess) { + this.instruction_require(container); + } + } + + switch (flag) { + //取货完成 + case 1: + return; + //放货完成 + case 2: + return; + + } + + } + last_mode = mode; + last_error = error; + + } + + + public boolean exe_error() { + if (this.error == 0) { + return true; + } else { + log.debug("设备报警"); + return false; + } + } + + protected void thingToNothing() { + log.debug("从有货到无货 清理数据"); + this.set_last_container(container, container_type_desc); + } + + public void set_last_container(String barcode, String type_desc) { + this.set_last_container(barcode); + this.set_last_container_type_desc(type_desc); + } + + public void set_last_container(String barcode) { + } + + public void set_last_container_type_desc(String type) { + } + + public boolean exe_business() { + return true; + } + + public void executing(Server server, Map itemMap) { + ReadUtil.write(itemMap, server); + } + + public boolean instruction_require(String container_code) { + return instruction_require(container_code, WcsConfig.task_container_type_default_desc); + } + + /** + * 请求指令 + * + * @param container_code + * @param container_type + */ + public synchronized boolean instruction_require(String container_code, String container_type) { + Date date = new Date(); + if (date.getTime() - this.instruction_require_time.getTime() < (long) this.instruction_require_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_require_time_out); + return false; + } else { + this.instruction_require_time = date; + TaskDto dto = new TaskDto(); + String now = DateUtil.now(); + dto.setTask_id(IdUtil.simpleUUID()); + dto.setCreate_by(this.getDevice().getDevice_code()); + dto.setUpdate_by(this.getDevice().getDevice_code()); + dto.setStart_point_code(this.getDevice().getDevice_code()); + dto.setVehicle_code(container_code); + dto.setVehicle_type(container_type); + + String taskcode = CodeUtil.getNewCode("TASK_NO"); + dto.setTask_code("-" + taskcode); + dto.setTask_status("0"); + dto.setPriority("101"); + RouteLineDto jo = routelineserver.findByCode(this.getDevice().getDevice_code()); + String next_device_codecode = jo.getNext_device_code(); + if (StrUtil.isEmpty(next_device_codecode)) { + throw new RuntimeException("该设备未找到对应路由"); + } + dto.setNext_point_code(next_device_codecode); + dto.setUpdate_time(now); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("acs_task"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + + wo.insert(json); + requireSucess = false; + return true; + } + } + + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_pallet_storage/ItemProtocol.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_pallet_storage/ItemProtocol.java new file mode 100644 index 0000000..b14c111 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_pallet_storage/ItemProtocol.java @@ -0,0 +1,129 @@ +package org.nl.acs.device_driver.lnsh.lnsh_pallet_storage; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Data +public class ItemProtocol { + public static String item_heartbeat = "heartbeat"; + public static String item_mode = "mode"; + public static String item_status = "status"; + public static String item_open_time = "open_time"; + public static String item_close_time = "close_time"; + public static String item_standby_time = "standby_time "; + public static String item_production_time = "production_time"; + public static String item_error_time = "error_time"; + public static String item_tray_crib_qty = "tray_crib_qty"; + public static String item_total_container = "total_container"; + public static String item_to_command = "to_command"; + public static String item_to_target = "to_target"; + public static String item_to_task = "to_task"; + Boolean isonline; + + private LnshPalletStorageDeviceDriver driver; + + public ItemProtocol(LnshPalletStorageDeviceDriver driver) { + this.driver = driver; + } + + public int getHeartbeat() { + return this.getOpcIntegerValue(item_heartbeat); + } + + public int getMode() { + return this.getOpcIntegerValue(item_mode); + } + + public int getStatus() { + return this.getOpcIntegerValue(item_status); + } + + public int getOpen_time() { + return this.getOpcIntegerValue(item_open_time); + } + + public int getClose_time() { + return this.getOpcIntegerValue(item_close_time); + } + + public int getStandby_time() { + return this.getOpcIntegerValue(item_standby_time); + } + + public int getProduction_time() { + return this.getOpcIntegerValue(item_production_time); + } + + public int getError_time() { + return this.getOpcIntegerValue(item_error_time); + } + + public int getTray_crib_qty() { + return this.getOpcIntegerValue(item_tray_crib_qty); + } + + public int getTotal_container() { + return this.getOpcIntegerValue(item_total_container); + } + + public int getToCommand() { + return this.getOpcIntegerValue(item_to_command); + } + + public int getToTarget() { + return this.getOpcIntegerValue(item_to_target); + } + + public int getToTask() { + return this.getOpcIntegerValue(item_to_task); + } + + //是否有货 + public int hasGoods(int move) { + return move; + } + + + public int getOpcIntegerValue(String protocol) { + Integer value = this.driver.getIntegeregerValue(protocol); + if (value == null) { + log.error(this.getDriver().getDeviceCode() + ":protocol " + protocol + " 信号同步异常!"); + setIsonline(false); + } else { + setIsonline(true); + return value; + } + return 0; + + } + + public static List getReadableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(item_mode, "工作状态", "DB600.B1", Boolean.valueOf(true))); + list.add(new ItemDto(item_status, "设备状态", "DB600.B2")); + list.add(new ItemDto(item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(item_close_time, "关机时间", "DB600.D5")); + list.add(new ItemDto(item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(item_error_time, "故障时间", "DB600.D8")); + list.add(new ItemDto(item_tray_crib_qty, "托盘垛数", "DB600.D8")); + list.add(new ItemDto(item_total_container, "托盘总数量", "DB600.D8")); + return list; + } + + public static List getWriteableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_to_command, "下发命令", "DB601.W2", Boolean.valueOf(true))); + list.add(new ItemDto(item_to_target, "下发目标站", "DB601.W4")); + list.add(new ItemDto(item_to_task, "下发任务号", "DB601.D8")); + return list; + } + +} + diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_pallet_storage/LnshPalletStorageDefination.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_pallet_storage/LnshPalletStorageDefination.java new file mode 100644 index 0000000..549b42c --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_pallet_storage/LnshPalletStorageDefination.java @@ -0,0 +1,76 @@ +package org.nl.acs.device_driver.lnsh.lnsh_pallet_storage; + +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.defination.OpcDeviceDriverDefination; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceType; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * 晟华托盘存储线 + */ +@Service +public class LnshPalletStorageDefination implements OpcDeviceDriverDefination { + @Override + public String getDriverCode() { + return "lnsh_pallet_storage"; + } + + @Override + public String getDriverName() { + return "晟华-托盘存储线"; + } + + @Override + public String getDriverDescription() { + return "晟华-托盘存储线"; + } + + @Override + public DeviceDriver getDriverInstance(Device device) { + return (new LnshPalletStorageDeviceDriver()).setDevice(device).setDriverDefination(this); + } + + @Override + public Class getDeviceDriverType() { + return LnshPalletStorageDeviceDriver.class; + } + + @Override + public List getFitDeviceTypes() { + List types = new LinkedList(); + types.add(DeviceType.conveyor); + return types; + } + + @Override + public List getReadableItemDtos() { + return getReadableItemDtos2(); + } + + public static List getReadableItemDtos2() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(ItemProtocol.item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(ItemProtocol.item_mode, "工作状态", "DB600.B1", Boolean.valueOf(true))); + list.add(new ItemDto(ItemProtocol.item_status, "设备状态", "DB600.B2")); + list.add(new ItemDto(ItemProtocol.item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(ItemProtocol.item_close_time, "关机时间", "DB600.D5")); + list.add(new ItemDto(ItemProtocol.item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(ItemProtocol.item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(ItemProtocol.item_error_time, "故障时间", "DB600.D8")); + list.add(new ItemDto(ItemProtocol.item_tray_crib_qty, "托盘垛数", "DB600.D8")); + list.add(new ItemDto(ItemProtocol.item_total_container, "托盘总数量", "DB600.D8")); + return list; + } + + @Override + public List getWriteableItemDtos() { + return ItemProtocol.getWriteableItemDtos(); + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_pallet_storage/LnshPalletStorageDeviceDriver.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_pallet_storage/LnshPalletStorageDeviceDriver.java new file mode 100644 index 0000000..0d888fd --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_pallet_storage/LnshPalletStorageDeviceDriver.java @@ -0,0 +1,346 @@ +package org.nl.acs.device_driver.lnsh.lnsh_pallet_storage; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ReadUtil; +import org.nl.acs.device.service.DeviceService; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.RouteableDeviceDriver; +import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; +import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.instruction.service.dto.Instruction; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.WcsConfig; +import org.nl.acs.route.service.RouteLineService; +import org.nl.acs.route.service.dto.RouteLineDto; +import org.nl.acs.task.service.TaskService; +import org.nl.acs.task.service.dto.TaskDto; +import org.nl.modules.system.util.CodeUtil; +import org.nl.utils.SpringContextHolder; +import org.nl.wql.core.bean.WQLObject; +import org.openscada.opc.lib.da.Server; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.*; + +/** + * 晟华托盘存储线 + */ +@Slf4j +@Data +@RequiredArgsConstructor +public class LnshPalletStorageDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver { + protected ItemProtocol itemProtocol = new ItemProtocol(this); + @Autowired + InstructionService instructionService = SpringContextHolder.getBean("instructionServiceImpl"); + @Autowired + DeviceService deviceservice = SpringContextHolder.getBean("deviceServiceImpl"); + @Autowired + RouteLineService routelineserver = SpringContextHolder.getBean("routeLineServiceImpl"); + @Autowired + TaskService taskserver = SpringContextHolder.getBean("taskServiceImpl"); + + + String container; + String container_type_desc; + String last_container_type_desc; + String last_container; + //放货准备锁 + String putReadyLock = null; + //有货标记 + protected boolean has_goods_tag = false; + + + String device_code; + int mode = 0; + int error = 0; + int move = 0; + int action; + int io_action; + int task = 0; + int container_type = 0; + int last_mode = 0; + int last_error = 0; + int last_move = 0; + int last_task = 0; + int last_container_type; + Boolean isonline = true; + int hasGoods = 0; + Boolean iserror = false; + + boolean hasVehicle = false; + boolean isReady = false; + protected int instruction_num = 0; + protected int instruction_num_truth = 0; + boolean isFold = false; + private String assemble_check_tag; + private Boolean sampleMode0; + private Boolean sampleMode3; + private Integer sampleError; + private Boolean sampleOnline; + protected String displayMessage = null; + public int display_message_time_out = 30000; + public Date display_message_time; + protected String current_stage_instruction_message; + protected String last_stage_instruction_message; + Integer heartbeat_tag; + private Date instruction_require_time = new Date(); + private Date instruction_finished_time = new Date(); + + private int instruction_require_time_out = 3000; + boolean requireSucess = false; + + private int instruction_finished_time_out; + + int heartbeat; + int last_heartbeat; + private Date checkHeartbeattime = new Date(); + private Date last_checkHeartbeattime = new Date(); + + int branchProtocol = 0; + //当前指令 + Instruction inst = null; + //上次指令 + Instruction last_inst = null; + + //触摸屏手动触发任务 + private Boolean is_has_task = false; + + String message; + + @Override + public Device getDevice() { + return this.device; + } + + + @Override + public void execute() { + String message = null; + try { + device_code = this.getDeviceCode(); + + mode = this.itemProtocol.getMode(); + + if (mode != last_mode) { + this.setRequireSucess(false); + } + if (move != last_move) { + thingToNothing(); + } + if (error != last_error) { + } + if (container_type != last_container_type) { + } + + } catch (Exception var17) { + return; + } + + //急停 + if (this.isStop()) { + + //未在线无心跳 + } else if (!this.itemProtocol.getIsonline()) { + this.setIsonline(false); + this.setIserror(true); + message = "信号量同步异常"; + //未联机 + } else if (mode == 0) { + this.setIsonline(false); + this.setIserror(true); + message = "未联机"; + //有报警 + } else if (error != 0) { + this.setIsonline(false); + this.setIserror(true); + message = "有报警"; + //无报警 + } else { + this.setIsonline(true); + this.setIserror(false); + message = ""; + Instruction instruction = null; + List toInstructions; + switch (mode) { + case 1: + log.debug("设备运转模式:等待工作"); + break; + case 2: + + break; + case 3: + + break; + case 4: + break; + } + } + + last_mode = mode; + last_error = error; + last_move = move; + last_task = task; + last_container_type = container_type; + } + + + protected void thingToNothing() throws Exception { + this.setRequireSucess(false); + } + + public void finish_instruction(Instruction instruction) throws Exception { + instruction_finished(instruction); + } + + /** + * 完成指令 + * + * @param instruction + * @return + */ + public boolean instruction_finished(Instruction instruction) throws Exception { + Date date = new Date(); + if (date.getTime() - this.instruction_finished_time.getTime() < (long) this.instruction_finished_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_finished_time_out); + return false; + } else { + instructionService.finish(instruction.getInstruction_id()); + this.instruction_finished_time = date; + return true; + } + } + + /** + * 完成并创建下一条指令 + * + * @param instruction + * @param needCreateNext + * @return + */ + public boolean instruction_finished(Instruction instruction, boolean needCreateNext) { + Date date = new Date(); + if (date.getTime() - this.instruction_finished_time.getTime() < (long) this.instruction_finished_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_finished_time_out); + return false; + } else { + this.instruction_finished_time = date; + return true; + } + } + + + private Instruction findInstruction() { + Instruction instruction = null; + if (this.instruction_num != 0) { + instruction = (Instruction) instructionService.findByCodeFromCache(String.valueOf(instruction_num)); + } + if (instruction != null) { + //可进行校验 + + + } else { + List container_instructions = new ArrayList(); + String barcode = this.getLast_container(); + + if (!StrUtil.isEmpty(barcode)) { + Map map = new HashMap(); + map.put("vehicle_code", barcode); + container_instructions = instructionService.queryAll(map); + } + + if (((List) container_instructions).size() > 1) { + log.debug("容器存在多个指令"); + } else { + if (((List) container_instructions).size() > 0) { + instruction = (Instruction) ((List) container_instructions).get(0); + } + } + } + return instruction; + } + + + public boolean exe_error() { + if (this.error == 0) { + return true; + } else { + log.debug("设备报警"); + return false; + } + } + + public void set_last_container(String barcode, String type_desc) { + this.set_last_container(barcode); + this.set_last_container_type_desc(type_desc); + } + + public void set_last_container(String barcode) { + } + + public void set_last_container_type_desc(String type) { + } + + public boolean exe_business() { + return true; + } + + public void executing(Server server, Map itemMap) { + ReadUtil.write(itemMap, server); + } + + public boolean instruction_require(String container_code) { + return instruction_require(container_code, WcsConfig.task_container_type_default_desc); + } + + /** + * 请求指令 + * + * @param container_code + * @param container_type + */ + public synchronized boolean instruction_require(String container_code, String container_type) { + Date date = new Date(); + if (date.getTime() - this.instruction_require_time.getTime() < (long) this.instruction_require_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_require_time_out); + return false; + } else { + this.instruction_require_time = date; + TaskDto dto = new TaskDto(); + String now = DateUtil.now(); + dto.setTask_id(IdUtil.simpleUUID()); + dto.setCreate_by(this.getDevice().getDevice_code()); + dto.setUpdate_by(this.getDevice().getDevice_code()); + dto.setStart_point_code(this.getDevice().getDevice_code()); + dto.setVehicle_code(container_code); + dto.setVehicle_type(container_type); + + String taskcode = CodeUtil.getNewCode("TASK_NO"); + dto.setTask_code("-" + taskcode); + dto.setTask_status("0"); + dto.setPriority("101"); + RouteLineDto jo = routelineserver.findByCode(this.getDevice().getDevice_code()); + String next_device_codecode = jo.getNext_device_code(); + if (StrUtil.isEmpty(next_device_codecode)) { + throw new RuntimeException("该设备未找到对应路由"); + } + dto.setNext_point_code(next_device_codecode); + dto.setUpdate_time(now); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("acs_task"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + + wo.insert(json); + requireSucess = false; + return true; + } + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_palletizing_manipulator/ItemProtocol.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_palletizing_manipulator/ItemProtocol.java new file mode 100644 index 0000000..5ed418c --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_palletizing_manipulator/ItemProtocol.java @@ -0,0 +1,162 @@ +package org.nl.acs.device_driver.lnsh.lnsh_palletizing_manipulator; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Data +public class ItemProtocol { + + public static String item_heartbeat = "heartbeat"; + public static String item_mode = "mode"; + public static String item_status = "status"; + public static String item_action = "action"; + public static String item_error = "error"; + public static String item_put_station = "put_station"; + public static String item_barcode = "barcode"; + public static String item_material = "material"; + public static String item_encoder_qty = "encoder_qty"; + public static String item_open_time = "open_time"; + public static String item_standby_time = "standby_time "; + public static String item_production_time = "production_time"; + public static String item_error_time = "error_time"; + public static String item_to_heartbeat = "to_heartbeat"; + public static String item_to_feedback = "to_feedback"; + public static String item_to_error = "to_error"; + public static String item_to_materialQty = "to_materialQty"; + public static String item_to_material_type = "to_material_type"; + public static String item_to_material_code = "to_material_code"; + + + private LnshPalletizingManipulatorDeviceDriver driver; + + public ItemProtocol(LnshPalletizingManipulatorDeviceDriver driver) { + this.driver = driver; + } + + public int getHeartbeat() { + return this.getOpcIntegerValue(item_heartbeat); + } + + public int getMode() { + return this.getOpcIntegerValue(item_mode); + } + + public int getStatus() { + return this.getOpcIntegerValue(item_status); + } + + public int getAction() { + return this.getOpcIntegerValue(item_action); + } + + public int getError() { + return this.getOpcIntegerValue(item_error); + } + + public int getPut_station() { + return this.getOpcIntegerValue(item_put_station); + } + + public int getBarcode() { + return this.getOpcIntegerValue(item_barcode); + } + + public int getMaterial() { + return this.getOpcIntegerValue(item_material); + } + + public int getEncoder_qty() { + return this.getOpcIntegerValue(item_encoder_qty); + } + + public int getOpen_time() { + return this.getOpcIntegerValue(item_open_time); + } + + public int getStandby_time() { + return this.getOpcIntegerValue(item_standby_time); + } + + public int getProduction_time() { + return this.getOpcIntegerValue(item_production_time); + } + + public int getError_time() { + return this.getOpcIntegerValue(item_error_time); + } + + public int getTo_heartbeat() { + return this.getOpcIntegerValue(item_to_heartbeat); + } + + public int getTo_feedback() { + return this.getOpcIntegerValue(item_to_feedback); + } + + public int getTo_error() { + return this.getOpcIntegerValue(item_to_error); + } + + public int getTo_materialQty() { + return this.getOpcIntegerValue(item_to_materialQty); + } + + public int getTo_material_type() { + return this.getOpcIntegerValue(item_to_material_type); + } + + public int getTo_material_code() { + return this.getOpcIntegerValue(item_to_material_code); + } + + Boolean isonline; + + public int getOpcIntegerValue(String protocol) { + Integer value = this.driver.getIntegeregerValue(protocol); + if (value == null) { + log.error(this.getDriver().getDeviceCode() + ":protocol " + protocol + " 信号同步异常!"); + setIsonline(false); + } else { + setIsonline(true); + return value; + } + return 0; + + } + + public static List getReadableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(item_mode, "工作状态", "DB600.B2", Boolean.valueOf(true))); + list.add(new ItemDto(item_status, "设备状态", "DB600.B3")); + list.add(new ItemDto(item_action, "动作", "DB600.B3")); + list.add(new ItemDto(item_error, "故障代码", "DB600.B3")); + list.add(new ItemDto(item_put_station, "当前码盘工位", "DB600.B3")); + list.add(new ItemDto(item_barcode, "当前码盘工位条码", "DB600.B3")); + list.add(new ItemDto(item_material, "码盘工位当前物料", "DB600.B3")); + list.add(new ItemDto(item_encoder_qty, "码盘位当前码盘数量", "DB600.B3")); + list.add(new ItemDto(item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(item_error_time, "故障时间", "DB600.D8")); + return list; + } + + public static List getWriteableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_to_heartbeat, "心跳", "DB601.W2")); + list.add(new ItemDto(item_to_feedback, "机器人动作反馈", "DB601.W2")); + list.add(new ItemDto(item_to_error, "故障代码", "DB601.W2")); + list.add(new ItemDto(item_to_materialQty, "托盘砖数量", "DB601.W2")); + list.add(new ItemDto(item_to_material_type, "箱型", "DB601.W2")); + list.add(new ItemDto(item_to_material_code, "下发物料编号", "DB601.W10")); + return list; + } + +} + diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_palletizing_manipulator/LnshPalletizingManipulatorDefination.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_palletizing_manipulator/LnshPalletizingManipulatorDefination.java new file mode 100644 index 0000000..d44f6d0 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_palletizing_manipulator/LnshPalletizingManipulatorDefination.java @@ -0,0 +1,81 @@ +package org.nl.acs.device_driver.lnsh.lnsh_palletizing_manipulator; + +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.defination.OpcDeviceDriverDefination; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceType; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * 晟华码垛机械手 + * + */ +@Service +public class LnshPalletizingManipulatorDefination implements OpcDeviceDriverDefination { + @Override + public String getDriverCode() { + return "lnsh_palletizing_manipulator"; + } + + @Override + public String getDriverName() { + return "晟华-码垛机械手"; + } + + @Override + public String getDriverDescription() { + return "晟华-码垛机械手"; + } + + @Override + public DeviceDriver getDriverInstance(Device device) { + return (new LnshPalletizingManipulatorDeviceDriver()).setDevice(device).setDriverDefination(this); + + } + + @Override + public Class getDeviceDriverType() { + return LnshPalletizingManipulatorDeviceDriver.class; + } + + @Override + public List getFitDeviceTypes() { + List types = new LinkedList(); + types.add(DeviceType.conveyor); + return types; + } + + @Override + public List getReadableItemDtos() { + return getReadableItemDtos2(); + } + + public static List getReadableItemDtos2() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(ItemProtocol.item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(ItemProtocol.item_mode, "工作状态", "DB600.B2", Boolean.valueOf(true))); + list.add(new ItemDto(ItemProtocol.item_status, "设备状态", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_action, "动作", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_error, "故障代码", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_put_station, "当前码盘工位", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_barcode, "当前码盘工位条码", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_material, "码盘工位当前物料", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_encoder_qty, "码盘位当前码盘数量", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(ItemProtocol.item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(ItemProtocol.item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(ItemProtocol.item_error_time, "故障时间", "DB600.D8")); + return list; + } + + @Override + public List getWriteableItemDtos() { + return ItemProtocol.getWriteableItemDtos(); + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_palletizing_manipulator/LnshPalletizingManipulatorDeviceDriver.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_palletizing_manipulator/LnshPalletizingManipulatorDeviceDriver.java new file mode 100644 index 0000000..d0ffc16 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_palletizing_manipulator/LnshPalletizingManipulatorDeviceDriver.java @@ -0,0 +1,313 @@ +package org.nl.acs.device_driver.lnsh.lnsh_palletizing_manipulator; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ReadUtil; +import org.nl.acs.device.service.DeviceService; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.RouteableDeviceDriver; +import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; +import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.instruction.service.dto.Instruction; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.WcsConfig; +import org.nl.acs.route.service.RouteLineService; +import org.nl.acs.route.service.dto.RouteLineDto; +import org.nl.acs.task.service.TaskService; +import org.nl.acs.task.service.dto.TaskDto; +import org.nl.modules.system.util.CodeUtil; +import org.nl.utils.SpringContextHolder; +import org.nl.wql.core.bean.WQLObject; +import org.openscada.opc.lib.da.Server; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 晟华码垛机械手 + */ +@Slf4j +@Data +@RequiredArgsConstructor +public class LnshPalletizingManipulatorDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver { + protected ItemProtocol itemProtocol = new ItemProtocol(this); + @Autowired + InstructionService instructionService = SpringContextHolder.getBean("instructionServiceImpl"); + @Autowired + DeviceService deviceservice = SpringContextHolder.getBean("deviceServiceImpl"); + @Autowired + RouteLineService routelineserver = SpringContextHolder.getBean("routeLineServiceImpl"); + @Autowired + TaskService taskserver = SpringContextHolder.getBean("taskServiceImpl"); + String container; + String container_type_desc; + String last_container_type_desc; + String last_container; + //放货准备锁 + String putReadyLock = null; + //有货标记 + protected boolean has_goods_tag = false; + + int mode = 0; + int error = 0; + int last_mode = 0; + int last_error = 0; + Boolean isonline = true; + int hasGoods = 0; + String message = null; + Boolean iserror = false; + + + boolean hasVehicle = false; + boolean isReady = false; + protected int instruction_num = 0; + protected int instruction_num_truth = 0; + boolean isFold = false; + private String assemble_check_tag; + + protected String current_stage_instruction_message; + protected String last_stage_instruction_message; + Integer heartbeat_tag; + private Date instruction_require_time = new Date(); + private Date instruction_finished_time = new Date(); + + private int instruction_require_time_out; + boolean requireSucess = false; + + private int instruction_finished_time_out; + + int branchProtocol = 0; + //备注 + String remark; + //数量 + String qty; + //物料 + String material; + //批次 + String batch; + //当前指令 + Instruction inst = null; + //上次指令 + Instruction last_inst = null; + + //触摸屏手动触发任务 + private Boolean is_has_task = false; + + //申请搬运任务 + private Boolean apply_handling = false; + //申请物料 + private Boolean apply_material = false; + + //暂定 0就绪 1请求取货 2取货完成 3请求放货 4放货完成 5取货完成离开 6放货完成离开 7请求进入区域 8请求离开区域 + int flag; + + String devicecode; + + @Override + public Device getDevice() { + return this.device; + } + + + @Override + public void execute() { + String message = null; + try { + String device_code = this.getDeviceCode(); + mode = this.itemProtocol.getMode(); + + if (mode != last_mode) { + this.setRequireSucess(false); + } + if (error != last_error) { + } + + } catch (Exception var17) { + return; + } + + if (!this.itemProtocol.getIsonline()) { + this.setIsonline(false); + this.setIserror(true); + message = "信号量同步异常"; + //未联机 + } else if (mode == 0) { + this.setIsonline(false); + this.setIserror(true); + message = "未联机"; + //有报警 + } else if (error != 0) { + this.setIsonline(false); + this.setIserror(true); + message = "有报警"; + //无报警 + } else { + this.setIsonline(true); + this.setIserror(false); + message = ""; + Instruction instruction = null; + List toInstructions; + switch (mode) { + case 1: + log.debug("设备运转模式:等待工作"); + return; + case 2: + if (material.length() > 0 && qty.length() > 0 && !requireSucess) { + this.instruction_require(container); + } + } + + switch (flag) { + //取货完成 + case 1: + writing(2); + return; + //放货完成 + case 2: + writing(3); + return; + + } + + } + last_mode = mode; + last_error = error; + + } + + + public boolean exe_error() { + if (this.error == 0) { + return true; + } else { + log.debug("设备报警"); + return false; + } + } + + protected void thingToNothing() { + log.debug("从有货到无货 清理数据"); + this.set_last_container(container, container_type_desc); + } + + public void set_last_container(String barcode, String type_desc) { + this.set_last_container(barcode); + this.set_last_container_type_desc(type_desc); + } + + public void set_last_container(String barcode) { + } + + public void set_last_container_type_desc(String type) { + } + + public boolean exe_business() { + return true; + } + + protected void executing(Instruction instruction) { + this.executing(1, instruction, ""); + } + + public void executing(int command, Instruction instruction, String appendMessage) { + String to_material_code = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code() + + "." + ItemProtocol.item_to_material_code; + if (appendMessage == null) { + appendMessage = ""; + } + if (instruction != null) { + instruction_num = Integer.parseInt(instruction.getInstruction_code()); + } + String opcservcerid = this.getDevice().getOpc_server_id(); + Server server = ReadUtil.getServer(opcservcerid); + Map itemMap = new HashMap(); + ReadUtil.write(itemMap, server); + + } + + public void executing(Server server, Map itemMap) { + ReadUtil.write(itemMap, server); + } + + public void writing(int command) { + + String opcservcerid = this.getDevice().getOpc_server_id(); + Server server = ReadUtil.getServer(opcservcerid); + Map itemMap = new HashMap(); + ReadUtil.write(itemMap, server); + + } + + public void writing(int type, int command) { + String to_material_code = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code() + + "." + ItemProtocol.item_to_material_code; + String opcservcerid = this.getDevice().getOpc_server_id(); + Server server = ReadUtil.getServer(opcservcerid); + Map itemMap = new HashMap(); + if (type == 2) { + itemMap.put(to_material_code, command); + + } + ReadUtil.write(itemMap, server); + + } + + public boolean instruction_require(String container_code) { + return instruction_require(container_code, WcsConfig.task_container_type_default_desc); + } + + /** + * 请求指令 + * + * @param container_code + * @param container_type + */ + public synchronized boolean instruction_require(String container_code, String container_type) { + Date date = new Date(); + if (date.getTime() - this.instruction_require_time.getTime() < (long) this.instruction_require_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_require_time_out); + return false; + } else { + this.instruction_require_time = date; + TaskDto dto = new TaskDto(); + String now = DateUtil.now(); + dto.setTask_id(IdUtil.simpleUUID()); + dto.setCreate_by(this.getDevice().getDevice_code()); + dto.setUpdate_by(this.getDevice().getDevice_code()); + dto.setStart_point_code(this.getDevice().getDevice_code()); + dto.setVehicle_code(container_code); + dto.setVehicle_type(container_type); + + String taskcode = CodeUtil.getNewCode("TASK_NO"); + dto.setTask_code("-" + taskcode); + dto.setTask_status("0"); + dto.setPriority("101"); + RouteLineDto jo = routelineserver.findByCode(this.getDevice().getDevice_code()); + String next_device_codecode = jo.getNext_device_code(); + if (StrUtil.isEmpty(next_device_codecode)) { + throw new RuntimeException("该设备未找到对应路由"); + } + dto.setNext_point_code(next_device_codecode); + dto.setUpdate_time(now); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("acs_task"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + + wo.insert(json); + requireSucess = false; + return true; + } + } + + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_press/ItemProtocol.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_press/ItemProtocol.java new file mode 100644 index 0000000..31d244f --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_press/ItemProtocol.java @@ -0,0 +1,167 @@ +package org.nl.acs.device_driver.lnsh.lnsh_press; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Data +public class ItemProtocol { + + public static String item_heartbeat = "heartbeat"; + public static String item_mode = "mode"; + public static String item_status = "status"; + public static String item_error = "error"; + public static String item_open_time = "open_time"; + public static String item_standby_time = "standby_time "; + public static String item_production_time = "production_time"; + public static String item_error_time = "error_time"; + public static String item_material = "material"; + public static String item_qty = "qty"; + public static String item_weight = "weight"; + public static String item_qualified = "qualified"; + public static String item_unqualified = "unqualified"; + public static String item_order_No = "order_No"; + public static String item_to_command = "to_command"; + public static String item_to_error = "to_error"; + public static String item_to_order_No = "to_order_No"; + public static String item_to_qty = "to_qty"; + public static String item_to_material_code = "to_material_code"; + + + private LnshPressDeviceDriver driver; + + public ItemProtocol(LnshPressDeviceDriver driver) { + this.driver = driver; + } + + public int getHeartbeat() { + return this.getOpcIntegerValue(item_heartbeat); + } + + public int getStatus() { + return this.getOpcIntegerValue(item_status); + } + + public int getMode() { + return this.getOpcIntegerValue(item_mode); + } + + public int getError() { + return this.getOpcIntegerValue(item_error); + } + + public int getOpen_time() { + return this.getOpcIntegerValue(item_open_time); + } + + public int getStandby_time() { + return this.getOpcIntegerValue(item_standby_time); + } + + public int getProduction_time() { + return this.getOpcIntegerValue(item_production_time); + } + + public int getError_time() { + return this.getOpcIntegerValue(item_error_time); + } + + public int getMaterial() { + return this.getOpcIntegerValue(item_material); + } + + public int getQty() { + return this.getOpcIntegerValue(item_qty); + } + + public int getWeight() { + return this.getOpcIntegerValue(item_weight); + } + + public int getQualified() { + return this.getOpcIntegerValue(item_qualified); + } + + public int getUnqualified() { + return this.getOpcIntegerValue(item_unqualified); + } + + public int getOrder_No() { + return this.getOpcIntegerValue(item_order_No); + } + + public int getTo_command() { + return this.getOpcIntegerValue(item_to_command); + } + + public int getTo_error() { + return this.getOpcIntegerValue(item_to_error); + } + + public int getTo_order_No() { + return this.getOpcIntegerValue(item_to_order_No); + } + + public int getTo_qty() { + return this.getOpcIntegerValue(item_to_qty); + } + + public int getTo_material_code() { + return this.getOpcIntegerValue(item_to_material_code); + } + + //是否有货 + public int hasGoods(int move) { + return move; + } + + Boolean isonline; + + public int getOpcIntegerValue(String protocol) { + Integer value = this.driver.getIntegeregerValue(protocol); + if (value == null) { + log.error(this.getDriver().getDeviceCode() + ":protocol " + protocol + " 信号同步异常!"); + setIsonline(false); + } else { + setIsonline(true); + return value; + } + return 0; + + } + + public static List getReadableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(item_mode, "工作状态", "DB600.B2", Boolean.valueOf(true))); + list.add(new ItemDto(item_status, "设备状态", "DB600.B3")); + list.add(new ItemDto(item_error, "故障", "DB600.B3")); + list.add(new ItemDto(item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(item_error_time, "故障时间", "DB600.D8")); + list.add(new ItemDto(item_material, "当前生产物料", "DB600.D9")); + list.add(new ItemDto(item_qty, "当前已生产数量", "DB600.D10")); + list.add(new ItemDto(item_weight, "当前已生产重量", "DB600.D10")); + list.add(new ItemDto(item_qualified, "当前已生产合格数", "DB600.D11")); + list.add(new ItemDto(item_unqualified, "当前已生产不合格数", "DB600.D12")); + list.add(new ItemDto(item_order_No, "工单号", "DB600.D13")); + return list; + } + + public static List getWriteableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_to_command, "反馈", "DB601.W2", Boolean.valueOf(true))); + list.add(new ItemDto(item_to_error, "error", "DB601.W2")); + list.add(new ItemDto(item_to_order_No, "工单号", "DB601.W2")); + list.add(new ItemDto(item_to_qty, "生产重量", "DB601.W2")); + list.add(new ItemDto(item_to_material_code, "下发物料编号", "DB601.W10")); + return list; + } + +} + diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_press/LnshPressDefination.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_press/LnshPressDefination.java new file mode 100644 index 0000000..0ca16f6 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_press/LnshPressDefination.java @@ -0,0 +1,82 @@ +package org.nl.acs.device_driver.lnsh.lnsh_press; + +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.defination.OpcDeviceDriverDefination; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceType; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * 晟华压力机 + * + */ +@Service +public class LnshPressDefination implements OpcDeviceDriverDefination { + @Override + public String getDriverCode() { + return "lnsh_press"; + } + + @Override + public String getDriverName() { + return "晟华-压力机"; + } + + @Override + public String getDriverDescription() { + return "晟华-压力机"; + } + + @Override + public DeviceDriver getDriverInstance(Device device) { + return (new LnshPressDeviceDriver()).setDevice(device).setDriverDefination(this); + + } + + @Override + public Class getDeviceDriverType() { + return LnshPressDeviceDriver.class; + } + + @Override + public List getFitDeviceTypes() { + List types = new LinkedList(); + types.add(DeviceType.conveyor); + return types; + } + + @Override + public List getReadableItemDtos() { + return getReadableItemDtos2(); + } + + public static List getReadableItemDtos2() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(ItemProtocol.item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(ItemProtocol.item_mode, "工作状态", "DB600.B2", Boolean.valueOf(true))); + list.add(new ItemDto(ItemProtocol.item_status, "设备状态", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_error, "故障", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(ItemProtocol.item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(ItemProtocol.item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(ItemProtocol.item_error_time, "故障时间", "DB600.D8")); + list.add(new ItemDto(ItemProtocol.item_material, "当前生产物料", "DB600.D9")); + list.add(new ItemDto(ItemProtocol.item_qty, "当前已生产数量", "DB600.D10")); + list.add(new ItemDto(ItemProtocol.item_weight, "当前已生产重量", "DB600.D10")); + list.add(new ItemDto(ItemProtocol.item_qualified, "当前已生产合格数", "DB600.D11")); + list.add(new ItemDto(ItemProtocol.item_unqualified, "当前已生产不合格数", "DB600.D12")); + list.add(new ItemDto(ItemProtocol.item_order_No, "工单号", "DB600.D13")); + return list; + } + + @Override + public List getWriteableItemDtos() { + return ItemProtocol.getWriteableItemDtos(); + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_press/LnshPressDeviceDriver.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_press/LnshPressDeviceDriver.java new file mode 100644 index 0000000..12dd35e --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_press/LnshPressDeviceDriver.java @@ -0,0 +1,313 @@ +package org.nl.acs.device_driver.lnsh.lnsh_press; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ReadUtil; +import org.nl.acs.device.service.DeviceService; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.RouteableDeviceDriver; +import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; +import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.instruction.service.dto.Instruction; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.WcsConfig; +import org.nl.acs.route.service.RouteLineService; +import org.nl.acs.route.service.dto.RouteLineDto; +import org.nl.acs.task.service.TaskService; +import org.nl.acs.task.service.dto.TaskDto; +import org.nl.modules.system.util.CodeUtil; +import org.nl.utils.SpringContextHolder; +import org.nl.wql.core.bean.WQLObject; +import org.openscada.opc.lib.da.Server; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 晟华压力机 + */ +@Slf4j +@Data +@RequiredArgsConstructor +public class LnshPressDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver { + protected ItemProtocol itemProtocol = new ItemProtocol(this); + @Autowired + InstructionService instructionService = SpringContextHolder.getBean("instructionServiceImpl"); + @Autowired + DeviceService deviceservice = SpringContextHolder.getBean("deviceServiceImpl"); + @Autowired + RouteLineService routelineserver = SpringContextHolder.getBean("routeLineServiceImpl"); + @Autowired + TaskService taskserver = SpringContextHolder.getBean("taskServiceImpl"); + String container; + String container_type_desc; + String last_container_type_desc; + String last_container; + //放货准备锁 + String putReadyLock = null; + //有货标记 + protected boolean has_goods_tag = false; + + int mode = 0; + int error = 0; + int last_mode = 0; + int last_error = 0; + Boolean isonline = true; + int hasGoods = 0; + String message = null; + Boolean iserror = false; + + + boolean hasVehicle = false; + boolean isReady = false; + protected int instruction_num = 0; + protected int instruction_num_truth = 0; + boolean isFold = false; + private String assemble_check_tag; + + protected String current_stage_instruction_message; + protected String last_stage_instruction_message; + Integer heartbeat_tag; + private Date instruction_require_time = new Date(); + private Date instruction_finished_time = new Date(); + + private int instruction_require_time_out; + boolean requireSucess = false; + + private int instruction_finished_time_out; + + int branchProtocol = 0; + //备注 + String remark; + //数量 + String qty; + //物料 + String material; + //批次 + String batch; + //当前指令 + Instruction inst = null; + //上次指令 + Instruction last_inst = null; + + //触摸屏手动触发任务 + private Boolean is_has_task = false; + + //申请搬运任务 + private Boolean apply_handling = false; + //申请物料 + private Boolean apply_material = false; + + //暂定 0就绪 1请求取货 2取货完成 3请求放货 4放货完成 5取货完成离开 6放货完成离开 7请求进入区域 8请求离开区域 + int flag; + + String devicecode; + + @Override + public Device getDevice() { + return this.device; + } + + + @Override + public void execute() { + String message = null; + try { + String device_code = this.getDeviceCode(); + mode = this.itemProtocol.getMode(); + + if (mode != last_mode) { + this.setRequireSucess(false); + } + if (error != last_error) { + } + + } catch (Exception var17) { + return; + } + + if (!this.itemProtocol.getIsonline()) { + this.setIsonline(false); + this.setIserror(true); + message = "信号量同步异常"; + //未联机 + } else if (mode == 0) { + this.setIsonline(false); + this.setIserror(true); + message = "未联机"; + //有报警 + } else if (error != 0) { + this.setIsonline(false); + this.setIserror(true); + message = "有报警"; + //无报警 + } else { + this.setIsonline(true); + this.setIserror(false); + message = ""; + Instruction instruction = null; + List toInstructions; + switch (mode) { + case 1: + log.debug("设备运转模式:等待工作"); + return; + case 2: + if (material.length() > 0 && qty.length() > 0 && !requireSucess) { + this.instruction_require(container); + } + } + + switch (flag) { + //取货完成 + case 1: + writing(2); + return; + //放货完成 + case 2: + writing(3); + return; + + } + + } + last_mode = mode; + last_error = error; + + } + + + public boolean exe_error() { + if (this.error == 0) { + return true; + } else { + log.debug("设备报警"); + return false; + } + } + + protected void thingToNothing() { + log.debug("从有货到无货 清理数据"); + this.set_last_container(container, container_type_desc); + } + + public void set_last_container(String barcode, String type_desc) { + this.set_last_container(barcode); + this.set_last_container_type_desc(type_desc); + } + + public void set_last_container(String barcode) { + } + + public void set_last_container_type_desc(String type) { + } + + public boolean exe_business() { + return true; + } + + protected void executing(Instruction instruction) { + this.executing(1, instruction, ""); + } + + public void executing(int command, Instruction instruction, String appendMessage) { + String to_material_code = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code() + + "." + ItemProtocol.item_to_material_code; + if (appendMessage == null) { + appendMessage = ""; + } + if (instruction != null) { + instruction_num = Integer.parseInt(instruction.getInstruction_code()); + } + String opcservcerid = this.getDevice().getOpc_server_id(); + Server server = ReadUtil.getServer(opcservcerid); + Map itemMap = new HashMap(); + ReadUtil.write(itemMap, server); + + } + + public void executing(Server server, Map itemMap) { + ReadUtil.write(itemMap, server); + } + + public void writing(int command) { + + String opcservcerid = this.getDevice().getOpc_server_id(); + Server server = ReadUtil.getServer(opcservcerid); + Map itemMap = new HashMap(); + ReadUtil.write(itemMap, server); + + } + + public void writing(int type, int command) { + String to_material_code = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code() + + "." + ItemProtocol.item_to_material_code; + String opcservcerid = this.getDevice().getOpc_server_id(); + Server server = ReadUtil.getServer(opcservcerid); + Map itemMap = new HashMap(); + if (type == 2) { + itemMap.put(to_material_code, command); + + } + ReadUtil.write(itemMap, server); + + } + + public boolean instruction_require(String container_code) { + return instruction_require(container_code, WcsConfig.task_container_type_default_desc); + } + + /** + * 请求指令 + * + * @param container_code + * @param container_type + */ + public synchronized boolean instruction_require(String container_code, String container_type) { + Date date = new Date(); + if (date.getTime() - this.instruction_require_time.getTime() < (long) this.instruction_require_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_require_time_out); + return false; + } else { + this.instruction_require_time = date; + TaskDto dto = new TaskDto(); + String now = DateUtil.now(); + dto.setTask_id(IdUtil.simpleUUID()); + dto.setCreate_by(this.getDevice().getDevice_code()); + dto.setUpdate_by(this.getDevice().getDevice_code()); + dto.setStart_point_code(this.getDevice().getDevice_code()); + dto.setVehicle_code(container_code); + dto.setVehicle_type(container_type); + + String taskcode = CodeUtil.getNewCode("TASK_NO"); + dto.setTask_code("-" + taskcode); + dto.setTask_status("0"); + dto.setPriority("101"); + RouteLineDto jo = routelineserver.findByCode(this.getDevice().getDevice_code()); + String next_device_codecode = jo.getNext_device_code(); + if (StrUtil.isEmpty(next_device_codecode)) { + throw new RuntimeException("该设备未找到对应路由"); + } + dto.setNext_point_code(next_device_codecode); + dto.setUpdate_time(now); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("acs_task"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + + wo.insert(json); + requireSucess = false; + return true; + } + } + + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_rgv/ItemProtocol.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_rgv/ItemProtocol.java new file mode 100644 index 0000000..8743d75 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_rgv/ItemProtocol.java @@ -0,0 +1,178 @@ +package org.nl.acs.device_driver.lnsh.lnsh_rgv; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Data +public class ItemProtocol { + + public static String item_heartbeat = "heartbeat"; + public static String item_mode = "mode"; + public static String item_status = "status"; + public static String item_move_1 = "move_1"; + public static String item_move_2 = "move_2"; + public static String item_action_1 = "action_1"; + public static String item_action_2 = "action_2"; + public static String item_walk_y = "walk_y"; + public static String item_error = "error"; + public static String item_task1 = "task1"; + public static String item_task2 = "task2"; + public static String item_open_time = "open_time"; + public static String item_standby_time = "standby_time "; + public static String item_production_time = "production_time"; + public static String item_error_time = "error_time"; + public static String item_to_command = "to_command"; + public static String item_to_onset1 = "to_onset1"; + public static String item_to_target1 = "to_target1"; + public static String item_to_task = "to_task"; + public static String item_to_onset2 = "to_onset2"; + public static String item_to_target2 = "to_target2"; + + private LnshRGVDeviceDriver driver; + + public ItemProtocol(LnshRGVDeviceDriver driver) { + this.driver = driver; + } + + public int getHeartbeat() { + return this.getOpcIntegerValue(item_heartbeat); + } + + public int getMode() { + return this.getOpcIntegerValue(item_mode); + } + + public int getStatus() { + return this.getOpcIntegerValue(item_status); + } + + public int getError() { + return this.getOpcIntegerValue(item_error); + } + + public int getOpen_time() { + return this.getOpcIntegerValue(item_open_time); + } + + public int getStandby_time() { + return this.getOpcIntegerValue(item_standby_time); + } + + public int getProduction_time() { + return this.getOpcIntegerValue(item_production_time); + } + + public int getError_time() { + return this.getOpcIntegerValue(item_error_time); + } + + public int getMove_1() { + return this.getOpcIntegerValue(item_move_1); + } + + public int getMove_2() { + return this.getOpcIntegerValue(item_move_2); + } + + public int getAction_1() { + return this.getOpcIntegerValue(item_action_1); + } + + public int getAction_2() { + return this.getOpcIntegerValue(item_action_2); + } + + public int getWalk_y() { + return this.getOpcIntegerValue(item_walk_y); + } + + public int getTask1() { + return this.getOpcIntegerValue(item_task1); + } + + public int getTask2() { + return this.getOpcIntegerValue(item_task2); + } + + public int getTo_command() { + return this.getOpcIntegerValue(item_to_command); + } + + public int getTo_onset1() { + return this.getOpcIntegerValue(item_to_onset1); + } + + public int getTo_onset2() { + return this.getOpcIntegerValue(item_to_onset2); + } + + public int getTo_target1() { + return this.getOpcIntegerValue(item_to_target1); + } + + public int getTo_target2() { + return this.getOpcIntegerValue(item_to_target2); + } + + public int getTo_task() { + return this.getOpcIntegerValue(item_to_task); + } + + //是否有货 + public int hasGoods(int move) { + return move; + } + + Boolean isonline; + + public int getOpcIntegerValue(String protocol) { + Integer value = this.driver.getIntegeregerValue(protocol); + if (value == null) { + log.error(this.getDriver().getDeviceCode() + ":protocol " + protocol + " 信号同步异常!"); + setIsonline(false); + } else { + setIsonline(true); + return value; + } + return 0; + + } + + public static List getReadableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(item_mode, "工作状态", "DB600.B2", Boolean.valueOf(true))); + list.add(new ItemDto(item_status, "设备状态", "DB600.B3")); + list.add(new ItemDto(item_move_1, "前工位光电信号", "DB600.B3")); + list.add(new ItemDto(item_move_2, "后工位光电信号", "DB600.B3")); + list.add(new ItemDto(item_action_1, "前工位动作信号", "DB600.B3")); + list.add(new ItemDto(item_action_2, "后工位动作信号", "DB600.B3")); + list.add(new ItemDto(item_walk_y, "行走列", "DB600.B3")); + list.add(new ItemDto(item_error, "车体报警", "DB600.B3")); + list.add(new ItemDto(item_task1, "前工位任务号", "DB600.B3")); + list.add(new ItemDto(item_task2, "后工位任务号", "DB600.B3")); + list.add(new ItemDto(item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(item_error_time, "故障时间", "DB600.D8")); + return list; + } + + public static List getWriteableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_to_command, "下发命令", "DB601.W02")); + list.add(new ItemDto(item_to_onset1, "下发起始站", "DB601.W4")); + list.add(new ItemDto(item_to_target1, "下发目标站", "DB601.W6")); + list.add(new ItemDto(item_to_task, "下发任务号", "DB601.W10")); + list.add(new ItemDto(item_to_onset2, "下发起始站", "DB601.W10")); + list.add(new ItemDto(item_to_target2, "下发目标站", "DB601.W10")); + return list; + } + +} + diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_rgv/LnshRGVDefination.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_rgv/LnshRGVDefination.java new file mode 100644 index 0000000..35b9731 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_rgv/LnshRGVDefination.java @@ -0,0 +1,83 @@ +package org.nl.acs.device_driver.lnsh.lnsh_rgv; + +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.defination.OpcDeviceDriverDefination; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceType; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * 晟华RGV + * + */ +@Service +public class LnshRGVDefination implements OpcDeviceDriverDefination { + @Override + public String getDriverCode() { + return "lnsh_rgv"; + } + + @Override + public String getDriverName() { + return "晟华-RGV"; + } + + @Override + public String getDriverDescription() { + return "晟华-RGV"; + } + + @Override + public DeviceDriver getDriverInstance(Device device) { + return (new LnshRGVDeviceDriver()).setDevice(device).setDriverDefination(this); + + } + + @Override + public Class getDeviceDriverType() { + return LnshRGVDeviceDriver.class; + } + + @Override + public List getFitDeviceTypes() { + List types = new LinkedList(); + types.add(DeviceType.conveyor); + return types; + } + + @Override + public List getReadableItemDtos() { + return getReadableItemDtos2(); + } + + public static List getReadableItemDtos2() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(ItemProtocol.item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(ItemProtocol.item_mode, "工作状态", "DB600.B2", Boolean.valueOf(true))); + list.add(new ItemDto(ItemProtocol.item_status, "设备状态", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_move_1, "前工位光电信号", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_move_2, "后工位光电信号", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_action_1, "前工位动作信号", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_action_2, "后工位动作信号", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_walk_y, "行走列", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_error, "车体报警", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_task1, "前工位任务号", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_task2, "后工位任务号", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(ItemProtocol.item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(ItemProtocol.item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(ItemProtocol.item_error_time, "故障时间", "DB600.D8")); + return list; + } + + @Override + public List getWriteableItemDtos() { + return ItemProtocol.getWriteableItemDtos(); + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_rgv/LnshRGVDeviceDriver.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_rgv/LnshRGVDeviceDriver.java new file mode 100644 index 0000000..d24c366 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_rgv/LnshRGVDeviceDriver.java @@ -0,0 +1,305 @@ +package org.nl.acs.device_driver.lnsh.lnsh_rgv; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ReadUtil; +import org.nl.acs.device.service.DeviceService; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.RouteableDeviceDriver; +import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; +import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.instruction.service.dto.Instruction; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.WcsConfig; +import org.nl.acs.route.service.RouteLineService; +import org.nl.acs.route.service.dto.RouteLineDto; +import org.nl.acs.task.service.TaskService; +import org.nl.acs.task.service.dto.TaskDto; +import org.nl.modules.system.util.CodeUtil; +import org.nl.utils.SpringContextHolder; +import org.nl.wql.core.bean.WQLObject; +import org.openscada.opc.lib.da.Server; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 晟华RGV + */ +@Slf4j +@Data +@RequiredArgsConstructor +public class LnshRGVDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver { + protected ItemProtocol itemProtocol = new ItemProtocol(this); + @Autowired + InstructionService instructionService = SpringContextHolder.getBean("instructionServiceImpl"); + @Autowired + DeviceService deviceservice = SpringContextHolder.getBean("deviceServiceImpl"); + @Autowired + RouteLineService routelineserver = SpringContextHolder.getBean("routeLineServiceImpl"); + @Autowired + TaskService taskserver = SpringContextHolder.getBean("taskServiceImpl"); + String container; + String container_type_desc; + String last_container_type_desc; + String last_container; + //放货准备锁 + String putReadyLock = null; + //有货标记 + protected boolean has_goods_tag = false; + + int mode = 0; + int error = 0; + int last_mode = 0; + int last_error = 0; + Boolean isonline = true; + int hasGoods = 0; + String message = null; + Boolean iserror = false; + + + boolean hasVehicle = false; + boolean isReady = false; + protected int instruction_num = 0; + protected int instruction_num_truth = 0; + boolean isFold = false; + private String assemble_check_tag; + + protected String current_stage_instruction_message; + protected String last_stage_instruction_message; + Integer heartbeat_tag; + private Date instruction_require_time = new Date(); + private Date instruction_finished_time = new Date(); + + private int instruction_require_time_out; + boolean requireSucess = false; + + private int instruction_finished_time_out; + + int branchProtocol = 0; + //备注 + String remark; + //数量 + String qty; + //物料 + String material; + //批次 + String batch; + //当前指令 + Instruction inst = null; + //上次指令 + Instruction last_inst = null; + + //触摸屏手动触发任务 + private Boolean is_has_task = false; + + //申请搬运任务 + private Boolean apply_handling = false; + //申请物料 + private Boolean apply_material = false; + + //暂定 0就绪 1请求取货 2取货完成 3请求放货 4放货完成 5取货完成离开 6放货完成离开 7请求进入区域 8请求离开区域 + int flag; + + String devicecode; + + @Override + public Device getDevice() { + return this.device; + } + + + @Override + public void execute() { + String message = null; + try { + String device_code = this.getDeviceCode(); + mode = this.itemProtocol.getMode(); + + if (mode != last_mode) { + this.setRequireSucess(false); + } + if (error != last_error) { + } + + } catch (Exception var17) { + return; + } + + if (!this.itemProtocol.getIsonline()) { + this.setIsonline(false); + this.setIserror(true); + message = "信号量同步异常"; + //未联机 + } else if (mode == 0) { + this.setIsonline(false); + this.setIserror(true); + message = "未联机"; + //有报警 + } else if (error != 0) { + this.setIsonline(false); + this.setIserror(true); + message = "有报警"; + //无报警 + } else { + this.setIsonline(true); + this.setIserror(false); + message = ""; + Instruction instruction = null; + List toInstructions; + switch (mode) { + case 1: + log.debug("设备运转模式:等待工作"); + return; + case 2: + if (material.length() > 0 && qty.length() > 0 && !requireSucess) { + this.instruction_require(container); + } + } + + switch (flag) { + //取货完成 + case 1: + writing(2); + return; + //放货完成 + case 2: + writing(3); + return; + + } + + } + last_mode = mode; + last_error = error; + + } + + + public boolean exe_error() { + if (this.error == 0) { + return true; + } else { + log.debug("设备报警"); + return false; + } + } + + protected void thingToNothing() { + log.debug("从有货到无货 清理数据"); + this.set_last_container(container, container_type_desc); + } + + public void set_last_container(String barcode, String type_desc) { + this.set_last_container(barcode); + this.set_last_container_type_desc(type_desc); + } + + public void set_last_container(String barcode) { + } + + public void set_last_container_type_desc(String type) { + } + + public boolean exe_business() { + return true; + } + + protected void executing(Instruction instruction) { + this.executing(1, instruction, ""); + } + + public void executing(int command, Instruction instruction, String appendMessage) { + if (appendMessage == null) { + appendMessage = ""; + } + if (instruction != null) { + instruction_num = Integer.parseInt(instruction.getInstruction_code()); + } + String opcservcerid = this.getDevice().getOpc_server_id(); + Server server = ReadUtil.getServer(opcservcerid); + Map itemMap = new HashMap(); + ReadUtil.write(itemMap, server); + + } + + public void executing(Server server, Map itemMap) { + ReadUtil.write(itemMap, server); + } + + public void writing(int command) { + + String opcservcerid = this.getDevice().getOpc_server_id(); + Server server = ReadUtil.getServer(opcservcerid); + Map itemMap = new HashMap(); + ReadUtil.write(itemMap, server); + + } + + public void writing(int type, int command) { + String opcservcerid = this.getDevice().getOpc_server_id(); + Server server = ReadUtil.getServer(opcservcerid); + Map itemMap = new HashMap(); + ReadUtil.write(itemMap, server); + + } + + public boolean instruction_require(String container_code) { + return instruction_require(container_code, WcsConfig.task_container_type_default_desc); + } + + /** + * 请求指令 + * + * @param container_code + * @param container_type + */ + public synchronized boolean instruction_require(String container_code, String container_type) { + Date date = new Date(); + if (date.getTime() - this.instruction_require_time.getTime() < (long) this.instruction_require_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_require_time_out); + return false; + } else { + this.instruction_require_time = date; + TaskDto dto = new TaskDto(); + String now = DateUtil.now(); + dto.setTask_id(IdUtil.simpleUUID()); + dto.setCreate_by(this.getDevice().getDevice_code()); + dto.setUpdate_by(this.getDevice().getDevice_code()); + dto.setStart_point_code(this.getDevice().getDevice_code()); + dto.setVehicle_code(container_code); + dto.setVehicle_type(container_type); + + String taskcode = CodeUtil.getNewCode("TASK_NO"); + dto.setTask_code("-" + taskcode); + dto.setTask_status("0"); + dto.setPriority("101"); + RouteLineDto jo = routelineserver.findByCode(this.getDevice().getDevice_code()); + String next_device_codecode = jo.getNext_device_code(); + if (StrUtil.isEmpty(next_device_codecode)) { + throw new RuntimeException("该设备未找到对应路由"); + } + dto.setNext_point_code(next_device_codecode); + dto.setUpdate_time(now); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("acs_task"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + + wo.insert(json); + requireSucess = false; + return true; + } + } + + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_split_manipulator/ItemProtocol.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_split_manipulator/ItemProtocol.java new file mode 100644 index 0000000..cc9f440 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_split_manipulator/ItemProtocol.java @@ -0,0 +1,143 @@ +package org.nl.acs.device_driver.lnsh.lnsh_split_manipulator; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Data +public class ItemProtocol { + + public static String item_heartbeat = "heartbeat"; + public static String item_mode = "mode"; + public static String item_error = "error"; + public static String item_getStation = "getStation"; + public static String item_barcode = "barcode"; + public static String item_open_time = "open_time"; + public static String item_standby_time = "standby_time "; + public static String item_production_time = "production_time"; + public static String item_error_time = "error_time"; + public static String item_material = "material"; + public static String item_total_split = "total_split"; + public static String item_to_heartbeat = "to_heartbeat"; + public static String item_to_feedback = "to_feedback"; + public static String item_to_error = "to_error"; + public static String item_to_material = "to_material"; + + + private LnshSplitManipulatorDeviceDriver driver; + + public ItemProtocol(LnshSplitManipulatorDeviceDriver driver) { + this.driver = driver; + } + + public int getHeartbeat() { + return this.getOpcIntegerValue(item_heartbeat); + } + + public int getMode() { + return this.getOpcIntegerValue(item_mode); + } + + public int getError() { + return this.getOpcIntegerValue(item_error); + } + + public int getBarcode() { + return this.getOpcIntegerValue(item_barcode); + } + + public int getOpen_time() { + return this.getOpcIntegerValue(item_open_time); + } + + public int getStandby_time() { + return this.getOpcIntegerValue(item_standby_time); + } + + public int getProduction_time() { + return this.getOpcIntegerValue(item_production_time); + } + + public int getError_time() { + return this.getOpcIntegerValue(item_error_time); + } + + public int getGetStation() { + return this.getOpcIntegerValue(item_getStation); + } + + public int getMaterial() { + return this.getOpcIntegerValue(item_material); + } + + public int getTotal_split() { + return this.getOpcIntegerValue(item_total_split); + } + + public int getTo_heartbeat() { + return this.getOpcIntegerValue(item_to_heartbeat); + } + + public int getTo_feedback() { + return this.getOpcIntegerValue(item_to_feedback); + } + + public int getTo_error() { + return this.getOpcIntegerValue(item_to_error); + } + + public int getTo_material() { + return this.getOpcIntegerValue(item_to_material); + } + + //是否有货 + public int hasGoods(int move) { + return move; + } + + Boolean isonline; + + public int getOpcIntegerValue(String protocol) { + Integer value = this.driver.getIntegeregerValue(protocol); + if (value == null) { + log.error(this.getDriver().getDeviceCode() + ":protocol " + protocol + " 信号同步异常!"); + setIsonline(false); + } else { + setIsonline(true); + return value; + } + return 0; + + } + + public static List getReadableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(item_mode, "工作状态", "DB600.B2", Boolean.valueOf(true))); + list.add(new ItemDto(item_error, "故障", "DB600.B3")); + list.add(new ItemDto(item_getStation, "当前抓取工位", "DB600.B3")); + list.add(new ItemDto(item_barcode, "条码", "DB600.B3")); + list.add(new ItemDto(item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(item_error_time, "故障时间", "DB600.D8")); + list.add(new ItemDto(item_material, "物料", "DB600.D8")); + list.add(new ItemDto(item_total_split, "累计拆垛数量", "DB600.D13")); + return list; + } + + public static List getWriteableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_to_heartbeat, "心跳", "DB601.W10")); + list.add(new ItemDto(item_to_feedback, "机器人动作反馈", "DB601.W10")); + list.add(new ItemDto(item_to_error, "故障代码", "DB601.W10")); + list.add(new ItemDto(item_to_material, "物料", "DB601.W10")); + return list; + } + +} + diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_split_manipulator/LnshSplitManipulatorDefination.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_split_manipulator/LnshSplitManipulatorDefination.java new file mode 100644 index 0000000..2c6b73c --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_split_manipulator/LnshSplitManipulatorDefination.java @@ -0,0 +1,79 @@ +package org.nl.acs.device_driver.lnsh.lnsh_split_manipulator; + +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.defination.OpcDeviceDriverDefination; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceType; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * 晟华拆垛机械手 + * + */ +@Service +public class LnshSplitManipulatorDefination implements OpcDeviceDriverDefination { + @Override + public String getDriverCode() { + return "lnsh_split_manipulator"; + } + + @Override + public String getDriverName() { + return "晟华-拆垛机械手"; + } + + @Override + public String getDriverDescription() { + return "晟华-拆垛机械手"; + } + + @Override + public DeviceDriver getDriverInstance(Device device) { + return (new LnshSplitManipulatorDeviceDriver()).setDevice(device).setDriverDefination(this); + + } + + @Override + public Class getDeviceDriverType() { + return LnshSplitManipulatorDeviceDriver.class; + } + + @Override + public List getFitDeviceTypes() { + List types = new LinkedList(); + types.add(DeviceType.conveyor); + return types; + } + + @Override + public List getReadableItemDtos() { + return getReadableItemDtos2(); + } + + public static List getReadableItemDtos2() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(ItemProtocol.item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(ItemProtocol.item_mode, "工作状态", "DB600.B2", Boolean.valueOf(true))); + list.add(new ItemDto(ItemProtocol.item_error, "故障", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_getStation, "当前抓取工位", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_barcode, "条码", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_open_time, "开机时间", "DB600.B4")); + list.add(new ItemDto(ItemProtocol.item_standby_time, "待机时间", "DB600.D6")); + list.add(new ItemDto(ItemProtocol.item_production_time, "生产时间", "DB600.D7")); + list.add(new ItemDto(ItemProtocol.item_error_time, "故障时间", "DB600.D8")); + list.add(new ItemDto(ItemProtocol.item_material, "物料", "DB600.D8")); + list.add(new ItemDto(ItemProtocol.item_total_split, "累计拆垛数量", "DB600.D13")); + return list; + } + + @Override + public List getWriteableItemDtos() { + return ItemProtocol.getWriteableItemDtos(); + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_split_manipulator/LnshSplitManipulatorDeviceDriver.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_split_manipulator/LnshSplitManipulatorDeviceDriver.java new file mode 100644 index 0000000..97d5c8c --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_split_manipulator/LnshSplitManipulatorDeviceDriver.java @@ -0,0 +1,305 @@ +package org.nl.acs.device_driver.lnsh.lnsh_split_manipulator; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ReadUtil; +import org.nl.acs.device.service.DeviceService; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.RouteableDeviceDriver; +import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; +import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.instruction.service.dto.Instruction; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.WcsConfig; +import org.nl.acs.route.service.RouteLineService; +import org.nl.acs.route.service.dto.RouteLineDto; +import org.nl.acs.task.service.TaskService; +import org.nl.acs.task.service.dto.TaskDto; +import org.nl.modules.system.util.CodeUtil; +import org.nl.utils.SpringContextHolder; +import org.nl.wql.core.bean.WQLObject; +import org.openscada.opc.lib.da.Server; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 晟华拆垛机械手 + */ +@Slf4j +@Data +@RequiredArgsConstructor +public class LnshSplitManipulatorDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver { + protected ItemProtocol itemProtocol = new ItemProtocol(this); + @Autowired + InstructionService instructionService = SpringContextHolder.getBean("instructionServiceImpl"); + @Autowired + DeviceService deviceservice = SpringContextHolder.getBean("deviceServiceImpl"); + @Autowired + RouteLineService routelineserver = SpringContextHolder.getBean("routeLineServiceImpl"); + @Autowired + TaskService taskserver = SpringContextHolder.getBean("taskServiceImpl"); + String container; + String container_type_desc; + String last_container_type_desc; + String last_container; + //放货准备锁 + String putReadyLock = null; + //有货标记 + protected boolean has_goods_tag = false; + + int mode = 0; + int error = 0; + int last_mode = 0; + int last_error = 0; + Boolean isonline = true; + int hasGoods = 0; + String message = null; + Boolean iserror = false; + + + boolean hasVehicle = false; + boolean isReady = false; + protected int instruction_num = 0; + protected int instruction_num_truth = 0; + boolean isFold = false; + private String assemble_check_tag; + + protected String current_stage_instruction_message; + protected String last_stage_instruction_message; + Integer heartbeat_tag; + private Date instruction_require_time = new Date(); + private Date instruction_finished_time = new Date(); + + private int instruction_require_time_out; + boolean requireSucess = false; + + private int instruction_finished_time_out; + + int branchProtocol = 0; + //备注 + String remark; + //数量 + String qty; + //物料 + String material; + //批次 + String batch; + //当前指令 + Instruction inst = null; + //上次指令 + Instruction last_inst = null; + + //触摸屏手动触发任务 + private Boolean is_has_task = false; + + //申请搬运任务 + private Boolean apply_handling = false; + //申请物料 + private Boolean apply_material = false; + + //暂定 0就绪 1请求取货 2取货完成 3请求放货 4放货完成 5取货完成离开 6放货完成离开 7请求进入区域 8请求离开区域 + int flag; + + String devicecode; + + @Override + public Device getDevice() { + return this.device; + } + + + @Override + public void execute() { + String message = null; + try { + String device_code = this.getDeviceCode(); + mode = this.itemProtocol.getMode(); + + if (mode != last_mode) { + this.setRequireSucess(false); + } + if (error != last_error) { + } + + } catch (Exception var17) { + return; + } + + if (!this.itemProtocol.getIsonline()) { + this.setIsonline(false); + this.setIserror(true); + message = "信号量同步异常"; + //未联机 + } else if (mode == 0) { + this.setIsonline(false); + this.setIserror(true); + message = "未联机"; + //有报警 + } else if (error != 0) { + this.setIsonline(false); + this.setIserror(true); + message = "有报警"; + //无报警 + } else { + this.setIsonline(true); + this.setIserror(false); + message = ""; + Instruction instruction = null; + List toInstructions; + switch (mode) { + case 1: + log.debug("设备运转模式:等待工作"); + return; + case 2: + if (material.length() > 0 && qty.length() > 0 && !requireSucess) { + this.instruction_require(container); + } + } + + switch (flag) { + //取货完成 + case 1: + writing(2); + return; + //放货完成 + case 2: + writing(3); + return; + + } + + } + last_mode = mode; + last_error = error; + + } + + + public boolean exe_error() { + if (this.error == 0) { + return true; + } else { + log.debug("设备报警"); + return false; + } + } + + protected void thingToNothing() { + log.debug("从有货到无货 清理数据"); + this.set_last_container(container, container_type_desc); + } + + public void set_last_container(String barcode, String type_desc) { + this.set_last_container(barcode); + this.set_last_container_type_desc(type_desc); + } + + public void set_last_container(String barcode) { + } + + public void set_last_container_type_desc(String type) { + } + + public boolean exe_business() { + return true; + } + + protected void executing(Instruction instruction) { + this.executing(1, instruction, ""); + } + + public void executing(int command, Instruction instruction, String appendMessage) { + if (appendMessage == null) { + appendMessage = ""; + } + if (instruction != null) { + instruction_num = Integer.parseInt(instruction.getInstruction_code()); + } + String opcservcerid = this.getDevice().getOpc_server_id(); + Server server = ReadUtil.getServer(opcservcerid); + Map itemMap = new HashMap(); + ReadUtil.write(itemMap, server); + + } + + public void executing(Server server, Map itemMap) { + ReadUtil.write(itemMap, server); + } + + public void writing(int command) { + + String opcservcerid = this.getDevice().getOpc_server_id(); + Server server = ReadUtil.getServer(opcservcerid); + Map itemMap = new HashMap(); + ReadUtil.write(itemMap, server); + + } + + public void writing(int type, int command) { + String opcservcerid = this.getDevice().getOpc_server_id(); + Server server = ReadUtil.getServer(opcservcerid); + Map itemMap = new HashMap(); + ReadUtil.write(itemMap, server); + + } + + public boolean instruction_require(String container_code) { + return instruction_require(container_code, WcsConfig.task_container_type_default_desc); + } + + /** + * 请求指令 + * + * @param container_code + * @param container_type + */ + public synchronized boolean instruction_require(String container_code, String container_type) { + Date date = new Date(); + if (date.getTime() - this.instruction_require_time.getTime() < (long) this.instruction_require_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_require_time_out); + return false; + } else { + this.instruction_require_time = date; + TaskDto dto = new TaskDto(); + String now = DateUtil.now(); + dto.setTask_id(IdUtil.simpleUUID()); + dto.setCreate_by(this.getDevice().getDevice_code()); + dto.setUpdate_by(this.getDevice().getDevice_code()); + dto.setStart_point_code(this.getDevice().getDevice_code()); + dto.setVehicle_code(container_code); + dto.setVehicle_type(container_type); + + String taskcode = CodeUtil.getNewCode("TASK_NO"); + dto.setTask_code("-" + taskcode); + dto.setTask_status("0"); + dto.setPriority("101"); + RouteLineDto jo = routelineserver.findByCode(this.getDevice().getDevice_code()); + String next_device_codecode = jo.getNext_device_code(); + if (StrUtil.isEmpty(next_device_codecode)) { + throw new RuntimeException("该设备未找到对应路由"); + } + dto.setNext_point_code(next_device_codecode); + dto.setUpdate_time(now); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("acs_task"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + + wo.insert(json); + requireSucess = false; + return true; + } + } + + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_station/ItemProtocol.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_station/ItemProtocol.java new file mode 100644 index 0000000..b36e1fc --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_station/ItemProtocol.java @@ -0,0 +1,131 @@ +package org.nl.acs.device_driver.lnsh.lnsh_station; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Data +public class ItemProtocol { + public static String item_heartbeat = "heartbeat"; + public static String item_mode = "mode"; + public static String item_move = "move"; + public static String item_action = "action"; + public static String item_ioaction = "ioaction"; + public static String item_error = "error"; + public static String item_task = "task"; + public static String item_weight = "weight"; + public static String item_material = "material"; + public static String item_barcode = "barcode"; + public static String item_to_command = "to_command"; + public static String item_to_target = "to_target"; + public static String item_to_task = "to_task"; + + + Boolean isonline; + + private LnshStationDeviceDriver driver; + + public ItemProtocol(LnshStationDeviceDriver driver) { + this.driver = driver; + } + + public int getHeartbeat() { + return this.getOpcIntegerValue(item_heartbeat); + } + + public int getMode() { + return this.getOpcIntegerValue(item_mode); + } + + public int getMove() { + return this.getOpcIntegerValue(item_move); + } + + public int getAction() { + return this.getOpcIntegerValue(item_action); + } + + public int getIoAction() { + return this.getOpcIntegerValue(item_ioaction); + } + + public int getError() { + return this.getOpcIntegerValue(item_error); + } + + public int getTask() { + return this.getOpcIntegerValue(item_task); + } + + public int getWeight() { + return this.getOpcIntegerValue(item_weight); + } + + public int getMaterial() { + return this.getOpcIntegerValue(item_material); + } + + public int getBarcode() { + return this.getOpcIntegerValue(item_barcode); + } + + public int getToCommand() { + return this.getOpcIntegerValue(item_to_command); + } + + public int getToTarget() { + return this.getOpcIntegerValue(item_to_target); + } + + public int getToTask() { + return this.getOpcIntegerValue(item_to_task); + } + + //是否有货 + public int hasGoods(int move) { + return move; + } + + + public int getOpcIntegerValue(String protocol) { + Integer value = this.driver.getIntegeregerValue(protocol); + if (value == null) { + log.error(this.getDriver().getDeviceCode() + ":protocol " + protocol + " 信号同步异常!"); + setIsonline(false); + } else { + setIsonline(true); + return value; + } + return 0; + + } + + public static List getReadableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(item_mode, "工作状态", "DB600.B2", Boolean.valueOf(true))); + list.add(new ItemDto(item_move, "光电开关信号", "DB600.B3")); + list.add(new ItemDto(item_action, "取放信号", "DB600.B4")); + list.add(new ItemDto(item_ioaction, "进出信号", "DB600.B5")); + list.add(new ItemDto(item_error, "报警信号", "DB600.B7")); + list.add(new ItemDto(item_task, "任务号", "DB600.D10")); + list.add(new ItemDto(item_weight, "重量", "DB600.D14")); + list.add(new ItemDto(item_material, "物料", "DB600.D18")); + list.add(new ItemDto(item_barcode, "条码", "DB600.D68")); + return list; + } + + public static List getWriteableItemDtos() { + ArrayList list = new ArrayList(); + list.add(new ItemDto(item_to_command, "作业命令", "DB601.W2", Boolean.valueOf(true))); + list.add(new ItemDto(item_to_target, "目标站", "DB601.W4")); + list.add(new ItemDto(item_to_task, "任务号", "DB601.D8")); + return list; + } + +} + diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_station/LnshStationDefination.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_station/LnshStationDefination.java new file mode 100644 index 0000000..4844194 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_station/LnshStationDefination.java @@ -0,0 +1,78 @@ +package org.nl.acs.device_driver.lnsh.lnsh_station; + +import org.nl.acs.device.device_driver.standard_inspect.ItemDto; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.defination.OpcDeviceDriverDefination; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceType; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * 晟华-工位(交互模板) + * + */ +@Service +public class LnshStationDefination implements OpcDeviceDriverDefination { + @Override + public String getDriverCode() { + return "lnsh_station"; + } + + @Override + public String getDriverName() { + return "晟华-工位(交互模板)"; + } + + @Override + public String getDriverDescription() { + return "晟华-工位(交互模板)"; + } + + @Override + public DeviceDriver getDriverInstance(Device device) { + return (new LnshStationDeviceDriver()).setDevice(device).setDriverDefination(this); + + } + + @Override + public Class getDeviceDriverType() { + return LnshStationDeviceDriver.class; + } + + @Override + public List getFitDeviceTypes() { + List types = new LinkedList(); + types.add(DeviceType.conveyor); + return types; + } + + @Override + public List getReadableItemDtos() { + return getReadableItemDtos2(); + } + + public static List getReadableItemDtos2() { + List list = new ArrayList(); + list.add(new ItemDto(ItemProtocol.item_heartbeat, "心跳", "DB600.B0")); + list.add(new ItemDto(ItemProtocol.item_mode, "工作状态", "DB600.B2", Boolean.valueOf(true))); + list.add(new ItemDto(ItemProtocol.item_move, "光电开关信号", "DB600.B3")); + list.add(new ItemDto(ItemProtocol.item_action, "取放信号", "DB600.B4")); + list.add(new ItemDto(ItemProtocol.item_ioaction, "进出信号", "DB600.B5")); + list.add(new ItemDto(ItemProtocol.item_error, "报警信号", "DB600.B7")); + list.add(new ItemDto(ItemProtocol.item_task, "任务号", "DB600.D10")); + list.add(new ItemDto(ItemProtocol.item_weight, "重量", "DB600.D14")); + list.add(new ItemDto(ItemProtocol.item_material, "物料", "DB600.D18")); + list.add(new ItemDto(ItemProtocol.item_barcode, "条码", "DB600.D68")); + return list; + } + + @Override + public List getWriteableItemDtos() { + return ItemProtocol.getWriteableItemDtos(); + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_station/LnshStationDeviceDriver.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_station/LnshStationDeviceDriver.java new file mode 100644 index 0000000..1a68b92 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_station/LnshStationDeviceDriver.java @@ -0,0 +1,538 @@ +package org.nl.acs.device_driver.lnsh.lnsh_station; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.device.device_driver.standard_inspect.ReadUtil; +import org.nl.acs.device.service.DeviceService; +import org.nl.acs.device_driver.DeviceDriver; +import org.nl.acs.device_driver.RouteableDeviceDriver; +import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver; +import org.nl.acs.device_driver.driver.ExecutableDeviceDriver; +import org.nl.acs.device_driver.standard_emptypallet_site.StandardEmptyPalletSiteDeviceDriver; +import org.nl.acs.device_driver.standard_inspect_site.StandardInspectSiteDeviceDriver; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.instruction.service.dto.Instruction; +import org.nl.acs.opc.Device; +import org.nl.acs.opc.DeviceAppService; +import org.nl.acs.opc.DeviceAppServiceImpl; +import org.nl.acs.opc.WcsConfig; +import org.nl.acs.route.service.RouteLineService; +import org.nl.acs.route.service.dto.RouteLineDto; +import org.nl.acs.task.service.TaskService; +import org.nl.acs.task.service.dto.TaskDto; +import org.nl.modules.system.util.CodeUtil; +import org.nl.utils.SpringContextHolder; +import org.nl.wql.core.bean.WQLObject; +import org.openscada.opc.lib.da.Server; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.*; + +/** + * 晟华-工位(交互模板) + */ +@Slf4j +@Data +@RequiredArgsConstructor +public class LnshStationDeviceDriver extends AbstractOpcDeviceDriver implements DeviceDriver, ExecutableDeviceDriver, RouteableDeviceDriver { + protected ItemProtocol itemProtocol = new ItemProtocol(this); + @Autowired + InstructionService instructionService = SpringContextHolder.getBean("instructionServiceImpl"); + @Autowired + DeviceService deviceservice = SpringContextHolder.getBean("deviceServiceImpl"); + @Autowired + RouteLineService routelineserver = SpringContextHolder.getBean("routeLineServiceImpl"); + @Autowired + TaskService taskserver = SpringContextHolder.getBean("taskServiceImpl"); + String container; + String container_type_desc; + String last_container_type_desc; + String last_container; + //放货准备锁 + String putReadyLock = null; + //有货标记 + protected boolean has_goods_tag = false; + String devicecode; + int mode = 0; + int error = 0; + int move = 0; + int actoin; + int io_action; + int task = 0; + int last_mode = 0; + int last_error = 0; + int last_move = 0; + int last_task = 0; + Boolean isonline = true; + int hasGoods = 0; + Boolean iserror = false; + + boolean hasVehicle = false; + boolean isReady = false; + protected int instruction_num = 0; + protected int instruction_num_truth = 0; + boolean isFold = false; + private String assemble_check_tag; + private Boolean sampleMode0; + private Boolean sampleMode3; + private Integer sampleError; + private Boolean sampleOnline; + protected String displayMessage = null; + public int display_message_time_out = 30000; + public Date display_message_time; + protected String current_stage_instruction_message; + protected String last_stage_instruction_message; + Integer heartbeat_tag; + private Date instruction_require_time = new Date(); + private Date instruction_finished_time = new Date(); + + private int instruction_require_time_out = 3000; + boolean requireSucess = false; + + private int instruction_finished_time_out; + + int heartbeat; + int last_heartbeat; + private Date checkHeartbeattime = new Date(); + private Date last_checkHeartbeattime = new Date(); + + + int branchProtocol = 0; + //当前指令 + Instruction inst = null; + //上次指令 + Instruction last_inst = null; + + //触摸屏手动触发任务 + private Boolean is_has_task = false; + + String message; + + @Override + public Device getDevice() { + return this.device; + } + + + @Override + public void execute() { + String message = null; + try { + String device_code = this.getDeviceCode(); + + mode = this.itemProtocol.getMode(); + error = this.itemProtocol.getError(); + move = this.itemProtocol.getMove(); + task = this.itemProtocol.getTask(); + hasGoods = this.itemProtocol.getMove(); + io_action = this.itemProtocol.getIoAction(); + actoin = this.itemProtocol.getAction(); + + if (mode != last_mode) { + this.setRequireSucess(false); + } + if (move != last_move) { + if (move == 0) { + thingToNothing(); + } + } + if (error != last_error) { + } + + } catch (Exception var17) { + return; + } + + //急停 + if (this.isStop()) { + + //未在线无心跳 + } else if (!this.itemProtocol.getIsonline()) { + this.setIsonline(false); + this.setIserror(true); + message = "信号量同步异常"; + //未联机 + } else if (mode == 0) { + this.setIsonline(false); + this.setIserror(true); + message = "未联机"; + //有报警 + } else if (error != 0) { + this.setIsonline(false); + this.setIserror(true); + message = "有报警"; + //无报警 + } else { + this.setIsonline(true); + this.setIserror(false); + message = ""; + Instruction instruction = null; + List toInstructions; + switch (mode) { + case 1: + log.debug("设备运转模式:等待工作"); + break; + case 2: + break; + case 3: + //申请空盘 + if (!requireSucess && this.move == 0) { + applyEmpty(); + } + break; + case 4: + //申请搬运任务 + if (!requireSucess && this.move != 0) { + autoCreateTask(); + } + break; + case 5: + break; + } + } + + last_mode = mode; + last_error = error; + last_move = move; + last_task = task; + } + + /** + * 生成搬运任务 + * + * @return + */ + public synchronized boolean autoCreateTask() { + Date date = new Date(); + if (date.getTime() - this.instruction_require_time.getTime() < (long) this.instruction_require_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_require_time_out); + return false; + } else { + this.instruction_require_time = date; + TaskDto dto = new TaskDto(); + String now = DateUtil.now(); + dto.setTask_id(IdUtil.simpleUUID()); + dto.setCreate_by(this.getDevice().getDevice_code()); + dto.setUpdate_by(this.getDevice().getDevice_code()); + dto.setStart_point_code(this.getDevice().getDevice_code()); + dto.setStart_device_code(this.getDevice().getDevice_code()); + dto.setTask_status("0"); + dto.setPriority("101"); + String next_device_code = ""; + + String plan_uuid = WQLObject.getWQLObject("acs_route_plan").query("plan_code= '" + dto.getRoute_plan_code() + "'").uniqueResult(0).getString("plan_uuid"); + JSONArray ja = routelineserver.queryNextLine(this.getDevice().getDevice_code(), plan_uuid); + DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class); + for (int i = 0; i < ja.size(); i++) { + JSONObject jo = (JSONObject) ja.get(i); + next_device_code = jo.get("next_device_code").toString(); + Device nextdevice = appService.findDeviceByCode(next_device_code); + StandardInspectSiteDeviceDriver standardInspectSiteDeviceDriver; + if (nextdevice.getDeviceDriver() instanceof StandardInspectSiteDeviceDriver) { + standardInspectSiteDeviceDriver = (StandardInspectSiteDeviceDriver) nextdevice.getDeviceDriver(); + String maxTaskNum = WQLObject.getWQLObject("sys_param").query("code= 'onePointMaxTask' and is_active='1' ").uniqueResult(0).getString("value"); + + if (taskserver.checkAllowCreate(next_device_code) >= Integer.parseInt(maxTaskNum)) { + next_device_code = ""; + continue; + } + if (standardInspectSiteDeviceDriver.getMode() == 2 && standardInspectSiteDeviceDriver.getMove() == 0) { + break; + } + } + } + if (StrUtil.isEmpty(next_device_code)) { + throw new RuntimeException("该设备未找到对应路由"); + } + dto.setNext_point_code(next_device_code); + dto.setNext_device_code(next_device_code); + dto.setUpdate_time(now); + dto.setCreate_time(now); + String taskcode = CodeUtil.getNewCode("TASK_NO"); + dto.setTask_code("-" + taskcode); + try { + taskserver.create(dto); + } catch (Exception e) { + e.printStackTrace(); + } + this.setRequireSucess(true); + return true; + } + + } + + + public synchronized boolean applyEmpty() { + + Date date = new Date(); + if (date.getTime() - this.instruction_require_time.getTime() < (long) this.instruction_require_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_require_time_out); + return false; + } else { + this.instruction_require_time = date; + TaskDto dto = new TaskDto(); + String now = DateUtil.now(); + dto.setTask_id(IdUtil.simpleUUID()); + dto.setCreate_by(this.getDevice().getDevice_code()); + dto.setUpdate_by(this.getDevice().getDevice_code()); + dto.setTask_status("0"); + dto.setPriority("101"); + String start_device_code = ""; + String plan_uuid = WQLObject.getWQLObject("acs_route_plan").query("plan_code= '" + dto.getRoute_plan_code() + "'").uniqueResult(0).getString("plan_uuid"); + + JSONArray ja = routelineserver.querySuperiorLine(this.getDevice().getDevice_code(), plan_uuid); + DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class); + for (int i = 0; i < ja.size(); i++) { + JSONObject jo = (JSONObject) ja.get(i); + start_device_code = jo.get("device_code").toString(); + Device start_device = appService.findDeviceByCode(start_device_code); + StandardEmptyPalletSiteDeviceDriver standardEmptyPalletSiteDeviceDriver; + if (start_device.getDeviceDriver() instanceof StandardEmptyPalletSiteDeviceDriver) { + standardEmptyPalletSiteDeviceDriver = (StandardEmptyPalletSiteDeviceDriver) start_device.getDeviceDriver(); + //根据路由 寻找取空盘的设备 +// if(standardEmptyPalletSiteDeviceDriver.getNumber() < Integer.parseInt(standardEmptyPalletSiteDeviceDriver.getDevice().getExtraValue().get("max_emptypalletnum").toString()) ) { +// break; +// } + if (standardEmptyPalletSiteDeviceDriver.getMode() == 2 && standardEmptyPalletSiteDeviceDriver.getNumber() > 0) { + break; + } + } + } + dto.setTask_type("1"); + dto.setEmptypallet_num("1"); + dto.setNext_device_code(this.getDevice().getDevice_code()); + dto.setNext_point_code(this.getDevice().getDevice_code()); + dto.setStart_point_code(start_device_code); + dto.setStart_device_code(start_device_code); + if (StrUtil.isEmpty(start_device_code)) { + throw new RuntimeException("该设备未找到对应路由"); + } + dto.setUpdate_time(now); + dto.setCreate_time(now); + String taskcode = CodeUtil.getNewCode("TASK_NO"); + dto.setTask_code("-" + taskcode); + try { + taskserver.create(dto); + } catch (Exception e) { + e.printStackTrace(); + } + this.setRequireSucess(true); + this.setBranchProtocol(0); + return true; + } + } + + public void finish_instruction(Instruction instruction) throws Exception { + instruction_finished(instruction); + } + + /** + * 完成指令 + * + * @param instruction + * @return + */ + public boolean instruction_finished(Instruction instruction) throws Exception { + Date date = new Date(); + if (date.getTime() - this.instruction_finished_time.getTime() < (long) this.instruction_finished_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_finished_time_out); + return false; + } else { + instructionService.finish(instruction.getInstruction_id()); + this.instruction_finished_time = date; + return true; + } + } + + /** + * 完成并创建下一条指令 + * + * @param instruction + * @param needCreateNext + * @return + */ + public boolean instruction_finished(Instruction instruction, boolean needCreateNext) { + Date date = new Date(); + if (date.getTime() - this.instruction_finished_time.getTime() < (long) this.instruction_finished_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_finished_time_out); + return false; + } else { + this.instruction_finished_time = date; + return true; + } + } + + + private Instruction findInstruction() { + Instruction instruction = null; + if (this.instruction_num != 0) { + instruction = (Instruction) instructionService.findByCodeFromCache(String.valueOf(instruction_num)); + } + if (instruction != null) { + //可进行校验 + + + } else { + List container_instructions = new ArrayList(); + String barcode = this.getLast_container(); + + if (!StrUtil.isEmpty(barcode)) { + Map map = new HashMap(); + map.put("vehicle_code", barcode); + container_instructions = instructionService.queryAll(map); + } + + if (((List) container_instructions).size() > 1) { + log.debug("容器存在多个指令"); + } else { + if (((List) container_instructions).size() > 0) { + instruction = (Instruction) ((List) container_instructions).get(0); + } + } + } + return instruction; + } + + + public boolean exe_error() { + if (this.error == 0) { + return true; + } else { + log.debug("设备报警"); + return false; + } + } + + protected void thingToNothing() { + log.debug("从有货到无货 清理数据"); + this.set_last_container(container, container_type_desc); + this.setRequireSucess(false); + } + + public void set_last_container(String barcode, String type_desc) { + this.set_last_container(barcode); + this.set_last_container_type_desc(type_desc); + } + + public void set_last_container(String barcode) { + } + + public void set_last_container_type_desc(String type) { + } + + public boolean exe_business() { + return true; + } + + protected void executing(Instruction instruction) { + this.executing(1, instruction, ""); + } + + public void executing(int command, Instruction instruction, String appendMessage) { + String to_command = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code() + + "." + ItemProtocol.item_to_command; + String to_target = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code() + + "." + ItemProtocol.item_to_target; + String to_task = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code() + + "." + ItemProtocol.item_to_task; + if (appendMessage == null) { + appendMessage = ""; + } + if (instruction != null) { + instruction_num = Integer.parseInt(instruction.getInstruction_code()); + } + String opcservcerid = this.getDevice().getOpc_server_id(); + Server server = ReadUtil.getServer(opcservcerid); + Map itemMap = new HashMap(); + itemMap.put(to_command, 1); + itemMap.put(to_task, instruction_num); + ReadUtil.write(itemMap, server); + + } + + public void executing(Server server, Map itemMap) { + ReadUtil.write(itemMap, server); + } + + + public boolean instruction_require(String container_code) { + return instruction_require(container_code, WcsConfig.task_container_type_default_desc); + } + + /** + * 请求指令 + * + * @param container_code + * @param container_type + */ + public synchronized boolean instruction_require(String container_code, String container_type) { + Date date = new Date(); + if (date.getTime() - this.instruction_require_time.getTime() < (long) this.instruction_require_time_out) { + log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_require_time_out); + return false; + } else { + this.instruction_require_time = date; + TaskDto dto = new TaskDto(); + String now = DateUtil.now(); + dto.setTask_id(IdUtil.simpleUUID()); + dto.setCreate_by(this.getDevice().getDevice_code()); + dto.setUpdate_by(this.getDevice().getDevice_code()); + dto.setStart_point_code(this.getDevice().getDevice_code()); + dto.setVehicle_code(container_code); + dto.setVehicle_type(container_type); + + String taskcode = CodeUtil.getNewCode("TASK_NO"); + dto.setTask_code("-" + taskcode); + dto.setTask_status("0"); + dto.setPriority("101"); + RouteLineDto jo = routelineserver.findByCode(this.getDevice().getDevice_code()); + String next_device_codecode = jo.getNext_device_code(); + if (StrUtil.isEmpty(next_device_codecode)) { + throw new RuntimeException("该设备未找到对应路由"); + } + dto.setNext_point_code(next_device_codecode); + dto.setUpdate_time(now); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("acs_task"); + JSONObject json = (JSONObject) JSONObject.toJSON(dto); + + wo.insert(json); + requireSucess = false; + return true; + } + } + + public void writing(int type, int command) { + String to_command = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code() + + "." + ItemProtocol.item_to_command; + String to_target = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code() + + "." + ItemProtocol.item_to_target; + String to_task = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code() + + "." + ItemProtocol.item_to_task; + String opcservcerid = this.getDevice().getOpc_server_id(); + Server server = ReadUtil.getServer(opcservcerid); + Map itemMap = new HashMap(); + if (type == 1) { + itemMap.put(to_command, command); + } else if (type == 2) { + itemMap.put(to_target, command); + + } else if (type == 3) { + itemMap.put(to_task, command); + } + ReadUtil.write(itemMap, server); + + } + + public String toString() { + return ""; + } + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/standard_conveyor_control_with_plcscanner/StandardCoveyorControlWithPlcScannerDeviceDriver.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/standard_conveyor_control_with_plcscanner/StandardCoveyorControlWithPlcScannerDeviceDriver.java index 97f2894..e698d37 100644 --- a/nladmin-system/src/main/java/org/nl/acs/device_driver/standard_conveyor_control_with_plcscanner/StandardCoveyorControlWithPlcScannerDeviceDriver.java +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/standard_conveyor_control_with_plcscanner/StandardCoveyorControlWithPlcScannerDeviceDriver.java @@ -638,8 +638,8 @@ public class StandardCoveyorControlWithPlcScannerDeviceDriver extends AbstractOp /** * 开始平均分配 */ - String this_coevice_code = taskserver.queryAssignedByDevice(device_code, task.getNext_device_code()); - if (StrUtil.isEmpty(this_coevice_code)) { + String this_device_code = taskserver.queryAssignedByDevice(device_code, task.getNext_device_code()); + if (StrUtil.isEmpty(this_device_code)) { List shortPathsList = routeLineService.getShortPathLines(start_device_code, task.getNext_device_code(), route_plan_code); RouteLineDto routeLineDto = shortPathsList.get(0); @@ -659,7 +659,7 @@ public class StandardCoveyorControlWithPlcScannerDeviceDriver extends AbstractOp } next_device_code = pathlist.get(index); } else { - next_device_code = this_coevice_code; + next_device_code = this_device_code; } //校验路由关系 List shortPathsList = routeLineService.getShortPathLines(start_device_code, next_device_code, route_plan_code); @@ -744,8 +744,8 @@ public class StandardCoveyorControlWithPlcScannerDeviceDriver extends AbstractOp /** * 开始平均分配 */ - String this_coevice_code = taskserver.queryAssignedByDevice(device_code, task.getNext_device_code()); - if (StrUtil.isEmpty(this_coevice_code)) { + String this_device_code = taskserver.queryAssignedByDevice(device_code, task.getNext_device_code()); + if (StrUtil.isEmpty(this_device_code)) { List shortPathsList = routeLineService.getShortPathLines(start_device_code, task.getNext_device_code(), route_plan_code); RouteLineDto routeLineDto = shortPathsList.get(0); @@ -765,7 +765,7 @@ public class StandardCoveyorControlWithPlcScannerDeviceDriver extends AbstractOp } next_device_code = pathlist.get(index); } else { - next_device_code = this_coevice_code; + next_device_code = this_device_code; } //校验路由关系 List shortPathsList = routeLineService.getShortPathLines(start_device_code, next_device_code, route_plan_code); diff --git a/nladmin-system/src/main/java/org/nl/acs/device_driver/standard_conveyor_control_with_scanner/StandardCoveyorControlWithScannerDeviceDriver.java b/nladmin-system/src/main/java/org/nl/acs/device_driver/standard_conveyor_control_with_scanner/StandardCoveyorControlWithScannerDeviceDriver.java index e84c85e..ee9b37f 100644 --- a/nladmin-system/src/main/java/org/nl/acs/device_driver/standard_conveyor_control_with_scanner/StandardCoveyorControlWithScannerDeviceDriver.java +++ b/nladmin-system/src/main/java/org/nl/acs/device_driver/standard_conveyor_control_with_scanner/StandardCoveyorControlWithScannerDeviceDriver.java @@ -458,8 +458,8 @@ public class StandardCoveyorControlWithScannerDeviceDriver extends AbstractOpcDe /** * 开始平均分配 */ - String this_coevice_code = taskserver.queryAssignedByDevice(device_code, task.getNext_device_code()); - if (StrUtil.isEmpty(this_coevice_code)) { + String this_device_code = taskserver.queryAssignedByDevice(device_code, task.getNext_device_code()); + if (StrUtil.isEmpty(this_device_code)) { List shortPathsList = routeLineService.getShortPathLines(start_device_code, task.getNext_device_code(), route_plan_code); RouteLineDto routeLineDto = shortPathsList.get(0); @@ -479,7 +479,7 @@ public class StandardCoveyorControlWithScannerDeviceDriver extends AbstractOpcDe } next_device_code = pathlist.get(index); } else { - next_device_code = this_coevice_code; + next_device_code = this_device_code; } //校验路由关系 List shortPathsList = routeLineService.getShortPathLines(start_device_code, next_device_code, route_plan_code); @@ -562,8 +562,8 @@ public class StandardCoveyorControlWithScannerDeviceDriver extends AbstractOpcDe /** * 开始平均分配 */ - String this_coevice_code = taskserver.queryAssignedByDevice(device_code, task.getNext_device_code()); - if (StrUtil.isEmpty(this_coevice_code)) { + String this_device_code = taskserver.queryAssignedByDevice(device_code, task.getNext_device_code()); + if (StrUtil.isEmpty(this_device_code)) { List shortPathsList = routeLineService.getShortPathLines(start_device_code, task.getNext_device_code(), route_plan_code); RouteLineDto routeLineDto = shortPathsList.get(0); @@ -583,7 +583,7 @@ public class StandardCoveyorControlWithScannerDeviceDriver extends AbstractOpcDe } next_device_code = pathlist.get(index); } else { - next_device_code = this_coevice_code; + next_device_code = this_device_code; } //校验路由关系 List shortPathsList = routeLineService.getShortPathLines(start_device_code, next_device_code, route_plan_code); diff --git a/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/WmsToAcsServiceImpl.java b/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/WmsToAcsServiceImpl.java index 0d93474..71c9eeb 100644 --- a/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/WmsToAcsServiceImpl.java +++ b/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/WmsToAcsServiceImpl.java @@ -68,7 +68,7 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { JSONArray errArr = new JSONArray(); for (int i = 0; i < tasks.size(); i++) { JSONObject task = tasks.getJSONObject(i); - String task_uuid = task.getString("task_uuid"); + String ext_task_uuid = task.getString("task_uuid"); String task_code = task.getString("task_code"); String start_point_code = task.getString("start_device_code"); String next_point_code = task.getString("next_device_code"); @@ -83,6 +83,9 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { if (StrUtil.isEmpty(next_point_code)) { throw new WDKException("终点不能为空"); } + if (StrUtil.isEmpty(ext_task_uuid)) { + throw new WDKException("外部系统标识不能为空"); + } JSONObject start_device_json = WQLObject.getWQLObject("acs_storage_cell").query("parent_storage_code ='" + start_point_code + "'").uniqueResult(0); if (!ObjectUtil.isEmpty(start_device_json)) { @@ -134,6 +137,7 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { } JSONObject jo = new JSONObject(); jo.put("task_code", task_code); + jo.put("ext_task_uuid", ext_task_uuid); jo.put("start_point_code", start_point_code); jo.put("next_point_code", next_point_code); jo.put("start_parent_code", start_point_code); @@ -146,9 +150,6 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { jo.put("remark", remark); jo.put("params", params); jo.put("task_type", StrUtil.isEmpty(task_type) ? 1 : Integer.parseInt(task_type)); - if (!StrUtil.isEmpty(task_uuid)) { - jo.put("task_id", task_uuid); - } // 如果是无光电的设备 指令完成变更起点、终点状态 JSONObject startjo = new JSONObject(); startjo.put("device_code", start_device_code); @@ -172,7 +173,7 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { e.printStackTrace(); JSONObject json = new JSONObject(); json.put("task_code", task_code); - json.put("task_uuid", task_uuid); + json.put("task_uuid", ext_task_uuid); json.put("message", e.getMessage()); errArr.add(json); } diff --git a/nladmin-system/src/main/java/org/nl/acs/instruction/rest/InstructionController.java b/nladmin-system/src/main/java/org/nl/acs/instruction/rest/InstructionController.java index c18ed84..b6dec60 100644 --- a/nladmin-system/src/main/java/org/nl/acs/instruction/rest/InstructionController.java +++ b/nladmin-system/src/main/java/org/nl/acs/instruction/rest/InstructionController.java @@ -48,6 +48,15 @@ public class InstructionController { return new ResponseEntity<>(instructionService.getAll(whereJson, page), HttpStatus.OK); } + @GetMapping("/reload") + @Log("数据同步") + @ApiOperation("数据同步") + //@PreAuthorize("@el.check('task:list')") + public ResponseEntity reload() { + instructionService.reload(); + return new ResponseEntity<>(HttpStatus.OK); + } + @GetMapping("/unfinish") @Log("查询所有未完成指令") @ApiOperation("查询所有未完成指令") diff --git a/nladmin-system/src/main/java/org/nl/acs/instruction/service/InstructionService.java b/nladmin-system/src/main/java/org/nl/acs/instruction/service/InstructionService.java index 2daaaf2..3342ef3 100644 --- a/nladmin-system/src/main/java/org/nl/acs/instruction/service/InstructionService.java +++ b/nladmin-system/src/main/java/org/nl/acs/instruction/service/InstructionService.java @@ -33,6 +33,11 @@ public interface InstructionService { */ Map getAll(Map whereJson, Pageable page); + /** + * 数据同步 + */ + void reload(); + /** * 查询指定任务的所有指令不分页 * diff --git a/nladmin-system/src/main/java/org/nl/acs/log/rest/LogsController.java b/nladmin-system/src/main/java/org/nl/acs/log/rest/LogsController.java index 481c96a..96de472 100644 --- a/nladmin-system/src/main/java/org/nl/acs/log/rest/LogsController.java +++ b/nladmin-system/src/main/java/org/nl/acs/log/rest/LogsController.java @@ -1,4 +1,3 @@ - package org.nl.acs.log.rest; @@ -17,6 +16,7 @@ import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.text.ParseException; import java.util.Map; /** @@ -36,8 +36,8 @@ public class LogsController { @Log("查询日志") @ApiOperation("查询日志") //@PreAuthorize("@el.check('log:list')") - public ResponseEntity query(@RequestParam Map whereJson, Pageable page) { + public ResponseEntity query(@RequestParam Map whereJson, Pageable page) throws ParseException { return new ResponseEntity<>(logService.queryAll(whereJson, page), HttpStatus.OK); } - } + diff --git a/nladmin-system/src/main/java/org/nl/acs/log/service/LogServer.java b/nladmin-system/src/main/java/org/nl/acs/log/service/LogServer.java index a7facbe..52ea2ae 100644 --- a/nladmin-system/src/main/java/org/nl/acs/log/service/LogServer.java +++ b/nladmin-system/src/main/java/org/nl/acs/log/service/LogServer.java @@ -1,11 +1,13 @@ package org.nl.acs.log.service; +import com.alibaba.fastjson.JSONObject; import org.nl.acs.log.service.dto.LogDto; import org.springframework.data.domain.Pageable; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.text.ParseException; import java.util.List; import java.util.Map; @@ -23,25 +25,7 @@ public interface LogServer { * @param page 分页参数 * @return Map */ - Object queryAll(Map whereJson, Pageable page); - - - /** - * 根据ID查询 - * - * @param log_uuid ID - * @return Log - */ - LogDto findById(String log_uuid); - - /** - * 根据编码查询 - * - * @param code code - * @return Log - */ - LogDto findByCode(String code); - + Object queryAll(Map whereJson, Pageable page) throws ParseException; /** * @param task_code 任务编码 diff --git a/nladmin-system/src/main/java/org/nl/acs/log/service/impl/LogServerImpl.java b/nladmin-system/src/main/java/org/nl/acs/log/service/impl/LogServerImpl.java index 487c67a..ba92ed3 100644 --- a/nladmin-system/src/main/java/org/nl/acs/log/service/impl/LogServerImpl.java +++ b/nladmin-system/src/main/java/org/nl/acs/log/service/impl/LogServerImpl.java @@ -45,36 +45,29 @@ public class LogServerImpl implements LogServer { @Autowired private MongoTemplate mongoTemplate; -// @Override -// public Object queryAll(Map whereJson, Pageable page) { -// String task_code = MapUtil.getStr(whereJson, "task_code"); -// HashMap map = new HashMap<>(); -// map.put("flag", "1"); -// if (whereJson.get("blurry") != null) { -// map.put("blurry", "%" + whereJson.get("blurry") + "%"); -// } -// map.put("task_code", task_code); -// WO wo = WQL.getWO("Qlog_query_001"); -// JSONObject json = wo.addParamMap(map).pageQuery(WqlUtil.getHttpContext(page), "create_time desc"); -// Object parse = com.alibaba.fastjson.JSONObject.parse(json.toString()); -// return parse; -// } - @Override - public Map queryAll(Map whereJson, Pageable page) { - String log_type = (String) whereJson.get("log_type"); - if (StrUtil.isEmpty(log_type)) { - log_type = "default"; + public Object queryAll(Map whereJson, Pageable page) { + String blurry = (String) whereJson.get("blurry"); + String begin_time = (String) whereJson.get("begin_time"); + String end_time = (String) whereJson.get("end_time"); + + Query query = new Query().with(Sort.by("create_time")); + + if (StrUtil.isNotEmpty(blurry)) { + query.addCriteria(Criteria.where("method").is(blurry).regex("^.*" + blurry + ".*$")); + } + if (StrUtil.isNotEmpty(begin_time) && StrUtil.isNotEmpty(end_time)) { + query.addCriteria(Criteria.where("create_time") + .gte(begin_time) + .lte(end_time)); } - //查询条件 - Query query = Query.query(Criteria.where("source").is("nlAdmin")).with(Sort.by("date")); //根据条件得到的总条数 - long totalSize = mongoTemplate.count(query, Map.class, log_type); + long totalSize = mongoTemplate.count(query, LogDto.class,"interface_log"); //处理分页 query.skip(page.getPageNumber()).limit(page.getPageSize()); - List list = mongoTemplate.find(query,Map.class, log_type); + List list = mongoTemplate.find(query,LogDto.class, "interface_log"); //封装前端分页查询结果 JSONObject result = new JSONObject(); @@ -83,29 +76,12 @@ public class LogServerImpl implements LogServer { return result; } - @Override - public LogDto findById(String log_uuid) { - WQLObject wo = WQLObject.getWQLObject("acs_log"); - JSONObject json = wo.query("log_uuid ='" + log_uuid + "'").uniqueResult(0); - final LogDto obj = json.toJavaObject(LogDto.class); - return obj; - } - - @Override - public LogDto findByCode(String code) { - WQLObject wo = WQLObject.getWQLObject("acs_log"); - JSONObject json = wo.query("code ='" + code + "'").uniqueResult(0); - final LogDto obj = json.toJavaObject(LogDto.class); - return obj; - } - @Override public void log(String task_code, String method, String type, String requestParam, String responseParam, String status_code, String requesturl, String vehicle_code) { String currentUsername = SecurityUtils.getCurrentUsername(); String now = DateUtil.now(); LogDto logDto = new LogDto(); - logDto.setLog_uuid(IdUtil.simpleUUID()); logDto.setTask_code(task_code); logDto.setMethod(method); logDto.setLog_type(type); @@ -120,9 +96,6 @@ public class LogServerImpl implements LogServer { logDto.setUpdate_time(now); logDto.setCreate_time(now); - WQLObject wo = WQLObject.getWQLObject("acs_log"); - - JSONObject json = (JSONObject) JSONObject.toJSON(logDto); - wo.insert(json); + mongoTemplate.save(logDto,"interface_log"); } } diff --git a/nladmin-system/src/main/java/org/nl/acs/order/rest/CustomerbaseController.java b/nladmin-system/src/main/java/org/nl/acs/order/rest/CustomerbaseController.java new file mode 100644 index 0000000..d12e317 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/order/rest/CustomerbaseController.java @@ -0,0 +1,75 @@ + +package org.nl.acs.order.rest; + + +import org.nl.acs.order.service.CustomerbaseService; +import org.nl.acs.order.service.dto.CustomerbaseDto; +import org.springframework.data.domain.Pageable; +import lombok.RequiredArgsConstructor; +import org.nl.annotation.Log; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import io.swagger.annotations.*; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; + +/** +* @author wangs +* @date 2022-03-31 +**/ +@RestController +@RequiredArgsConstructor +@Api(tags = "order管理") +@RequestMapping("/api/customerbase") +@Slf4j +public class CustomerbaseController { + + private final CustomerbaseService customerbaseService; + + @GetMapping + @Log("查询order") + @ApiOperation("查询order") + //@PreAuthorize("@el.check('customerbase:list')") + public ResponseEntity query(@RequestParam Map whereJson, Pageable page){ + return new ResponseEntity<>(customerbaseService.queryAll(whereJson,page),HttpStatus.OK); + } + + @PostMapping + @Log("新增order") + @ApiOperation("新增order") + //@PreAuthorize("@el.check('customerbase:add')") + public ResponseEntity create(@Validated @RequestBody CustomerbaseDto dto){ + customerbaseService.create(dto); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @PutMapping + @Log("修改order") + @ApiOperation("修改order") + //@PreAuthorize("@el.check('customerbase:edit')") + public ResponseEntity update(@Validated @RequestBody CustomerbaseDto dto){ + customerbaseService.update(dto); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除order") + @ApiOperation("删除order") + //@PreAuthorize("@el.check('customerbase:del')") + @DeleteMapping + public ResponseEntity delete(@RequestBody String[] ids) { + customerbaseService.deleteAll(ids); + return new ResponseEntity<>(HttpStatus.OK); + } + + @Log("导出order") + @ApiOperation("导出order") + @GetMapping(value = "/download") + //@PreAuthorize("@el.check('customerbase:list')") + public void download(HttpServletResponse response, @RequestParam Map whereJson) throws IOException { + customerbaseService.download(customerbaseService.queryAll(whereJson), response); + } +} diff --git a/nladmin-system/src/main/java/org/nl/acs/order/rest/MaterialbaseController.java b/nladmin-system/src/main/java/org/nl/acs/order/rest/MaterialbaseController.java new file mode 100644 index 0000000..3cf9b9f --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/order/rest/MaterialbaseController.java @@ -0,0 +1,76 @@ + +package org.nl.acs.order.rest; + + +import org.nl.acs.order.service.MaterialbaseService; +import org.nl.acs.order.service.dto.MaterialbaseDto; +import org.springframework.data.domain.Pageable; +import lombok.RequiredArgsConstructor; +import org.nl.annotation.Log; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import io.swagger.annotations.*; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; + +/** +* @author wangs +* @date 2022-03-31 +**/ +@RestController +@RequiredArgsConstructor +@Api(tags = "物料维护") +@RequestMapping("/api/materialbase") +@Slf4j +public class MaterialbaseController { + + private final MaterialbaseService materialbaseService; + + @GetMapping + @Log("查询物料") + @ApiOperation("查询物料") + //@PreAuthorize("@el.check('materialbase:list')") + public ResponseEntity query(@RequestParam Map whereJson, Pageable page){ + return new ResponseEntity<>(materialbaseService.queryAll(whereJson,page),HttpStatus.OK); + } + + @PostMapping + @Log("新增order") + @ApiOperation("新增order") + //@PreAuthorize("@el.check('materialbase:add')") + public ResponseEntity create(@Validated @RequestBody MaterialbaseDto dto){ + materialbaseService.create(dto); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @PutMapping + @Log("修改order") + @ApiOperation("修改order") + //@PreAuthorize("@el.check('materialbase:edit')") + public ResponseEntity update(@Validated @RequestBody MaterialbaseDto dto){ + materialbaseService.update(dto); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除order") + @ApiOperation("删除order") + //@PreAuthorize("@el.check('materialbase:del')") + @DeleteMapping + public ResponseEntity delete(@RequestBody String[] ids) { + materialbaseService.deleteAll(ids); + return new ResponseEntity<>(HttpStatus.OK); + } + + @Log("导出order") + @ApiOperation("导出order") + @GetMapping(value = "/download") + //@PreAuthorize("@el.check('materialbase:list')") + public void download(HttpServletResponse response, @RequestParam Map whereJson) throws IOException { + materialbaseService.download(materialbaseService.queryAll(whereJson), response); + } +} diff --git a/nladmin-system/src/main/java/org/nl/acs/order/rest/ProduceshiftorderController.java b/nladmin-system/src/main/java/org/nl/acs/order/rest/ProduceshiftorderController.java new file mode 100644 index 0000000..49b4329 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/order/rest/ProduceshiftorderController.java @@ -0,0 +1,95 @@ + +package org.nl.acs.order.rest; + + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.order.service.ProduceshiftorderService; +import org.nl.acs.order.service.dto.ProduceshiftorderDto; +import org.nl.annotation.Log; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Map; + +/** + * @author wangs + * @date 2022-01-21 + **/ +@RestController +@RequiredArgsConstructor +@Api(tags = "工单管理") +@RequestMapping("/api/produceshiftorder") +@Slf4j +public class ProduceshiftorderController { + + private final ProduceshiftorderService produceshiftorderService; + + @GetMapping + @Log("查询工单") + @ApiOperation("查询工单") + //@PreAuthorize("@el.check('produceshiftorder:list')") + public ResponseEntity query(@RequestParam Map whereJson, Pageable page) { + return new ResponseEntity<>(produceshiftorderService.queryAll(whereJson, page), HttpStatus.OK); + } + + @Log("查询工单明细") + @ApiOperation("查询工单") + @GetMapping(value = "/getDtl") + //@PreAuthorize("@el.check('produceshiftorder:list')") + public ResponseEntity getDtl(@RequestParam Map whereJson) { + return new ResponseEntity<>(produceshiftorderService.getDtl(whereJson), HttpStatus.OK); + } + + @PostMapping + @Log("新增工单") + @ApiOperation("新增工单") + //@PreAuthorize("@el.check('produceshiftorder:add')") + public ResponseEntity create(@Validated @RequestBody Map whereJson) { + produceshiftorderService.create(whereJson); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @PutMapping + @Log("修改工单") + @ApiOperation("修改工单") + //@PreAuthorize("@el.check('produceshiftorder:edit')") + public ResponseEntity update(@Validated @RequestBody ProduceshiftorderDto dto) { + produceshiftorderService.update(dto); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除工单") + @ApiOperation("删除工单") + //@PreAuthorize("@el.check('produceshiftorder:del')") + @DeleteMapping + public ResponseEntity delete(@RequestBody String[] ids) { + produceshiftorderService.deleteAll(ids); + return new ResponseEntity<>(HttpStatus.OK); + } + + @Log("导出工单") + @ApiOperation("导出工单") + @GetMapping(value = "/download") + //@PreAuthorize("@el.check('produceshiftorder:list')") + public void download(HttpServletResponse response, @RequestParam Map whereJson) throws IOException { + produceshiftorderService.download(produceshiftorderService.queryAll(whereJson), response); + } + + @Log("导入工单excel") + @ApiOperation("导入工单excel") + @GetMapping("/importExcel/{id}") + public ResponseEntity importExcel(@PathVariable String id) { + produceshiftorderService.importExcel(id); + return new ResponseEntity<>(HttpStatus.OK); + } + + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/order/service/CustomerbaseService.java b/nladmin-system/src/main/java/org/nl/acs/order/service/CustomerbaseService.java new file mode 100644 index 0000000..abdd688 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/order/service/CustomerbaseService.java @@ -0,0 +1,73 @@ + +package org.nl.acs.order.service; + +import org.nl.acs.order.service.dto.CustomerbaseDto; +import org.springframework.data.domain.Pageable; +import java.util.Map; +import java.util.List; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; + +/** +* @description 服务接口 +* @author wangs +* @date 2022-03-31 +**/ +public interface CustomerbaseService { + + /** + * 查询数据分页 + * @param whereJson 条件 + * @param page 分页参数 + * @return Map + */ + Map queryAll(Map whereJson, Pageable page); + + /** + * 查询所有数据不分页 + * @param whereJson 条件参数 + * @return List + */ + List queryAll(Map whereJson); + + /** + * 根据ID查询 + * @param cust_id ID + * @return Customerbase + */ + CustomerbaseDto findById(String cust_id); + + /** + * 根据编码查询 + * @param code code + * @return Customerbase + */ + CustomerbaseDto findByCode(String code); + + + /** + * 创建 + * @param dto / + */ + void create(CustomerbaseDto dto); + + /** + * 编辑 + * @param dto / + */ + void update(CustomerbaseDto dto); + + /** + * 多选删除 + * @param ids / + */ + void deleteAll(String[] ids); + + /** + * 导出数据 + * @param dtos 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List dtos, HttpServletResponse response) throws IOException; +} diff --git a/nladmin-system/src/main/java/org/nl/acs/order/service/MaterialbaseService.java b/nladmin-system/src/main/java/org/nl/acs/order/service/MaterialbaseService.java new file mode 100644 index 0000000..ff9dbd0 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/order/service/MaterialbaseService.java @@ -0,0 +1,75 @@ + +package org.nl.acs.order.service; + +import org.nl.acs.order.service.dto.MaterialbaseDto; +import org.springframework.data.domain.Pageable; +import java.util.Map; +import java.util.List; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; + +/** +* @description 服务接口 +* @author wangs +* @date 2022-03-31 +**/ +public interface MaterialbaseService { + + /** + * 查询数据分页 + * @param whereJson 条件 + * @param page 分页参数 + * @return Map + */ + Map queryAll(Map whereJson, Pageable page); + + /** + * 查询所有数据不分页 + * @param whereJson 条件参数 + * @return List + */ + List queryAll(Map whereJson); + + List queryAll(); + + /** + * 根据ID查询 + * @param material_id ID + * @return Materialbase + */ + MaterialbaseDto findById(String material_id); + + /** + * 根据编码查询 + * @param code code + * @return Materialbase + */ + MaterialbaseDto findByCode(String code); + + + /** + * 创建 + * @param dto / + */ + void create(MaterialbaseDto dto); + + /** + * 编辑 + * @param dto / + */ + void update(MaterialbaseDto dto); + + /** + * 多选删除 + * @param ids / + */ + void deleteAll(String[] ids); + + /** + * 导出数据 + * @param dtos 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List dtos, HttpServletResponse response) throws IOException; +} diff --git a/nladmin-system/src/main/java/org/nl/acs/order/service/ProduceshiftorderService.java b/nladmin-system/src/main/java/org/nl/acs/order/service/ProduceshiftorderService.java new file mode 100644 index 0000000..251d53b --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/order/service/ProduceshiftorderService.java @@ -0,0 +1,101 @@ + +package org.nl.acs.order.service; + +import com.alibaba.fastjson.JSONArray; +import org.nl.acs.order.service.dto.ProduceshiftorderDto; +import org.springframework.data.domain.Pageable; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * @author wangs + * @description 服务接口 + * @date 2022-01-21 + **/ +public interface ProduceshiftorderService { + + /** + * 查询数据分页 + * + * @param whereJson 条件 + * @param page 分页参数 + * @return Map + */ + Map queryAll(Map whereJson, Pageable page); + + /** + * 查询所有数据不分页 + * + * @param whereJson 条件参数 + * @return List + */ + List queryAll(Map whereJson); + + /** + * 根据ID查询 + * + * @param order_id ID + * @return Produceshiftorder + */ + ProduceshiftorderDto findById(String order_id); + + /** + * 根据编码查询 + * + * @param code code + * @return Produceshiftorder + */ + ProduceshiftorderDto findByCode(String code); + + + /** + * 创建 + * + * @param / + */ + void create(Map whereJson); + + /** + * 编辑 + * + * @param dto / + */ + void update(ProduceshiftorderDto dto); + + /** + * 多选删除 + * + * @param ids / + */ + void deleteAll(String[] ids); + + /** + * 取消任务 + * + * @param ids + */ + void cancel(String ids) throws Exception; + + /** + * 导出数据 + * + * @param dtos 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List dtos, HttpServletResponse response) throws IOException; + + + /** + * 导入工单 + * + * @param id / + */ + void importExcel(String id); + + JSONArray getDtl(Map whereJson); + +} diff --git a/nladmin-system/src/main/java/org/nl/acs/order/service/dto/CustomerbaseDto.java b/nladmin-system/src/main/java/org/nl/acs/order/service/dto/CustomerbaseDto.java new file mode 100644 index 0000000..dcf6f3c --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/order/service/dto/CustomerbaseDto.java @@ -0,0 +1,65 @@ +package org.nl.acs.order.service.dto; + +import lombok.Data; +import java.io.Serializable; + import com.fasterxml.jackson.databind.annotation.JsonSerialize; + import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; + +/** +* @description / +* @author wangs +* @date 2022-03-31 +**/ +@Data +public class CustomerbaseDto implements Serializable { + + /** 客户标识 */ + /** 防止精度丢失 */ + @JsonSerialize(using= ToStringSerializer.class) + private String cust_id; + + /** 客户编码 */ + private String cust_code; + + /** 客户名称 */ + private String cust_name; + + /** 工商注册号 */ + private String register_no; + + /** 经营许可证号 */ + private String manage_lice_no; + + /** 营业执照 */ + private String busi_char_name; + + /** 邮政编码 */ + private String zip_code; + + /** 公司电话 */ + private String corp_tele_no; + + /** 公司地址 */ + private String corp_address; + + /** 创建者 */ + private String create_by; + + /** 创建时间 */ + private String create_time; + + /** 修改者 */ + private String update_by; + + /** 修改时间 */ + private String update_time; + + /** 是否启用 */ + private String is_used; + + /** 是否删除 */ + private String is_delete; + + /** 备注 */ + private String remark; +} diff --git a/nladmin-system/src/main/java/org/nl/acs/order/service/dto/MaterialbaseDto.java b/nladmin-system/src/main/java/org/nl/acs/order/service/dto/MaterialbaseDto.java new file mode 100644 index 0000000..cd968d9 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/order/service/dto/MaterialbaseDto.java @@ -0,0 +1,87 @@ +package org.nl.acs.order.service.dto; + +import lombok.Data; + import java.math.BigDecimal; +import java.io.Serializable; + import com.fasterxml.jackson.databind.annotation.JsonSerialize; + import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; + +/** +* @description / +* @author wangs +* @date 2022-03-31 +**/ +@Data +public class MaterialbaseDto implements Serializable { + + /** 物料标识 */ + /** 防止精度丢失 */ + @JsonSerialize(using= ToStringSerializer.class) + private String material_id; + + /** 物料编码 */ + private String material_code; + + /** 物料名称 */ + private String material_name; + + /** 规格 */ + private String material_spec; + + /** 型号 */ + private String material_model; + + /** 基本计量单位 */ + private String base_unit_id; + + /** 工程图号 */ + private String print_no; + + /** 长度单位 */ + private String len_unit_id; + + /** 物料长度 */ + private BigDecimal length; + + /** 物料宽度 */ + private BigDecimal width; + + /** 物料高度 */ + private BigDecimal height; + + /** 重量单位 */ + private String weight_unit_id; + + /** 物料毛重 */ + private BigDecimal gross_weight; + + /** 物料净重 */ + private BigDecimal net_weight; + + /** 体积单位 */ + private String cubage_unit_id; + + /** 物料体积 */ + private BigDecimal cubage; + + /** 创建者 */ + private String create_by; + + /** 创建时间 */ + private String create_time; + + /** 修改者 */ + private String update_by; + + /** 修改时间 */ + private String update_time; + + /** 启用时间 */ + private String is_used_time; + + /** 是否启用 */ + private String is_used; + + /** 是否删除 */ + private String is_delete; +} diff --git a/nladmin-system/src/main/java/org/nl/acs/order/service/dto/ProduceshiftorderDto.java b/nladmin-system/src/main/java/org/nl/acs/order/service/dto/ProduceshiftorderDto.java new file mode 100644 index 0000000..320688d --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/order/service/dto/ProduceshiftorderDto.java @@ -0,0 +1,60 @@ +package org.nl.acs.order.service.dto; + +import lombok.Data; + import java.math.BigDecimal; +import java.io.Serializable; + import com.fasterxml.jackson.databind.annotation.JsonSerialize; + import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; + +/** +* @description / +* @author wangs +* @date 2022-03-18 +**/ +@Data +public class ProduceshiftorderDto implements Serializable { + + /** 工单标识 */ + /** 防止精度丢失 */ +// @JsonSerialize(using= ToStringSerializer.class) + private String order_id; + + /** 工单编码 */ + private String order_code; + + /** 是否已拆分 */ + private String is_unbundling; + + /** 工单状态 */ + private String order_status; + + /** 物料编码 */ + private String material_code; + + /** 物料名称 */ + private String material_name; + + /** 物料标识 */ + private String material_id; + + /** 规格型号 */ + private String material_spec; + + /** 创建者 */ + private String create_by; + + /** 创建时间 */ + private String create_time; + + /** 修改者 */ + private String update_by; + + /** 修改时间 */ + private String update_time; + + /** 是否删除 */ + private String is_deleted; + + /** 下料数量 */ + private String qty; +} diff --git a/nladmin-system/src/main/java/org/nl/acs/order/service/dto/ProduceshiftorderdetailDto.java b/nladmin-system/src/main/java/org/nl/acs/order/service/dto/ProduceshiftorderdetailDto.java new file mode 100644 index 0000000..e153e2c --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/order/service/dto/ProduceshiftorderdetailDto.java @@ -0,0 +1,99 @@ +package org.nl.acs.order.service.dto; + +import lombok.Data; +import java.math.BigDecimal; +import java.io.Serializable; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; + +/** + * @description / + * @author wangs + * @date 2022-03-18 + **/ +@Data +public class ProduceshiftorderdetailDto implements Serializable { + + /** 工单明细标识 */ + /** 防止精度丢失 */ +// @JsonSerialize(using= ToStringSerializer.class) + private String orderDetail_id; + + /** 工单明细编码 */ + private String orderDetail_code; + + /** 工单明细类型 */ + private String orderDetail_type; + + /** 优先级 */ + private BigDecimal priority; + + /** 顺序号 */ + private String sequence_number; + + /** 工单标识 */ + private String order_id; + + /** 工单编码 */ + private String order_code; + + /** 客户标识 */ + private String cust_id; + + /** 客户编码 */ + private String cust_code; + + /** 客户名称 */ + private String cust_name; + + /** 明细状态 */ + private String order_status; + + /** 客户明细数量 */ + private String detail_qty; + + /** 捆扎包数 */ + private String strap_pack_number; + + /** 当前捆扎包数 */ + private String present_strap_pack_number; + + /** 每捆数量 */ + private String strap_number; + + /** 捆扎尾料数量 */ + private String strap_tailint_number; + + /** 捆扎直径 */ + private String starp_diameter; + + /** 捆扎尾料直径 */ + private String starp_tailint_diameter; + + /** 刻字信息 */ + private String lettering_message; + + /** 当前刻字数量 */ + private String present_lettering_numer; + + /** 贴标信息 */ + private String labeling_message; + + /** 当前贴标数量 */ + private String present_labeling_number; + + /** 创建者 */ + private String create_by; + + /** 创建时间 */ + private String create_time; + + /** 修改者 */ + private String update_by; + + /** 修改时间 */ + private String update_time; + + /** 是否删除 */ + private String is_deleted; +} diff --git a/nladmin-system/src/main/java/org/nl/acs/order/service/impl/CustomerbaseServiceImpl.java b/nladmin-system/src/main/java/org/nl/acs/order/service/impl/CustomerbaseServiceImpl.java new file mode 100644 index 0000000..f368057 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/order/service/impl/CustomerbaseServiceImpl.java @@ -0,0 +1,140 @@ + +package org.nl.acs.order.service.impl; + + +import lombok.RequiredArgsConstructor; +import org.nl.acs.order.service.CustomerbaseService; +import org.nl.acs.order.service.dto.CustomerbaseDto; +import org.nl.exception.BadRequestException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import org.springframework.data.domain.Pageable; +import java.util.List; +import java.util.Map; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.LinkedHashMap; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.bean.BeanUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import org.nl.utils.SecurityUtils; +import org.nl.wql.core.bean.ResultBean; +import org.nl.wql.core.bean.WQLObject; +import org.nl.wql.util.WqlUtil; +import org.nl.utils.FileUtil; +import lombok.extern.slf4j.Slf4j; + +/** +* @description 服务实现 +* @author wangs +* @date 2022-03-31 +**/ +@Service +@RequiredArgsConstructor +@Slf4j +public class CustomerbaseServiceImpl implements CustomerbaseService { + + @Override + public Map queryAll(Map whereJson, Pageable page){ + WQLObject wo = WQLObject.getWQLObject("acs_customerbase"); + ResultBean rb = wo.pagequery(WqlUtil.getHttpContext(page), "", "update_time desc"); + final JSONObject json = rb.pageResult(); + return json; + } + + @Override + public List queryAll(Map whereJson){ + WQLObject wo = WQLObject.getWQLObject("acs_customerbase"); + JSONArray arr = wo.query().getResultJSONArray(0); + List list = arr.toJavaList(CustomerbaseDto.class); + return list; + } + + @Override + public CustomerbaseDto findById(String cust_id) { + WQLObject wo = WQLObject.getWQLObject("acs_customerbase"); + JSONObject json = wo.query("cust_id ='" + cust_id + "'").uniqueResult(0); + final CustomerbaseDto obj = (CustomerbaseDto) JSONObject.toJavaObject(json, CustomerbaseDto.class); + return obj; + } + + @Override + public CustomerbaseDto findByCode(String code) { + WQLObject wo = WQLObject.getWQLObject("acs_customerbase"); + JSONObject json = wo.query("code ='" + code + "'").uniqueResult(0); + final CustomerbaseDto obj = (CustomerbaseDto) JSONObject.toJavaObject(json, CustomerbaseDto.class); + return obj; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(CustomerbaseDto dto) { + String currentUsername = SecurityUtils.getCurrentUsername(); + String now = DateUtil.now(); + + dto.setCust_id(IdUtil.simpleUUID()); + dto.setCreate_by(currentUsername); + dto.setUpdate_by(currentUsername); + dto.setUpdate_time(now); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("acs_customerbase"); + JSONObject json= (JSONObject) JSONObject.toJSON(dto); + wo.insert(json); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(CustomerbaseDto dto) { + CustomerbaseDto entity = this.findById(dto.getCust_id()); + if (entity == null) throw new BadRequestException("被删除或无权限,操作失败!"); + + String currentUsername = SecurityUtils.getCurrentUsername(); + String now = DateUtil.now(); + dto.setUpdate_time(now); + dto.setUpdate_by(currentUsername); + + WQLObject wo = WQLObject.getWQLObject("acs_customerbase"); + JSONObject json= (JSONObject) JSONObject.toJSON(dto); + wo.update(json); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteAll(String[] ids) { + WQLObject wo = WQLObject.getWQLObject("acs_customerbase"); + for (String cust_id: ids) { + wo.delete("cust_id = '" + cust_id + "'"); + } + } + + @Override + public void download(List all, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (CustomerbaseDto customerbase : all) { + Map map = new LinkedHashMap<>(); + map.put("客户编码", customerbase.getCust_code()); + map.put("客户名称 ", customerbase.getCust_name()); + map.put("工商注册号", customerbase.getRegister_no()); + map.put("经营许可证号", customerbase.getManage_lice_no()); + map.put("营业执照", customerbase.getBusi_char_name()); + map.put("邮政编码", customerbase.getZip_code()); + map.put("公司电话", customerbase.getCorp_tele_no()); + map.put("公司地址", customerbase.getCorp_address()); + map.put("创建者", customerbase.getCreate_by()); + map.put("创建时间", customerbase.getCreate_time()); + map.put("修改者", customerbase.getUpdate_by()); + map.put("修改时间", customerbase.getUpdate_time()); + map.put("是否启用", customerbase.getIs_used()); + map.put("是否删除", customerbase.getIs_delete()); + map.put("备注", customerbase.getRemark()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } +} diff --git a/nladmin-system/src/main/java/org/nl/acs/order/service/impl/MaterialbaseServiceImpl.java b/nladmin-system/src/main/java/org/nl/acs/order/service/impl/MaterialbaseServiceImpl.java new file mode 100644 index 0000000..7273b6f --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/order/service/impl/MaterialbaseServiceImpl.java @@ -0,0 +1,158 @@ + +package org.nl.acs.order.service.impl; + + +import com.alibaba.fastjson.JSON; +import lombok.RequiredArgsConstructor; +import org.nl.acs.order.service.MaterialbaseService; +import org.nl.acs.order.service.dto.MaterialbaseDto; +import org.nl.exception.BadRequestException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import org.springframework.data.domain.Pageable; +import java.util.List; +import java.util.Map; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.LinkedHashMap; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.bean.BeanUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import org.nl.utils.SecurityUtils; +import org.nl.wql.core.bean.ResultBean; +import org.nl.wql.core.bean.WQLObject; +import org.nl.wql.util.WqlUtil; +import org.nl.utils.FileUtil; +import lombok.extern.slf4j.Slf4j; + +/** +* @description 服务实现 +* @author wangs +* @date 2022-03-31 +**/ +@Service +@RequiredArgsConstructor +@Slf4j +public class MaterialbaseServiceImpl implements MaterialbaseService { + + @Override + public Map queryAll(Map whereJson, Pageable page){ + WQLObject wo = WQLObject.getWQLObject("acs_materialbase"); + ResultBean rb = wo.pagequery(WqlUtil.getHttpContext(page), "", "update_time desc"); + final JSONObject json = rb.pageResult(); + return json; + } + + @Override + public List queryAll(Map whereJson){ + WQLObject wo = WQLObject.getWQLObject("acs_materialbase"); + JSONArray arr = wo.query().getResultJSONArray(0); + List list = arr.toJavaList(MaterialbaseDto.class); + return list; + } + + + + @Override + public List queryAll(){ + WQLObject wo = WQLObject.getWQLObject("acs_materialbase"); + JSONArray arr = wo.query().getResultJSONArray(0); + List list = arr.toJavaList(MaterialbaseDto.class); + return list; + } + + @Override + public MaterialbaseDto findById(String material_id) { + WQLObject wo = WQLObject.getWQLObject("acs_materialbase"); + JSONObject json = wo.query("material_id ='" + material_id + "'").uniqueResult(0); + final MaterialbaseDto obj = (MaterialbaseDto) JSONObject.toJavaObject(json, MaterialbaseDto.class); + return obj; + } + + @Override + public MaterialbaseDto findByCode(String code) { + WQLObject wo = WQLObject.getWQLObject("acs_materialbase"); + JSONObject json = wo.query("code ='" + code + "'").uniqueResult(0); + final MaterialbaseDto obj = (MaterialbaseDto) JSONObject.toJavaObject(json, MaterialbaseDto.class); + return obj; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(MaterialbaseDto dto) { + String currentUsername = SecurityUtils.getCurrentUsername(); + String now = DateUtil.now(); + + dto.setMaterial_id(IdUtil.simpleUUID()); + dto.setCreate_by(currentUsername); + dto.setUpdate_by(currentUsername); + dto.setUpdate_time(now); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("acs_materialbase"); + JSONObject json= (JSONObject) JSONObject.toJSON(dto); + wo.insert(json); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(MaterialbaseDto dto) { + MaterialbaseDto entity = this.findById(dto.getMaterial_id()); + if (entity == null) throw new BadRequestException("被删除或无权限,操作失败!"); + + String currentUsername = SecurityUtils.getCurrentUsername(); + String now = DateUtil.now(); + dto.setUpdate_time(now); + dto.setUpdate_by(currentUsername); + + WQLObject wo = WQLObject.getWQLObject("acs_materialbase"); + JSONObject json= (JSONObject) JSONObject.toJSON(dto); + wo.update(json); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteAll(String[] ids) { + WQLObject wo = WQLObject.getWQLObject("acs_materialbase"); + for (String material_id: ids) { + wo.delete("material_id = '" + material_id + "'"); + } + } + + @Override + public void download(List all, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (MaterialbaseDto materialbase : all) { + Map map = new LinkedHashMap<>(); + map.put("物料编码", materialbase.getMaterial_code()); + map.put("物料名称 ", materialbase.getMaterial_name()); + map.put("规格", materialbase.getMaterial_spec()); + map.put("型号", materialbase.getMaterial_model()); + map.put("基本计量单位", materialbase.getBase_unit_id()); + map.put("工程图号", materialbase.getPrint_no()); + map.put("长度单位", materialbase.getLen_unit_id()); + map.put("物料长度", materialbase.getLength()); + map.put("物料宽度", materialbase.getWidth()); + map.put("物料高度", materialbase.getHeight()); + map.put("重量单位", materialbase.getWeight_unit_id()); + map.put("物料毛重", materialbase.getGross_weight()); + map.put("物料净重", materialbase.getNet_weight()); + map.put("体积单位", materialbase.getCubage_unit_id()); + map.put("物料体积", materialbase.getCubage()); + map.put("创建者", materialbase.getCreate_by()); + map.put("创建时间", materialbase.getCreate_time()); + map.put("修改者", materialbase.getUpdate_by()); + map.put("修改时间", materialbase.getUpdate_time()); + map.put("启用时间", materialbase.getIs_used_time()); + map.put("是否启用", materialbase.getIs_used()); + map.put("是否删除", materialbase.getIs_delete()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } +} diff --git a/nladmin-system/src/main/java/org/nl/acs/order/service/impl/ProduceshiftorderServiceImpl.java b/nladmin-system/src/main/java/org/nl/acs/order/service/impl/ProduceshiftorderServiceImpl.java new file mode 100644 index 0000000..c531aa5 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/order/service/impl/ProduceshiftorderServiceImpl.java @@ -0,0 +1,234 @@ +package org.nl.acs.order.service.impl; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.acs.order.service.ProduceshiftorderService; +import org.nl.acs.order.service.dto.CustomerbaseDto; +import org.nl.acs.order.service.dto.ProduceshiftorderDto; +import org.nl.acs.order.service.dto.ProduceshiftorderdetailDto; +import org.nl.exception.BadRequestException; +import org.nl.modules.system.util.CodeUtil; +import org.nl.utils.SecurityUtils; +import org.nl.wql.WQL; +import org.nl.wql.core.bean.ResultBean; +import org.nl.wql.core.bean.WQLObject; +import org.nl.wql.util.WqlUtil; +import org.springframework.data.domain.Pageable; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.data.mongodb.core.query.Update; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author wangs + * @description 服务实现 + * @date 2022-01-21 + **/ +@Service +@RequiredArgsConstructor +@Slf4j +public class ProduceshiftorderServiceImpl implements ProduceshiftorderService { + + private final MongoTemplate mongoTemplate; + + @Override + public Map queryAll(Map whereJson, Pageable page) { + WQLObject wo = WQLObject.getWQLObject("acs_produceshiftorder"); + String where = "1=1 and is_deleted= '0'"; + ResultBean rb = wo.pagequery(WqlUtil.getHttpContext(page), where, "order_id desc"); + final JSONObject json = rb.pageResult(); + JSONArray newja = new JSONArray(); + JSONArray ja = json.getJSONArray("content"); + for (int i = 0; i < ja.size(); i++) { + JSONObject jo = (JSONObject) ja.get(i); + JSONArray orderDteail_ja = WQLObject.getWQLObject("acs_produceshiftorderdetail").query("is_deleted= '0' and order_id ='" + jo.getString("order_id") + "'").getResultJSONArray(0); + if (orderDteail_ja.size() > 0) { + JSONArray children = new JSONArray(); + for (int j = 0; j < orderDteail_ja.size(); j++) { + JSONObject orderDteail_jo = orderDteail_ja.getJSONObject(j); + JSONObject new_jo = new JSONObject(); + new_jo.put("order_id", orderDteail_jo.getString("orderdetail_id")); + new_jo.put("order_code", orderDteail_jo.getString("orderdetail_code")); + new_jo.put("is_active", orderDteail_jo.getString("is_active")); + new_jo.put("is_delete", orderDteail_jo.getString("is_delete")); + new_jo.put("create_by", orderDteail_jo.getString("create_by")); + new_jo.put("create_time", orderDteail_jo.getString("create_time")); + new_jo.put("update_by", orderDteail_jo.getString("update_by")); + new_jo.put("update_time", orderDteail_jo.getString("update_time")); + new_jo.put("cust_id", orderDteail_jo.getString("cust_id")); + new_jo.put("cust_code", orderDteail_jo.getString("cust_code")); + new_jo.put("cust_name", orderDteail_jo.getString("cust_name")); + new_jo.put("order_qty", orderDteail_jo.getString("order_qty")); + new_jo.put("type", "orderDteail"); + jo.put("is_flag", "0"); + children.add(new_jo); + } + jo.put("children", children); + } + jo.put("type", "order"); + //区分工单明细 + jo.put("is_flag", "1"); + newja.add(jo); + } + json.put("content", newja); + System.out.println("json:" + json); + return json; + } + + @Override + public List queryAll(Map whereJson) { + return null; + } + + @Override + public ProduceshiftorderDto findById(String order_id) { + WQLObject wo = WQLObject.getWQLObject("acs_produceshiftorder"); + JSONObject json = wo.query("order_id ='" + order_id + "'").uniqueResult(0); + final ProduceshiftorderDto obj = JSONObject.toJavaObject(json, ProduceshiftorderDto.class); + return obj; + } + + @Override + public ProduceshiftorderDto findByCode(String code) { + return null; + } + + @Override + public void create(Map whereJson) { + JSONObject param=new JSONObject(whereJson); + String currentUsername = SecurityUtils.getCurrentUsername(); + ProduceshiftorderDto orderDto = new ProduceshiftorderDto(); + String material_id = MapUtil.getStr(whereJson, "material_id"); + String material_code = MapUtil.getStr(whereJson, "material_code"); + String material_name = MapUtil.getStr(whereJson, "material_name"); + String material_spec = MapUtil.getStr(whereJson, "material_spec"); + String qty = MapUtil.getStr(whereJson, "qty"); + + if(StrUtil.isEmpty(material_code)){ + throw new RuntimeException("物料编号不可为空!"); + } + JSONArray tableData = param.getJSONArray("tableData"); + if (ObjectUtil.isEmpty(tableData)){ + throw new BadRequestException("客户信息不可为空!"); + } + String order_code = CodeUtil.getNewCode("ORDER_NO"); + String order_id = IdUtil.simpleUUID(); + orderDto.setMaterial_code(material_code); + orderDto.setMaterial_name(material_name); + orderDto.setMaterial_spec(material_spec); + orderDto.setOrder_id(order_id); + orderDto.setOrder_code(order_code); + orderDto.setQty(qty); + orderDto.setOrder_status("0"); + orderDto.setIs_deleted("0"); + orderDto.setCreate_by(currentUsername); + + for(int i=0; i map = new HashMap<>(); + map.put("is_deleted","1"); + WQLObject.getWQLObject("acs_produceshiftorderdetail").update(map,"order_id = '"+ id + "'"); + + } + + @Override + public void download(List dtos, HttpServletResponse response) throws IOException { + + } + + @Override + public void importExcel(String id) { + + } + + @Override + public JSONArray getDtl(Map whereJson) { + String order_id = (String) whereJson.get("order_id"); + WQLObject wo = WQLObject.getWQLObject("acs_produceshiftorderdetail"); + JSONArray arr = wo.query("order_id = '"+order_id+"'").getResultJSONArray(0); + return arr; + } +} \ No newline at end of file diff --git a/nladmin-system/src/main/java/org/nl/acs/order/service/wql/QPRODUCESHIFTORDER.wql b/nladmin-system/src/main/java/org/nl/acs/order/service/wql/QPRODUCESHIFTORDER.wql new file mode 100644 index 0000000..cf132f7 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/acs/order/service/wql/QPRODUCESHIFTORDER.wql @@ -0,0 +1,52 @@ +[交易说明] + 交易名: 包装工单查询 + 所属模块: + 功能简述: + 版权所有: + 表引用: + 版本经历: + +[数据库] + --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 + +[IO定义] + ################################################# + ## 表字段对应输入参数 + ################################################# + 输入.flag TYPEAS s_string + + +[临时表] + --这边列出来的临时表就会在运行期动态创建 + +[临时变量] + --所有中间过程变量均可在此处定义 + +[业务过程] + + ########################################## + # 1、输入输出检查 # + ########################################## + + + ########################################## + # 2、主过程前处理 # + ########################################## + + + ########################################## + # 3、业务主过程 # + ########################################## + + IF 输入.flag = "1" + QUERY + SELECT + * + FROM + acs_produceshiftorder t + + ENDSELECT + ENDQUERY + ENDIF + + diff --git a/nladmin-system/src/main/java/org/nl/acs/order/service/wql/order.xls b/nladmin-system/src/main/java/org/nl/acs/order/service/wql/order.xls new file mode 100644 index 0000000000000000000000000000000000000000..1c40ed31c0ff004da54f28f3340410cdebfa4c24 GIT binary patch literal 221696 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�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 aYXs4;H;Y+ub4aOjA4ulsb^E`|fqwu$q$DH& literal 0 HcmV?d00001 diff --git a/nladmin-system/src/main/java/org/nl/acs/route/rest/RouteLineController.java b/nladmin-system/src/main/java/org/nl/acs/route/rest/RouteLineController.java index f8926d1..cc14de6 100644 --- a/nladmin-system/src/main/java/org/nl/acs/route/rest/RouteLineController.java +++ b/nladmin-system/src/main/java/org/nl/acs/route/rest/RouteLineController.java @@ -41,6 +41,15 @@ public class RouteLineController { return new ResponseEntity<>(routeLineService.queryAll(whereJson, page), HttpStatus.OK); } + @GetMapping("/reload") + @Log("数据同步") + @ApiOperation("数据同步") + //@PreAuthorize("@el.check('task:list')") + public ResponseEntity reload() throws SQLException { + routeLineService.reload(); + return new ResponseEntity<>(HttpStatus.OK); + } + @PostMapping @Log("新增路由路线") @ApiOperation("新增路由路线") diff --git a/nladmin-system/src/main/java/org/nl/acs/route/service/impl/RouteLineServiceImpl.java b/nladmin-system/src/main/java/org/nl/acs/route/service/impl/RouteLineServiceImpl.java index 21abce3..de91337 100644 --- a/nladmin-system/src/main/java/org/nl/acs/route/service/impl/RouteLineServiceImpl.java +++ b/nladmin-system/src/main/java/org/nl/acs/route/service/impl/RouteLineServiceImpl.java @@ -261,7 +261,7 @@ public class RouteLineServiceImpl implements RouteLineService, ApplicationAutoIn } } } - reload(); +// reload(); } @Override diff --git a/nladmin-system/src/main/java/org/nl/acs/stage/rest/StageActorController.java b/nladmin-system/src/main/java/org/nl/acs/stage/rest/StageActorController.java index 27f83cb..cf4fa52 100644 --- a/nladmin-system/src/main/java/org/nl/acs/stage/rest/StageActorController.java +++ b/nladmin-system/src/main/java/org/nl/acs/stage/rest/StageActorController.java @@ -2,6 +2,7 @@ package org.nl.acs.stage.rest; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import io.swagger.annotations.Api; @@ -86,7 +87,7 @@ public class StageActorController { String grid_width = String.valueOf(map.get("grid_width")); String grid_length = String.valueOf(map.get("grid_length")); - JSONArray actors = JSONArray.parseArray((map.get("list")).toString()); + JSONArray actors = JSONArray.parseArray((JSON.toJSONString(map.get("list")))); JSONObject mstForm = new JSONObject(); mstForm.put("stage_code", stage_code); mstForm.put("grid_width", grid_width); diff --git a/nladmin-system/src/main/java/org/nl/acs/task/rest/TaskController.java b/nladmin-system/src/main/java/org/nl/acs/task/rest/TaskController.java index 26417ad..7e9b0ca 100644 --- a/nladmin-system/src/main/java/org/nl/acs/task/rest/TaskController.java +++ b/nladmin-system/src/main/java/org/nl/acs/task/rest/TaskController.java @@ -43,6 +43,15 @@ public class TaskController { return new ResponseEntity<>(taskService.queryAllByCache(whereJson, page), HttpStatus.OK); } + @GetMapping("/reload") + @Log("数据同步") + @ApiOperation("数据同步") + //@PreAuthorize("@el.check('task:list')") + public ResponseEntity reload() { + taskService.reload(); + return new ResponseEntity<>(HttpStatus.OK); + } + @GetMapping("/getAll") @Log("历史查询任务") @ApiOperation("历史查询任务") diff --git a/nladmin-system/src/main/java/org/nl/acs/task/service/TaskService.java b/nladmin-system/src/main/java/org/nl/acs/task/service/TaskService.java index 9d24f71..9d84a3d 100644 --- a/nladmin-system/src/main/java/org/nl/acs/task/service/TaskService.java +++ b/nladmin-system/src/main/java/org/nl/acs/task/service/TaskService.java @@ -27,6 +27,11 @@ public interface TaskService { */ Map queryAll(Map whereJson, Pageable page); + /** + * 数据同步 + */ + void reload(); + /** * 在缓存中查询所有任务列表 * diff --git a/nladmin-system/src/main/java/org/nl/acs/task/service/dto/TaskDto.java b/nladmin-system/src/main/java/org/nl/acs/task/service/dto/TaskDto.java index df61300..96e79e0 100644 --- a/nladmin-system/src/main/java/org/nl/acs/task/service/dto/TaskDto.java +++ b/nladmin-system/src/main/java/org/nl/acs/task/service/dto/TaskDto.java @@ -212,4 +212,9 @@ public class TaskDto implements Serializable { * 终点父级编码 */ private String next_parent_code; + + /** + * 外部系统标识 + */ + private String ext_task_uuid; } diff --git a/nladmin-system/src/main/java/org/nl/acs/task/service/impl/TaskServiceImpl.java b/nladmin-system/src/main/java/org/nl/acs/task/service/impl/TaskServiceImpl.java index c974c40..f1be4fd 100644 --- a/nladmin-system/src/main/java/org/nl/acs/task/service/impl/TaskServiceImpl.java +++ b/nladmin-system/src/main/java/org/nl/acs/task/service/impl/TaskServiceImpl.java @@ -605,7 +605,7 @@ public class TaskServiceImpl implements TaskService, ApplicationAutoInitial { if (!StrUtil.startWith(dto.getTask_code(), "-") && StrUtil.equals(hasWms, "1")) { TaskFeedbackDto feefbackdto = taskFeedbackService.findByCode(entity.getTask_code()); JSONObject feed_jo = new JSONObject(); - feed_jo.put("task_uuid", dto.getTask_id()); + feed_jo.put("ext_task_uuid", entity.getExt_task_uuid()); feed_jo.put("task_code", dto.getTask_code()); feed_jo.put("task_status", dto.getTask_status()); JSONArray ja = new JSONArray(); @@ -721,7 +721,7 @@ public class TaskServiceImpl implements TaskService, ApplicationAutoInitial { if (!StrUtil.startWith(entity.getTask_code(), "-") && StrUtil.equals(hasWms, "1")) { TaskFeedbackDto feefbackdto = taskFeedbackService.findByCode(entity.getTask_code()); JSONObject feed_jo = new JSONObject(); - feed_jo.put("task_uuid", entity.getTask_id()); + feed_jo.put("ext_task_uuid", entity.getExt_task_uuid()); feed_jo.put("task_code", entity.getTask_code()); feed_jo.put("task_status", entity.getTask_status()); JSONArray ja = new JSONArray(); @@ -844,7 +844,7 @@ public class TaskServiceImpl implements TaskService, ApplicationAutoInitial { String hasWms = acsConfigService.findConfigFromCache().get(AcsConfig.HASWMS); if (!StrUtil.startWith(entity.getTask_code(), "-") && StrUtil.equals(hasWms, "1")) { JSONObject feed_jo = new JSONObject(); - feed_jo.put("task_uuid", entity.getTask_id()); + feed_jo.put("ext_task_uuid", entity.getExt_task_uuid()); feed_jo.put("task_code", entity.getTask_code()); feed_jo.put("task_status", entity.getTask_status()); JSONArray ja = new JSONArray(); @@ -867,6 +867,7 @@ public class TaskServiceImpl implements TaskService, ApplicationAutoInitial { TaskDto acsTask = this.findById(ids); if (acsTask == null) throw new BadRequestException("被删除或无权限,操作失败!"); AcsConfigService acsConfigService = SpringContextHolder.getBean(AcsConfigService.class); + DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class); InstructionService instructionservice = SpringContextHolder.getBean("instructionServiceImpl"); InstructionDto inst = instructionservice.findByTaskid(ids, "instruction_status < 2 "); if (inst != null) throw new BadRequestException("有指令未完成!"); @@ -885,6 +886,35 @@ public class TaskServiceImpl implements TaskService, ApplicationAutoInitial { String next_device_code = acsTask.getNext_device_code(); String maxInstnumber = acsConfigService.findConfigFromCache().get(AcsConfig.MAXINSTNUMBER); + /** + * 开始平均分解校验 + */ + String this_device_code = this.queryAssignedByDevice(acsTask.getStart_device_code(), acsTask.getNext_device_code()); + if (StrUtil.isEmpty(this_device_code)) { + List shortPathsList = routeLineService.getShortPathLines(start_device_code, acsTask.getNext_device_code(), route_plan_code); + RouteLineDto routeLineDto = shortPathsList.get(0); + String path = routeLineDto.getPath(); + String type = routeLineDto.getType(); + String[] str = path.split("->"); + List pathlist = Arrays.asList(str); + int index = 0; + for (int m = 0; m < pathlist.size(); m++) { + if (pathlist.get(m).equals(start_device_code)) { + index = m + 1; + break; + } + } + next_device_code = pathlist.get(index); + } else { + next_device_code = this_device_code; + } + + if (StrUtil.equals(appService.findDeviceTypeByCode(next_device_code), "storage")) { + next_point_code = next_device_code + "-" + acsTask.getTo_y() + "-" + acsTask.getTo_z(); + } else { + next_point_code = next_device_code; + } + Instruction instdto = new Instruction(); instdto.setInstruction_type(acsTask.getTask_type()); instdto.setInstruction_id(IdUtil.simpleUUID()); diff --git a/nladmin-system/src/main/java/org/nl/modules/log/MongoDBAppender.java b/nladmin-system/src/main/java/org/nl/modules/log/MongoDBAppender.java index 6af3945..5abe4fd 100644 --- a/nladmin-system/src/main/java/org/nl/modules/log/MongoDBAppender.java +++ b/nladmin-system/src/main/java/org/nl/modules/log/MongoDBAppender.java @@ -2,6 +2,7 @@ package org.nl.modules.log; import ch.qos.logback.classic.spi.ILoggingEvent; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import org.bson.Document; import org.slf4j.Marker; @@ -24,6 +25,8 @@ public class MongoDBAppender extends MongoDBAppenderBase { protected Document toMongoDocument(ILoggingEvent eventObject) { final Document doc = new Document(); + doc.append("_id",IdUtil.simpleUUID()); + doc.append("date", DateUtil.now()); doc.append("source", source); try { diff --git a/nladmin-system/src/main/java/org/nl/modules/log/MongoDBAppenderBase.java b/nladmin-system/src/main/java/org/nl/modules/log/MongoDBAppenderBase.java index 47bf023..3aece6e 100644 --- a/nladmin-system/src/main/java/org/nl/modules/log/MongoDBAppenderBase.java +++ b/nladmin-system/src/main/java/org/nl/modules/log/MongoDBAppenderBase.java @@ -25,7 +25,7 @@ public abstract class MongoDBAppenderBase extends UnsynchronizedAppenderBase< MongoDatabase db; private MongoCollection eventsCollection; - private String host = "47.97.157.227"; // 地址 + private String host = "192.168.81.251"; // 地址 private int port = 27017; // 端口号 private String dbName = "db"; // 库名 private String collectionName; // 集合名 diff --git a/nladmin-system/src/main/java/org/nl/modules/log/rest/RootLogController.java b/nladmin-system/src/main/java/org/nl/modules/log/rest/RootLogController.java index 0ad0ee4..3363c3b 100644 --- a/nladmin-system/src/main/java/org/nl/modules/log/rest/RootLogController.java +++ b/nladmin-system/src/main/java/org/nl/modules/log/rest/RootLogController.java @@ -11,16 +11,14 @@ import org.nl.modules.log.service.RootLogService; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; +import java.text.ParseException; import java.util.Map; /** - * @author ldjun - * @date 2021-08-19 + * @author loujf + * @date 2021-04-02 **/ @RestController @RequiredArgsConstructor @@ -32,11 +30,18 @@ public class RootLogController { private final RootLogService rootLogService; @GetMapping - @Log("查询系统日志") - @ApiOperation("查询系统日志") - //@PreAuthorize("@el.check('point:list')") - public ResponseEntity query(@RequestParam Map whereJson, Pageable page) { + @Log("查询日志") + @ApiOperation("查询日志") + //@PreAuthorize("@el.check('log:list')") + public ResponseEntity query(@RequestParam Map whereJson, Pageable page) throws ParseException { return new ResponseEntity<>(rootLogService.queryAll(whereJson, page), HttpStatus.OK); } + @PostMapping( "/error") + @Log("查询异常详情") + @ApiOperation("查询异常详情") + public ResponseEntity findError(@RequestBody Map whereJson) { + return new ResponseEntity<>(rootLogService.findError(whereJson), HttpStatus.OK); + } + } diff --git a/nladmin-system/src/main/java/org/nl/modules/log/service/RootLogService.java b/nladmin-system/src/main/java/org/nl/modules/log/service/RootLogService.java index b76d889..9ad1227 100644 --- a/nladmin-system/src/main/java/org/nl/modules/log/service/RootLogService.java +++ b/nladmin-system/src/main/java/org/nl/modules/log/service/RootLogService.java @@ -2,6 +2,7 @@ package org.nl.modules.log.service; import org.springframework.data.domain.Pageable; +import java.text.ParseException; import java.util.Map; /** @@ -10,9 +11,19 @@ import java.util.Map; public interface RootLogService { /** * 查询数据分页 + * * @param whereJson 条件 - * @param page 分页参数 - * @return Map + * @param page 分页参数 + * @return Map */ - Map queryAll(Map whereJson, Pageable page); + Object queryAll(Map whereJson, Pageable page) throws ParseException; + + + /** + * 查询异常详情 + * + * @param whereJson + * @return Log + */ + String findError(Map whereJson); } diff --git a/nladmin-system/src/main/java/org/nl/modules/log/service/impl/RootLogServiceImpl.java b/nladmin-system/src/main/java/org/nl/modules/log/service/impl/RootLogServiceImpl.java index 3f15590..7efc415 100644 --- a/nladmin-system/src/main/java/org/nl/modules/log/service/impl/RootLogServiceImpl.java +++ b/nladmin-system/src/main/java/org/nl/modules/log/service/impl/RootLogServiceImpl.java @@ -1,10 +1,13 @@ package org.nl.modules.log.service.impl; +import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.nl.acs.log.service.LogServer; import org.nl.modules.log.service.RootLogService; import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; @@ -14,9 +17,9 @@ import java.util.List; import java.util.Map; /** - * @author ldjun + * @author loujf * @description 服务实现 - * @date 2021-08-19 + * @date 2022-04-02 **/ @Service @RequiredArgsConstructor @@ -25,24 +28,49 @@ public class RootLogServiceImpl implements RootLogService { private final MongoTemplate mongoTemplate; + private final LogServer logServer; + @Override - public Map queryAll(Map whereJson, Pageable page) { - //查询条件 - Query query = Query.query(Criteria.where("level").is("INFO")); + public Map queryAll(Map whereJson, Pageable page){ + String log_type = (String) whereJson.get("log_type"); + String log_level = (String) whereJson.get("log_level"); + String begin_time = (String) whereJson.get("begin_time"); + String end_time = (String) whereJson.get("end_time"); + + Query query = new Query().with(Sort.by("date")); + + if (StrUtil.isEmpty(log_type)) { + log_type = "default"; + } + if (StrUtil.isNotEmpty(log_level)){ + query.addCriteria(Criteria.where("level").is(log_level)); + } + if (StrUtil.isNotEmpty(begin_time) && StrUtil.isNotEmpty(end_time)) { + query.addCriteria(Criteria.where("date") + .gte(begin_time) + .lte(end_time)); + } //根据条件得到的总条数 - long totalSize = mongoTemplate.count(query, Map.class, "log_root"); + long totalSize = mongoTemplate.count(query, Map.class, log_type); //处理分页 query.skip(page.getPageNumber()).limit(page.getPageSize()); - List list = mongoTemplate.find(query, Map.class, "log_root"); - + List list = mongoTemplate.find(query,Map.class, log_type); //封装前端分页查询结果 JSONObject result = new JSONObject(); result.put("content", list); result.put("totalElements", totalSize); - - mongoTemplate.findById("",null,null); return result; } + + @Override + public String findError(Map map) { + String id = (String) map.get("id"); + String marker = (String) map.get("marker"); + Query query = Query.query(Criteria.where("_id").is(id)).with(Sort.by("date")); + JSONObject list = mongoTemplate.findOne(query,JSONObject.class,marker); + + return list.getString("message"); + } } diff --git a/nladmin-system/src/main/java/org/nl/modules/quartz/task/AutoCreateInst.java b/nladmin-system/src/main/java/org/nl/modules/quartz/task/AutoCreateInst.java index 8028932..8c1179c 100644 --- a/nladmin-system/src/main/java/org/nl/modules/quartz/task/AutoCreateInst.java +++ b/nladmin-system/src/main/java/org/nl/modules/quartz/task/AutoCreateInst.java @@ -7,7 +7,6 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; import org.nl.acs.config.AcsConfig; import org.nl.acs.config.server.AcsConfigService; -import org.nl.acs.device_driver.electric_fence.ElectricFenceDeviceDriver; import org.nl.acs.device_driver.lamp_three_color.LampThreecolorDeviceDriver; import org.nl.acs.device_driver.standard_emptypallet_site.StandardEmptyPalletSiteDeviceDriver; import org.nl.acs.device_driver.standard_inspect_site.StandardInspectSiteDeviceDriver; @@ -24,7 +23,6 @@ import org.nl.acs.task.service.TaskService; import org.nl.acs.task.service.dto.TaskDto; import org.nl.modules.log.LogMarkerTypeEnum; import org.nl.utils.SpringContextHolder; -import org.slf4j.MarkerFactory; import org.springframework.stereotype.Component; import java.util.Arrays; @@ -36,331 +34,11 @@ import java.util.List; @Slf4j @Component public class AutoCreateInst { - - /** * 根据任务状态创建指令、生成下一条指令 * 创建指令前需要判断是否条件具备:起始位置是否有货、目标位置是否有货 */ public void run() throws Exception { - TaskService taskserver = SpringContextHolder.getBean(TaskService.class); - InstructionService instructionService = SpringContextHolder.getBean(InstructionService.class); - RouteLineService routeLineService = SpringContextHolder.getBean(RouteLineService.class); - AcsConfigService acsConfigService = SpringContextHolder.getBean(AcsConfigService.class); - List list = taskserver.queryByStauts("0"); - DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class); - for (int i = 0; i < list.size(); i++) { - TaskDto acsTask = list.get(i); - String taskid = acsTask.getTask_id(); - String taskcode = acsTask.getTask_code(); - String vehiclecode = acsTask.getVehicle_code(); - String priority = acsTask.getPriority(); - String start_point_code = acsTask.getStart_point_code(); - String start_device_code = acsTask.getStart_device_code(); - String route_plan_code = acsTask.getRoute_plan_code(); - String vehicleType = acsTask.getVehicle_type(); - //是否复合任务 =0非复合任务 - String compound_task = acsTask.getCompound_task(); - String next_point_code = acsTask.getNext_point_code(); - String next_device_code = acsTask.getNext_device_code(); - if (StrUtil.isEmpty(start_device_code)) { - log.info("起点设备:" + start_device_code + "起始设备不能为空,任务号:" + taskcode); - acsTask.setRemark("起始设备不能为空"); - taskserver.updateByCodeFromCache(acsTask); - continue; - } - if (StrUtil.isEmpty(next_device_code)) { - log.info("目标设备:" + next_device_code + "目标设备不能为空,任务号:" + taskcode); - acsTask.setRemark("目标设备不能为空"); - taskserver.updateByCodeFromCache(acsTask); - continue; - } - List instructions = instructionService.queryAll("instruction_status < 2"); - String maxInstnumber = acsConfigService.findConfigFromCache().get(AcsConfig.MAXINSTNUMBER); - if (ObjectUtils.isNotEmpty(maxInstnumber)) { - if (instructions.size() >= Integer.parseInt(maxInstnumber)) { - log.info("系统参数配置最大指令数为:" + maxInstnumber + "无法生成指令"); - acsTask.setRemark("系统参数配置最大指令数为:" + maxInstnumber + "无法生成指令"); - taskserver.updateByCodeFromCache(acsTask); - log.info(LogMarkerTypeEnum.getMarker(LogMarkerTypeEnum.AUTO_CREATE_INST),"系统参数配置最大指令数为:{}无法生成指令",maxInstnumber); - continue; - } - } -// JSONArray acs_deviceja = WQLObject.getWQLObject("acs_device").query("device_name").getResultJSONArray(0); -// for (int j = 0; j < acs_deviceja.size(); j++) { -// JSONObject json = acs_deviceja.getJSONObject(j); -// String device_code = json.optString("device_code"); -// Device deviceByCode = appService.findDeviceByCode(device_code); -// ElectricFenceDeviceDriver electricFenceDeviceDriver; -// if (deviceByCode.getDeviceDriver() instanceof ElectricFenceDeviceDriver) { -// electricFenceDeviceDriver = (ElectricFenceDeviceDriver) deviceByCode.getDeviceDriver(); -// if (electricFenceDeviceDriver.getSuspended()) { -// return; -// } -// } -// } - List allDevice = appService.findAllDevice(); - for (int j = 0; j < allDevice.size(); j++) { - Device deviceByCode = allDevice.get(j); - ElectricFenceDeviceDriver electricFenceDeviceDriver; - if (deviceByCode.getDeviceDriver() instanceof ElectricFenceDeviceDriver) { - electricFenceDeviceDriver = (ElectricFenceDeviceDriver) deviceByCode.getDeviceDriver(); - if (electricFenceDeviceDriver.getSuspended()) { - return; - } - } - } - //特殊任务 起点终点处理 -// if (StrUtil.equals("2", acsTask.getTask_type())) { -// next_device_code = acsTask.getNext_device_code(); -// if (StrUtil.equals(appService.findDeviceTypeByCode(next_device_code), "storage")) { -// next_point_code = next_device_code + "-" + acsTask.getTo_y() + "-" + acsTask.getTo_z(); -// } else { -// next_point_code = next_device_code; -// } -// if(taskserver.querySameTaskByType("2")>0){ -// acsTask.setRemark("该任务类型任务暂不允许生成指令"); -// log.debug("该任务类型任务暂不允许生成指令"); -// taskserver.updateByCodeFromCache(acsTask); -// continue; -// } -// } - - /** - * 开始平均分解校验 - */ - String this_coevice_code = taskserver.queryAssignedByDevice(acsTask.getStart_device_code(), acsTask.getNext_device_code()); - if (StrUtil.isEmpty(this_coevice_code)) { - List shortPathsList = routeLineService.getShortPathLines(start_device_code, acsTask.getNext_device_code(), route_plan_code); - RouteLineDto routeLineDto = shortPathsList.get(0); - String path = routeLineDto.getPath(); - String type = routeLineDto.getType(); - String[] str = path.split("->"); - List pathlist = Arrays.asList(str); - int index = 0; - for (int m = 0; m < pathlist.size(); m++) { - if (pathlist.get(m).equals(start_device_code)) { - index = m + 1; - break; - } - } - next_device_code = pathlist.get(index); - } else { - next_device_code = this_coevice_code; - } - //校验路由关系 - List shortPathsList = routeLineService.getShortPathLines(start_device_code, next_device_code, route_plan_code); - if (ObjectUtils.isEmpty(shortPathsList)) { - acsTask.setRemark("路由不通无法生成指令"); - taskserver.updateByCodeFromCache(acsTask); - continue; - } - - if (!StrUtil.equals(shortPathsList.get(0).getType(), "1")) { - continue; - } - Device startdevice = appService.findDeviceByCode(start_device_code); - Device nextdevice = appService.findDeviceByCode(next_device_code); - if (StrUtil.equals(appService.findDeviceTypeByCode(next_device_code), "storage")) { - next_point_code = next_device_code + "-" + acsTask.getTo_y() + "-" + acsTask.getTo_z(); - } else { - next_point_code = next_device_code; - } - if (ObjectUtils.isEmpty(appService)) { - log.info("地址对应设备未找到"); - continue; - } - if (ObjectUtils.isEmpty(startdevice)) { - log.info("地址对应设备未找到"); - continue; - } - //普通站点 - StandardOrdinarySiteDeviceDriver standardOrdinarySiteDeviceDriver; - StandardInspectSiteDeviceDriver standardInspectSiteDeviceDriver; - StandardEmptyPalletSiteDeviceDriver standardEmptsyPalletSiteDeviceDriver; - LampThreecolorDeviceDriver lampThreecolorDeviceDriver; - - String createTaskCheck = acsConfigService.findConfigFromCache().get(AcsConfig.CREATETASKCHECK); - - if (StrUtil.equals(createTaskCheck, "1")) { - if (startdevice.getDeviceDriver() instanceof StandardInspectSiteDeviceDriver) { - standardInspectSiteDeviceDriver = (StandardInspectSiteDeviceDriver) startdevice.getDeviceDriver(); - if (standardInspectSiteDeviceDriver.getMode() != 2) { - log.info("起点设备:" + startdevice.getDevice_code() + "设备未待机,任务号:" + taskcode); - acsTask.setRemark("起点设备:" + startdevice.getDevice_code() + "设备未待机,任务号:" + taskcode); - taskserver.updateByCodeFromCache(acsTask); - log.info(LogMarkerTypeEnum.getMarker(LogMarkerTypeEnum.AUTO_CREATE_INST),"起点设备:{}设备未待机,任务号:{}",startdevice.getDevice_code(),taskcode); - //this.execute_log.setResource(startdevice.getDevice_code(), startdevice.getDevice_code()); - //this.execute_log.log("起点设备:" + startdevice.getDevice_code() + "设备未待机,任务号:" + taskcode); - continue; - } - } - if (startdevice.getDeviceDriver() instanceof StandardEmptyPalletSiteDeviceDriver) { - standardEmptsyPalletSiteDeviceDriver = (StandardEmptyPalletSiteDeviceDriver) startdevice.getDeviceDriver(); - if (standardEmptsyPalletSiteDeviceDriver.getMode() != 2) { - log.info("目标设备:" + nextdevice.getDevice_code() + "设备未待机,任务号:" + taskcode); - acsTask.setRemark("目标设备:" + nextdevice.getDevice_code() + "设备未待机,任务号:" + taskcode); - taskserver.updateByCodeFromCache(acsTask); - log.info(LogMarkerTypeEnum.getMarker(LogMarkerTypeEnum.AUTO_CREATE_INST),"目标设备:{}设备未待机,任务号:{}",nextdevice.getDevice_code(),taskcode); - //this.execute_log.setResource(nextdevice.getDevice_code(), nextdevice.getDevice_code()); - //this.execute_log.log("目标设备:" + nextdevice.getDevice_code() + "设备未待机,任务号:" + taskcode); - continue; - } - - if (StrUtil.equals(acsTask.getTask_type(), TaskTypeEnum.APPLY_EMPTY.getCode())) { - int nowNumber = standardEmptsyPalletSiteDeviceDriver.getNumber(); - start_point_code = start_point_code + "." + nowNumber; - } - } - - //目的点校验 - if (nextdevice.getDeviceDriver() instanceof StandardInspectSiteDeviceDriver) { - standardInspectSiteDeviceDriver = (StandardInspectSiteDeviceDriver) nextdevice.getDeviceDriver(); - if (standardInspectSiteDeviceDriver.getMode() != 2) { - log.info("目标设备:" + nextdevice.getDevice_code() + "设备未待机,任务号:" + taskcode); - acsTask.setRemark("目标设备:" + nextdevice.getDevice_code() + "设备未待机,任务号:" + taskcode); - taskserver.updateByCodeFromCache(acsTask); - log.info(LogMarkerTypeEnum.getMarker(LogMarkerTypeEnum.AUTO_CREATE_INST),"目标设备:{}设备未待机,任务号:{}",nextdevice.getDevice_code(),taskcode); - //this.execute_log.setResource(nextdevice.getDevice_code(), nextdevice.getDevice_code()); - //this.execute_log.log("目标设备:" + nextdevice.getDevice_code() + "设备未待机,任务号:" + taskcode); - continue; - } - if (standardInspectSiteDeviceDriver.getMove() != 0) { - log.info("目标设备:" + nextdevice.getDevice_code() + "设备不满足放货条件,任务号:" + taskcode); - acsTask.setRemark("目标设备:" + nextdevice.getDevice_code() + "设备不满足放货条件,任务号:" + taskcode); - taskserver.updateByCodeFromCache(acsTask); - log.info(LogMarkerTypeEnum.getMarker(LogMarkerTypeEnum.AUTO_CREATE_INST),"目标设备:{}设备不满足放货条件,任务号:{}",nextdevice.getDevice_code(),taskcode); - //this.execute_log.setResource(nextdevice.getDevice_code(), nextdevice.getDevice_code()); - //this.execute_log.log("目标设备:" + nextdevice.getDevice_code() + "设备不满足放货条件,任务号:" + taskcode); - continue; - } - } - - - if (nextdevice.getDeviceDriver() instanceof StandardOrdinarySiteDeviceDriver) { - standardOrdinarySiteDeviceDriver = (StandardOrdinarySiteDeviceDriver) nextdevice.getDeviceDriver(); - if (standardOrdinarySiteDeviceDriver.getHasGoods() != 0) { - log.info("目标设备:" + nextdevice.getDevice_code() + "有货,无法生成任务,任务号:" + taskcode); - acsTask.setRemark("目标设备:" + nextdevice.getDevice_code() + "有货,无法生成任务,任务号:" + taskcode); - taskserver.updateByCodeFromCache(acsTask); - log.info(LogMarkerTypeEnum.getMarker(LogMarkerTypeEnum.AUTO_CREATE_INST),"目标设备:{}有货,无法生成任务,任务号:{}",nextdevice.getDevice_code(),taskcode); - //this.execute_log.setResource(nextdevice.getDevice_code(), nextdevice.getDevice_code()); - //this.execute_log.log("目标设备:" + nextdevice.getDevice_code() + "有货,无法生成任务,任务号:" + taskcode); - continue; - } - } - - //校验 是否同任务是否存在相同终点、未完成的指令 - int sameqty = instructionService.querySameDestinationInst(next_point_code); - if (sameqty > 0) { - log.info("存在相同终点的指令,任务号:" + taskcode); - acsTask.setRemark("存在相同终点的指令,任务号:" + taskcode); - taskserver.updateByCodeFromCache(acsTask); - log.info(LogMarkerTypeEnum.getMarker(LogMarkerTypeEnum.AUTO_CREATE_INST),"存在相同的指令,任务号:{}",taskcode); - //this.execute_log.setResource(nextdevice.getDevice_code(), nextdevice.getDevice_code()); - //this.execute_log.log("存在相同终点的指令,任务号:" + taskcode); - continue; - } - } - - //空盘位生成指令需要另外逻辑 - if (nextdevice.getDeviceDriver() instanceof StandardEmptyPalletSiteDeviceDriver) { - standardEmptsyPalletSiteDeviceDriver = (StandardEmptyPalletSiteDeviceDriver) nextdevice.getDeviceDriver(); - if (standardEmptsyPalletSiteDeviceDriver.getMode() != 2) { - log.info(("目标设备:" + nextdevice.getDevice_code() + "设备未待机,任务号:" + taskcode)); - acsTask.setRemark("目标设备:" + nextdevice.getDevice_code() + "设备未待机"); - taskserver.updateByCodeFromCache(acsTask); - log.info(LogMarkerTypeEnum.getMarker(LogMarkerTypeEnum.AUTO_CREATE_INST),"目标设备:{}设备未待机,任务号:{}",nextdevice.getDevice_code(),taskcode); - //this.execute_log.setResource(nextdevice.getDevice_code(), nextdevice.getDevice_code()); - //this.execute_log.log("目标设备:" + nextdevice.getDevice_code() + "设备未待机,任务号:" + taskcode); - continue; - } - int max_emptypalletnum = Integer.parseInt(nextdevice.getExtraValue().get("max_emptypalletnum").toString()); - int nowNumber = standardEmptsyPalletSiteDeviceDriver.getNumber(); - if (nowNumber == max_emptypalletnum) { - log.info("目标设备:" + nextdevice.getDevice_code() + "空盘位已满等待入库,任务号:" + taskcode); - acsTask.setRemark("目标设备:" + nextdevice.getDevice_code() + "空盘位已满等待入库,任务号:" + taskcode); - taskserver.updateByCodeFromCache(acsTask); - log.info(LogMarkerTypeEnum.getMarker(LogMarkerTypeEnum.AUTO_CREATE_INST),"目标设备:{}空盘位已满等待入库,任务号:{}",nextdevice.getDevice_code(),taskcode); - //this.execute_log.log("目标设备:" + nextdevice.getDevice_code() + "空盘位已满等待入库,任务号:" + taskcode); - continue; - } - // 查看是否有相同终点的指令 - int sameqty = instructionService.querySameDestinationInst(next_point_code); - if (sameqty > 0) { - log.info("存在相同终点的指令,任务号:" + taskcode); - acsTask.setRemark("存在相同终点的指令,任务号:" + taskcode); - taskserver.updateByCodeFromCache(acsTask); - log.info(LogMarkerTypeEnum.getMarker(LogMarkerTypeEnum.AUTO_CREATE_INST),"存在相同终点的指令,任务号:{}",taskcode); - //this.execute_log.setResource(nextdevice.getDevice_code(), nextdevice.getDevice_code()); - //this.execute_log.log("存在相同终点的指令,任务号:" + taskcode); - continue; - } - next_point_code = next_point_code + "." + (nowNumber + sameqty + 1); - } - if (startdevice.getDeviceDriver() instanceof StandardEmptyPalletSiteDeviceDriver) { - standardEmptsyPalletSiteDeviceDriver = (StandardEmptyPalletSiteDeviceDriver) startdevice.getDeviceDriver(); - - int sameqty = instructionService.querySameOriginInst(start_point_code); - if (sameqty > 0) { - log.info("存在相同终点的指令,任务号:" + taskcode); - acsTask.setRemark("存在相同终点的指令,任务号:" + taskcode); - taskserver.updateByCodeFromCache(acsTask); - log.info(LogMarkerTypeEnum.getMarker(LogMarkerTypeEnum.AUTO_CREATE_INST),"存在相同终点的指令,任务号:{}",taskcode); - //this.execute_log.setResource(nextdevice.getDevice_code(), nextdevice.getDevice_code()); - //this.execute_log.log("存在相同终点的指令,任务号:" + taskcode); - continue; - } - - if (!StrUtil.equals(acsTask.getEmptypallet_num(), "0")) { - Integer.parseInt(acsTask.getEmptypallet_num()); - int num = standardEmptsyPalletSiteDeviceDriver.getNumber() - Integer.parseInt(acsTask.getEmptypallet_num()) + 1 - sameqty; - if (num <= 0) { - acsTask.setRemark("叠盘位可用空盘数量不足无法生成"); - taskserver.updateByCodeFromCache(acsTask); - continue; - } else { - start_point_code = start_point_code + "." + num; - } - } else { - start_point_code = start_point_code + "." + 1; - } - } - Instruction instdto = new Instruction(); - instdto.setInstruction_type(acsTask.getTask_type()); - instdto.setInstruction_id(IdUtil.simpleUUID()); - instdto.setRoute_plan_code(route_plan_code); - instdto.setRemark(acsTask.getRemark()); - instdto.setMaterial(acsTask.getMaterial()); - instdto.setQuantity(acsTask.getQuantity()); - instdto.setTask_id(taskid); - instdto.setTask_code(taskcode); - instdto.setVehicle_code(vehiclecode); - String now = DateUtil.now(); - instdto.setCreate_time(now); - instdto.setCreate_by("auto"); - instdto.setStart_device_code(start_device_code); - instdto.setNext_device_code(next_device_code); - instdto.setStart_point_code(start_point_code); - instdto.setNext_point_code(next_point_code); - instdto.setPriority(priority); - instdto.setInstruction_status("0"); - instdto.setExecute_device_code(start_point_code); - instdto.setVehicle_type(vehicleType); - try { - instructionService.create(instdto); - } catch (Exception e) { - acsTask.setRemark(e.getMessage()); - taskserver.updateByCodeFromCache(acsTask); - continue; - } - log.info("任务号:" + taskcode + "的指令生成成功"); - log.info(LogMarkerTypeEnum.getMarker(LogMarkerTypeEnum.AUTO_CREATE_INST),"任务号:{}的指令生成成功",taskcode); - //创建指令后修改任务状态 - acsTask.setTask_status("1"); - taskserver.update(acsTask); - - } } } diff --git a/nladmin-system/src/main/java/org/nl/modules/quartz/task/ToAgvDevice.java b/nladmin-system/src/main/java/org/nl/modules/quartz/task/ToAgvDevice.java index 76f136c..3576d83 100644 --- a/nladmin-system/src/main/java/org/nl/modules/quartz/task/ToAgvDevice.java +++ b/nladmin-system/src/main/java/org/nl/modules/quartz/task/ToAgvDevice.java @@ -70,7 +70,7 @@ public class ToAgvDevice { SocketMsg deviceInfo = new SocketMsg(json, MsgType.INFO); WebSocketServer.sendInfo(deviceInfo, "toAgvDevice_data"); - // acsToWmsService.feedbackAgv(row); + acsToWmsService.feedbackAgv(agv_rows); } } diff --git a/nladmin-system/src/main/java/org/nl/modules/quartz/task/queryAOrderDterail.java b/nladmin-system/src/main/java/org/nl/modules/quartz/task/queryAOrderDterail.java new file mode 100644 index 0000000..ef86639 --- /dev/null +++ b/nladmin-system/src/main/java/org/nl/modules/quartz/task/queryAOrderDterail.java @@ -0,0 +1,90 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.nl.modules.quartz.task; + +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.nl.modules.mnt.websocket.MsgType; +import org.nl.modules.mnt.websocket.SocketMsg; +import org.nl.modules.mnt.websocket.WebSocketServer; +import org.nl.wql.core.bean.ResultBean; +import org.nl.wql.core.bean.WQLObject; +import org.nl.wql.util.WqlUtil; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Component; + +import java.io.IOException; + +/** + * 测试用 + * + * @author Zheng Jie + * @date 2019-01-08 + */ +@Slf4j +@Component +public class queryAOrderDterail { + + public void run() { + try { + WQLObject wo = WQLObject.getWQLObject("acs_produceshiftorder"); + String where = "1=1 and is_deleted= '0'"; + ResultBean rb = wo.query( where, "order_id desc"); + final JSONObject json = rb.pageResult(); + JSONArray newja = new JSONArray(); + JSONArray ja = json.getJSONArray("content"); + for (int i = 0; i < ja.size(); i++) { + JSONObject jo = (JSONObject) ja.get(i); + JSONArray orderDteail_ja = WQLObject.getWQLObject("acs_produceshiftorderdetail").query("is_deleted= '0' and order_id ='" + jo.getString("order_id") + "'").getResultJSONArray(0); + if (orderDteail_ja.size() > 0) { + JSONArray children = new JSONArray(); + for (int j = 0; j < orderDteail_ja.size(); j++) { + JSONObject orderDteail_jo = orderDteail_ja.getJSONObject(j); + JSONObject new_jo = new JSONObject(); + new_jo.put("order_id", orderDteail_jo.getString("orderdetail_id")); + new_jo.put("order_code", orderDteail_jo.getString("orderdetail_code")); + new_jo.put("is_active", orderDteail_jo.getString("is_active")); + new_jo.put("is_delete", orderDteail_jo.getString("is_delete")); + new_jo.put("create_by", orderDteail_jo.getString("create_by")); + new_jo.put("create_time", orderDteail_jo.getString("create_time")); + new_jo.put("update_by", orderDteail_jo.getString("update_by")); + new_jo.put("update_time", orderDteail_jo.getString("update_time")); + new_jo.put("customer_code", orderDteail_jo.getString("customer_code")); + new_jo.put("customer_name", orderDteail_jo.getString("customer_name")); + new_jo.put("order_qty", orderDteail_jo.getString("order_qty")); + new_jo.put("type", "orderDteail"); + jo.put("flag", "1"); + children.add(new_jo); + } + jo.put("children", children); + } + jo.put("type", "order"); + //区分工单明细 + jo.put("flag", "0"); + newja.add(jo); + } + json.put("content", newja); + System.out.println("json:" + json); + SocketMsg deviceInfo = new SocketMsg(json, MsgType.INFO); + WebSocketServer.sendInfo(deviceInfo, "queryAOrderDterail"); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/nladmin-system/src/main/resources/config/application-dev.yml b/nladmin-system/src/main/resources/config/application-dev.yml index 6d94e87..fd4192d 100644 --- a/nladmin-system/src/main/resources/config/application-dev.yml +++ b/nladmin-system/src/main/resources/config/application-dev.yml @@ -8,7 +8,7 @@ spring: druid: db-type: com.alibaba.druid.pool.DruidDataSource driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy - url: jdbc:log4jdbc:mysql://${DB_HOST:192.168.81.252}:${DB_PORT:3306}/${DB_NAME:ndxy2_acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true + url: jdbc:log4jdbc:mysql://${DB_HOST:192.168.81.252}:${DB_PORT:3306}/${DB_NAME:hl_zgbz_acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true username: ${DB_USER:root} #password: ${DB_PWD:P@ssw0rd} password: ${DB_PWD:Root.123456} @@ -57,13 +57,13 @@ spring: multi-statement-alagvslow: true data: mongodb: - host: 47.97.157.227 + host: 192.168.81.251 port: 27017 database: nlacs redis: #数据库索引 database: ${REDIS_DB:0} - host: ${REDIS_HOST:47.97.157.227} + host: ${REDIS_HOST:127.0.0.1} port: ${REDIS_PORT:6379} password: ${REDIS_PWD:} #连接超时时间 @@ -160,5 +160,5 @@ jetcache: maxIdle: 200 maxTotal: 1000 uri: - - redis://47.97.157.227:6379 + - redis://127.0.0.1:6379 diff --git a/nladmin-system/src/main/resources/log/AcsToErp.xml b/nladmin-system/src/main/resources/log/AcsToErp.xml index 46f3bc9..3eef302 100644 --- a/nladmin-system/src/main/resources/log/AcsToErp.xml +++ b/nladmin-system/src/main/resources/log/AcsToErp.xml @@ -11,7 +11,7 @@ - + diff --git a/nladmin-system/src/main/resources/logback-spring.xml b/nladmin-system/src/main/resources/logback-spring.xml index 6f88ba8..0bb9721 100644 --- a/nladmin-system/src/main/resources/logback-spring.xml +++ b/nladmin-system/src/main/resources/logback-spring.xml @@ -58,7 +58,7 @@ https://juejin.cn/post/6844903775631572999 - 47.97.157.227 + 192.168.81.251 27017 @@ -116,9 +116,9 @@ https://juejin.cn/post/6844903775631572999 - - - + + +