From 727a69f859060093e685582fa10e5de82dcc138a Mon Sep 17 00:00:00 2001
From: Van333 <van666666@foxmail.com>
Date: 星期四, 29 十二月 2022 15:37:49 +0800
Subject: [PATCH] 放假备份。完成集中控制器对接。

---
 ximon-admin/src/main/java/com/sandu/ximon/admin/utils/MybatisPlusUtil.java                                                  |   89 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcResetReqInnerFrame.java                |   22 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcResetRespInnerFrame.java              |   47 
 ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcReportDataService.java                                           |  168 +
 ximon-admin/src/main/resources/application.yml                                                                              |    4 
 dao/src/main/resources/mapper/PlcReportDataMapper.xml                                                                       |   69 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/A7PlcReportEnum.java                                 |   29 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/A7Frame.java                                              |   60 
 dao/src/main/java/com/sandu/ximon/dao/bo/PlcTaskNameIdBo.java                                                               |   18 
 ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcTaskService.java                                                 |  909 +++++++++
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcSetCalendarReqInnerFrame.java          |   33 
 ximon-admin/src/main/java/com/sandu/ximon/admin/vo/PlcTaskRelationVO.java                                                   |   32 
 dao/src/main/resources/mapper/PlcReportErrorMapper.xml                                                                      |   64 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/PlcErrorEnum.java                                    |  186 +
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcSettingHeartBeatTimeReqInnerFrame.java |   45 
 ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcTaskPoleRelationService.java                                     |   17 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcTimerReqInnerFrame.java                |   44 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcQueryVersionRespInnerFrame.java       |   61 
 dao/src/main/java/com/sandu/ximon/dao/mapper/PlcTaskMapper.java                                                             |   26 
 ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcTaskParam.java                                                     |   56 
 dao/pom.xml                                                                                                                 |    6 
 ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcRemarkParam.java                                                   |   20 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcManualLightSwitchReportInnerFrame.java  |   48 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/A7OrderEnum.java                                     |   31 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcQueryHeartBeatDataReqInnerFrame.java   |   38 
 ximon-admin/src/main/java/com/sandu/ximon/admin/vo/PlcTaskInfoVO.java                                                       |   21 
 ximon-admin/src/main/java/com/sandu/ximon/admin/vo/PlcTaskVO.java                                                           |   52 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A1DeviceMacRespInnerFrame.java             |    2 
 dao/src/main/java/com/sandu/ximon/dao/bo/PlcReportErrorBo.java                                                              |   15 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcTimerRespInnerFrame.java              |   47 
 ximon-admin/src/main/java/com/sandu/ximon/admin/service/PoleService.java                                                    |   44 
 ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PoleController.java                                              |    4 
 ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcReportErrorService.java                                          |  122 +
 ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcTaskDelParam.java                                                  |   17 
 dao/src/main/java/com/sandu/ximon/dao/domain/PlcReportError.java                                                            |   43 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcRespInnerFrame.java                   |   47 
 ximon-admin/src/main/resources/application-xm_local.yml                                                                     |  129 +
 dao/src/main/java/com/sandu/ximon/dao/enums/OrderByEnums.java                                                               |    1 
 dao/src/main/java/com/sandu/ximon/dao/mapper/PlcTaskPoleRelationMapper.java                                                 |   16 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/amqp/processor/PlcDataProcessor.java                            |   93 
 ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcControlParam.java                                                  |   35 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcTimeSyncReportInnerFrame.java           |   48 
 dao/src/main/java/com/sandu/ximon/dao/mapper/PlcMapper.java                                                                 |   46 
 dao/src/main/java/com/sandu/ximon/dao/mapper/PlcReportErrorMapper.java                                                      |   22 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/A7PlcDataEnum.java                                   |   45 
 ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcReportDataController.java                                     |   34 
 dao/src/main/java/com/sandu/ximon/dao/domain/PlcTask.java                                                                   |   64 
 dao/src/main/java/com/sandu/ximon/dao/enums/PoleBindingEnums.java                                                           |    7 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/FunctionCodeEnum.java                                |    7 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcHeartbeatReportInnerFrame.java          |  308 +++
 dao/src/main/resources/mapper/PlcLightMapper.xml                                                                            |   76 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcBrightnessReqInnerFrame.java           |   47 
 dao/src/main/java/com/sandu/ximon/dao/domain/Plc.java                                                                       |   66 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcRebootReqInnerFrame.java               |   21 
 dao/src/main/java/com/sandu/ximon/dao/domain/PoleBinding.java                                                               |   11 
 dao/src/main/resources/mapper/PlcTaskDao.xml                                                                                |   91 
 ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcController.java                                               |  201 ++
 dao/src/main/java/com/sandu/ximon/dao/domain/PlcTaskPoleRelation.java                                                       |   49 
 ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcTaskIssueParam.java                                                |   20 
 dao/src/main/java/com/sandu/ximon/dao/enums/MenuEnum.java                                                                   |   19 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcBrightnessRespInnerFrame.java         |   47 
 sandu-common/src/main/resources/logback-spring.xml                                                                          |    7 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcQueryHeartBeatTimeRespInnerFrame.java |   48 
 ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcService.java                                                     |  647 ++++++
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcQueryHeartBeatTimeReqInnerFrame.java   |   38 
 ximon-admin/src/main/java/com/sandu/ximon/admin/service/PoleBindingService.java                                             |    3 
 dao/src/main/java/com/sandu/ximon/dao/mapper/PlcReportDataMapper.java                                                       |   19 
 ximon-admin/pom.xml                                                                                                         |    5 
 dao/src/main/java/com/sandu/ximon/dao/bo/PlcBo.java                                                                         |   24 
 dao/src/main/java/com/sandu/ximon/dao/bo/PlcReportDataBo.java                                                               |   16 
 ximon-admin/src/main/java/com/sandu/ximon/admin/dto/PlcTaskDto.java                                                         |   31 
 ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcTaskController.java                                           |  142 +
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcCleanErrorCodeInnerFrame.java          |   27 
 ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcTaskPoleRelationController.java                               |   88 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/FrameBuilder.java                                         |    5 
 /dev/null                                                                                                                   |   23 
 dao/src/main/java/com/sandu/ximon/dao/domain/PlcReportData.java                                                             |  208 ++
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcQueryHeartBeatDataRespInnerFrame.java |   50 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcQueryVersionReqInnerFrame.java         |   38 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/amqp/AmqpMessageListener.java                                   |   56 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcOperationReportInnerFrame.java          |   67 
 ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcErrorCodeReportInnerFrame.java          |   54 
 82 files changed, 5,567 insertions(+), 68 deletions(-)

diff --git a/dao/pom.xml b/dao/pom.xml
index 67d34e5..7ee9003 100644
--- a/dao/pom.xml
+++ b/dao/pom.xml
@@ -29,6 +29,12 @@
             <version>3.4.2</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-annotations</artifactId>
+            <version>1.6.2</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
 
 </project>
diff --git a/dao/src/main/java/com/sandu/ximon/dao/bo/PlcBo.java b/dao/src/main/java/com/sandu/ximon/dao/bo/PlcBo.java
new file mode 100644
index 0000000..e9e1e0a
--- /dev/null
+++ b/dao/src/main/java/com/sandu/ximon/dao/bo/PlcBo.java
@@ -0,0 +1,24 @@
+package com.sandu.ximon.dao.bo;
+
+import com.sandu.ximon.dao.domain.Plc;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * @author van
+ * @version 1.0
+ * msg锛�
+ * @date 2022/12/15 17:15
+ */
+@Data
+public class PlcBo extends Plc {
+    private Long poleId;
+    private String poleCode;
+    private String poleName;
+    private String taskName;
+    private LocalDateTime reportTime;
+
+    private List<PlcTaskNameIdBo> taskNameIdBos;
+}
diff --git a/dao/src/main/java/com/sandu/ximon/dao/bo/PlcReportDataBo.java b/dao/src/main/java/com/sandu/ximon/dao/bo/PlcReportDataBo.java
new file mode 100644
index 0000000..cefdc23
--- /dev/null
+++ b/dao/src/main/java/com/sandu/ximon/dao/bo/PlcReportDataBo.java
@@ -0,0 +1,16 @@
+package com.sandu.ximon.dao.bo;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.sandu.ximon.dao.domain.LightReportData;
+import com.sandu.ximon.dao.domain.PlcReportData;
+import lombok.Data;
+
+/**
+ * @author van
+ */
+@Data
+public class PlcReportDataBo extends PlcReportData {
+
+    @ExcelProperty("鐏潌鍚嶇О")
+    private String poleName;
+}
diff --git a/dao/src/main/java/com/sandu/ximon/dao/bo/PlcReportErrorBo.java b/dao/src/main/java/com/sandu/ximon/dao/bo/PlcReportErrorBo.java
new file mode 100644
index 0000000..f6de455
--- /dev/null
+++ b/dao/src/main/java/com/sandu/ximon/dao/bo/PlcReportErrorBo.java
@@ -0,0 +1,15 @@
+package com.sandu.ximon.dao.bo;
+
+import com.sandu.ximon.dao.domain.LightReportError;
+import com.sandu.ximon.dao.domain.PlcReportError;
+import lombok.Data;
+
+/**
+ * @author van
+ */
+@Data
+public class PlcReportErrorBo extends PlcReportError {
+
+    private String poleName;
+    private String errorMsg;
+}
diff --git a/dao/src/main/java/com/sandu/ximon/dao/bo/PlcTaskNameIdBo.java b/dao/src/main/java/com/sandu/ximon/dao/bo/PlcTaskNameIdBo.java
new file mode 100644
index 0000000..8bc7b8e
--- /dev/null
+++ b/dao/src/main/java/com/sandu/ximon/dao/bo/PlcTaskNameIdBo.java
@@ -0,0 +1,18 @@
+package com.sandu.ximon.dao.bo;
+
+import lombok.Data;
+
+/**
+ * @author van
+ * @version 1.0
+ * msg锛�
+ * @date 2022/12/15 17:44
+ */
+@Data
+public class PlcTaskNameIdBo {
+    private Long taskId;
+
+    private String taskName;
+
+    private String plcAddress;
+}
diff --git a/dao/src/main/java/com/sandu/ximon/dao/domain/Plc.java b/dao/src/main/java/com/sandu/ximon/dao/domain/Plc.java
new file mode 100644
index 0000000..714ec10
--- /dev/null
+++ b/dao/src/main/java/com/sandu/ximon/dao/domain/Plc.java
@@ -0,0 +1,66 @@
+package com.sandu.ximon.dao.domain;
+
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * plc璺伅琛�(Plc)琛ㄥ疄浣撶被
+ *
+ * @author van
+ * @since 2022-12-15 14:41:22
+ */
+@TableName(value = "plc")
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class Plc implements Serializable{
+
+    @TableId(type = IdType.AUTO)
+    private Long plcId;
+    //璁惧璇嗗埆鐮�
+    private String deviceCode;
+    //澶囨敞淇℃伅
+    private String plcRemark;
+    //璺暟锛岄粯璁�3
+    private Integer plcCount;
+    //鐏ご1寮�鍏崇姸鎬侊紝1 寮� 0 鍏�
+    private Integer plcLight1;
+    //鐏ご2寮�鍏崇姸鎬侊紝1 寮� 0 鍏�
+    private Integer plcLight2;
+    //鐏ご3寮�鍏崇姸鎬侊紝1 寮� 0 鍏�
+    private Integer plcLight3;
+    //瀹氭椂浠诲姟寮�鍏崇姸鎬侊紝1 寮� 0 鍏�
+    private Integer plcTimingControl;
+    //鍏夋劅寮�鍏崇姸鎬侊紝1 寮� 0 鍏�
+    private Integer plcSensorControl;
+    //杞欢鐗堟湰
+    private String plcSoftwareVersion;
+    //纭欢鐗堟湰
+    private String plcHardwareVersion;
+    //IEMI
+    private String plcIemi;
+    //ICCID
+    private String plcIccid;
+    //鍒涘缓鏃堕棿
+    private LocalDateTime plcCreateTime;
+
+    private LocalDateTime plcUpdateTime;
+
+    /**
+     * 鍦ㄧ嚎鐘舵�� 0锛氱绾� 1锛氬湪绾�
+     */
+    @TableField(exist = false)
+    private Integer onlineStatus;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}
diff --git a/dao/src/main/java/com/sandu/ximon/dao/domain/PlcReportData.java b/dao/src/main/java/com/sandu/ximon/dao/domain/PlcReportData.java
new file mode 100644
index 0000000..9740f88
--- /dev/null
+++ b/dao/src/main/java/com/sandu/ximon/dao/domain/PlcReportData.java
@@ -0,0 +1,208 @@
+package com.sandu.ximon.dao.domain;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.Data;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.experimental.Accessors;
+import lombok.EqualsAndHashCode;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import org.springframework.format.annotation.DateTimeFormat;
+
+/**
+ * PLC涓婃姤鏁版嵁琛�(PlcReportData)琛ㄥ疄浣撶被
+ *
+ * @author van
+ * @since 2022-12-16 10:52:52
+ */
+@ApiModel("PlcReportData")
+@Data
+@TableName("plc_report_data")
+public class PlcReportData implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    //plcReportDataId
+    @ApiModelProperty("reportDataId")
+    @TableId(value = "report_data_id", type = IdType.AUTO)
+    private Long reportDataId;
+    //璁惧mac
+    @ApiModelProperty("璁惧mac")
+    @TableField(value = "device_code")
+    private String deviceCode;
+    //璁惧娓╁害
+    @ApiModelProperty("璁惧娓╁害")
+    @TableField(value = "device_temperature")
+    private Double deviceTemperature;
+    //鐢电綉鐩告暟(鍗曘�佷笁鐩�)
+    @ApiModelProperty("鐢电綉鐩告暟(鍗曘�佷笁鐩�)")
+    private Long phase;
+    //A鐩哥數鍘�
+    @ApiModelProperty("A鐩哥數鍘�")
+    @TableField(value = "voltage_A")
+    private Double voltageA;
+    //B鐩哥數鍘�
+    @ApiModelProperty("B鐩哥數鍘�")
+    @TableField(value = "voltage_B")
+    private Double voltageB;
+    //B鐩哥數鍘�
+    @ApiModelProperty("C鐩哥數鍘�")
+    @TableField(value = "voltage_C")
+    private Double voltageC;
+    //A鐩哥數娴�
+    @ApiModelProperty("A鐩哥數娴�")
+    @TableField(value = "electric_current_A")
+    private Double electricCurrentA;
+    //B鐩哥數娴�
+    @ApiModelProperty("B鐩哥數娴�")
+    @TableField(value = "electric_current_B")
+    private Double electricCurrentB;
+    //C鐩哥數娴�
+    @ApiModelProperty("C鐩哥數娴�")
+    @TableField(value = "electric_current_C")
+    private Double electricCurrentC;
+    //鍚堢浉鏈夊姛鍔熺巼
+    @ApiModelProperty("鍚堢浉鏈夊姛鍔熺巼")
+    @TableField(value = "active_power_All")
+    private Double activePowerAll;
+    //A鐩告湁鍔熷姛鐜�
+    @ApiModelProperty("A鐩告湁鍔熷姛鐜�")
+    @TableField(value = "active_power_A")
+    private Double activePowerA;
+    //B鐩告湁鍔熷姛鐜�
+    @ApiModelProperty("B鐩告湁鍔熷姛鐜�")
+    @TableField(value = "active_power_B")
+    private Double activePowerB;
+    //C鐩告湁鍔熷姛鐜�
+    @ApiModelProperty("C鐩告湁鍔熷姛鐜�")
+    @TableField(value = "active_power_C")
+    private Double activePowerC;
+    //鍚堢浉鏃犲姛鍔熺巼
+    @ApiModelProperty("鍚堢浉鏃犲姛鍔熺巼")
+    @TableField(value = "reactive_power_All")
+    private Double reactivePowerAll;
+    //A鐩告棤鍔熷姛鐜�
+    @ApiModelProperty("A鐩告棤鍔熷姛鐜�")
+    @TableField(value = "reactive_power_A")
+    private Double reactivePowerA;
+    //B鐩告棤鍔熷姛鐜�
+    @ApiModelProperty("B鐩告棤鍔熷姛鐜�")
+    @TableField(value = "reactive_power_B")
+    private Double reactivePowerB;
+    //C鐩告棤鍔熷姛鐜�
+    @ApiModelProperty("C鐩告棤鍔熷姛鐜�")
+    @TableField(value = "reactive_power_C")
+    private Double reactivePowerC;
+    //鍚堢浉瑙嗗湪鍔熺巼
+    @ApiModelProperty("鍚堢浉瑙嗗湪鍔熺巼")
+    @TableField(value = "apparent_power_All")
+    private Double apparentPowerAll;
+    //A鐩歌鍦ㄥ姛鐜�
+    @ApiModelProperty("A鐩歌鍦ㄥ姛鐜�")
+    @TableField(value = "apparent_power_A")
+    private Double apparentPowerA;
+    //B鐩歌鍦ㄥ姛鐜�
+    @ApiModelProperty("B鐩歌鍦ㄥ姛鐜�")
+    @TableField(value = "apparent_power_B")
+    private Double apparentPowerB;
+    //C鐩歌鍦ㄥ姛鐜�
+    @ApiModelProperty("C鐩歌鍦ㄥ姛鐜�")
+    @TableField(value = "apparent_power_C")
+    private Double apparentPowerC;
+    //鍚堢浉鍔熺巼鍥犵礌
+    @ApiModelProperty("鍚堢浉鍔熺巼鍥犵礌")
+    @TableField(value = "power_factor_All")
+    private Double powerFactorAll;
+    //A鐩稿姛鐜囧洜绱�
+    @ApiModelProperty("A鐩稿姛鐜囧洜绱�")
+    @TableField(value = "power_factor_A")
+    private Double powerFactorA;
+    //B鐩稿姛鐜囧洜绱�
+    @ApiModelProperty("B鐩稿姛鐜囧洜绱�")
+    @TableField(value = "power_factor_B")
+    private Double powerFactorB;
+    //C鐩稿姛鐜囧洜绱�
+    @ApiModelProperty("C鐩稿姛鐜囧洜绱�")
+    @TableField(value = "power_factor_C")
+    private Double powerFactorC;
+    //姝e悜鏈夊姛鎬荤數閲�
+    @ApiModelProperty("姝e悜鏈夊姛鎬荤數閲�")
+    @TableField(value = "total_positive_using_power")
+    private Double totalPositiveUsingPower;
+    //鍙嶅悜鏈夊姛鎬荤數閲�
+    @ApiModelProperty("鍙嶅悜鏈夊姛鎬荤數閲�")
+    @TableField(value = "total_reverse_using_power")
+    private Double totalReverseUsingPower;
+    //鍏夊己鍊�
+    @ApiModelProperty("鍏夊己鍊�")
+    @TableField(value = "light_intensity")
+    private Long lightIntensity;
+    //0鏃舵帶/1鍏夋帶
+    @ApiModelProperty("0鏃舵帶/1鍏夋帶")
+    @TableField(value = "control_1")
+    private Long control1;
+    //0鍏�/64寮�
+    @ApiModelProperty("0鍏�/64寮�")
+    @TableField(value = "status_1")
+    private Long status1;
+    //0鏃舵帶/1鍏夋帶
+    @ApiModelProperty("0鏃舵帶/1鍏夋帶")
+    @TableField(value = "control_2")
+    private Long control2;
+    //0鍏�/64寮�
+    @ApiModelProperty("0鍏�/64寮�")
+    @TableField(value = "status_2")
+    private Long status2;
+    //0鏃舵帶/1鍏夋帶
+    @ApiModelProperty("0鏃舵帶/1鍏夋帶")
+    @TableField(value = "control_3")
+    private Long control3;
+    //0鍏�/64寮�
+    @ApiModelProperty("0鍏�/64寮�")
+    @TableField(value = "status_3")
+    private Long status3;
+    //0鏃舵帶/1鍏夋帶
+    @ApiModelProperty("0鏃舵帶/1鍏夋帶")
+    @TableField(value = "control_n")
+    private Long controlN;
+    //0鍏�/64寮�
+    @ApiModelProperty("0鍏�/64寮�")
+    @TableField(value = "status_n")
+    private Long statusN;
+    //鍒涘缓鏃堕棿
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    @TableField(value = "create_time1")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonIgnore
+    private LocalDateTime createTime1;
+    //updateTime1
+    @ApiModelProperty("updateTime1")
+    @TableField(value = "update_time1")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonIgnore
+    private LocalDateTime updateTime1;
+
+    /**
+     * 鐢ㄤ簬鍓嶆灞曠ず
+     */
+    @TableField(exist = false)
+    private String updateTime;
+
+    /**
+     * 鐢ㄤ簬鍓嶆灞曠ず
+     */
+    @TableField(exist = false)
+    private String createTime;
+}
+
diff --git a/dao/src/main/java/com/sandu/ximon/dao/domain/PlcReportError.java b/dao/src/main/java/com/sandu/ximon/dao/domain/PlcReportError.java
new file mode 100644
index 0000000..f0c4792
--- /dev/null
+++ b/dao/src/main/java/com/sandu/ximon/dao/domain/PlcReportError.java
@@ -0,0 +1,43 @@
+package com.sandu.ximon.dao.domain;
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * plc鍗曠伅鏁呴殰鏁版嵁鍒楄〃(PlcReportError)琛ㄥ疄浣撶被
+ *
+ * @author van
+ * @since 2022-12-17 14:38:59
+ */
+@TableName(value ="plc_report_error")
+@Data
+public class PlcReportError implements Serializable {
+    @TableId(type = IdType.AUTO)
+    private Long plcReportErrorId;
+
+    private String plcDeviceCode;
+    //plc鍦板潃
+    @JsonIgnore
+    private String plcAddress;
+
+    @JsonIgnore
+    private Long errorCode;
+
+    @JsonIgnore
+    private Date createTime;
+
+    private Date updateTime;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+
+}
+
diff --git a/dao/src/main/java/com/sandu/ximon/dao/domain/PlcTask.java b/dao/src/main/java/com/sandu/ximon/dao/domain/PlcTask.java
new file mode 100644
index 0000000..a01cdc1
--- /dev/null
+++ b/dao/src/main/java/com/sandu/ximon/dao/domain/PlcTask.java
@@ -0,0 +1,64 @@
+package com.sandu.ximon.dao.domain;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * plc浠诲姟琛�(PlcTask)琛ㄥ疄浣撶被
+ *
+ * @author van
+ * @since 2022-12-19 16:42:56
+ */
+@TableName(value = "plc_task")
+@Data
+public class PlcTask implements Serializable {
+
+    @TableId(type = IdType.AUTO)
+    private Long taskId;
+    //鐢ㄦ埛ID
+    private Long userId;
+    //瀹㈡埛id
+    private Long clientId;
+    //浠诲姟鍚嶇О
+    private String taskName;
+    //1鏆傚仠銆�0鍚敤
+    @JsonIgnore
+    private Integer pause;
+    //鎺х伅鍦板潃
+    private String plcAdress;
+    //鏄熸湡鍑狅紝浣嶈繍绠椾繚瀛橈紝1浠h〃鏄熸湡涓�锛�2鏄熸湡浜岋紝4鏄熸湡涓夛紝8鏄熸湡鍥涳紝16鏄熸湡浜旓紝32鏄熸湡鍏紝64鏄熸湡鏃�
+    @JsonIgnore
+    private Integer week;
+    //寮�鐏懡浠�
+    private String openOrder;
+    //鍏抽棴鐏懡浠�
+    private String closeOrder;
+    //鐏帶鍛戒护
+    private String controlOrder;
+    //鍙戦�佺殑甯ц礋鑽�
+    @JsonIgnore
+    private String framePayload;
+    //鍒涘缓鐢ㄦ埛
+    private String createUser;
+    //鍒涘缓鏃堕棿
+    private LocalDateTime createTime;
+
+    private LocalDateTime updateTime;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+
+
+    @TableField(exist = false)
+    private List<Integer> weekList;
+}
diff --git a/dao/src/main/java/com/sandu/ximon/dao/domain/PlcTaskPoleRelation.java b/dao/src/main/java/com/sandu/ximon/dao/domain/PlcTaskPoleRelation.java
new file mode 100644
index 0000000..9762a7f
--- /dev/null
+++ b/dao/src/main/java/com/sandu/ximon/dao/domain/PlcTaskPoleRelation.java
@@ -0,0 +1,49 @@
+package com.sandu.ximon.dao.domain;
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * plc浠诲姟鍜岀伅鏉嗗叧绯昏〃(PlcTaskPoleRelation)琛ㄥ疄浣撶被
+ *
+ * @author van
+ * @since 2022-12-19 16:52:25
+ */
+@TableName(value = "plc_task_pole_relation")
+@Data
+public class PlcTaskPoleRelation implements Serializable{
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    //浠诲姟id
+    private Long taskId;
+    //鐏潌id
+    private Long poleId;
+    //plc鍦板潃
+    private String plcAddress;
+    //浠诲姟涓嬪彂鐘舵�侊紝0鎴愬姛锛�1鏍¢獙鐮侀敊璇紝2闀垮害閿欒锛�3鍐檉lash閿欒锛�255鍏朵粬閿欒
+    private Integer issueStatus;
+    //mac
+    @JsonIgnore
+    private String deviceCode;
+    //绯荤粺瀹氭椂
+    private String sysScheduled;
+    //纭欢瀹氭椂
+    private String deviceScheduled;
+    //鍒涘缓鏃堕棿
+    private Date createTime;
+    //鏇存柊鏃堕棿
+    private Date updateTime;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}
+
diff --git a/dao/src/main/java/com/sandu/ximon/dao/domain/PoleBinding.java b/dao/src/main/java/com/sandu/ximon/dao/domain/PoleBinding.java
index e4b4eb0..5358c2e 100644
--- a/dao/src/main/java/com/sandu/ximon/dao/domain/PoleBinding.java
+++ b/dao/src/main/java/com/sandu/ximon/dao/domain/PoleBinding.java
@@ -16,7 +16,7 @@
 @Data
 public class PoleBinding implements Serializable {
     /**
-     * 
+     *
      */
     @TableId(type = IdType.AUTO)
     private Long id;
@@ -37,7 +37,10 @@
     private String deviceCode;
 
     /**
-     * 璁惧绫诲瀷锛�0璺伅锛�1璇虹摝锛�2鍏呯數妗╋紝3澶ф皵鐩戞祴锛�4姘磋川鐩戞祴锛�5ip闊虫煴锛�6lcd骞垮憡鏈猴紝7鎽勫儚澶达紝8鏉嗕綋鍊炬祴锛�9涓�閿晳鍔� ,10 鐔欒  11澶ф皵鍐滆��
+     * 璁惧绫诲瀷锛�0璺伅锛�1璇虹摝锛�2鍏呯數妗╋紝3澶ф皵鐩戞祴锛�
+     * 4姘磋川鐩戞祴锛�5ip闊虫煴锛�6lcd骞垮憡鏈猴紝7鎽勫儚澶达紝
+     * 8鏉嗕綋鍊炬祴锛�9涓�閿晳鍔� ,10 鐔欒  11澶ф皵鍐滆��
+     * 12鏈湴璇虹摝 13PLC
      */
     private Integer deviceType;
 
@@ -47,10 +50,10 @@
     private LocalDateTime createTime;
 
     /**
-     * 
+     *
      */
     private LocalDateTime updateTime;
 
     @TableField(exist = false)
     private static final long serialVersionUID = 1L;
-}
\ No newline at end of file
+}
diff --git a/dao/src/main/java/com/sandu/ximon/dao/enums/MenuEnum.java b/dao/src/main/java/com/sandu/ximon/dao/enums/MenuEnum.java
index 0a88c66..1523c5b 100644
--- a/dao/src/main/java/com/sandu/ximon/dao/enums/MenuEnum.java
+++ b/dao/src/main/java/com/sandu/ximon/dao/enums/MenuEnum.java
@@ -23,11 +23,15 @@
     SYSTEM_SETTINGS("绯荤粺璁剧疆"),
     CLIENT_LIST("瀹㈡埛鍒楄〃"),
     LIGHT_LIST("璺伅鍒楄〃"),
+    PLC_LIST("PLC鍒楄〃"),
     GROUP_LIST("鍒嗙粍鍒楄〃"),
     LIGHT_TASK_LIST("璺伅浠诲姟鍒楄〃"),
+    PLC_TASK_LIST("PLC浠诲姟鍒楄〃"),
     LIGHT_DATA("鍗曠伅鐩戞帶鏁版嵁"),
+    PLC_DATA("PLC鐩戞帶鏁版嵁"),
     LIGHT_SETCALENDAR("鍗曠伅璁剧疆鏃ュ巻"),
     LIGHT_ERROR_LIST("鍗曠伅鏁呴殰鍒楄〃"),
+    PLC_ERROR_LIST("PLC鏁呴殰鍒楄〃"),
     LED_LIST("LED灞忓垪琛�"),
     LED_PROGRAM_LIST("鑺傜洰鍒楄〃"),
     PLAYPLAN_LIST("鎾斁璁″垝鍒楄〃"),
@@ -106,8 +110,15 @@
     LED_FILE_S_ADD("娣诲姞鐔欐睕鏂囦欢"),
     LED_FILE_S_DELETE("鍒犻櫎鐔欐睕鏂囦欢"),
     LIGHT_REMARK("娣诲姞鍗曠伅澶囨敞"),
+    PLC_REMARK("娣诲姞PLC澶囨敞"),
     LIGHT_EXPORT_LIST("瀵煎嚭鍗曠伅鏁版嵁"),
     LIGHT_CONTROL("鍗曠伅鎺у埗"),
+    PLC_CONTROL("PLC鎺у埗"),
+    PLC_RESET("PLC鎭㈠鍑哄巶璁剧疆"),
+    PLC_REBOOT("PLC閲嶅惎"),
+    PLC_HEARTBEAT_PACKAGE_QUERY_TIME("PLC蹇冭烦鍖呴棿闅旀椂闂�"),
+    PLC_HEARTBEAT_PACKAGE_SET_TIME("璁剧疆PLC蹇冭烦鍖呴棿闅旀椂闂�"),
+    PLC_HEARTBEAT_PACKAGE("PLC蹇冭烦鍖�"),
     LIGHT_SET_POWER("璁剧疆鍗曠伅鍔熺巼"),
     LIGHT_POLE_HEELING_HEARTBEAT_PACKAGE("鐏潌鍊炬枩蹇冭烦鍖�"),
     LIGHT_POLE_HEELING_HEARTBEAT_PACKAGE_QUERY_TIME("鐏潌鍊炬枩蹇冭烦鍖呴棿闅旀椂闂�"),
@@ -122,6 +133,11 @@
     LIGHT_TASK_UPDATE("缂栬緫璺伅浠诲姟"),
     LIGHT_TASK_DETAIL("璺伅浠诲姟璇︽儏"),
     LIGHT_TASK_ISSUE("涓嬪彂璺伅浠诲姟"),
+    PLC_TASK_ADD("娣诲姞PLC浠诲姟"),
+    PLC_TASK_DELETE("鍒犻櫎PLC浠诲姟"),
+    PLC_TASK_UPDATE("缂栬緫PLC浠诲姟"),
+    PLC_TASK_DETAIL("PLC瀹氭椂浠诲姟琛ュ彂"),
+    PLC_TASK_ISSUE("涓嬪彂PLC浠诲姟"),
     MONITOR_DELETE("鍒犻櫎鎽勫儚澶�"),
     MONITOR_ADD("娣诲姞鎽勫儚澶�"),
     MONITOR_INFO("鑾峰彇鎽勫儚澶翠俊鎭�"),
@@ -234,7 +250,8 @@
     C3_REFUND("鍏呯數妗╅��娆�"),
     CHARGE_UPDATE("缂栬緫璐圭巼"),
     ORDER_LIST("璁㈠崟鍒楄〃"),
-    CHARGE_LIST("鑾峰彇璐圭巼");
+    CHARGE_LIST("鑾峰彇璐圭巼"),
+    PLC_VERSION_QUERY("PLC鐗堟湰鏌ヨ");
 
 
     private final String code;
diff --git a/dao/src/main/java/com/sandu/ximon/dao/enums/OrderByEnums.java b/dao/src/main/java/com/sandu/ximon/dao/enums/OrderByEnums.java
index 8607ab3..c5dbf36 100644
--- a/dao/src/main/java/com/sandu/ximon/dao/enums/OrderByEnums.java
+++ b/dao/src/main/java/com/sandu/ximon/dao/enums/OrderByEnums.java
@@ -134,6 +134,7 @@
      * 鍗曠伅鏁版嵁鍒楄〃
      */
     LIGHT_DATA_CREATE_TIME("t1.create_time"),
+    PLC_DATA_CREATE_TIME("t1.plc_create_time"),
 
     /**
      * 鍏呯數妗╁垪琛�
diff --git a/dao/src/main/java/com/sandu/ximon/dao/enums/PoleBindingEnums.java b/dao/src/main/java/com/sandu/ximon/dao/enums/PoleBindingEnums.java
index f571bfb..0a64916 100644
--- a/dao/src/main/java/com/sandu/ximon/dao/enums/PoleBindingEnums.java
+++ b/dao/src/main/java/com/sandu/ximon/dao/enums/PoleBindingEnums.java
@@ -64,4 +64,9 @@
      * 鍐滆��
      */
     public static final String ATMOSPHERIC_NONG_GENG = "11";
-}
\ No newline at end of file
+
+    /*
+    * plc
+    * */
+    public static final String PLC = "13";
+}
diff --git a/dao/src/main/java/com/sandu/ximon/dao/mapper/PlcMapper.java b/dao/src/main/java/com/sandu/ximon/dao/mapper/PlcMapper.java
new file mode 100644
index 0000000..039cda8
--- /dev/null
+++ b/dao/src/main/java/com/sandu/ximon/dao/mapper/PlcMapper.java
@@ -0,0 +1,46 @@
+package com.sandu.ximon.dao.mapper;
+
+import java.util.List;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sandu.ximon.dao.bo.PlcBo;
+import com.sandu.ximon.dao.domain.Plc;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * plc璺伅琛�(Plc)琛ㄦ暟鎹簱璁块棶灞�
+ *
+ * @author van
+ * @since 2022-12-15 14:45:19
+ */
+@Mapper
+public interface PlcMapper extends BaseMapper<Plc> {
+
+/**
+* 鎵归噺鏂板鏁版嵁锛圡yBatis鍘熺敓foreach鏂规硶锛�
+*
+* @param entities List<Plc> 瀹炰緥瀵硅薄鍒楄〃
+* @return 褰卞搷琛屾暟
+*/
+int insertBatch(@Param("entities") List<Plc> entities);
+
+/**
+* 鎵归噺鏂板鎴栨寜涓婚敭鏇存柊鏁版嵁锛圡yBatis鍘熺敓foreach鏂规硶锛�
+*
+* @param entities List<Plc> 瀹炰緥瀵硅薄鍒楄〃
+* @return 褰卞搷琛屾暟
+* @throws org.springframework.jdbc.BadSqlGrammarException 鍏ュ弬鏄┖List鐨勬椂鍊欎細鎶汼QL璇彞閿欒鐨勫紓甯革紝璇疯嚜琛屾牎楠屽叆鍙�
+*/
+int insertOrUpdateBatch(@Param("entities") List<Plc> entities);
+
+    List<PlcBo> listPlc(Long clientId, String keyword);
+    /**
+     * 鑾峰彇鐢ㄦ埛鎵�鎷ユ湁鐨勭伅鏉嗕笂鐨勮矾鐏痗ode
+     *
+     * @param userId
+     * @return
+     */
+    List<String> listCode(Long userId, String keyword, String deviceCode);
+}
+
diff --git a/dao/src/main/java/com/sandu/ximon/dao/mapper/PlcReportDataMapper.java b/dao/src/main/java/com/sandu/ximon/dao/mapper/PlcReportDataMapper.java
new file mode 100644
index 0000000..c5afa82
--- /dev/null
+++ b/dao/src/main/java/com/sandu/ximon/dao/mapper/PlcReportDataMapper.java
@@ -0,0 +1,19 @@
+package com.sandu.ximon.dao.mapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sandu.ximon.dao.domain.PlcReportData;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * PLC涓婃姤鏁版嵁琛�(PlcReportData)琛ㄦ暟鎹簱璁块棶灞�
+ *
+ * @author van
+ * @since 2022-12-16 10:52:56
+ */
+@Mapper
+public interface PlcReportDataMapper extends BaseMapper<PlcReportData> {
+
+    List<PlcReportData> getNewestReportByDeviceCode(List<String> deviceCodeList);
+}
+
diff --git a/dao/src/main/java/com/sandu/ximon/dao/mapper/PlcReportErrorMapper.java b/dao/src/main/java/com/sandu/ximon/dao/mapper/PlcReportErrorMapper.java
new file mode 100644
index 0000000..f07c386
--- /dev/null
+++ b/dao/src/main/java/com/sandu/ximon/dao/mapper/PlcReportErrorMapper.java
@@ -0,0 +1,22 @@
+package com.sandu.ximon.dao.mapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sandu.ximon.dao.bo.PlcReportErrorBo;
+import com.sandu.ximon.dao.domain.PlcReportError;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * plc鍗曠伅鏁呴殰鏁版嵁鍒楄〃(PlcReportError)琛ㄦ暟鎹簱璁块棶灞�
+ *
+ * @author van
+ * @since 2022-12-17 14:38:52
+ */
+@Mapper
+public interface PlcReportErrorMapper extends BaseMapper<PlcReportError> {
+
+    List<PlcReportErrorBo> listReportError(String keyword, Long error_code, Long userid);
+
+    List<PlcReportErrorBo> listError(Long userid);
+}
+
diff --git a/dao/src/main/java/com/sandu/ximon/dao/mapper/PlcTaskMapper.java b/dao/src/main/java/com/sandu/ximon/dao/mapper/PlcTaskMapper.java
new file mode 100644
index 0000000..df4e6c3
--- /dev/null
+++ b/dao/src/main/java/com/sandu/ximon/dao/mapper/PlcTaskMapper.java
@@ -0,0 +1,26 @@
+package com.sandu.ximon.dao.mapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sandu.ximon.dao.domain.LightTask;
+import com.sandu.ximon.dao.domain.PlcTask;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * plc浠诲姟琛�(PlcTask)琛ㄦ暟鎹簱璁块棶灞�
+ *
+ * @author van
+ * @since 2022-12-19 16:42:54
+ */
+@Mapper
+public interface PlcTaskMapper extends BaseMapper<PlcTask> {
+
+    List<PlcTask> listPlcTask(Long userId);
+
+    List<PlcTask> listTask(Long userId , String keyword, String orderBy);
+
+    Integer successCount(Long taskId);
+
+    Integer toTalCount(Long taskId);
+}
+
diff --git a/dao/src/main/java/com/sandu/ximon/dao/mapper/PlcTaskPoleRelationMapper.java b/dao/src/main/java/com/sandu/ximon/dao/mapper/PlcTaskPoleRelationMapper.java
new file mode 100644
index 0000000..5cdbe5a
--- /dev/null
+++ b/dao/src/main/java/com/sandu/ximon/dao/mapper/PlcTaskPoleRelationMapper.java
@@ -0,0 +1,16 @@
+package com.sandu.ximon.dao.mapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sandu.ximon.dao.domain.PlcTaskPoleRelation;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * plc浠诲姟鍜岀伅鏉嗗叧绯昏〃(PlcTaskPoleRelation)琛ㄦ暟鎹簱璁块棶灞�
+ *
+ * @author van
+ * @since 2022-12-19 16:52:24
+ */
+@Mapper
+public interface PlcTaskPoleRelationMapper extends BaseMapper<PlcTaskPoleRelation> {
+
+}
+
diff --git a/dao/src/main/resources/mapper/LedSFileMapper.xml b/dao/src/main/resources/mapper/LedSFileMapper.xml
deleted file mode 100644
index 30303cc..0000000
--- a/dao/src/main/resources/mapper/LedSFileMapper.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE mapper
-        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.sandu.ximon.dao.mapper.LedSFileMapper">
-
-    <resultMap id="BaseResultMap" type="com.sandu.ximon.dao.domain.LedSFile">
-        <id property="fileId" column="file_id" jdbcType="BIGINT"/>
-        <result property="userId" column="user_id" jdbcType="BIGINT"/>
-        <result property="cilentId" column="cilent_id" jdbcType="BIGINT"/>
-        <result property="userName" column="user_name" jdbcType="VARCHAR"/>
-        <result property="originName" column="origin_name" jdbcType="VARCHAR"/>
-        <result property="fileUrl" column="file_url" jdbcType="VARCHAR"/>
-        <result property="screenShot" column="screen_shot" jdbcType="VARCHAR"/>
-        <result property="fileType" column="file_type" jdbcType="VARCHAR"/>
-        <result property="md5" column="md5" jdbcType="VARCHAR"/>
-        <result property="fileSize" column="file_size" jdbcType="BIGINT"/>
-        <result property="height" column="height" jdbcType="INTEGER"/>
-        <result property="width" column="width" jdbcType="INTEGER"/>
-        <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
-    </resultMap>
-
-</mapper>
diff --git a/dao/src/main/resources/mapper/PlcLightMapper.xml b/dao/src/main/resources/mapper/PlcLightMapper.xml
new file mode 100644
index 0000000..5e4235d
--- /dev/null
+++ b/dao/src/main/resources/mapper/PlcLightMapper.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.sandu.ximon.dao.mapper.PlcMapper">
+
+    <resultMap type="com.sandu.ximon.dao.domain.Plc" id="BaseResultMap">
+        <result property="plcId" column="plc_light_id" jdbcType="INTEGER"/>
+        <result property="deviceCode" column="device_code" jdbcType="VARCHAR"/>
+        <result property="plcRemark" column="plc_remark" jdbcType="VARCHAR"/>
+        <result property="plcCount" column="plc_light_count" jdbcType="INTEGER"/>
+        <result property="plcLight1" column="plc_light1" jdbcType="INTEGER"/>
+        <result property="plcLight2" column="plc_light2" jdbcType="INTEGER"/>
+        <result property="plcLight3" column="plc_light3" jdbcType="INTEGER"/>
+        <result property="plcTimingControl" column="plc_timing_control" jdbcType="INTEGER"/>
+        <result property="plcSensorControl" column="plc_sensor_control" jdbcType="INTEGER"/>
+        <result property="plcSoftwareVersion" column="plc_software_version" jdbcType="VARCHAR"/>
+        <result property="plcHardwareVersion" column="plc_hardware_version" jdbcType="VARCHAR"/>
+        <result property="plcIemi" column="plc_IEMI" jdbcType="VARCHAR"/>
+        <result property="plcIccid" column="plc_ICCID" jdbcType="VARCHAR"/>
+        <result property="plcCreateTime" column="plc_create_time" jdbcType="TIMESTAMP"/>
+        <result property="plcUpdateTime" column="plc_update_time" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <select id="listPlc" resultType="com.sandu.ximon.dao.bo.PlcBo">
+        SELECT
+        t1.*,
+        t2.id AS pole_id,
+        t2.pole_code,
+        t2.pole_name,
+        t4.task_id AS task_id,
+        t4.task_name AS task_name,
+        t3.plc_address AS plc_address
+        FROM
+        plc t1
+        LEFT JOIN pole_binding t5 ON t1.device_code = t5.device_code
+        LEFT JOIN pole t2 ON t2.id=t5.pole_id AND t5.device_type=13
+        LEFT JOIN plc_task_pole_relation t3 ON t3.pole_id = t2.id
+        LEFT JOIN plc_task t4 ON t3.task_id = t4.task_id
+        <where>
+            <if test="clientId != null">
+                AND (t2.user_id = #{clientId} OR t2.client_id = #{clientId})
+            </if>
+            <if test="keyword != null and keyword != ''">
+                AND (
+                t1.device_code LIKE CONCAT('%', #{keyword},'%')
+                OR t2.pole_name LIKE CONCAT('%', #{keyword},'%')
+                )
+            </if>
+        </where>
+
+    </select>
+
+    <select id="listCode" resultType="java.lang.String">
+        SELECT
+        t1.device_code
+        FROM
+        plc t1
+        LEFT JOIN pole t2 ON t1.device_code = t2.device_code
+        <where>
+            <if test="userId != null">
+                AND (t2.user_id = #{userId} OR t2.client_id = #{userId})
+            </if>
+            <if test="keyword != null and keyword != ''">
+                AND (
+                t1.device_code LIKE CONCAT('%', #{keyword},'%')
+                OR t2.pole_name LIKE CONCAT('%', #{keyword},'%')
+                )
+            </if>
+            <if test="deviceCode != null and deviceCode!= ''">
+                AND t1.device_code = #{deviceCode}
+            </if>
+        </where>
+
+    </select>
+
+</mapper>
+
diff --git a/dao/src/main/resources/mapper/PlcReportDataMapper.xml b/dao/src/main/resources/mapper/PlcReportDataMapper.xml
new file mode 100644
index 0000000..d8bcbe3
--- /dev/null
+++ b/dao/src/main/resources/mapper/PlcReportDataMapper.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.sandu.ximon.dao.mapper.PlcReportDataMapper">
+
+    <resultMap type="com.sandu.ximon.dao.domain.PlcReportData" id="plcReportDataMap">
+        <result property="reportDataId" column="report_data_id"/>
+        <result property="deviceCode" column="device_code"/>
+        <result property="deviceTemperature" column="device_temperature"/>
+        <result property="phase" column="phase"/>
+        <result property="voltageA" column="voltage_A"/>
+        <result property="voltageB" column="voltage_B"/>
+        <result property="voltageC" column="voltage_C"/>
+        <result property="electricCurrentA" column="electric_current_A"/>
+        <result property="electricCurrentB" column="electric_current_B"/>
+        <result property="electricCurrentC" column="electric_current_C"/>
+        <result property="activePowerAll" column="active_power_All"/>
+        <result property="activePowerA" column="active_power_A"/>
+        <result property="activePowerB" column="active_power_B"/>
+        <result property="activePowerC" column="active_power_C"/>
+        <result property="reactivePowerAll" column="reactive_power_All"/>
+        <result property="reactivePowerA" column="reactive_power_A"/>
+        <result property="reactivePowerB" column="reactive_power_B"/>
+        <result property="reactivePowerC" column="reactive_power_C"/>
+        <result property="apparentPowerAll" column="apparent_power_All"/>
+        <result property="apparentPowerA" column="apparent_power_A"/>
+        <result property="apparentPowerB" column="apparent_power_B"/>
+        <result property="apparentPowerC" column="apparent_power_C"/>
+        <result property="powerFactorAll" column="power_factor_All"/>
+        <result property="powerFactorA" column="power_factor_A"/>
+        <result property="powerFactorB" column="power_factor_B"/>
+        <result property="powerFactorC" column="power_factor_C"/>
+        <result property="totalPositiveUsingPower" column="total_positive_using_power"/>
+        <result property="totalReverseUsingPower" column="total_reverse_using_power"/>
+        <result property="lightIntensity" column="light_intensity"/>
+        <result property="control1" column="control_1"/>
+        <result property="status1" column="status_1"/>
+        <result property="control2" column="control_2"/>
+        <result property="status2" column="status_2"/>
+        <result property="control3" column="control_3"/>
+        <result property="status3" column="status_3"/>
+        <result property="controlN" column="control_n"/>
+        <result property="statusN" column="status_n"/>
+        <result property="createTime1" column="create_time1"/>
+        <result property="updateTime1" column="update_time1"/>
+    </resultMap>
+    <select id="getNewestReportByDeviceCode" resultMap="plcReportDataMap"
+            >
+        SELECT
+        t1.*
+        FROM
+        plc_report_data t1
+        JOIN (
+        SELECT
+        MAX( report_data_id ) AS report_data_id
+        FROM
+        plc_report_data
+        WHERE device_code IN
+        <foreach collection="deviceCodeList" open="(" close=")" separator="," item="deviceCode">
+            #{deviceCode}
+        </foreach>
+        GROUP BY device_code
+        ) AS t2 USING ( report_data_id )
+
+    </select>
+
+
+</mapper>
+
+
diff --git a/dao/src/main/resources/mapper/PlcReportErrorMapper.xml b/dao/src/main/resources/mapper/PlcReportErrorMapper.xml
new file mode 100644
index 0000000..951e119
--- /dev/null
+++ b/dao/src/main/resources/mapper/PlcReportErrorMapper.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.sandu.ximon.dao.mapper.PlcReportErrorMapper">
+
+    <resultMap type="com.sandu.ximon.dao.domain.PlcReportError" id="BaseResultMap">
+        <result property="plcReportErrorId" column="plc_report_error_id" jdbcType="INTEGER"/>
+        <result property="plcDeviceCode" column="plc_device_code" jdbcType="VARCHAR"/>
+        <result property="plcAddress" column="plc_address" jdbcType="VARCHAR"/>
+        <result property="errorCode" column="error_code" jdbcType="BIGINT"/>
+        <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+        <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
+    </resultMap>
+    <resultMap id="listReportError" type="com.sandu.ximon.dao.bo.PlcReportErrorBo" extends="BaseResultMap">
+        <result property="poleName" column="pole_name" jdbcType="VARCHAR"/>
+    </resultMap>
+
+    <select id="listReportError" resultType="com.sandu.ximon.dao.bo.PlcReportErrorBo">
+        SELECT
+        t1.*,
+        t3.pole_name,
+        t3.id
+        FROM
+        plc_report_error t1
+        LEFT JOIN pole_binding t2 ON t1.plc_device_code = t2.device_code
+        AND t2.device_type = 13
+        LEFT JOIN pole t3 ON t3.id = t2.pole_id
+        <where>
+            t1.error_code != 0
+            <if test="keyword != null and keyword != ''">
+                AND (
+                t3.id LIKE CONCAT('%', #{keyword},'%')
+                OR t3.pole_name LIKE CONCAT('%', #{keyword},'%')
+                OR t1.plc_device_code LIKE CONCAT('%', #{keyword},'%')
+                )
+            </if>
+            <if test="userid != null">
+                AND (t3.user_id = #{userid} OR t3.client_id = #{userid})
+            </if>
+            <if test="error_code != null">
+                AND t1.error_code = #{error_code}
+            </if>
+        </where>
+        ORDER BY t1.plc_report_error_id DESC
+
+    </select>
+    <select id="listError" resultType="com.sandu.ximon.dao.bo.PlcReportErrorBo" parameterType="java.lang.Long">
+        SELECT
+        t1.*
+        FROM
+        plc_report_error t1
+        LEFT JOIN pole t3 ON t1.plc_device_code = t3.device_code
+        WHERE
+        t1.plc_report_error_id IN ( SELECT t.max_id FROM ( SELECT Max( plc_report_error.plc_report_error_id ) AS
+        max_id FROM plc_report_error GROUP BY plc_report_error.plc_device_code ) AS t )
+        <if test="userid != null">
+            AND  t3.client_id = #{userId} OR t3.user_id = #{userId}
+        </if>
+        ORDER BY
+        t1.create_time DESC
+    </select>
+
+
+</mapper>
+
diff --git a/dao/src/main/resources/mapper/PlcTaskDao.xml b/dao/src/main/resources/mapper/PlcTaskDao.xml
new file mode 100644
index 0000000..4b3acd4
--- /dev/null
+++ b/dao/src/main/resources/mapper/PlcTaskDao.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.sandu.ximon.dao.mapper.PlcTaskMapper">
+
+    <resultMap type="com.sandu.ximon.dao.domain.PlcTask" id="PlcTaskMap">
+        <result property="taskId" column="task_id" jdbcType="INTEGER"/>
+        <result property="userId" column="user_id" jdbcType="INTEGER"/>
+        <result property="clientId" column="client_id" jdbcType="INTEGER"/>
+        <result property="taskName" column="task_name" jdbcType="VARCHAR"/>
+        <result property="pause" column="pause" jdbcType="INTEGER"/>
+        <result property="plcAdress" column="plc_adress" jdbcType="VARCHAR"/>
+        <result property="week" column="week" jdbcType="INTEGER"/>
+        <result property="openOrder" column="open_order" jdbcType="VARCHAR"/>
+        <result property="closeOrder" column="close_order" jdbcType="VARCHAR"/>
+        <result property="controlOrder" column="control_order" jdbcType="VARCHAR"/>
+        <result property="framePayload" column="frame_payload" jdbcType="VARCHAR"/>
+        <result property="createUser" column="create_user" jdbcType="VARCHAR"/>
+        <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+        <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <!-- 鎵归噺鎻掑叆 -->
+    <insert id="insertBatch" keyProperty="taskId" useGeneratedKeys="true">
+        insert into xm_dev.plc_task(user_id, client_id, task_name, pause, plc_adress, week, open_order, close_order, control_order, frame_payload, create_user, create_time, update_time)
+        values
+        <foreach collection="entities" item="entity" separator=",">
+        (#{entity.userId}, #{entity.clientId}, #{entity.taskName}, #{entity.pause}, #{entity.plcAdress}, #{entity.week}, #{entity.openOrder}, #{entity.closeOrder}, #{entity.controlOrder}, #{entity.framePayload}, #{entity.createUser}, #{entity.createTime}, #{entity.updateTime})
+        </foreach>
+    </insert>
+    <!-- 鎵归噺鎻掑叆鎴栨寜涓婚敭鏇存柊 -->
+    <insert id="insertOrUpdateBatch" keyProperty="taskId" useGeneratedKeys="true">
+        insert into xm_dev.plc_task(user_id, client_id, task_name, pause, plc_adress, week, open_order, close_order, control_order, frame_payload, create_user, create_time, update_time)
+        values
+        <foreach collection="entities" item="entity" separator=",">
+            (#{entity.userId}, #{entity.clientId}, #{entity.taskName}, #{entity.pause}, #{entity.plcAdress}, #{entity.week}, #{entity.openOrder}, #{entity.closeOrder}, #{entity.controlOrder}, #{entity.framePayload}, #{entity.createUser}, #{entity.createTime}, #{entity.updateTime})
+        </foreach>
+        on duplicate key update
+         user_id = values(user_id) , client_id = values(client_id) , task_name = values(task_name) , pause = values(pause) , plc_adress = values(plc_adress) , week = values(week) , open_order = values(open_order) , close_order = values(close_order) , control_order = values(control_order) , frame_payload = values(frame_payload) , create_user = values(create_user) , create_time = values(create_time) , update_time = values(update_time)     </insert>
+
+    <select id="listPlcTask" resultType="com.sandu.ximon.dao.domain.PlcTask"
+            parameterType="java.lang.Long">
+            SELECT t1.*
+            FROM plc_task t1
+            LEFT JOIN plc_task_pole_relation t2 ON t1.task_id = t2.task_id
+            LEFT JOIN pole t3 ON t2.pole_id = t3.id
+            WHERE t2.issue_status = 0
+            <if test="userid != null">
+                AND (t3.user_id = #{userid} OR t3.client_id = #{userid})
+            </if>
+
+    </select>
+    <select id="listTask" resultType="com.sandu.ximon.dao.domain.PlcTask">
+        SELECT
+        t1.*
+        FROM
+        plc_task t1
+        LEFT JOIN plc_task_pole_relation t2 ON t1.task_id = t2.task_id
+        LEFT JOIN pole t3 ON t3.id = t2.pole_id
+        LEFT JOIN pole_binding t4 ON t3.id = t4.pole_id
+        LEFT JOIN plc t5 ON t5.device_code = t4.device_code
+        WHERE
+        1=1
+        <if test="keyword != null and keyword != ''">
+            AND ( t1.task_name LIKE CONCAT(CONCAT('%', #{keyword}), '%') OR t5.device_code LIKE CONCAT(CONCAT('%',
+            #{keyword}), '%'))
+        </if>
+        <if test="userId != null">
+            AND ( t1.client_id =#{userId} OR t1.user_id =#{userId} )
+        </if>
+        GROUP BY
+        task_id
+        ORDER BY
+        t1.${orderBy}
+    </select>
+
+    <select id="successCount" resultType="java.lang.Integer">
+        SELECT count(*)
+        FROM plc_task t1
+                 LEFT JOIN plc_task_pole_relation t2 ON t1.task_id = t2.task_id
+        WHERE t1.task_id = #{taskId}
+    </select>
+
+    <select id="toTalCount" resultType="java.lang.Integer">
+        SELECT count(*)
+        FROM plc_task t1
+                 LEFT JOIN plc_task_pole_relation t2 ON t1.task_id = t2.task_id
+        WHERE t1.task_id = #{taskId}
+    </select>
+
+</mapper>
+
diff --git a/sandu-common/src/main/resources/logback-spring.xml b/sandu-common/src/main/resources/logback-spring.xml
index a64bb41..664d1f9 100644
--- a/sandu-common/src/main/resources/logback-spring.xml
+++ b/sandu-common/src/main/resources/logback-spring.xml
@@ -74,8 +74,13 @@
         </root>
     </springProfile>
 
+    <springProfile name="xm_local">
+        <root level="info" >
+            <appender-ref ref="STDOUT"/>
+        </root>
+    </springProfile>
     <!-- 鐢熶骇鐜. 鏃ュ織绾у埆涓篧ARN涓斿啓鏃ュ織鏂囦欢-->
-    <springProfile name="prod,docker">
+    <springProfile name="prod,docker,xm_lj">
         <root level="warn">
             <appender-ref ref="STDOUT"/>
             <appender-ref ref="ASYNC"/>
diff --git a/ximon-admin/pom.xml b/ximon-admin/pom.xml
index 046861c..e71cd2c 100644
--- a/ximon-admin/pom.xml
+++ b/ximon-admin/pom.xml
@@ -105,6 +105,11 @@
                 </exclusion>
             </exclusions>
         </dependency>
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-annotations</artifactId>
+            <version>1.6.2</version>
+        </dependency>
     </dependencies>
 
 
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcController.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcController.java
new file mode 100644
index 0000000..0430381
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcController.java
@@ -0,0 +1,201 @@
+package com.sandu.ximon.admin.controller;
+
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.api.ApiController;
+import com.baomidou.mybatisplus.extension.api.R;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.sandu.common.domain.CommonPage;
+import com.sandu.common.domain.ResponseVO;
+import com.sandu.common.object.BaseConditionVO;
+import com.sandu.common.util.ResponseUtil;
+import com.sandu.ximon.admin.param.LightControlParam;
+import com.sandu.ximon.admin.param.LightRemarkParam;
+import com.sandu.ximon.admin.param.PlcControlParam;
+import com.sandu.ximon.admin.param.PlcRemarkParam;
+import com.sandu.ximon.admin.security.PermissionConfig;
+import com.sandu.ximon.admin.service.PlcReportDataService;
+import com.sandu.ximon.admin.service.PlcReportErrorService;
+import com.sandu.ximon.admin.service.PlcService;
+import com.sandu.ximon.dao.bo.*;
+import com.sandu.ximon.dao.domain.LightReportData;
+import com.sandu.ximon.dao.domain.Plc;
+import com.sandu.ximon.dao.domain.PlcReportData;
+import com.sandu.ximon.dao.domain.PlcReportError;
+import com.sandu.ximon.dao.enums.MenuEnum;
+import lombok.AllArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * plc璺伅琛�(Plc)琛ㄦ帶鍒跺眰
+ *
+ * @author van
+ * @since 2022-12-15 14:45:18
+ */
+@AllArgsConstructor
+@RestController
+@RequestMapping("plc")
+public class PlcController {
+
+    private final PlcService plcService;
+
+    private final PlcReportDataService plcReportDataService;
+
+    private final PlcReportErrorService plcReportErrorService;
+    private final PermissionConfig permissionConfig;
+
+    @GetMapping("list")
+    public ResponseVO<Object> selectAll(BaseConditionVO conditionVO,
+                                        @RequestParam(value = "keyword", required = false) String keyword,
+                                        @RequestParam(value = "order", required = false) Integer order,
+                                        @RequestParam(value = "seq", required = false) Integer seq) {
+        if (!permissionConfig.check(MenuEnum.PLC_LIST.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+        List<PlcBo> plcBos = plcService.listPlc(conditionVO.getPageNo(), conditionVO.getPageSize(), keyword, order, seq);
+
+        return ResponseUtil.successPage(plcBos);
+    }
+
+    @PostMapping("/remark")
+    public ResponseVO<Object> addRemark(@RequestBody @Validated PlcRemarkParam param) {
+        if (!permissionConfig.check(MenuEnum.PLC_REMARK.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+        boolean result = plcService.addRemark(param);
+        if (result) {
+            return ResponseUtil.success("娣诲姞鎴愬姛");
+        } else {
+            return ResponseUtil.fail("娣诲姞澶辫触");
+        }
+    }
+
+    /**
+     * 鑾峰彇涓婃姤鏁版嵁
+     *
+     * @param conditionVO
+     * @return
+     */
+    @GetMapping("/report/list")
+    public ResponseVO<Object> listReportData(BaseConditionVO conditionVO
+            , @RequestParam(value = "keyword", required = false) String keyword
+            , @RequestParam(value = "deviceCode", required = false) String deviceCode
+            , @RequestParam(value = "order", required = false) Integer order
+            ,@RequestParam(value = "seq", required = false) Integer seq) {
+        if (!permissionConfig.check(MenuEnum.PLC_DATA.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+        CommonPage commonPage = plcReportDataService.listReportData(conditionVO.getPageNo(), conditionVO.getPageSize(), keyword, deviceCode,order,seq);
+        List<PlcReportDataBo> plcReportDataBos = (List<PlcReportDataBo>) commonPage.getList();
+
+        if (plcReportDataBos == null) {
+            return ResponseUtil.success(CommonPage.restPage(new ArrayList<>()));
+        }
+        CommonPage commonPage1 = CommonPage.restPage(plcReportDataBos);
+        commonPage1.setTotal(commonPage.getTotal());
+        commonPage1.setTotalPage(commonPage.getTotalPage());
+
+        return ResponseUtil.success(commonPage1);
+    }
+
+    @GetMapping("/error/list")
+    public ResponseVO<Object> listReportError(BaseConditionVO conditionVO, @RequestParam(value = "keyword", required = false) String keyword
+            , @RequestParam(value = "errorCode", required = false) Long errorCode) {
+        if (!permissionConfig.check(MenuEnum.PLC_ERROR_LIST.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+        List<PlcReportErrorBo> list = plcReportErrorService.listReportError(conditionVO.getPageNo(), conditionVO.getPageSize(), keyword, errorCode);
+        return ResponseUtil.success(list);
+    }
+
+    @GetMapping("/data/list")
+    public ResponseVO<Object> listData(BaseConditionVO conditionVO, @RequestParam(value = "deviceCode", required = false) String deviceCode) {
+        if (!permissionConfig.check(MenuEnum.PLC_DATA.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+        List<PlcReportData> reportDataList = plcReportDataService.getReportDataList(conditionVO, deviceCode);
+
+        return ResponseUtil.success(reportDataList);
+    }
+    // 浜害鎺у埗
+    @PostMapping("/control")
+    public ResponseVO<Object> controlBrightness(@RequestBody @Validated List<PlcControlParam> paramList) {
+        if (!permissionConfig.check(MenuEnum.PLC_CONTROL.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+        List<Map<String, Object>> list = plcService.controlBrightness(paramList);
+        return ResponseUtil.success(list);
+    }
+
+    // 璁剧疆蹇冭烦鏃堕棿
+    @PostMapping("/setHeartBeatTime")
+    public ResponseVO<Object> setHeartBeatTime(@RequestBody @Validated List<PlcControlParam> paramList) {
+        if (!permissionConfig.check(MenuEnum.PLC_HEARTBEAT_PACKAGE_SET_TIME.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+        List<Map<String, Object>> list = plcService.setHeartBeatTime(paramList);
+        return ResponseUtil.success(list);
+    }
+
+    // 鏌ヨ蹇冭烦鏃堕棿
+    @PostMapping("/queryHeartBeatTime")
+    public ResponseVO<Object> queryHeartBeatTime(@RequestBody @Validated List<PlcControlParam> paramList) {
+        if (!permissionConfig.check(MenuEnum.PLC_HEARTBEAT_PACKAGE_QUERY_TIME.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+        List<Map<String, Object>> list = plcService.queryHeartBeatTime(paramList);
+        return ResponseUtil.success(list);
+    }
+
+    // 鏌ヨ蹇冭烦
+    @PostMapping("/queryHeartBeatData")
+    public ResponseVO<Object> queryHeartBeatData(@RequestBody @Validated List<PlcControlParam> paramList) {
+        if (!permissionConfig.check(MenuEnum.PLC_HEARTBEAT_PACKAGE.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+        List<Map<String, Object>> list = plcService.queryHeartBeatData(paramList);
+        return ResponseUtil.success(list);
+    }
+
+    // 鏌ヨ蹇冭烦
+    @PostMapping("/queryVersion")
+    public ResponseVO<Object> queryVersion(@RequestBody @Validated List<PlcControlParam> paramList) {
+        if (!permissionConfig.check(MenuEnum.PLC_VERSION_QUERY.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+        List<Map<String, Object>> list = plcService.queryVersion(paramList);
+        return ResponseUtil.success(list);
+    }
+
+    // 閲嶅惎
+    @PostMapping("/reboot")
+    public ResponseVO<Object> reboot(@RequestBody @Validated List<PlcControlParam> paramList) {
+        if (!permissionConfig.check(MenuEnum.PLC_REBOOT.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+        List<Map<String, Object>> list = plcService.reboot(paramList);
+        return ResponseUtil.success(list);
+    }
+
+    // 鎭㈠鍑哄巶璁剧疆
+    @PostMapping("/reset")
+    public ResponseVO<Object> reset(@RequestBody @Validated List<PlcControlParam> paramList) {
+        if (!permissionConfig.check(MenuEnum.PLC_RESET.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+        List<Map<String, Object>> list = plcService.reset(paramList);
+        return ResponseUtil.success(list);
+    }
+
+
+
+}
+
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcReportDataController.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcReportDataController.java
new file mode 100644
index 0000000..21e12fe
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcReportDataController.java
@@ -0,0 +1,34 @@
+package com.sandu.ximon.admin.controller;
+
+
+
+import cn.hutool.db.PageResult;
+import com.baomidou.mybatisplus.extension.api.R;
+import com.sandu.ximon.admin.service.PlcReportDataService;
+import com.sandu.ximon.dao.domain.PlcReportData;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.Serializable;
+
+/**
+ * PLC涓婃姤鏁版嵁琛�(PlcReportData)琛ㄦ帶鍒跺眰
+ *
+ * @author van
+ * @since 2022-12-16 10:54:58
+ */
+@Api(tags = "PLC涓婃姤鏁版嵁琛�(plcReportData)" , value = "PLC涓婃姤鏁版嵁琛�(PlcReportData)")
+@RestController
+@RequestMapping("/admin/plcReportData")
+public class PlcReportDataController {
+    /**
+     * 鏈嶅姟瀵硅薄
+     */
+    @Autowired
+    private PlcReportDataService plcReportDataService;
+
+
+}
+
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcTaskController.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcTaskController.java
new file mode 100644
index 0000000..8454c85
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcTaskController.java
@@ -0,0 +1,142 @@
+package com.sandu.ximon.admin.controller;
+
+import com.sandu.common.domain.ResponseVO;
+import com.sandu.common.execption.BusinessException;
+import com.sandu.common.object.BaseConditionVO;
+import com.sandu.common.util.ResponseUtil;
+import com.sandu.ximon.admin.dto.LightTaskDto;
+import com.sandu.ximon.admin.dto.PlcTaskDto;
+import com.sandu.ximon.admin.param.*;
+import com.sandu.ximon.admin.security.PermissionConfig;
+import com.sandu.ximon.admin.service.LightEnergyDataService;
+import com.sandu.ximon.admin.service.LightTaskService;
+import com.sandu.ximon.admin.service.PlcTaskService;
+import com.sandu.ximon.dao.enums.MenuEnum;
+import lombok.AllArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * Plc浠诲姟鐩稿叧鎺у埗绫�
+ *
+ * @author van
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/plc/task")
+public class PlcTaskController {
+
+    private final PlcTaskService plcTaskService;
+    private PermissionConfig permissionConfig;
+
+    @PostMapping("/add")
+    public ResponseVO<Object> addPlcTask(@RequestBody @Validated PlcTaskParam param) {
+        if (!permissionConfig.check(MenuEnum.PLC_TASK_ADD.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+        return ResponseUtil.success(plcTaskService.AddPlcTask(param));
+    }
+
+
+    @GetMapping("/list")
+    public ResponseVO<Object> listPlcTask(BaseConditionVO conditionVO,
+                                            @RequestParam(value = "keyword", required = false) String keyword,
+                                            @RequestParam(value = "order", required = false) Integer order,
+                                            @RequestParam(value = "seq", required = false) Integer seq) {
+        if (!permissionConfig.check(MenuEnum.PLC_TASK_LIST.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+        List<PlcTaskDto> taskList = plcTaskService.listPlcTask(conditionVO, keyword, order, seq);
+        return ResponseUtil.successPage(taskList);
+    }
+
+    @PostMapping("/del")
+    public ResponseVO<Object> delPlcTask(@RequestBody @Validated PlcTaskDelParam param) {
+        if (!permissionConfig.check(MenuEnum.PLC_TASK_DELETE.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+        String result = plcTaskService.delPlcTask(param.getTaskId());
+        return ResponseUtil.success(result);
+
+    }
+
+    @PostMapping("/update/{taskId}")
+    public ResponseVO<Object> updatePlcTask(@PathVariable Long taskId, @RequestBody @Validated PlcTaskParam param) {
+        if (!permissionConfig.check(MenuEnum.PLC_TASK_UPDATE.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+        String result = plcTaskService.newUpdatePlcTask(taskId, param);
+        return ResponseUtil.success(result);
+
+    }
+
+//
+//    /**
+//     * 娓呴櫎浠诲姟
+//     *
+//     * @param
+//     * @return
+//     */
+////    @PostMapping("/clear")
+////    public ResponseVO<Object> clearLightTask(@RequestBody List<Long> poleIds) {
+////        if (!permissionConfig.check(MenuEnum.PLC_TASK_UPDATE.getCode())) {
+////            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+////        }
+////        boolean result = plcTaskService.clearLightTask(poleIds);
+////        return ResponseUtil.success(result);
+////    }
+    @GetMapping("/{taskId}")
+    public ResponseVO<Object> detailPlcTask(@PathVariable Long taskId) {
+        if (!permissionConfig.check(MenuEnum.PLC_TASK_DETAIL.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+
+        return ResponseUtil.success(plcTaskService.detailPlcTask(taskId));
+    }
+
+    /**
+     * 鍗曠伅涓嬪彂
+     *
+     * @param param
+     * @return
+     */
+    @PostMapping("/issue")
+    public ResponseVO<Object> issueLightTask(@RequestBody @Validated PlcTaskIssueParam param) {
+        if (!permissionConfig.check(MenuEnum.PLC_TASK_ISSUE.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+        boolean result = plcTaskService.issuePlcTask(param);
+        if (result) {
+            return ResponseUtil.success("涓嬪彂鎴愬姛");
+        } else {
+            return ResponseUtil.fail("涓嬪彂澶辫触");
+        }
+    }
+//
+//
+//    @PostMapping("/energy")
+//    public ResponseVO<Object> energy() {
+//
+//
+//        plcTaskService.energy();
+//        return ResponseUtil.success("lightEnergyDataService.energy(0)");
+//    }
+//
+//
+    @PostMapping("/check")
+    public ResponseVO<Object> checkTask(@RequestBody PlcTaskParam param) {
+        if (!permissionConfig.check(MenuEnum.PLC_TASK_UPDATE.getCode())) {
+            return ResponseUtil.fail("缂哄皯瀵瑰簲鐢ㄦ埛鏉冮檺");
+        }
+        if (!"0001".equals(param.getPlcAddress())
+                && !"0002".equals(param.getPlcAddress())
+                    && !"0003".equals(param.getPlcAddress())) {
+            throw new BusinessException("鐏ご鍦板潃鏍煎紡涓嶆纭�");
+        }
+        return ResponseUtil.success(plcTaskService.checkTask(param));
+
+    }
+
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcTaskPoleRelationController.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcTaskPoleRelationController.java
new file mode 100644
index 0000000..dd5910f
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcTaskPoleRelationController.java
@@ -0,0 +1,88 @@
+package com.sandu.ximon.admin.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.api.ApiController;
+import com.baomidou.mybatisplus.extension.api.R;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.sandu.ximon.admin.service.PlcTaskPoleRelationService;
+import com.sandu.ximon.dao.domain.PlcTaskPoleRelation;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * plc浠诲姟鍜岀伅鏉嗗叧绯昏〃(PlcTaskPoleRelation)琛ㄦ帶鍒跺眰
+ *
+ * @author van
+ * @since 2022-12-19 16:54:14
+ */
+@AllArgsConstructor
+@RestController
+@RequestMapping("plcTaskPoleRelation")
+public class PlcTaskPoleRelationController extends ApiController {
+    /**
+     * 鏈嶅姟瀵硅薄
+     */
+    private final PlcTaskPoleRelationService plcTaskPoleRelationService;
+
+    /**
+     * 鍒嗛〉鏌ヨ鎵�鏈夋暟鎹�
+     *
+     * @param page 鍒嗛〉瀵硅薄
+     * @param plcTaskPoleRelation 鏌ヨ瀹炰綋
+     * @return 鎵�鏈夋暟鎹�
+     */
+    @GetMapping
+    public R selectAll(Page<PlcTaskPoleRelation> page, PlcTaskPoleRelation plcTaskPoleRelation) {
+        return success(this.plcTaskPoleRelationService.page(page, new QueryWrapper<>(plcTaskPoleRelation)));
+    }
+
+    /**
+     * 閫氳繃涓婚敭鏌ヨ鍗曟潯鏁版嵁
+     *
+     * @param id 涓婚敭
+     * @return 鍗曟潯鏁版嵁
+     */
+    @GetMapping("{id}")
+    public R selectOne(@PathVariable Serializable id) {
+        return success(this.plcTaskPoleRelationService.getById(id));
+    }
+
+    /**
+     * 鏂板鏁版嵁
+     *
+     * @param plcTaskPoleRelation 瀹炰綋瀵硅薄
+     * @return 鏂板缁撴灉
+     */
+    @PostMapping
+    public R insert(@RequestBody PlcTaskPoleRelation plcTaskPoleRelation) {
+        return success(this.plcTaskPoleRelationService.save(plcTaskPoleRelation));
+    }
+
+    /**
+     * 淇敼鏁版嵁
+     *
+     * @param plcTaskPoleRelation 瀹炰綋瀵硅薄
+     * @return 淇敼缁撴灉
+     */
+    @PutMapping
+    public R update(@RequestBody PlcTaskPoleRelation plcTaskPoleRelation) {
+        return success(this.plcTaskPoleRelationService.updateById(plcTaskPoleRelation));
+    }
+
+    /**
+     * 鍒犻櫎鏁版嵁
+     *
+     * @param idList 涓婚敭缁撳悎
+     * @return 鍒犻櫎缁撴灉
+     */
+    @DeleteMapping
+    public R delete(@RequestParam("idList") List<Long> idList) {
+        return success(this.plcTaskPoleRelationService.removeByIds(idList));
+    }
+}
+
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PoleController.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PoleController.java
index b7a59ec..60a29fa 100644
--- a/ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PoleController.java
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PoleController.java
@@ -171,9 +171,11 @@
         }
         boolean result = poleService.bindPole(poleId, param);
         if (result) {
-            //璁惧绫诲瀷锛�0璺伅锛�1nove锛�2鍏呯數妗╋紝3澶ф皵鐩戞祴锛�4姘磋川鐩戞祴锛�5ip闊虫煴锛�6lcd骞垮憡鏈猴紝7鎽勫儚澶达紝8鏉嗕綋鍊炬祴锛�9涓�閿晳鍔�, 10鐔欒, 11鍐滆��
+            //璁惧绫诲瀷锛�0璺伅锛�1nove锛�2鍏呯數妗╋紝3澶ф皵鐩戞祴锛�4姘磋川鐩戞祴锛�5ip闊虫煴锛�6lcd骞垮憡鏈猴紝7鎽勫儚澶达紝8鏉嗕綋鍊炬祴锛�
+            // 9涓�閿晳鍔�, 10鐔欒, 11鍐滆��,12鏈湴璇虹摝锛�13PLC
             switch (param.getDeviceType().toString()) {
                 case PoleBindingEnums.LIGHT:
+                case PoleBindingEnums.PLC:
                     Pole pole = poleService.getById(poleId);
                     if (pole != null) {
                         pole.setPoleName(param.getDeviceName());
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/dto/PlcTaskDto.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/dto/PlcTaskDto.java
new file mode 100644
index 0000000..3b15f35
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/dto/PlcTaskDto.java
@@ -0,0 +1,31 @@
+package com.sandu.ximon.admin.dto;
+
+import com.sandu.ximon.dao.domain.LightTask;
+import com.sandu.ximon.dao.domain.PlcTask;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author van
+ */
+@Data
+public class PlcTaskDto extends PlcTask {
+
+    private List<Integer> weekList;
+
+    /**
+     * 鍚屾鐘舵��
+     */
+    private String syncStatus;
+
+    /**
+     * 鐏ご1鏄惁鎵ц
+     */
+//    private Boolean light1 = false;
+
+    /**
+     * 鐏ご2鏄惁鎵ц
+     */
+//    private Boolean light2 = false;
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/amqp/AmqpMessageListener.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/amqp/AmqpMessageListener.java
index 75a9dbc..b753cdc 100644
--- a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/amqp/AmqpMessageListener.java
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/amqp/AmqpMessageListener.java
@@ -2,19 +2,14 @@
 
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.sandu.ximon.admin.manager.iot.amqp.processor.AirDataProcessor;
-import com.sandu.ximon.admin.manager.iot.amqp.processor.LightDataProcessor;
-import com.sandu.ximon.admin.manager.iot.amqp.processor.PoleMonitorDataProcessor;
-import com.sandu.ximon.admin.manager.iot.amqp.processor.c3ChargingProcessor;
+import com.sandu.ximon.admin.manager.iot.amqp.processor.*;
 import com.sandu.ximon.admin.manager.iot.frame.inner.report.A5AtmosphereHeartbeatReportInnerFrame;
 import com.sandu.ximon.admin.manager.iot.frame.inner.report.A5C3CommonReportInnerFrame;
 import com.sandu.ximon.admin.manager.iot.frame.inner.report.A5C3ErrorCodeReportInnerFrame;
 import com.sandu.ximon.admin.manager.iot.frame.inner.report.A5C3HeartbeatReportInnerFrame;
 import com.sandu.ximon.admin.manager.iot.rrpc.dto.CommonFrame;
 import com.sandu.ximon.admin.manager.iot.rrpc.dto.CommonReportMessage;
-import com.sandu.ximon.admin.manager.iot.rrpc.enums.A5OrderEnum;
-import com.sandu.ximon.admin.manager.iot.rrpc.enums.C3ChargingEnum;
-import com.sandu.ximon.admin.manager.iot.rrpc.enums.C3mRedisConstant;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.*;
 import com.sandu.ximon.admin.manager.iot.rrpc.util.FrameUtils;
 import com.sandu.ximon.admin.service.C3ChargingService;
 import com.sandu.ximon.admin.service.C3mOrderService;
@@ -48,8 +43,8 @@
 
 
     protected final static ExecutorService EXECUTOR_SERVICE = new ThreadPoolExecutor(
-            Runtime.getRuntime().availableProcessors(),
-            Runtime.getRuntime().availableProcessors() * 2, 60, TimeUnit.SECONDS,
+            Runtime.getRuntime().availableProcessors()  * 2,
+            Runtime.getRuntime().availableProcessors() * 4, 60, TimeUnit.SECONDS,
             new LinkedBlockingQueue<>(50000), new NameTreadFactory());
 
     static class NameTreadFactory implements ThreadFactory {
@@ -79,8 +74,8 @@
             String topic = message.getStringProperty("topic");
             String messageId = message.getStringProperty("messageId");
 
-            log.info("鏀跺埌璁㈤槄" + topic + "," + messageId);
-            log.info(content);
+//            log.info("鏀跺埌璁㈤槄" + topic + "," + messageId);
+//            log.info(content);
 
             if (null != map.get("status")) {
                 // 涓婁笅绾夸笂鎶ュ鐞�
@@ -111,19 +106,32 @@
         if (frame == null) {
             return;
         }
-        log.info("澶勭悊璁㈤槄");
-        log.info(frame.toString());
-        if (frame.getOrderType().equals(A5OrderEnum.RESPONSE_LIGHT_DATA.getCode())) {
-            // 鍗曠伅鏁版嵁涓婃姤澶勭悊
-            LightDataProcessor.getInstance().process(productKey, deviceName, frame);
-        } else if (frame.getOrderType().equals(A5OrderEnum.RESPONSE_C3_DATA.getCode())) {
-            // C3鍏呯數妗╀笂鎶ュ鐞�
-            c3ChargingProcessor.c3ChargingProcessorgetInstance().process(productKey, deviceName, frame);
-        } else if (frame.getOrderType().equals(A5OrderEnum.RESPONSE_ATMOSPHERE_DATA.getCode())) {
-            // 澶ф皵鏁版嵁鎸囦护涓婃姤
-            AirDataProcessor.getInstance().process(productKey, deviceName, frame);
-        } else if (frame.getOrderType().equals(A5OrderEnum.RESPONSE_POLE_MONITOR_DATA.getCode())) {
-            PoleMonitorDataProcessor.getInstance().process(productKey, deviceName, frame);
+//        if (!deviceName.equals("3930364d485010ff803affff")){
+//            return;
+//        }
+        log.info("澶勭悊璁㈤槄:\nmac:{},frame:{}",deviceName,frame.toString());
+        if (frame.getFunctionCode().equals("A5")){
+            log.info("A5");
+            if (frame.getOrderType().equals(A5OrderEnum.RESPONSE_LIGHT_DATA.getCode())) {
+                // 鍗曠伅鏁版嵁涓婃姤澶勭悊
+                LightDataProcessor.getInstance().process(productKey, deviceName, frame);
+            } else if (frame.getOrderType().equals(A5OrderEnum.RESPONSE_C3_DATA.getCode())) {
+                // C3鍏呯數妗╀笂鎶ュ鐞�
+                c3ChargingProcessor.c3ChargingProcessorgetInstance().process(productKey, deviceName, frame);
+            } else if (frame.getOrderType().equals(A5OrderEnum.RESPONSE_ATMOSPHERE_DATA.getCode())) {
+                // 澶ф皵鏁版嵁鎸囦护涓婃姤
+                AirDataProcessor.getInstance().process(productKey, deviceName, frame);
+            } else if (frame.getOrderType().equals(A5OrderEnum.RESPONSE_POLE_MONITOR_DATA.getCode())) {
+                PoleMonitorDataProcessor.getInstance().process(productKey, deviceName, frame);
+            }
+        } else if (frame.getFunctionCode().equals("A7")) {
+            log.info("A7");
+
+            if (frame.getOrderType().equals(A7OrderEnum.RESPONSE_PLC_DATA.getCode())){
+//                PLC
+                PlcDataProcessor.getInstance().process(productKey, deviceName,frame);
+            }
         }
+
     }
 }
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/amqp/processor/PlcDataProcessor.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/amqp/processor/PlcDataProcessor.java
new file mode 100644
index 0000000..e25731a
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/amqp/processor/PlcDataProcessor.java
@@ -0,0 +1,93 @@
+package com.sandu.ximon.admin.manager.iot.amqp.processor;
+
+import com.alibaba.fastjson.JSON;
+import com.sandu.common.util.SpringContextHolder;
+import com.sandu.ximon.admin.manager.iot.frame.inner.report.A7PlcErrorCodeReportInnerFrame;
+import com.sandu.ximon.admin.manager.iot.frame.inner.report.A7PlcHeartbeatReportInnerFrame;
+import com.sandu.ximon.admin.manager.iot.frame.inner.report.A7PlcManualLightSwitchReportInnerFrame;
+import com.sandu.ximon.admin.manager.iot.frame.inner.report.A7PlcTimeSyncReportInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.dto.CommonFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A7PlcReportEnum;
+import com.sandu.ximon.admin.service.*;
+import com.sandu.ximon.dao.domain.Plc;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @author van
+ * PLC鏁版嵁涓婃姤澶勭悊
+ */
+@Slf4j
+public class PlcDataProcessor implements IMessageProcessor {
+
+    private PlcDataProcessor() {
+    }
+
+    public static PlcDataProcessor getInstance() {
+        return PlcDataProcessorHolder.INSTANCE;
+    }
+
+    private static class PlcDataProcessorHolder {
+
+        private static final PlcDataProcessor INSTANCE = new PlcDataProcessor();
+    }
+
+    @Override
+    public void process(String productKey, String deviceName, CommonFrame frame) {
+        String functionCode = frame.getPayload().substring(2, 4);
+        if (A7PlcReportEnum.HeartBeat_Data.getCode().equals(functionCode)) {
+            log.error("蹇冭烦鐩稿簲");
+            A7PlcHeartbeatReportInnerFrame heartbeatReportInnerFrame = new A7PlcHeartbeatReportInnerFrame().transformFrame(frame.getPayload());
+
+//            if ("3930364d485010ff803affff".equals(deviceName)) {
+//                System.out.println("蹇冭烦鍖�: " + JSON.toJSONString(heartbeatReportInnerFrame));
+//                System.out.println("crc32鏍¢獙缁撴灉锛�"+heartbeatReportInnerFrame.isValidate());
+//            }
+            if (heartbeatReportInnerFrame.isValidate()) {
+                SpringContextHolder.getBean(PlcReportDataService.class).saveReportData(deviceName, heartbeatReportInnerFrame.getHeartBeatDataPackage());
+                //蹇冭烦鍖呬笂鎶ヤ笉淇濆瓨纭欢璁惧淇℃伅
+//                SpringContextHolder.getBean(LightService.class).saveLight(deviceName, heartbeatReportInnerFrame.getHeartBeatDataPackage());
+            }
+
+        } else if (A7PlcReportEnum.Time_Synchronized.getCode().equals(functionCode)) {
+            log.error("璇锋眰鏃堕棿鍚屾");
+            A7PlcTimeSyncReportInnerFrame syncRespInnerFrame = new A7PlcTimeSyncReportInnerFrame().transformFrame(frame.getPayload());
+            if (syncRespInnerFrame.isValidate()) {
+                SpringContextHolder.getBean(PlcService.class).timeSynchronizationInitiative(deviceName, syncRespInnerFrame.getDestinationAddress());
+            }
+
+        } else if (A7PlcReportEnum.Error_Code.getCode().equals(functionCode)) {
+            log.error("鏁呴殰鐮佷笂鎶�");
+            A7PlcErrorCodeReportInnerFrame codeRespInnerFrame = new A7PlcErrorCodeReportInnerFrame().transformFrame(frame.getPayload());
+            log.error(codeRespInnerFrame.isValidate() + "鏄惁閫氳繃鏍¢獙");
+            log.error(codeRespInnerFrame.getErrorCode() + "鏁呴殰鐮�");
+            if (codeRespInnerFrame.isValidate()) {
+                SpringContextHolder.getBean(PlcReportErrorService.class).saveReportError(deviceName, codeRespInnerFrame);
+            }
+//            0000  琛ㄧず娌℃湁鏁呴殰锛屽彂閫佹竻闄ゆ晠闅滄寚浠�
+            if (codeRespInnerFrame.getErrorCode() == 0) {
+                System.out.println("娓呴櫎鏁呴殰鎿嶄綔!");
+                SpringContextHolder.getBean(PlcReportErrorService.class).saveReportError(deviceName, codeRespInnerFrame);
+                SpringContextHolder.getBean(LightReportErrorService.class).cleanErrorCode(deviceName, codeRespInnerFrame.getDestinationAddress());
+            }
+        } else if (A7PlcReportEnum.Manual_LightSwitch_Request.getCode().equals(functionCode)){
+            A7PlcManualLightSwitchReportInnerFrame syncRespInnerFrame = new A7PlcManualLightSwitchReportInnerFrame().transformFrame(frame.getPayload());
+            if (syncRespInnerFrame.isValidate()) {
+                Plc plc = SpringContextHolder.getBean(PlcService.class).getPlc(deviceName);
+                String responseStatus = syncRespInnerFrame.getResponseStatus();
+                if (plc != null) {
+//                    鎵嬪姩寮�鍏冲姩浣滀笂鎶ャ��0x00-鍏ㄥ叧锛�0x64-鍏ㄥ紑
+                    if (responseStatus.equals("00")){
+                        plc.setPlcLight1(0);
+                        plc.setPlcLight2(0);
+                        plc.setPlcLight3(0);
+                    } else if (responseStatus.equals("64")) {
+                        plc.setPlcLight1(1);
+                        plc.setPlcLight2(1);
+                        plc.setPlcLight3(1);
+                    }
+                    SpringContextHolder.getBean(PlcService.class).updateById(plc);
+                }
+            }
+        }
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/A7Frame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/A7Frame.java
new file mode 100644
index 0000000..3d92ea3
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/A7Frame.java
@@ -0,0 +1,60 @@
+package com.sandu.ximon.admin.manager.iot.frame;
+
+import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.FunctionCodeEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.SupplementUtils;
+
+/**
+ * @author van
+ * A7 鍔熻兘灏佽鐨勫抚
+ */
+public class A7Frame extends BaseRequestFrame {
+
+    private String orderType;
+    private String payloadLength;
+    private String payload;
+
+    public A7Frame(String orderType, IRequestInnerFrame innerFrame) {
+        this.orderType = orderType;
+        this.payloadLength = SupplementUtils.suppleZero(Integer.toHexString((innerFrame.getEncodeFrame().length() / 2)).toUpperCase(), 4);
+        this.payload = innerFrame.getEncodeFrame();
+    }
+
+    @Override
+    public String getConnectType() {
+        return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode();
+    }
+
+    @Override
+    public String getFunctionCode() {
+        return FunctionCodeEnum.PLC.getCode();
+    }
+
+    @Override
+    public String getOrderType() {
+        return orderType;
+    }
+
+    @Override
+    public String getPayloadLength() {
+        return payloadLength;
+    }
+
+    @Override
+    public String getPayload() {
+        return payload;
+    }
+
+    @Override
+    public String toString() {
+//        return "A5Frame{" +
+//                "orderType='" + orderType + '\'' +
+//                ", payloadLength='" + payloadLength + '\'' +
+//                ", payload='" + payload + '\'' +
+//                '}';
+        return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode()
+                + FunctionCodeEnum.PLC.getCode()
+                + orderType + payloadLength + payload;
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/FrameBuilder.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/FrameBuilder.java
index 726f0b0..58b21e1 100644
--- a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/FrameBuilder.java
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/FrameBuilder.java
@@ -30,6 +30,9 @@
     public static FrameBuilder builderA5() {
         return new FrameBuilder(FunctionCodeEnum.DATA_TRANSPORT_DATA.getCode());
     }
+    public static FrameBuilder builderA7() {
+        return new FrameBuilder(FunctionCodeEnum.PLC.getCode());
+    }
 
     public FrameBuilder orderType(String orderType) {
         this.orderType = orderType;
@@ -51,6 +54,8 @@
             iRequestFrame = new A2Frame(orderType, innerFrame);
         }  else if (FunctionCodeEnum.DATA_TRANSPORT_DATA.getCode().equals(functionCode)) {
             iRequestFrame = new A5Frame(orderType, innerFrame);
+        }  else if (FunctionCodeEnum.PLC.getCode().equals(functionCode)) {
+            iRequestFrame = new A7Frame(orderType, innerFrame);
         } else {
             throw new RuntimeException("鎵句笉鍒扮鍚堟潯浠剁殑璇锋眰甯�");
         }
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcErrorCodeReportInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcErrorCodeReportInnerFrame.java
new file mode 100644
index 0000000..a782919
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcErrorCodeReportInnerFrame.java
@@ -0,0 +1,54 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.report;
+
+import cn.hutool.core.util.HexUtil;
+import cn.hutool.core.util.StrUtil;
+import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author van
+ * A7-81-42
+ * PLC涓婃姤ampq 鏁呴殰鐮�
+ */
+@Data
+@ToString(callSuper = true)
+public class A7PlcErrorCodeReportInnerFrame extends BaseResponseInnerFrame<A7PlcErrorCodeReportInnerFrame> {
+
+    /**
+     * 鐩爣鍦板潃 2
+     */
+    private String destinationAddress;
+    /**
+     * 鏁呴殰鐮�
+     */
+    private Long errorCode;
+
+    @Override
+    public A7PlcErrorCodeReportInnerFrame transformFrame(String hex) {
+        if (StrUtil.isBlank(hex) || hex.length() != 36) {
+            System.out.println("hex is blank or length is not 32");
+            return null;
+
+        }
+        // MQTT閫氫俊鏂瑰紡(1)
+        setConnectType(hex.substring(0, 2));
+        //  鍔熻兘鐮�(1)
+        setFunctionCode(hex.substring(2, 4));
+        //  璐熻嵎闀垮害(2)
+        setPayloadLength(hex.substring(4, 8));
+
+        setDestinationAddress(hex.substring(8, 12));
+
+        String errorCodeHex = hex.substring(12, 28);
+        errorCode = HexUtil.hexToLong(errorCodeHex);
+        System.out.println("鏁呴殰鐮侊細" + errorCodeHex + " - " + errorCode);
+
+        setCrc32(hex.substring(hex.length() - 8));
+        //  鏍¢獙CRC32
+        String frame = getFunctionCode() + getPayloadLength() + getDestinationAddress() + errorCodeHex;
+        this.setValidate(CRC32Utils.validateFrame(frame, getCrc32()));
+        return this;
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcHeartbeatReportInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcHeartbeatReportInnerFrame.java
new file mode 100644
index 0000000..2a9c87a
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcHeartbeatReportInnerFrame.java
@@ -0,0 +1,308 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.report;
+
+import cn.hutool.core.util.HexUtil;
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.StrUtil;
+import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame;
+import com.sandu.ximon.admin.manager.iot.frame.inner.IResponseInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author van
+ * A7-81-40
+ * PLC璇诲績璺冲寘 涓婃姤
+ */
+@Data
+@ToString(callSuper = true)
+public class A7PlcHeartbeatReportInnerFrame extends BaseResponseInnerFrame<A7PlcHeartbeatReportInnerFrame> {
+
+    //  鐩爣鍦板潃    2
+    private String destinationAddress;
+    //  蹇冭烦鍖呮暟鎹�   104
+    private HeartBeatDataPackage heartBeatDataPackage;
+
+    private String originFrame;
+
+    @Override
+    public A7PlcHeartbeatReportInnerFrame transformFrame(String hex) {
+        //  闀垮害涓嶄竴鑷存椂锛岃繑鍥瀗ull
+        if (StrUtil.isBlank(hex)) {
+            return null;
+        }
+        // MQTT閫氫俊鏂瑰紡(1)
+        setConnectType(hex.substring(0, 2));
+        //  鍔熻兘鐮�(1)
+        setFunctionCode(hex.substring(2, 4));
+        //  璐熻嵎闀垮害(2)
+        setPayloadLength(hex.substring(4, 8));
+
+        setDestinationAddress(hex.substring(8, 12));
+
+        String heartBeatData = hex.substring(12, 172);
+        HeartBeatDataPackage heartBeatDataPackage = new HeartBeatDataPackage();
+        heartBeatDataPackage.transformFrame(heartBeatData);
+        setHeartBeatDataPackage(heartBeatDataPackage);
+
+        setCrc32(hex.substring( hex.length() - 8));
+        //  鏍¢獙CRC32
+        String frame = hex.substring(2, hex.length() - 8);
+        this.setValidate(CRC32Utils.validateFrame(frame, getCrc32()));
+        return this;
+    }
+
+    @Data
+    public static class HeartBeatDataPackage implements IResponseInnerFrame<HeartBeatDataPackage> {
+        //  骞碦TC 1
+        private Integer year;
+        //  鏈圧TC 1
+        private Integer month;
+        //  鏃TC 1
+        private Integer day;
+        //  鏃禦TC 1
+        private Integer hour;
+        //  鍒哛TC 1
+        private Integer min;
+        //  绉扲TC 1
+        private Integer sec;
+        //  璁惧娓╁害 2  1瀛楄妭鏁存暟1瀛楄妭灏忔暟
+        private Double deviceTemperature;
+        //@ApiModelProperty("鐢电綉鐩告暟(鍗曘�佷笁鐩�)")
+        private Long phase;
+        //A鐩哥數鍘�
+        //@ApiModelProperty("A鐩哥數鍘�")
+        private Double voltageA;
+        //B鐩哥數鍘�
+        //@ApiModelProperty("B鐩哥數鍘�")
+        private Double voltageB;
+        //B鐩哥數鍘�
+        //@ApiModelProperty("B鐩哥數鍘�")
+        private Double voltageC;
+        //A鐩哥數娴�
+        //@ApiModelProperty("A鐩哥數娴�")
+       // @TableField(value = "electric_current_A")
+        private Double electricCurrentA;
+        //B鐩哥數娴�
+        //@ApiModelProperty("B鐩哥數娴�")
+       // @TableField(value = "electric_current_B")
+        private Double electricCurrentB;
+        //C鐩哥數娴�
+        //@ApiModelProperty("C鐩哥數娴�")
+       // @TableField(value = "electric_current_C")
+        private Double electricCurrentC;
+        //鍚堢浉鏈夊姛鍔熺巼
+        //@ApiModelProperty("鍚堢浉鏈夊姛鍔熺巼")
+       // @TableField(value = "active_power_All")
+        private Double activePowerAll;
+        //A鐩告湁鍔熷姛鐜�
+        //@ApiModelProperty("A鐩告湁鍔熷姛鐜�")
+       // @TableField(value = "active_power_A")
+        private Double activePowerA;
+        //B鐩告湁鍔熷姛鐜�
+        //@ApiModelProperty("B鐩告湁鍔熷姛鐜�")
+       // @TableField(value = "active_power_B")
+        private Double activePowerB;
+        //C鐩告湁鍔熷姛鐜�
+        //@ApiModelProperty("C鐩告湁鍔熷姛鐜�")
+       // @TableField(value = "active_power_C")
+        private Double activePowerC;
+        //鍚堢浉鏃犲姛鍔熺巼
+        //@ApiModelProperty("鍚堢浉鏃犲姛鍔熺巼")
+       // @TableField(value = "reactive_power_All")
+        private Double reactivePowerAll;
+        //A鐩告棤鍔熷姛鐜�
+        //@ApiModelProperty("A鐩告棤鍔熷姛鐜�")
+       // @TableField(value = "reactive_power_A")
+        private Double reactivePowerA;
+        //B鐩告棤鍔熷姛鐜�
+        //@ApiModelProperty("B鐩告棤鍔熷姛鐜�")
+       // @TableField(value = "reactive_power_B")
+        private Double reactivePowerB;
+        //C鐩告棤鍔熷姛鐜�
+        //@ApiModelProperty("C鐩告棤鍔熷姛鐜�")
+       // @TableField(value = "reactive_power_C")
+        private Double reactivePowerC;
+        //鍚堢浉瑙嗗湪鍔熺巼
+        //@ApiModelProperty("鍚堢浉瑙嗗湪鍔熺巼")
+       // @TableField(value = "apparent_power_All")
+        private Double apparentPowerAll;
+        //A鐩歌鍦ㄥ姛鐜�
+        //@ApiModelProperty("A鐩歌鍦ㄥ姛鐜�")
+       // @TableField(value = "apparent_power_A")
+        private Double apparentPowerA;
+        //B鐩歌鍦ㄥ姛鐜�
+        //@ApiModelProperty("B鐩歌鍦ㄥ姛鐜�")
+       // @TableField(value = "apparent_power_B")
+        private Double apparentPowerB;
+        //C鐩歌鍦ㄥ姛鐜�
+        //@ApiModelProperty("C鐩歌鍦ㄥ姛鐜�")
+       // @TableField(value = "apparent_power_C")
+        private Double apparentPowerC;
+        //鍚堢浉鍔熺巼鍥犵礌
+        //@ApiModelProperty("鍚堢浉鍔熺巼鍥犵礌")
+       // @TableField(value = "power_factor_All")
+        private Double powerFactorAll;
+        //A鐩稿姛鐜囧洜绱�
+        //@ApiModelProperty("A鐩稿姛鐜囧洜绱�")
+       // @TableField(value = "power_factor_A")
+        private Double powerFactorA;
+        //B鐩稿姛鐜囧洜绱�
+        //@ApiModelProperty("B鐩稿姛鐜囧洜绱�")
+       // @TableField(value = "power_factor_B")
+        private Double powerFactorB;
+        //C鐩稿姛鐜囧洜绱�
+        //@ApiModelProperty("C鐩稿姛鐜囧洜绱�")
+       // @TableField(value = "power_factor_C")
+        private Double powerFactorC;
+        //姝e悜鏈夊姛鎬荤數閲�
+        //@ApiModelProperty("姝e悜鏈夊姛鎬荤數閲�")
+       // @TableField(value = "total_positive_using_power")
+        private Double totalPositiveUsingPower;
+        //鍙嶅悜鏈夊姛鎬荤數閲�
+        //@ApiModelProperty("鍙嶅悜鏈夊姛鎬荤數閲�")
+       // @TableField(value = "total_reverse_using_power")
+        private Double totalReverseUsingPower;
+        //鍏夊己鍊�
+        //@ApiModelProperty("鍏夊己鍊�")
+       // @TableField(value = "light_intensity")
+        private Long lightIntensity;
+        //0鏃舵帶/1鍏夋帶
+        //@ApiModelProperty("0鏃舵帶/1鍏夋帶")
+       // @TableField(value = "control_1")
+        private Long control1;
+        //0鍏�/64寮�
+        //@ApiModelProperty("0鍏�/64寮�")
+       // @TableField(value = "status_1")
+        private Long status1;
+        //0鏃舵帶/1鍏夋帶
+        //@ApiModelProperty("0鏃舵帶/1鍏夋帶")
+       // @TableField(value = "control_2")
+        private Long control2;
+        //0鍏�/64寮�
+        //@ApiModelProperty("0鍏�/64寮�")
+       // @TableField(value = "status_2")
+        private Long status2;
+        //0鏃舵帶/1鍏夋帶
+        //@ApiModelProperty("0鏃舵帶/1鍏夋帶")
+       // @TableField(value = "control_3")
+        private Long control3;
+        //0鍏�/64寮�
+        //@ApiModelProperty("0鍏�/64寮�")
+       // @TableField(value = "status_3")
+        private Long status3;
+        //0鏃舵帶/1鍏夋帶
+        //@ApiModelProperty("0鏃舵帶/1鍏夋帶")
+       // @TableField(value = "control_n")
+        private Long controlN;
+        //0鍏�/64寮�
+        //@ApiModelProperty("0鍏�/64寮�")
+       // @TableField(value = "status_n")
+        private Long statusN;
+
+        //  淇濈暀 14
+        private String retain;
+        //  鍘熷抚
+        private String originFrame;
+
+        @Override
+        public HeartBeatDataPackage transformFrame(String hex) {
+            this.originFrame = hex;
+            this.year = HexUtil.hexToInt(hex.substring(0, 2));
+            this.month = HexUtil.hexToInt(hex.substring(2, 4));
+            this.day = HexUtil.hexToInt(hex.substring(4, 6));
+            this.hour = HexUtil.hexToInt(hex.substring(6, 8));
+            this.min = HexUtil.hexToInt(hex.substring(8, 10));
+            this.sec = HexUtil.hexToInt(hex.substring(10, 12));
+
+//            //闇�瑕佹妸鍗佸叚杩涘埗杞簩杩涘埗
+            this.deviceTemperature = NumberUtil.round(temperatureTransition(hex.substring(12, 16)), 2).doubleValue();
+            this.phase = Long.valueOf(HexUtil.hexToInt(hex.substring(16, 18)));
+            this.voltageA = NumberUtil.round(HexUtil.hexToInt(hex.substring(18, 22)) * 0.1, 1).doubleValue();
+            this.voltageB = NumberUtil.round(HexUtil.hexToInt(hex.substring(22, 26)) * 0.1, 1).doubleValue();
+            this.voltageC = NumberUtil.round(HexUtil.hexToInt(hex.substring(26, 30)) * 0.1, 1).doubleValue();
+            this.electricCurrentA = NumberUtil.round(HexUtil.hexToInt(hex.substring(30, 34)) * 0.01, 2).doubleValue();
+            this.electricCurrentB = NumberUtil.round(HexUtil.hexToInt(hex.substring(34, 38)) * 0.01, 2).doubleValue();
+            this.electricCurrentC = NumberUtil.round(HexUtil.hexToInt(hex.substring(38, 42)) * 0.01, 2).doubleValue();
+            this.activePowerAll = NumberUtil.round(HexUtil.hexToInt(hex.substring(42, 46)) * 1.00, 2).doubleValue();
+            this.activePowerA = NumberUtil.round(HexUtil.hexToInt(hex.substring(46, 50)) * 1.00, 2).doubleValue();
+            this.activePowerB = NumberUtil.round(HexUtil.hexToInt(hex.substring(50, 54)) * 1.00, 2).doubleValue();
+            this.activePowerC = NumberUtil.round(HexUtil.hexToInt(hex.substring(54, 58)) * 1.00, 2).doubleValue();
+            this.reactivePowerAll = NumberUtil.round(HexUtil.hexToInt(hex.substring(58, 62)) * 1.00, 2).doubleValue();
+            this.reactivePowerA = NumberUtil.round(HexUtil.hexToInt(hex.substring(62, 66)) * 1.00, 2).doubleValue();
+            this.reactivePowerB = NumberUtil.round(HexUtil.hexToInt(hex.substring(66, 70)) * 1.00, 2).doubleValue();
+            this.reactivePowerC = NumberUtil.round(HexUtil.hexToInt(hex.substring(70, 74)) * 1.00, 2).doubleValue();
+            this.apparentPowerAll = NumberUtil.round(HexUtil.hexToInt(hex.substring(74, 78)) * 1.00, 2).doubleValue();
+            this.apparentPowerA = NumberUtil.round(HexUtil.hexToInt(hex.substring(78, 82)) * 1.00, 2).doubleValue();
+            this.apparentPowerB = NumberUtil.round(HexUtil.hexToInt(hex.substring(82, 86)) * 1.00, 2).doubleValue();
+            this.apparentPowerC = NumberUtil.round(HexUtil.hexToInt(hex.substring(86, 90)) * 1.00, 2).doubleValue();
+            this.powerFactorAll = NumberUtil.round(HexUtil.hexToInt(hex.substring(90, 94)) * 0.001, 3).doubleValue();
+            this.powerFactorA = NumberUtil.round(HexUtil.hexToInt(hex.substring(94, 98)) * 0.001, 3).doubleValue();
+            this.powerFactorB = NumberUtil.round(HexUtil.hexToInt(hex.substring(98, 102)) * 0.001, 3).doubleValue();
+            this.powerFactorC = NumberUtil.round(HexUtil.hexToInt(hex.substring(102, 106)) * 0.001, 3).doubleValue();
+
+            this.totalPositiveUsingPower = NumberUtil.round(HexUtil.hexToLong(hex.substring(106, 114)) * 0.01, 2).doubleValue();
+            this.totalReverseUsingPower = NumberUtil.round(HexUtil.hexToLong(hex.substring(114, 122)) * 0.01, 2).doubleValue();
+
+            this.lightIntensity = (long) HexUtil.hexToInt(hex.substring(122, 128));
+
+
+            this.control1 = (long) HexUtil.hexToInt(hex.substring(128, 130));
+            this.status1 = (long) HexUtil.hexToInt(hex.substring(130, 132));
+            this.control2 = (long) HexUtil.hexToInt(hex.substring(132, 134));
+            this.status2 = (long) HexUtil.hexToInt(hex.substring(134, 136));
+            this.control3 = (long) HexUtil.hexToInt(hex.substring(136, 138));
+            this.status3 = (long) HexUtil.hexToInt(hex.substring(138, 140));
+            this.controlN = (long) HexUtil.hexToInt(hex.substring(140, 142));
+            this.statusN = (long) HexUtil.hexToInt(hex.substring(142, 144));
+
+            this.retain = hex.substring(144, 160);
+            return this;
+        }
+
+        /**
+         * 灏�16杩涘埗杞垚2杩涘埗锛岃繘琛岃ˉ鐮侊紙鍙嶇爜鍩虹涓�+1锛夛紝寰楀埌姝g‘鏁板��
+         * 浼犲叆16杩涘埗鐨勬俯搴︼紝绫诲瀷涓篠tring
+         * 濡侳500
+         */
+        public static Double temperatureTransition(String temperature) {
+
+            //灏嗕紶杩涙潵鐨�16杩涘埗鐨勮浆涓�2杩涘埗
+            String twoBinStr = hexStr2BinStr(temperature);
+
+            if ("1".equals(twoBinStr.substring(0, 1))) {
+                //鏈�楂樹綅鏄�1锛屼负璐熸暟,灏�16杩涘埗鐨勮繘琛岃ˉ鐮侊紝杩斿洖
+                int max = 0b1111111111111111;
+                double result = (max-HexUtil.hexToInt(temperature))*(-0.01);
+                return result;
+
+            } else if ("0".equals(twoBinStr.substring(0, 1))) {
+                //鏈�楂樹綅鏄�0锛屾鏁帮紝鐩存帴杩斿洖
+                double result = (HexUtil.hexToInt(temperature))*(0.01);
+                return result;
+
+            }
+            //
+            return 0.00;
+        }
+        /**
+         * 16杩涘埗瀛楃涓茶浆涓轰簩杩涘埗
+         * */
+        public static String hexStr2BinStr(String hexStr)
+        {
+            if (hexStr == null || hexStr.length() % 2 != 0)
+            {
+                return null;
+            }
+            String bString = "", tmp;
+            for (int i = 0; i < hexStr.length(); i++)
+            {
+                tmp = "0000" + Integer.toBinaryString(Integer.parseInt(hexStr.substring(i, i + 1), 16));
+                bString += tmp.substring(tmp.length() - 4);
+            }
+            return bString;
+        }
+
+    }
+
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcManualLightSwitchReportInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcManualLightSwitchReportInnerFrame.java
new file mode 100644
index 0000000..e162b9b
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcManualLightSwitchReportInnerFrame.java
@@ -0,0 +1,48 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.report;
+
+import cn.hutool.core.util.StrUtil;
+import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author van
+ * A7-81-44
+ * PLC 鎵嬪姩寮�鍏冲姩浣滀笂鎶ャ��0x00-鍏ㄥ叧锛�0x64-鍏ㄥ紑
+ */
+@Data
+@ToString(callSuper = true)
+public class A7PlcManualLightSwitchReportInnerFrame extends BaseResponseInnerFrame<A7PlcManualLightSwitchReportInnerFrame> {
+
+    /**
+     * 鐩爣鍦板潃 2
+     */
+    private String destinationAddress;
+    /**
+     * 0x00-鍏ㄥ叧锛�0x64-鍏ㄥ紑
+     */
+    private String responseStatus;
+
+    @Override
+    public A7PlcManualLightSwitchReportInnerFrame transformFrame(String hex) {
+        if (StrUtil.isBlank(hex)) {
+            return null;
+        }
+        // MQTT閫氫俊鏂瑰紡(1)
+        setConnectType(hex.substring(0, 2));
+        //  鍔熻兘鐮�(1)
+        setFunctionCode(hex.substring(2, 4));
+        //  璐熻嵎闀垮害(2)
+        setPayloadLength(hex.substring(4, 8));
+
+        setDestinationAddress(hex.substring(8, 12));
+
+        setResponseStatus(hex.substring(12, hex.length() - 8));
+        setCrc32(hex.substring(hex.length() - 8));
+        //  鏍¢獙CRC32
+        String frame = getFunctionCode() + getPayloadLength() + getDestinationAddress() + getResponseStatus();
+        this.setValidate(CRC32Utils.validateFrame(frame, getCrc32()));
+        return this;
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcOperationReportInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcOperationReportInnerFrame.java
new file mode 100644
index 0000000..ef2bd09
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcOperationReportInnerFrame.java
@@ -0,0 +1,67 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.report;
+
+import cn.hutool.core.util.StrUtil;
+import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author van
+ * PLC鎿嶄綔鎸囦护鍝嶅簲甯�
+ */
+@Data
+@ToString(callSuper = true)
+public class A7PlcOperationReportInnerFrame extends BaseResponseInnerFrame<A7PlcOperationReportInnerFrame> {
+    //MAC鍦板潃
+    private String address;
+
+    private String state;
+
+    @Override
+    public A7PlcOperationReportInnerFrame transformFrame(String hex) {        //  闀垮害涓嶄竴鑷存椂锛岃繑鍥瀗ull
+        if (StrUtil.isBlank(hex)) {
+            return null;
+        }
+        // MQTT閫氫俊鏂瑰紡(1)
+        setConnectType(hex.substring(0, 2));
+        //  鍔熻兘鐮�(1)
+        setFunctionCode(hex.substring(2, 4));
+        //  璐熻嵎闀垮害(2)
+        setPayloadLength(hex.substring(4, 8));
+        //MAC鍦板潃
+        setAddress(hex.substring(8, 12));
+        //纭欢浜や簰鍝嶅簲缁撴灉
+        setState(returnState(hex.substring(12, 14)));
+
+        setCrc32(hex.substring(hex.length() - 8));
+        //  鏍¢獙CRC32
+        String frame = hex.substring(2, hex.length() - 8);
+        this.setValidate(CRC32Utils.validateFrame(frame, getCrc32()));
+        return this;
+    }
+
+    public String returnState(String stateCode) {
+        String State = "";
+        switch (stateCode) {
+            case "00":
+                State = "鎿嶄綔鎴愬姛";
+                break;
+            case "01":
+                State = "鏍¢獙鐮侀敊璇�";
+                break;
+            case "02":
+                State = "闀垮害閿欒";
+                break;
+            case "03":
+                State = "鍐橣lash澶辫触閿欒";
+                break;
+            case "FF":
+                State = "鍏朵粬閿欒";
+                break;
+            default:
+                State = "鏈煡閿欒";
+        }
+        return State;
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcTimeSyncReportInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcTimeSyncReportInnerFrame.java
new file mode 100644
index 0000000..1d92044
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcTimeSyncReportInnerFrame.java
@@ -0,0 +1,48 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.report;
+
+import cn.hutool.core.util.StrUtil;
+import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author van
+ * A7-81-41
+ * PLC 涓婃姤ampq 璇锋眰鏃堕棿鍚屾
+ */
+@Data
+@ToString(callSuper = true)
+public class A7PlcTimeSyncReportInnerFrame extends BaseResponseInnerFrame<A7PlcTimeSyncReportInnerFrame> {
+
+    /**
+     * 鐩爣鍦板潃 2
+     */
+    private String destinationAddress;
+    /**
+     * 0x00锛氳姹傚悓姝�
+     */
+    private String responseStatus;
+
+    @Override
+    public A7PlcTimeSyncReportInnerFrame transformFrame(String hex) {
+        if (StrUtil.isBlank(hex)) {
+            return null;
+        }
+        // MQTT閫氫俊鏂瑰紡(1)
+        setConnectType(hex.substring(0, 2));
+        //  鍔熻兘鐮�(1)
+        setFunctionCode(hex.substring(2, 4));
+        //  璐熻嵎闀垮害(2)
+        setPayloadLength(hex.substring(4, 8));
+
+        setDestinationAddress(hex.substring(8, 12));
+
+        setResponseStatus(hex.substring(12, hex.length() - 8));
+        setCrc32(hex.substring(hex.length() - 8));
+        //  鏍¢獙CRC32
+        String frame = getFunctionCode() + getPayloadLength() + getDestinationAddress() + getResponseStatus();
+        this.setValidate(CRC32Utils.validateFrame(frame, getCrc32()));
+        return this;
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcBrightnessReqInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcBrightnessReqInnerFrame.java
new file mode 100644
index 0000000..1c1dba7
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcBrightnessReqInnerFrame.java
@@ -0,0 +1,47 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.request;
+
+import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A5LightDataEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.SupplementUtils;
+
+/**
+ * @author van
+ * A5->01->01
+ * "寮�/鍏崇伅(鍗充寒搴﹀�硷級
+ * 0x00锛氬叧鐏�
+ * 鍏跺畠锛氬紑鐏�&浜害鍊�"
+ */
+public class A7PlcBrightnessReqInnerFrame implements IRequestInnerFrame {
+
+    private final String payload;
+
+    /**
+     * @param lightLevel 浜害绛夌骇 [0,100]
+     */
+    public A7PlcBrightnessReqInnerFrame(Integer lightLevel, String lightAddress) {
+        String destinationAddress;
+        if (lightAddress == null || (!lightAddress.equals("0001") && !lightAddress.equals("0002")) && !lightAddress.equals("0003")) {
+            destinationAddress = "FFFF";
+        } else {
+            destinationAddress = lightAddress;
+        }
+        //  灏嗘暣鍨嬩寒搴﹁浆鎹负Hex
+        if (lightLevel <= 0) {
+            lightLevel = 0;
+        } else {
+            lightLevel = 100;
+        }
+        payload = destinationAddress + SupplementUtils.suppleZero(Integer.toHexString(lightLevel).toUpperCase(), 2);
+    }
+
+    @Override
+    public String getEncodeFrame() {
+        String functionCode = A5LightDataEnum.LightControl.getCode();
+        String payloadLength = "0003";
+        String frame = functionCode + payloadLength + payload;
+        return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode() + frame.toUpperCase() + CRC32Utils.getCRC32(frame.toUpperCase());
+    }
+
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcCleanErrorCodeInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcCleanErrorCodeInnerFrame.java
new file mode 100644
index 0000000..70ece75
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcCleanErrorCodeInnerFrame.java
@@ -0,0 +1,27 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.request;
+
+import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A5LightDataEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A7PlcDataEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+
+/**
+ * A7->01->29 鏁呴殰鐮佷笂鎶ユ竻闄�
+ */
+public class A7PlcCleanErrorCodeInnerFrame implements IRequestInnerFrame {
+    //鐏ご鍦板潃
+    private String payload;
+
+    public A7PlcCleanErrorCodeInnerFrame(String address) {
+        this.payload = address;
+    }
+
+    @Override
+    public String getEncodeFrame() {
+        String functionCode = A7PlcDataEnum.PlcCleanErrorCode.getCode();
+        String payloadLength = "0002";
+        String frame = functionCode + payloadLength + payload;
+        return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode() + frame.toUpperCase() + CRC32Utils.getCRC32(frame.toUpperCase());
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcQueryHeartBeatDataReqInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcQueryHeartBeatDataReqInnerFrame.java
new file mode 100644
index 0000000..af303da
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcQueryHeartBeatDataReqInnerFrame.java
@@ -0,0 +1,38 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.request;
+
+import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A7PlcDataEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+
+
+/**
+ * PLC蹇冭烦鍖�
+ */
+public class A7PlcQueryHeartBeatDataReqInnerFrame implements IRequestInnerFrame {
+
+
+    private final String payload;
+
+
+    public A7PlcQueryHeartBeatDataReqInnerFrame() {
+
+        String destinationAddress = "FFFF";
+
+        payload = destinationAddress ;
+
+    }
+
+
+
+
+    @Override
+    public String getEncodeFrame() {
+        String functionCode = A7PlcDataEnum.ReadHeartBeatData.getCode();
+        String payloadLength = "0002";
+        String frame = functionCode + payloadLength + payload;
+        return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode() + frame.toUpperCase() + CRC32Utils.getCRC32(frame.toUpperCase());
+
+    }
+}
+
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcQueryHeartBeatTimeReqInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcQueryHeartBeatTimeReqInnerFrame.java
new file mode 100644
index 0000000..b3a059f
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcQueryHeartBeatTimeReqInnerFrame.java
@@ -0,0 +1,38 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.request;
+
+import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A7PlcDataEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+
+
+/**
+ * 鍗曠伅蹇冭烦鍖呴棿闅旀煡璇�
+ */
+public class A7PlcQueryHeartBeatTimeReqInnerFrame implements IRequestInnerFrame {
+
+
+    private final String payload;
+
+
+    public A7PlcQueryHeartBeatTimeReqInnerFrame() {
+
+        String destinationAddress = "FFFF";
+
+        payload = destinationAddress ;
+
+    }
+
+
+
+
+    @Override
+    public String getEncodeFrame() {
+        String functionCode = A7PlcDataEnum.ReadHeartBeatTime.getCode();
+        String payloadLength = "0002";
+        String frame = functionCode + payloadLength + payload;
+        return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode() + frame.toUpperCase() + CRC32Utils.getCRC32(frame.toUpperCase());
+
+    }
+}
+
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcQueryVersionReqInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcQueryVersionReqInnerFrame.java
new file mode 100644
index 0000000..e10bb6e
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcQueryVersionReqInnerFrame.java
@@ -0,0 +1,38 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.request;
+
+import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A7PlcDataEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+
+
+/**
+ * PLC鐗堟湰
+ */
+public class A7PlcQueryVersionReqInnerFrame implements IRequestInnerFrame {
+
+
+    private final String payload;
+
+
+    public A7PlcQueryVersionReqInnerFrame() {
+
+        String destinationAddress = "FFFF";
+
+        payload = destinationAddress ;
+
+    }
+
+
+
+
+    @Override
+    public String getEncodeFrame() {
+        String functionCode = A7PlcDataEnum.ReadVersion.getCode();
+        String payloadLength = "0002";
+        String frame = functionCode + payloadLength + payload;
+        return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode() + frame.toUpperCase() + CRC32Utils.getCRC32(frame.toUpperCase());
+
+    }
+}
+
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcRebootReqInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcRebootReqInnerFrame.java
new file mode 100644
index 0000000..c27ca1a
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcRebootReqInnerFrame.java
@@ -0,0 +1,21 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.request;
+
+import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A7PlcDataEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+
+/**
+ * @author van
+ * A7->01->2A PLC杞噸鍚�
+ */
+public class A7PlcRebootReqInnerFrame implements IRequestInnerFrame {
+    @Override
+    public String getEncodeFrame() {
+        String functionCode = A7PlcDataEnum.PlcReboot.getCode();
+        String payloadLength = "0002";
+        String payload = "FFFF";
+        String frame = functionCode + payloadLength + payload;
+        return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode() + frame.toUpperCase() + CRC32Utils.getCRC32(frame.toUpperCase());
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcResetReqInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcResetReqInnerFrame.java
new file mode 100644
index 0000000..4b5fc4f
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcResetReqInnerFrame.java
@@ -0,0 +1,22 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.request;
+
+import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A5LightDataEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A7PlcDataEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+
+/**
+ * @author van
+ * A7->01->2A PLC鎭㈠鍑哄巶璁剧疆
+ */
+public class A7PlcResetReqInnerFrame implements IRequestInnerFrame {
+    @Override
+    public String getEncodeFrame() {
+        String functionCode = A7PlcDataEnum.PlcReset.getCode();
+        String payloadLength = "0002";
+        String payload = "FFFF";
+        String frame = functionCode + payloadLength + payload;
+        return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode() + frame.toUpperCase() + CRC32Utils.getCRC32(frame.toUpperCase());
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcSetCalendarReqInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcSetCalendarReqInnerFrame.java
new file mode 100644
index 0000000..75a2e3c
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcSetCalendarReqInnerFrame.java
@@ -0,0 +1,33 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.request;
+
+import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A5LightDataEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A7PlcDataEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+
+/**
+ * PLC璁剧疆鏃ュ巻
+ * @author van
+ */
+public class A7PlcSetCalendarReqInnerFrame implements IRequestInnerFrame {
+    private final String payload;
+
+    public A7PlcSetCalendarReqInnerFrame(String lightAddress, int year, int month, int day, int hour, int min, int sec) {
+
+        payload = lightAddress + hex10To16(year) + hex10To16(month) + hex10To16(day) + hex10To16(hour) + hex10To16(min) + hex10To16(sec);
+    }
+
+    @Override
+    public String getEncodeFrame() {
+        String functionCode = A7PlcDataEnum.SetCalendar.getCode();
+        String payloadLength = "0008";
+        String frame = functionCode + payloadLength + payload;
+        return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode() + frame.toUpperCase() + CRC32Utils.getCRC32(frame.toUpperCase());
+//        return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode() + frame.toUpperCase() + CRC32Utils.getCRC32(payload.toUpperCase());
+    }
+
+    private String hex10To16(int value) {
+        return String.format("%02X", value);
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcSettingHeartBeatTimeReqInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcSettingHeartBeatTimeReqInnerFrame.java
new file mode 100644
index 0000000..876fe8f
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcSettingHeartBeatTimeReqInnerFrame.java
@@ -0,0 +1,45 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.request;
+
+import cn.hutool.core.util.HexUtil;
+import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A7PlcDataEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.SupplementUtils;
+
+
+/**
+ * 鍗曠伅蹇冭烦鍖呰缃�
+ */
+public class A7PlcSettingHeartBeatTimeReqInnerFrame implements IRequestInnerFrame {
+
+
+    private final String payload;
+
+
+    public A7PlcSettingHeartBeatTimeReqInnerFrame(Integer sec) {
+        String secHex;
+        String destinationAddress = "FFFF";
+        if(sec < HexUtil.hexToInt("FFFF")) {
+            secHex = HexUtil.toHex(sec);
+        }else {
+            secHex = "FFFF";
+        }
+
+        payload = destinationAddress + SupplementUtils.suppleZero(Integer.toHexString(sec).toUpperCase(), 4);
+
+    }
+
+
+
+
+    @Override
+    public String getEncodeFrame() {
+        String functionCode = A7PlcDataEnum.SetHeartBeatTime.getCode();
+        String payloadLength = "0004";
+        String frame = functionCode + payloadLength + payload;
+        return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode() + frame.toUpperCase() + CRC32Utils.getCRC32(frame.toUpperCase());
+
+    }
+}
+
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcTimerReqInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcTimerReqInnerFrame.java
new file mode 100644
index 0000000..35434ca
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcTimerReqInnerFrame.java
@@ -0,0 +1,44 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.request;
+
+import com.sandu.ximon.admin.manager.iot.frame.inner.IRequestInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A5LightDataEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A7PlcDataEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.MQTTConnectTypeEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.SupplementUtils;
+
+/**
+ * @author van
+ * A7->01->23
+ * 瀹氭椂鎺х伅
+ * 0x00锛氬叧鐏�
+ * 鍏跺畠锛氬紑鐏�&浜害鍊�"
+ */
+public class A7PlcTimerReqInnerFrame implements IRequestInnerFrame {
+
+    private final String payload;
+    private final String functionCode = A7PlcDataEnum.PlcTimer.getCode();
+    private final String payloadLength;
+
+    /**
+     * @param framePayload 澶氫釜璺伅瀹氭椂鎸囦护锛�
+     */
+    public A7PlcTimerReqInnerFrame(String framePayload, String lightAddress) {
+        String destinationAddress;
+        if (lightAddress == null || (!lightAddress.equals("0001") && !lightAddress.equals("0002") && !lightAddress.equals("0003"))) {
+            destinationAddress = "FFFF";
+        } else {
+            destinationAddress = lightAddress;
+        }
+        payload = destinationAddress + framePayload;
+        this.payloadLength = SupplementUtils.suppleZero(Integer.toHexString((payload.length() / 2)).toUpperCase(), 4);
+    }
+
+    @Override
+    public String getEncodeFrame() {
+        String frame = functionCode + payloadLength + payload;
+        return MQTTConnectTypeEnum.SYNCHRONIZATION.getCode() + frame.toUpperCase() + CRC32Utils.getCRC32(frame.toUpperCase());
+    }
+
+
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A1DeviceMacRespInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A1DeviceMacRespInnerFrame.java
index b05bc67..0c4b1f9 100644
--- a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A1DeviceMacRespInnerFrame.java
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A1DeviceMacRespInnerFrame.java
@@ -22,7 +22,7 @@
     private String mac;
 
     /**
-     * 1瀛楄妭 璁惧绫诲瀷 璁惧绫诲瀷00浠h〃MQTT涓插彛锛�01浠h〃CAT1
+     * 1瀛楄妭 璁惧绫诲瀷 璁惧绫诲瀷00浠h〃MQTT涓插彛锛�01浠h〃CAT1锛�02浠h〃PLC
      */
     private String type;
 
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcBrightnessRespInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcBrightnessRespInnerFrame.java
new file mode 100644
index 0000000..313086a
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcBrightnessRespInnerFrame.java
@@ -0,0 +1,47 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.response;
+
+import cn.hutool.core.util.StrUtil;
+import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author van
+ * A7-81-01PLC鎺у埗 搴旂瓟
+ */
+@Data
+@ToString(callSuper = true)
+public class A7PlcBrightnessRespInnerFrame extends BaseResponseInnerFrame<A7PlcBrightnessRespInnerFrame> {
+
+    /**
+     * 鐩爣鍦板潃 2
+     */
+    private String destinationAddress;
+    /**
+     * PLC寮�鍏崇姸鎬�
+     */
+    private String responseStatus;
+
+    @Override
+    public A7PlcBrightnessRespInnerFrame transformFrame(String hex) {
+        if (StrUtil.isBlank(hex)) {
+            return null;
+        }
+        // MQTT閫氫俊鏂瑰紡(1)
+        setConnectType(hex.substring(0, 2));
+        //  鍔熻兘鐮�(1)
+        setFunctionCode(hex.substring(2, 4));
+        //  璐熻嵎闀垮害(2)
+        setPayloadLength(hex.substring(4, 8));
+
+        setDestinationAddress(hex.substring(8, 12));
+
+        setResponseStatus(hex.substring(12, 14));
+        setCrc32(hex.substring(14, 22));
+        //  鏍¢獙CRC32
+        String frame = getFunctionCode() + getPayloadLength() + getDestinationAddress() + getResponseStatus();
+        this.setValidate(CRC32Utils.validateFrame(frame, getCrc32()));
+        return this;
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcQueryHeartBeatDataRespInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcQueryHeartBeatDataRespInnerFrame.java
new file mode 100644
index 0000000..469758b
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcQueryHeartBeatDataRespInnerFrame.java
@@ -0,0 +1,50 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.response;
+
+import cn.hutool.core.util.HexUtil;
+import cn.hutool.core.util.StrUtil;
+import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame;
+import com.sandu.ximon.admin.manager.iot.frame.inner.report.A7PlcHeartbeatReportInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author van
+ * A7-81-01PLC鎺у埗 搴旂瓟
+ */
+@Data
+@ToString(callSuper = true)
+public class A7PlcQueryHeartBeatDataRespInnerFrame extends BaseResponseInnerFrame<A7PlcQueryHeartBeatDataRespInnerFrame> {
+
+    /**
+     * 鐩爣鍦板潃 2
+     */
+    private String destinationAddress;
+
+    private A7PlcHeartbeatReportInnerFrame heartbeatReportInnerFrame;
+
+
+
+    @Override
+    public A7PlcQueryHeartBeatDataRespInnerFrame transformFrame(String hex) {
+        if (StrUtil.isBlank(hex)) {
+            return null;
+        }
+        // MQTT閫氫俊鏂瑰紡(1)
+        setConnectType(hex.substring(0, 2));
+        //  鍔熻兘鐮�(1)
+        setFunctionCode(hex.substring(2, 4));
+        //  璐熻嵎闀垮害(2)
+        setPayloadLength(hex.substring(4, 8));
+
+        setDestinationAddress(hex.substring(8, 12));
+
+        setHeartbeatReportInnerFrame(new A7PlcHeartbeatReportInnerFrame().transformFrame(hex));
+
+        setCrc32(hex.substring(hex.length()-8));
+        //  鏍¢獙CRC32
+        String frame = getFunctionCode() + getPayloadLength() + getDestinationAddress() + hex.substring(12,hex.length()-8);
+        this.setValidate(CRC32Utils.validateFrame(frame, getCrc32()));
+        return this;
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcQueryHeartBeatTimeRespInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcQueryHeartBeatTimeRespInnerFrame.java
new file mode 100644
index 0000000..24854e3
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcQueryHeartBeatTimeRespInnerFrame.java
@@ -0,0 +1,48 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.response;
+
+import cn.hutool.core.util.HexUtil;
+import cn.hutool.core.util.StrUtil;
+import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author van
+ * A7-81-01PLC鎺у埗 搴旂瓟
+ */
+@Data
+@ToString(callSuper = true)
+public class A7PlcQueryHeartBeatTimeRespInnerFrame extends BaseResponseInnerFrame<A7PlcQueryHeartBeatTimeRespInnerFrame> {
+
+    /**
+     * 鐩爣鍦板潃 2
+     */
+    private String destinationAddress;
+
+    private String time;
+
+
+    @Override
+    public A7PlcQueryHeartBeatTimeRespInnerFrame transformFrame(String hex) {
+        if (StrUtil.isBlank(hex)) {
+            return null;
+        }
+        // MQTT閫氫俊鏂瑰紡(1)
+        setConnectType(hex.substring(0, 2));
+        //  鍔熻兘鐮�(1)
+        setFunctionCode(hex.substring(2, 4));
+        //  璐熻嵎闀垮害(2)
+        setPayloadLength(hex.substring(4, 8));
+
+        setDestinationAddress(hex.substring(8, 12));
+
+        setTime(String.valueOf(HexUtil.hexToInt(hex.substring(12, 16))));
+
+        setCrc32(hex.substring(16, 24));
+        //  鏍¢獙CRC32
+        String frame = getFunctionCode() + getPayloadLength() + getDestinationAddress() + getTime();
+        this.setValidate(CRC32Utils.validateFrame(frame, getCrc32()));
+        return this;
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcQueryVersionRespInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcQueryVersionRespInnerFrame.java
new file mode 100644
index 0000000..e4c9b46
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcQueryVersionRespInnerFrame.java
@@ -0,0 +1,61 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.response;
+
+import cn.hutool.core.util.HexUtil;
+import cn.hutool.core.util.StrUtil;
+import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author van
+ * A7-81-01PLC鎺у埗 搴旂瓟
+ */
+@Data
+@ToString(callSuper = true)
+public class A7PlcQueryVersionRespInnerFrame extends BaseResponseInnerFrame<A7PlcQueryVersionRespInnerFrame> {
+
+    /**
+     * 鐩爣鍦板潃 2
+     */
+    private String destinationAddress;
+
+
+    //  纭欢鐗堟湰
+    private String hardwareVersion;
+    private Double hardwareVersionDouble;
+    //  杞欢鐗堟湰
+    private String softwareVersion;
+    private Double softwareVersionDouble;
+
+    @Override
+    public A7PlcQueryVersionRespInnerFrame transformFrame(String hex) {
+        if (StrUtil.isBlank(hex)) {
+            return null;
+        }
+        // MQTT閫氫俊鏂瑰紡(1)
+        setConnectType(hex.substring(0, 2));
+        //  鍔熻兘鐮�(1)
+        setFunctionCode(hex.substring(2, 4));
+        //  璐熻嵎闀垮害(2)
+        setPayloadLength(hex.substring(4, 8));
+
+        setDestinationAddress(hex.substring(8, 12));
+
+        this.hardwareVersion = hex.substring(12, 16);
+        this.hardwareVersionDouble = Double.parseDouble(
+                HexUtil.hexToInt(this.hardwareVersion.substring(0, 2))
+                        + "." + HexUtil.hexToInt(this.hardwareVersion.substring(2, 4))
+        );
+        this.softwareVersion = hex.substring(16,20);
+        this.softwareVersionDouble = Double.parseDouble(
+                HexUtil.hexToInt(this.softwareVersion.substring(0, 2))
+                        + "." + HexUtil.hexToInt(this.softwareVersion.substring(2, 4))
+        );
+        setCrc32(hex.substring(20, 28));
+        //  鏍¢獙CRC32
+        String frame = getFunctionCode() + getPayloadLength() + getDestinationAddress() + getHardwareVersion() + getSoftwareVersion();
+        this.setValidate(CRC32Utils.validateFrame(frame, getCrc32()));
+        return this;
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcResetRespInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcResetRespInnerFrame.java
new file mode 100644
index 0000000..257b7a7
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcResetRespInnerFrame.java
@@ -0,0 +1,47 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.response;
+
+import cn.hutool.core.util.StrUtil;
+import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author van
+ * A7-81-01PLC鎺у埗 搴旂瓟
+ */
+@Data
+@ToString(callSuper = true)
+public class A7PlcResetRespInnerFrame extends BaseResponseInnerFrame<A7PlcResetRespInnerFrame> {
+
+    /**
+     * 鐩爣鍦板潃 2
+     */
+    private String destinationAddress;
+    /**
+     * PLC寮�鍏崇姸鎬�
+     */
+    private String responseStatus;
+
+    @Override
+    public A7PlcResetRespInnerFrame transformFrame(String hex) {
+        if (StrUtil.isBlank(hex)) {
+            return null;
+        }
+        // MQTT閫氫俊鏂瑰紡(1)
+        setConnectType(hex.substring(0, 2));
+        //  鍔熻兘鐮�(1)
+        setFunctionCode(hex.substring(2, 4));
+        //  璐熻嵎闀垮害(2)
+        setPayloadLength(hex.substring(4, 8));
+
+        setDestinationAddress(hex.substring(8, 12));
+
+        setResponseStatus(hex.substring(12, 14));
+        setCrc32(hex.substring(14, 22));
+        //  鏍¢獙CRC32
+        String frame = getFunctionCode() + getPayloadLength() + getDestinationAddress() + getResponseStatus();
+        this.setValidate(CRC32Utils.validateFrame(frame, getCrc32()));
+        return this;
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcRespInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcRespInnerFrame.java
new file mode 100644
index 0000000..66391e7
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcRespInnerFrame.java
@@ -0,0 +1,47 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.response;
+
+import cn.hutool.core.util.StrUtil;
+import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author van
+ * A7-81-01PLC鎺у埗 搴旂瓟
+ */
+@Data
+@ToString(callSuper = true)
+public class A7PlcRespInnerFrame extends BaseResponseInnerFrame<A7PlcRespInnerFrame> {
+
+    /**
+     * 鐩爣鍦板潃 2
+     */
+    private String destinationAddress;
+    /**
+     * PLC寮�鍏崇姸鎬�
+     */
+    private String responseStatus;
+
+    @Override
+    public A7PlcRespInnerFrame transformFrame(String hex) {
+        if (StrUtil.isBlank(hex)) {
+            return null;
+        }
+        // MQTT閫氫俊鏂瑰紡(1)
+        setConnectType(hex.substring(0, 2));
+        //  鍔熻兘鐮�(1)
+        setFunctionCode(hex.substring(2, 4));
+        //  璐熻嵎闀垮害(2)
+        setPayloadLength(hex.substring(4, 8));
+
+        setDestinationAddress(hex.substring(8, 12));
+
+        setResponseStatus(hex.substring(12, 14));
+        setCrc32(hex.substring(14, 22));
+        //  鏍¢獙CRC32
+        String frame = getFunctionCode() + getPayloadLength() + getDestinationAddress() + getResponseStatus();
+        this.setValidate(CRC32Utils.validateFrame(frame, getCrc32()));
+        return this;
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcTimerRespInnerFrame.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcTimerRespInnerFrame.java
new file mode 100644
index 0000000..78ce1a8
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcTimerRespInnerFrame.java
@@ -0,0 +1,47 @@
+package com.sandu.ximon.admin.manager.iot.frame.inner.response;
+
+import cn.hutool.core.util.StrUtil;
+import com.sandu.ximon.admin.manager.iot.frame.inner.BaseResponseInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.CRC32Utils;
+import lombok.Data;
+import lombok.ToString;
+
+/**
+ * @author van
+ * A7-81-23鐏畾鏃朵换鍔� 搴旂瓟
+ */
+@Data
+@ToString(callSuper = true)
+public class A7PlcTimerRespInnerFrame extends BaseResponseInnerFrame<A7PlcTimerRespInnerFrame> {
+
+    /**
+     * 鐩爣鍦板潃 2
+     */
+    private String destinationAddress;
+    /**
+     * 鍝嶅簲鐘舵�� 1
+     */
+    private String responseStatus;
+
+    @Override
+    public A7PlcTimerRespInnerFrame transformFrame(String hex) {
+        if (StrUtil.isBlank(hex)) {
+            return null;
+        }
+        // MQTT閫氫俊鏂瑰紡(1)
+        setConnectType(hex.substring(0, 2));
+        //  鍔熻兘鐮�(1)
+        setFunctionCode(hex.substring(2, 4));
+        //  璐熻嵎闀垮害(2)
+        setPayloadLength(hex.substring(4, 8));
+
+        setDestinationAddress(hex.substring(8, 12));
+
+        setResponseStatus(hex.substring(12, 14));
+        setCrc32(hex.substring(14, 22));
+        //  鏍¢獙CRC32
+        String frame = getFunctionCode() + getPayloadLength() + getDestinationAddress() + getResponseStatus();
+        this.setValidate(CRC32Utils.validateFrame(frame, getCrc32()));
+        return this;
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/A7OrderEnum.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/A7OrderEnum.java
new file mode 100644
index 0000000..19cb209
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/A7OrderEnum.java
@@ -0,0 +1,31 @@
+package com.sandu.ximon.admin.manager.iot.rrpc.enums;
+
+/**
+ * @author van
+ * 涓诲璁炬暟鎹�(A7)涓嬬殑鍛戒护
+ */
+public enum A7OrderEnum {
+    //-------------------------------------------- 鏈嶅姟鍣ㄤ笅鍙�----------------------------------------------------//
+    /**
+     * 0x01:闆嗕腑绾挎帶鍣ㄦ暟鎹寚浠わ紙鍨嬪彿01锛� 璐熻嵎鏁版嵁A
+     */
+    REQUEST_PLC_DATA("01"),
+
+
+
+
+    //-------------------------------------------- 璁惧涓婃姤----------------------------------------------------//
+    //   0x01:闆嗕腑绾挎帶鍣ㄦ暟鎹寚浠わ紙鍨嬪彿01锛� 璐熻嵎鏁版嵁A
+    RESPONSE_PLC_DATA("81");
+
+
+    A7OrderEnum(String code) {
+        this.code = code;
+    }
+
+    private final String code;
+
+    public String getCode() {
+        return code;
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/A7PlcDataEnum.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/A7PlcDataEnum.java
new file mode 100644
index 0000000..4239599
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/A7PlcDataEnum.java
@@ -0,0 +1,45 @@
+package com.sandu.ximon.admin.manager.iot.rrpc.enums;
+
+/**
+ * @author van
+ * A7-01 Plc鏁版嵁鎸囦护 鍒楄〃
+ */
+public enum A7PlcDataEnum {
+    //  鍗曠伅鎺у埗
+    PlcControl("01"),
+    //  瀹氭椂鎺у埗
+    TimingLightControl("02"),
+    //  鍏夋劅鎺у埗
+    PlcSensorControl("03"),
+
+    //  璇荤増鏈�
+    ReadVersion("10"),
+    //  璇诲績璺冲寘鏃堕棿
+    ReadHeartBeatTime("11"),
+    //  璇诲績璺冲寘
+    ReadHeartBeatData("16"),
+
+    SetHeartBeatTime("21"),
+    //璁剧疆瀹氭椂鎺х伅鍙傛暟
+    PlcTimer("23"),
+    // 閲嶅惎
+    Reboot("25"),
+    //璁剧疆鏃ュ巻锛堝悓蹇冭烦鍖呬腑鐨�6瀛楄妭鏃ユ湡鏃堕棿锛�
+    SetCalendar("28"),
+    //鏁呴殰鐮佷笂鎶ユ竻闄�
+    PlcCleanErrorCode("29"),
+
+    PlcReset("2A"),
+    PlcReboot("26"),
+    PLC_HEART_BEAT("PlcReportData:plc_heart_beat/");
+
+    A7PlcDataEnum(String code) {
+        this.code = code;
+    }
+
+    private final String code;
+
+    public String getCode() {
+        return code;
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/A7PlcReportEnum.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/A7PlcReportEnum.java
new file mode 100644
index 0000000..7ef87f6
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/A7PlcReportEnum.java
@@ -0,0 +1,29 @@
+package com.sandu.ximon.admin.manager.iot.rrpc.enums;
+
+/**
+ * @author van
+ * A5-81 PLC涓诲姩涓婃姤锛氾紙amqp锛�
+ */
+public enum A7PlcReportEnum {
+    //  涓婃姤蹇冭烦鍖�
+    HeartBeat_Data("40"),
+    //  璇锋眰鏃堕棿鍚屾
+    Time_Synchronized("41"),
+    //  鏁呴殰鐮�
+    Error_Code("42"),
+    //  鏈湴瀹氭椂/鍏夋帶寮�鍏崇伅鍔ㄤ綔涓婃姤
+    Timing_LightSwitch_Report("43"),
+    //  鎵嬪姩寮�鍏冲姩浣滀笂鎶ャ��0x00-鍏ㄥ叧锛�0x64-鍏ㄥ紑
+    Manual_LightSwitch_Request("44");
+
+
+    A7PlcReportEnum(String code) {
+        this.code = code;
+    }
+
+    private final String code;
+
+    public String getCode() {
+        return code;
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/FunctionCodeEnum.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/FunctionCodeEnum.java
index 17656e4..306c3fe 100644
--- a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/FunctionCodeEnum.java
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/FunctionCodeEnum.java
@@ -25,7 +25,12 @@
     /**
      * 澶栬鏁版嵁    鐢ㄤ簬澶栬鏁版嵁浼犺緭浣跨敤鎺ュ彛
      */
-    DATA_TRANSPORT_DATA("A5");
+    DATA_TRANSPORT_DATA("A5"),
+
+    /**
+     * PLC
+     */
+    PLC("A7");
 
     private final String code;
 
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/PlcErrorEnum.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/PlcErrorEnum.java
new file mode 100644
index 0000000..50953ed
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/PlcErrorEnum.java
@@ -0,0 +1,186 @@
+package com.sandu.ximon.admin.manager.iot.rrpc.enums;
+
+/**
+ * @author van
+ * PLC閿欒涓婃姤鐮�
+ * "鏁呴殰鐮侊細锛堢敤浜岃繘鍒惰〃绀猴級
+ * 0x00000000,0x00000000 浜岃繘鍒跺嵆涓篬bit64:bit0]銆�
+浣嶏紙ibt锛�	鏁呴殰鐮佸畾涔�	澶囨敞
+0	缃戠粶涓嶇ǔ瀹�/4G淇″彿寮�
+1	璁惧娓╁害杩囬珮	锛堥槇鍊煎浐瀹氳涓�80搴︼級
+2	闆嗕腑绾挎帶鍣‥EPROM鏁呴殰
+3	闆嗕腑绾挎帶鍣≧TC鏁呴殰
+4	A鐩稿け鍘�
+5	A鐩告瑺鍘�	鏃犵數娴�
+6	A鐩歌繃鍘�	缂虹浉
+7	A鐩稿け娴�	鐢垫祦鍙嶅悜
+8	A鐩歌繃娴�
+9	A鐩歌繃杞�
+10	A鐩告疆娴佸弽鍚�	鐢垫祦杩囦綆
+11	A鐩告柇鐩�
+12	A鐩告柇娴�	鐢靛帇杩囦綆
+13	A鐩告湁鍔熺巼璐熷��	鏃犵數鍘�
+14	A鐩告紡鐢�	涓夌浉鍥涚嚎寮忥紝鐏浂闂寸洃娴�
+15	B鐩稿け鍘�
+16	B鐩告瑺鍘�
+17	B鐩歌繃鍘�
+18	B鐩稿け娴�
+19	B鐩歌繃娴�
+20	B鐩歌繃杞�
+21	B鐩告疆娴佸弽鍚�
+22	B鐩告柇鐩�
+23	B鐩告柇娴�
+24	B鐩告湁鍔熺巼璐熷��
+25	B鐩告紡鐢�
+26	C鐩稿け鍘�
+27	C鐩告瑺鍘�
+28	C鐩歌繃鍘�
+29	C鐩稿け娴�
+30	C鐩歌繃娴�
+31	C鐩歌繃杞�
+32	C鐩告疆娴佸弽鍚�
+33	C鐩告柇鐩�
+34	C鐩告柇娴�
+35	C鐩告湁鍔熺巼璐熷��
+36	C鐩告紡鐢�
+37	鐢甸噺璁℃ā鍧楁晠闅�	妯″潡鑷韩鎶ユ晠闅�
+38	鍏変紶鎰熷櫒鏁呴殰	鏃犳暟鍊�/鏁板�奸敊璇�
+39	闆嗕腑绾挎帶鍣ㄦ帀鐢�
+
+40	閰嶇數绠遍棬琚墦寮�
+41	绗�1璺紑鍏抽�氭柇鏁呴殰
+42	绗�2璺紑鍏抽�氭柇鏁呴殰
+43	绗�3璺紑鍏抽�氭柇鏁呴殰
+44	绗�4璺紑鍏抽�氭柇鏁呴殰
+45	绗�5璺紑鍏抽�氭柇鏁呴殰
+46	绗�6璺紑鍏抽�氭柇鏁呴殰
+
+"48
+.
+.
+.
+.
+63"	澶囩敤
+ */
+public enum PlcErrorEnum {
+
+
+    /*
+        0	缃戠粶涓嶇ǔ瀹�/4G淇″彿寮�
+        1	璁惧娓╁害杩囬珮	锛堥槇鍊煎浐瀹氳涓�80搴︼級
+        2	闆嗕腑绾挎帶鍣‥EPROM鏁呴殰
+        3	闆嗕腑绾挎帶鍣≧TC鏁呴殰
+        4	A鐩稿け鍘�
+        5	A鐩告瑺鍘�	鏃犵數娴�
+        6	A鐩歌繃鍘�	缂虹浉
+        7	A鐩稿け娴�	鐢垫祦鍙嶅悜
+        8	A鐩歌繃娴�
+        9	A鐩歌繃杞�*/
+    E0(1,"缃戠粶涓嶇ǔ瀹�/4G淇″彿寮�"),
+    E1(2,"璁惧娓╁害杩囬珮"),
+    E2(2<<1,"闆嗕腑绾挎帶鍣‥EPROM鏁呴殰"),
+    E3(2<<2,"闆嗕腑绾挎帶鍣≧TC鏁呴殰"),
+    E4(2<<3,"A鐩稿け鍘�"),
+    E5(2<<4,"A鐩告瑺鍘�"),
+    E6(2<<5,"A鐩歌繃鍘�"),
+    E7(2<<6,"A鐩稿け娴�"),
+    E8(2<<7,"A鐩歌繃娴�"),
+    E9(2<<8,"A鐩歌繃杞�"),
+    /*
+        10	A鐩告疆娴佸弽鍚�	鐢垫祦杩囦綆
+        11	A鐩告柇鐩�
+        12	A鐩告柇娴�	鐢靛帇杩囦綆
+        13	A鐩告湁鍔熺巼璐熷��	鏃犵數鍘�
+        14	A鐩告紡鐢�	涓夌浉鍥涚嚎寮忥紝鐏浂闂寸洃娴�
+        15	B鐩稿け鍘�
+        16	B鐩告瑺鍘�
+        17	B鐩歌繃鍘�
+        18	B鐩稿け娴�
+        19	B鐩歌繃娴�*/
+    E10(2<<9,"A鐩告疆娴佸弽鍚�"),
+    E11(2<<10,"A鐩告柇鐩�"),
+    E12(2<<11,"A鐩告柇娴�"),
+    E13(2<<12,"A鐩告湁鍔熺巼璐熷��"),
+    E14(2<<13,"A鐩告紡鐢�"),
+    E15(2<<14,"B鐩稿け鍘�"),
+    E16(2<<15,"B鐩告瑺鍘�"),
+    E17(2<<16,"B鐩歌繃鍘�"),
+    E18(2<<17,"B鐩稿け娴�"),
+    E19(2<<18,"B鐩歌繃娴�"),
+    /*
+        20	B鐩歌繃杞�
+        21	B鐩告疆娴佸弽鍚�
+        22	B鐩告柇鐩�
+        23	B鐩告柇娴�
+        24	B鐩告湁鍔熺巼璐熷��
+        25	B鐩告紡鐢�
+        26	C鐩稿け鍘�
+        27	C鐩告瑺鍘�
+        28	C鐩歌繃鍘�
+        29	C鐩稿け娴�
+    * */
+    E20(2<<19,"B鐩歌繃杞�"),
+    E21(2<<20,"B鐩告疆娴佸弽鍚�"),
+    E22(2<<21,"B鐩告柇鐩�"),
+    E23(2<<22,"B鐩告柇娴�"),
+    E24(2<<23,"B鐩告湁鍔熺巼璐熷��"),
+    E25(2<<24,"B鐩告紡鐢�"),
+    E26(2<<25,"C鐩稿け鍘�"),
+    E27(2<<26,"C鐩告瑺鍘�"),
+    E28(2<<27,"C鐩歌繃鍘�"),
+    E29(2<<28,"C鐩稿け娴�"),
+    /*
+        30	C鐩歌繃娴�
+        31	C鐩歌繃杞�
+        32	C鐩告疆娴佸弽鍚�
+        33	C鐩告柇鐩�
+        34	C鐩告柇娴�
+        35	C鐩告湁鍔熺巼璐熷��
+        36	C鐩告紡鐢�
+        37	鐢甸噺璁℃ā鍧楁晠闅�	妯″潡鑷韩鎶ユ晠闅�
+        38	鍏変紶鎰熷櫒鏁呴殰	鏃犳暟鍊�/鏁板�奸敊璇�
+        39	闆嗕腑绾挎帶鍣ㄦ帀鐢�
+    * */
+    E30(2<<29,"C鐩歌繃娴�"),
+    E31(2<<30,"C鐩歌繃杞�"),
+    E32(2<<31,"C鐩告疆娴佸弽鍚�"),
+    E33(2<<32,"C鐩告柇鐩�"),
+    E34(2<<33,"C鐩告柇娴�"),
+    E35(2<<34,"C鐩告湁鍔熺巼璐熷��"),
+    E36(2<<35,"C鐩告紡鐢�"),
+    E37(2<<36,"鐢甸噺璁℃ā鍧楁晠闅�"),
+    E38(2<<37,"鍏変紶鎰熷櫒鏁呴殰"),
+    E39(2<<38,"闆嗕腑绾挎帶鍣ㄦ帀鐢�"),
+    /*
+        40	閰嶇數绠遍棬琚墦寮�
+        41	绗�1璺紑鍏抽�氭柇鏁呴殰
+        42	绗�2璺紑鍏抽�氭柇鏁呴殰
+        43	绗�3璺紑鍏抽�氭柇鏁呴殰
+        44	绗�4璺紑鍏抽�氭柇鏁呴殰
+        45	绗�5璺紑鍏抽�氭柇鏁呴殰
+        46	绗�6璺紑鍏抽�氭柇鏁呴殰
+
+    *  */
+    E40(2<<39,"閰嶇數绠遍棬琚墦寮�"),
+    E41(2<<40,"绗�1璺紑鍏抽�氭柇鏁呴殰"),
+    E42(2<<41,"绗�2璺紑鍏抽�氭柇鏁呴殰"),
+    E43(2<<42,"绗�3璺紑鍏抽�氭柇鏁呴殰"),
+    E44(2<<43,"绗�4璺紑鍏抽�氭柇鏁呴殰"),
+    E45(2<<44,"绗�5璺紑鍏抽�氭柇鏁呴殰"),
+    E46(2<<45,"绗�6璺紑鍏抽�氭柇鏁呴殰");
+    private final Integer code;
+    private final String message;
+
+    PlcErrorEnum(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcControlParam.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcControlParam.java
new file mode 100644
index 0000000..955aeaf
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcControlParam.java
@@ -0,0 +1,35 @@
+package com.sandu.ximon.admin.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.lang.annotation.Target;
+
+/**
+ * @author van
+ * @version 1.0
+ * msg锛�
+ * @date 2022/12/16 11:55
+ */
+@Data
+public class PlcControlParam {
+    @NotBlank(message = "璁惧鐮佷笉鑳戒负绌�")
+    private String deviceCode;
+
+    //鍙岀伅澶存帶鍒跺弬鏁�
+    private String plcAddress = "FFFF";
+
+
+    @NotNull(message = "浜害涓嶈兘涓虹┖")
+    @Min(value = 0, message = "浜害鏈�灏忎负0")
+    @Max(value = 100, message = "浜害鏈�澶т负100")
+    private Integer brightness;
+
+    @Min(value = 0, message = "heartBeatTime鏈�灏忎负0")
+    @Max(value = 3600, message = "heartBeatTime鏈�澶т负3600")
+    private Integer heartBeatTime;
+
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcRemarkParam.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcRemarkParam.java
new file mode 100644
index 0000000..fde464c
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcRemarkParam.java
@@ -0,0 +1,20 @@
+package com.sandu.ximon.admin.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author van
+ * @version 1.0
+ * msg锛�
+ * @date 2022/12/16 11:38
+ */
+@Data
+public class PlcRemarkParam {
+    @NotNull(message = "plcId涓嶈兘涓虹┖")
+    private Long plcId;
+    @NotEmpty(message = "澶囨敞涓嶈兘涓虹┖")
+    private String plcRemark;
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcTaskDelParam.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcTaskDelParam.java
new file mode 100644
index 0000000..4bf2f67
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcTaskDelParam.java
@@ -0,0 +1,17 @@
+package com.sandu.ximon.admin.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author van
+ * 璺伅浠诲姟
+ */
+@Data
+public class PlcTaskDelParam {
+
+    @NotNull(message = "浠诲姟id涓嶈兘涓虹┖")
+    private Long taskId;
+
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcTaskIssueParam.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcTaskIssueParam.java
new file mode 100644
index 0000000..d7ede1a
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcTaskIssueParam.java
@@ -0,0 +1,20 @@
+package com.sandu.ximon.admin.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author van
+ * 璺伅涓嬪彂浠诲姟
+ */
+@Data
+public class PlcTaskIssueParam {
+
+    @NotNull(message = "浠诲姟id涓嶈兘涓虹┖")
+    private Long taskId;
+
+    @NotNull(message = "鐏潌id涓嶈兘涓虹┖")
+    private Long poleId;
+
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcTaskParam.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcTaskParam.java
new file mode 100644
index 0000000..ce79144
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcTaskParam.java
@@ -0,0 +1,56 @@
+package com.sandu.ximon.admin.param;
+
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import java.util.List;
+
+/**
+ * @author van
+ * PLC浠诲姟
+ */
+@Data
+public class PlcTaskParam {
+
+    public static final int REQUEST_ORDER_LENGTH = 7;
+    /**
+     * 浠诲姟鍚嶇О
+     */
+    @NotBlank(message = "浠诲姟鍚嶇О涓嶈兘涓虹┖")
+    private String taskName;
+
+    /**
+     * 鏄熸湡鍑狅紝浣嶈繍绠椾繚瀛橈紝1浠h〃鏄熸湡涓�锛�2鏄熸湡浜岋紝4鏄熸湡涓夛紝8鏄熸湡鍥涳紝16鏄熸湡浜旓紝32鏄熸湡鍏紝64鏄熸湡鏃�
+     */
+    @NotEmpty(message = "鏄熸湡涓嶈兘涓虹┖")
+    private List<Integer> weekList;
+
+
+    /**
+     * 寮�鐏懡浠�
+     */
+    @Length(min = REQUEST_ORDER_LENGTH, max = REQUEST_ORDER_LENGTH, message = "寮�鐏懡浠ら暱搴﹂敊璇�")
+    private String openOrder;
+
+    /**
+     * 鍏抽棴鐏懡浠�
+     */
+    @Length(min = REQUEST_ORDER_LENGTH, max = REQUEST_ORDER_LENGTH, message = "鍏崇伅鍛戒护闀垮害閿欒")
+    private String closeOrder;
+    /**
+     * 鐏帶鍛戒护
+     */
+    private String controlOrder;
+
+    /**
+     * 鐏ご,榛樿鍏ㄤ寒
+     */
+    private String plcAddress;
+
+    private List<Long> poleIdList;
+
+
+    private Long taskId;
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcReportDataService.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcReportDataService.java
new file mode 100644
index 0000000..178fabd
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcReportDataService.java
@@ -0,0 +1,168 @@
+package com.sandu.ximon.admin.service;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.db.PageResult;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.github.pagehelper.PageHelper;
+import com.sandu.common.domain.CommonPage;
+import com.sandu.common.execption.BusinessException;
+import com.sandu.common.object.BaseConditionVO;
+import com.sandu.common.service.impl.BaseServiceImpl;
+import com.sandu.common.util.SpringContextHolder;
+import com.sandu.ximon.admin.manager.iot.frame.inner.report.A5LightHeartbeatReportInnerFrame;
+import com.sandu.ximon.admin.manager.iot.frame.inner.report.A7PlcHeartbeatReportInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A5LightDataEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A7PlcDataEnum;
+import com.sandu.ximon.admin.utils.RedisUtils;
+import com.sandu.ximon.dao.bo.LightReportDataBo;
+import com.sandu.ximon.dao.bo.PlcReportDataBo;
+import com.sandu.ximon.dao.domain.*;
+import com.sandu.ximon.dao.enums.OrderByEnums;
+import com.sandu.ximon.dao.mapper.PlcReportDataMapper;
+import lombok.AllArgsConstructor;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * PLC涓婃姤鏁版嵁琛�(PlcReportData)琛ㄦ湇鍔℃帴鍙�
+ *
+ * @author van
+ * @since 2022-12-16 10:54:58
+ */
+@Service
+@AllArgsConstructor
+public class PlcReportDataService extends BaseServiceImpl<PlcReportDataMapper,PlcReportData> {
+
+    private final PlcReportDataMapper plcReportDataMapper;
+
+//    PageResult getPage(Integer currentPage, Integer size, PlcReportData plcReportData);
+
+
+    /**
+     * 淇濆瓨涓婃姤鐨凱LC蹇冭烦鏁版嵁
+     *
+     * @return 鏄惁鎴愬姛
+     */
+    public boolean saveReportData(String deviceName, A7PlcHeartbeatReportInnerFrame.HeartBeatDataPackage heartBeatDataPackage) {
+
+        String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss"));
+
+        PlcReportData plcReportData = new PlcReportData();
+
+        if (plcReportData == null) {
+            plcReportData = new PlcReportData();
+            plcReportData.setCreateTime(format);
+        }
+        plcReportData.setCreateTime(format);
+        BeanUtils.copyProperties(heartBeatDataPackage, plcReportData);
+        plcReportData.setDeviceCode(deviceName);
+
+        plcReportData.setUpdateTime(format);
+        //PLC鏁版嵁淇濆瓨鍒扮紦瀛橀噷
+        RedisUtils.getBean().set(A7PlcDataEnum.PLC_HEART_BEAT.getCode() + deviceName, plcReportData);
+
+        return save(plcReportData);
+
+
+    }
+
+        List<PlcReportData> getNewestReportByDeviceCode(List<String> deviceCodeList){
+        return baseMapper.getNewestReportByDeviceCode(deviceCodeList);
+    }
+    /**
+     * 鑾峰彇涓婃姤鏁版嵁
+     *
+     * @param keyword    鍏抽敭璇�
+     * @param deviceCode 璁惧鐮�
+     */
+    public CommonPage listReportData(int pageNo, int pageSize, String keyword, String deviceCode, Integer order, Integer seq) {
+
+        List<PlcReportDataBo> plcReportDataBos = new ArrayList<>(pageSize);
+        //鎺掑簭瀛楁
+        String orderByResult = "t1.plc_create_time";
+        //姝e簭銆佸�掑彊
+        String orderBySeq = OrderByEnums.ASC.getCode();
+        if (order != null) {
+            switch (order) {
+                case 1:
+                    orderByResult = OrderByEnums.PLC_DATA_CREATE_TIME.getCode();
+                    break;
+                default:
+            }
+        }
+        if (seq != null) {
+            switch (seq) {
+                case 1:
+                    orderBySeq = " ASC";
+                    break;
+                case 2:
+                    orderBySeq = " DESC";
+                    break;
+                default:
+                    break;
+            }
+        }
+        //鎺掑簭鏂瑰紡
+        String orderBy = orderByResult + " " + orderBySeq;
+        CommonPage<String> stringCommonPage = SpringContextHolder.getBean(PlcService.class).listDeviceCode(pageNo, pageSize, keyword, deviceCode, orderBy);
+        List<String> macList = stringCommonPage.getList();
+        if (CollUtil.isEmpty(macList)) {
+            return new CommonPage();
+        }
+        for (String macCode : macList) {
+            try {
+                PlcReportData plcReportData
+                        = JSON.parseObject(RedisUtils.getBean().get(A7PlcDataEnum.PLC_HEART_BEAT.getCode() + macCode), PlcReportData.class);
+
+                PlcReportDataBo plcReportDataBo = new PlcReportDataBo();
+                if (plcReportData != null) {
+                    BeanUtils.copyProperties(plcReportData, plcReportDataBo);
+                }
+                plcReportDataBo.setDeviceCode(macCode);
+                Pole pole = SpringContextHolder.getBean(PoleService.class).getOne(Wrappers.lambdaQuery(Pole.class).eq(Pole::getDeviceCode, macCode));
+                if (pole != null) {
+                    plcReportDataBo.setPoleName(pole.getPoleName());
+                }
+                plcReportDataBos.add(plcReportDataBo);
+
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        CommonPage commonPage = CommonPage.restPage(plcReportDataBos);
+        commonPage.setTotal(stringCommonPage.getTotal());
+        commonPage.setTotalPage(stringCommonPage.getTotalPage());
+        commonPage.setPageNum(pageNo);
+
+        return commonPage;
+    }
+
+    public List<PlcReportData> getReportDataList(BaseConditionVO conditionVO, String macCode) {
+        if (macCode.isEmpty()) {
+            throw new BusinessException("mac涓嶈兘涓虹┖");
+        }
+
+        Plc plc = SpringContextHolder.getBean(PlcService.class)
+                .getOne(Wrappers.lambdaQuery(Plc.class).eq(Plc::getDeviceCode, macCode));
+        if (plc == null) {
+            throw new BusinessException("绯荤粺涓笉瀛樺湪璇lc");
+        }
+        PageHelper.startPage(conditionVO.getPageNo(), conditionVO.getPageSize());
+        List<PlcReportData> list = list(Wrappers.lambdaQuery(PlcReportData.class).eq(PlcReportData::getDeviceCode, macCode).orderByDesc(PlcReportData::getReportDataId));
+        list.forEach(
+                plcReportData -> {
+                    plcReportData.setCreateTime(plcReportData.getCreateTime1().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+                    plcReportData.setUpdateTime(plcReportData.getUpdateTime1().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+                }
+        );
+        return list;
+    }
+}
+
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcReportErrorService.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcReportErrorService.java
new file mode 100644
index 0000000..f7e5348
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcReportErrorService.java
@@ -0,0 +1,122 @@
+package com.sandu.ximon.admin.service;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.github.pagehelper.PageHelper;
+import com.sandu.common.domain.CommonPage;
+import com.sandu.common.object.BaseConditionVO;
+import com.sandu.common.service.BaseService;
+import com.sandu.common.service.impl.BaseServiceImpl;
+import com.sandu.ximon.admin.manager.iot.frame.A5Frame;
+import com.sandu.ximon.admin.manager.iot.frame.A7Frame;
+import com.sandu.ximon.admin.manager.iot.frame.inner.report.A5LightOperationReportInnerFrame;
+import com.sandu.ximon.admin.manager.iot.frame.inner.report.A7PlcErrorCodeReportInnerFrame;
+import com.sandu.ximon.admin.manager.iot.frame.inner.report.A7PlcOperationReportInnerFrame;
+import com.sandu.ximon.admin.manager.iot.frame.inner.request.A5LightCleanErrorCodeInnerFrame;
+import com.sandu.ximon.admin.manager.iot.frame.inner.request.A7PlcCleanErrorCodeInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.dto.CommonFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A5OrderEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A7OrderEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.PlcErrorEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.mainboard.MainBoardInvokeSyncService;
+import com.sandu.ximon.admin.security.SecurityUtils;
+import com.sandu.ximon.admin.utils.ListPagingUtils;
+import com.sandu.ximon.admin.utils.StoreOperationRecordsUtils;
+import com.sandu.ximon.dao.bo.PlcReportErrorBo;
+import com.sandu.ximon.dao.bo.PlcReportErrorBo;
+import com.sandu.ximon.dao.domain.PlcReportError;
+import com.sandu.ximon.dao.mapper.PlcReportErrorMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * plc鍗曠伅鏁呴殰鏁版嵁鍒楄〃(PlcReportError)琛ㄦ湇鍔℃帴鍙�
+ *
+ * @author van
+ * @since 2022-12-17 14:42:19
+ */
+@Slf4j
+@Service
+public class PlcReportErrorService extends BaseServiceImpl<PlcReportErrorMapper,PlcReportError> {
+
+
+    public void saveReportError(String deviceName, A7PlcErrorCodeReportInnerFrame codeRespInnerFrame) {
+        PlcReportError plcReportError = new PlcReportError();
+        plcReportError.setPlcDeviceCode(deviceName);
+        plcReportError.setErrorCode(codeRespInnerFrame.getErrorCode());
+        plcReportError.setPlcAddress(codeRespInnerFrame.getDestinationAddress());
+        save(plcReportError);
+    }
+
+    public List<PlcReportErrorBo> listReportError(int pageNo, int pageSize, String keyword, Long error_code) {
+        PageHelper.startPage(pageNo, pageSize);
+        List<PlcReportErrorBo> plcReportErrorBos;
+        //涓簄ull鐨勮瘽鏄秴绠�
+        if (SecurityUtils.getClientId() == null) {
+            plcReportErrorBos = baseMapper.listReportError(keyword, error_code, null);
+        } else {
+            plcReportErrorBos = baseMapper.listReportError(keyword, error_code, SecurityUtils.getUserId());
+        }
+
+        for (PlcReportErrorBo lightReportErrorBo : plcReportErrorBos) {
+            Long errorCode = lightReportErrorBo.getErrorCode();
+            StringBuilder sb = new StringBuilder();
+            PlcErrorEnum[] values = PlcErrorEnum.values();
+            for (PlcErrorEnum value : values) {
+                if ((value.getCode() & errorCode) > 0) {
+                    sb.append(value.getMessage() + ";");
+                }
+            }
+            lightReportErrorBo.setErrorMsg(sb.toString());
+        }
+        return plcReportErrorBos;
+    }
+
+    /**
+     * 鏌ヨ鏁呭父鏁版嵁
+     *
+     * @return
+     */
+    public CommonPage queryErrorCode(BaseConditionVO baseConditionVO) {
+        List<PlcReportErrorBo> plcReportErrorBos = baseMapper.listError(SecurityUtils.getClientId());
+        plcReportErrorBos = plcReportErrorBos.stream().filter(bean -> bean.getErrorCode() != 0).collect(Collectors.toList());
+        CommonPage commonPage = ListPagingUtils.pages(plcReportErrorBos, baseConditionVO.getPageNo(), baseConditionVO.getPageSize());
+
+        for (PlcReportErrorBo lightReportErrorBo : (List<PlcReportErrorBo>) commonPage.getList()) {
+            Long errorCode = lightReportErrorBo.getErrorCode();
+            StringBuilder sb = new StringBuilder();
+            PlcErrorEnum[] values = PlcErrorEnum.values();
+            for (PlcErrorEnum value : values) {
+                if ((value.getCode() & errorCode) > 0) {
+                    sb.append(value.getMessage());
+                }
+            }
+            lightReportErrorBo.setErrorMsg(sb.toString());
+        }
+        return commonPage;
+    }
+
+    /**
+     * 娓呴櫎鏁呴殰鐮�
+     *
+     * @param deviceName
+     * @param address
+     */
+    public void cleanErrorCode(String deviceName, String address) {
+        A7PlcCleanErrorCodeInnerFrame a7PlcCleanErrorCodeInnerFrame = new A7PlcCleanErrorCodeInnerFrame(address);
+
+        A7Frame a7Frame = new A7Frame(A7OrderEnum.REQUEST_PLC_DATA.getCode(), a7PlcCleanErrorCodeInnerFrame);
+        System.out.println(a7Frame + "            -----a7Frame");
+
+        CommonFrame commonFrame = MainBoardInvokeSyncService.getInstance().sendRRPC(deviceName, a7Frame);
+        StoreOperationRecordsUtils.storeInnerFrameData(deviceName, "PLC甯�-鏁呴殰娓呴櫎", a7Frame, commonFrame);
+
+        System.out.println(commonFrame + "            -----commonFrame");
+        A7PlcOperationReportInnerFrame operationReportInnerFrame = new A7PlcOperationReportInnerFrame().transformFrame(commonFrame.getPayload());
+        if (operationReportInnerFrame.isValidate()) {
+            log.error("娓呴櫎鏁呴殰鐮佹垚鍔燂紝code锛�" + deviceName + "锛岀伅澶村湴鍧�锛�" + address);
+        }
+    }
+}
+
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcService.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcService.java
new file mode 100644
index 0000000..0bd2fff
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcService.java
@@ -0,0 +1,647 @@
+package com.sandu.ximon.admin.service;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.HexUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.aliyuncs.iot.model.v20180120.BatchGetDeviceStateResponse;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.github.pagehelper.PageHelper;
+import com.sandu.common.domain.CommonPage;
+import com.sandu.common.execption.BusinessException;
+import com.sandu.common.redis.RedisService;
+import com.sandu.common.service.impl.BaseServiceImpl;
+import com.sandu.ximon.admin.manager.iot.frame.A7Frame;
+import com.sandu.ximon.admin.manager.iot.frame.FrameBuilder;
+import com.sandu.ximon.admin.manager.iot.frame.IRequestFrame;
+import com.sandu.ximon.admin.manager.iot.frame.inner.report.A7PlcOperationReportInnerFrame;
+import com.sandu.ximon.admin.manager.iot.frame.inner.request.*;
+import com.sandu.ximon.admin.manager.iot.frame.inner.response.*;
+import com.sandu.ximon.admin.manager.iot.rrpc.dto.CommonFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.dto.WrapResponseCommonFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A2OrderEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A5OrderEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A7OrderEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.mainboard.MainBoardInvokeSyncService;
+import com.sandu.ximon.admin.param.PlcControlParam;
+import com.sandu.ximon.admin.param.PlcRemarkParam;
+import com.sandu.ximon.admin.redis.LightKey;
+import com.sandu.ximon.admin.security.SecurityUtils;
+import com.sandu.ximon.admin.utils.RedisUtils;
+import com.sandu.ximon.admin.utils.StoreOperationRecordsUtils;
+import com.sandu.ximon.dao.bo.PlcBo;
+import com.sandu.ximon.dao.domain.*;
+import com.sandu.ximon.dao.enums.DeviceRespStatusEnums;
+import com.sandu.ximon.dao.enums.OrderByEnums;
+import com.sandu.ximon.dao.mapper.PlcMapper;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * plc璺伅琛�(Plc)琛ㄦ湇鍔℃帴鍙�
+ *
+ * @author van
+ * @since 2022-12-15 14:45:27
+ */
+@Service
+@Slf4j
+@AllArgsConstructor
+public class PlcService extends BaseServiceImpl<PlcMapper,Plc> {
+
+    private final RedisService redisService;
+    private final PlcReportDataService plcReportDataService;
+    private final PoleBindingService bindingService;
+    private final PoleService poleService;
+    private final RedisUtils redisUtils;
+
+    public List<PlcBo> listPlc(int pageNo, int pageSize, String keyword, Integer order, Integer seq) {
+        Long clientId = SecurityUtils.getClientId();
+
+        //鎺掑簭瀛楁
+        String orderByResult = "plc_id";
+        //姝e簭銆佸�掑彊
+        String orderBySeq = OrderByEnums.ASC.getCode();
+        if (order != null) {
+            switch (order) {
+                case 1:
+                    orderByResult = OrderByEnums.LIGHT_POLE_NAME.getCode();
+                    break;
+                case 2:
+                    orderByResult = OrderByEnums.LIGHT_UPDATE_TIME.getCode();
+                    break;
+                case 3:
+                    orderByResult = OrderByEnums.LIGHT_CREATE_TIME.getCode();
+                    break;
+                default:
+            }
+        }
+        if (seq != null) {
+            switch (seq) {
+                case 1:
+                    orderBySeq = OrderByEnums.ASC.getCode();
+                    break;
+                case 2:
+                    orderBySeq = OrderByEnums.DESC.getCode();
+                    break;
+                default:
+                    break;
+            }
+        }
+        //鎺掑簭鏂瑰紡
+        String orderBy = orderByResult + " " + orderBySeq;
+
+        PageHelper.startPage(pageNo, pageSize, orderBy);
+
+        List<PlcBo> listPlc = baseMapper.listPlc(clientId, keyword);
+
+        // 鑾峰彇鏈�杩戠殑涓婃姤鏃堕棿
+        List<String> deviceCodeList = listPlc.stream().map(Plc::getDeviceCode).collect(Collectors.toList());
+        //鎷嗗垎list
+        List<List<String>> split = CollectionUtil.split(deviceCodeList, 100);
+
+        List<BatchGetDeviceStateResponse.DeviceStatus> deviceStatuses = null;
+        for (List<String> splist : split) {
+            deviceStatuses = MainBoardInvokeSyncService.getInstance().batchGetDeviceState(splist);
+            if (deviceStatuses != null) {
+                for (PlcBo plcBo : listPlc ) {
+                    for (BatchGetDeviceStateResponse.DeviceStatus deviceStatus : deviceStatuses) {
+
+                        if (plcBo.getDeviceCode() != null && plcBo.getDeviceCode().equals(deviceStatus.getDeviceName())) {
+                            if ("ONLINE".equals(deviceStatus.getStatus())) {
+                                plcBo.setOnlineStatus(0);
+                            } else if ("OFFLINE".equals(deviceStatus.getStatus())) {
+                                plcBo.setOnlineStatus(1);
+                            } else {
+                                plcBo.setOnlineStatus(2);
+                            }
+
+                        }
+                    }
+
+                }
+            }
+        }
+
+        if (CollectionUtil.isNotEmpty(deviceCodeList)) {
+            List<PlcReportData> reportDataList = plcReportDataService.getNewestReportByDeviceCode(deviceCodeList);
+            for (PlcBo plcBo : listPlc) {
+                deviceCodeList.forEach(code -> {
+                    PoleBinding bind = bindingService.getPoleIdByMac(code);
+                    if (bind != null && plcBo.getDeviceCode().equals(bind.getDeviceCode())) {
+                        Long poleId = bind.getPoleId();
+                        Pole pole = poleService.getById(poleId);
+                        plcBo.setPoleId(pole.getId());
+                        plcBo.setPoleCode(pole.getDeviceCode());
+                        plcBo.setPoleName(pole.getPoleName());
+                    }
+                });
+                for (PlcReportData plcReportData : reportDataList) {
+                    if (StrUtil.equals(plcBo.getDeviceCode(), plcReportData.getDeviceCode())) {
+                        plcBo.setReportTime(plcReportData.getCreateTime1());
+                        break;
+                    }
+                }
+            }
+        }
+        return listPlc;
+    }
+
+    /**
+     * 鑾峰彇鍗曚釜plc淇℃伅
+     *
+     * @param deviceCode 璁惧鐮�
+     * @return
+     */
+    public Plc getPlc(String deviceCode) {
+        Plc one = getOne(Wrappers.<Plc>lambdaQuery().eq(Plc::getDeviceCode, deviceCode));
+        if (one == null) {
+            return null;
+        } else {
+            Object o = redisService.get(LightKey.REPORT_MAC.key(deviceCode));
+            if (o != null) {
+                one.setOnlineStatus(1);
+            } else {
+                one.setOnlineStatus(0);
+            }
+            return one;
+        }
+    }
+
+    public boolean addRemark(PlcRemarkParam param) {
+        Plc plc = getById(param.getPlcId());
+        if (plc == null) {
+            throw new BusinessException("鎵句笉鍒癙LC");
+        }
+        Plc update = new Plc();
+        update.setPlcId(param.getPlcId());
+        update.setPlcRemark(param.getPlcRemark());
+        return updateById(update);
+    }
+
+    /**
+     * PLC浜害鎺у埗
+     *
+     * @return com.sandu.ximon.dao.enums.DeviceRespStatusEnums
+     */
+    public List<Map<String, Object>> controlBrightness(List<PlcControlParam> paramList) {
+        if (CollectionUtil.isEmpty(paramList)) {
+            throw new BusinessException("鍙傛暟涓嶈兘涓虹┖");
+        }
+
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        for (PlcControlParam param : paramList) {
+            A7PlcBrightnessReqInnerFrame plcControlFrame = new A7PlcBrightnessReqInnerFrame(param.getBrightness(), param.getPlcAddress());
+            A7Frame a7Frame = new A7Frame(A7OrderEnum.REQUEST_PLC_DATA.getCode(), plcControlFrame);
+            Map<String, Object> map = new HashMap<>();
+            try {
+                map.put("deviceCode", param.getDeviceCode());
+                WrapResponseCommonFrame<A7PlcBrightnessRespInnerFrame> frame
+                        = MainBoardInvokeSyncService.getInstance().sendRRPC(param.getDeviceCode(), a7Frame, A7PlcBrightnessRespInnerFrame.class);
+                //瀛樺偍鎺у埗甯ф寚浠�
+                StoreOperationRecordsUtils.storeInnerFrameData(param.getDeviceCode(), "PLC甯�-浜害寮�鍏虫帶鍒�", a7Frame, frame);
+
+                if (frame == null) {
+                    map.put("status", DeviceRespStatusEnums.OTHER_ERROR.getCode());
+                    resultList.add(map);
+                    continue;
+                }
+                String responseStatus = frame.getResponseInnerFrame().getResponseStatus();
+                int status = HexUtil.hexToInt(responseStatus);
+                map.put("status", status);
+                resultList.add(map);
+                // 鏇存柊浜害鎴愬姛锛屼慨鏀瑰埌鏁版嵁搴�
+                if (DeviceRespStatusEnums.SUCCESS.getCode().equals(status)) {
+                    Plc plc = new Plc();
+                    if (param.getPlcAddress().equals("0001")){
+                        plc.setPlcLight1(param.getBrightness());
+                    }
+                    else if (param.getPlcAddress().equals("0002")){
+                        plc.setPlcLight2(param.getBrightness());
+                    }
+                    else if (param.getPlcAddress().equals("0003")){
+                        plc.setPlcLight3(param.getBrightness());
+                    }
+                    else if (param.getPlcAddress().equals("FFFF")){
+                        plc.setPlcLight1(param.getBrightness());
+                        plc.setPlcLight2(param.getBrightness());
+                        plc.setPlcLight3(param.getBrightness());
+
+                    }
+                    update(plc, Wrappers.lambdaUpdate(Plc.class).eq(Plc::getDeviceCode, param.getDeviceCode()));
+
+                }
+            } catch (BusinessException e) {
+                map.put("status", DeviceRespStatusEnums.OTHER_ERROR.getCode());
+                resultList.add(map);
+            }
+        }
+
+        /**
+         * 鏈嶅姟绔壒閲忔帶鐏棩蹇楄褰曞紑濮�
+         */
+        String content = "{PLC鎺х伅璇锋眰锛�" + paramList.toString()
+                + "锛� PLC鎺х伅缁撴灉锛�" + resultList.toString() + "}";
+        List<String> codeList = new ArrayList<>();
+        for (PlcControlParam bean : paramList) {
+            codeList.add(bean.getDeviceCode());
+        }
+        StoreOperationRecordsUtils.storeOperationData(codeList, null, "鏈嶅姟绔壒閲廝LC鎺х伅", content);
+        /**
+         * 鏈嶅姟绔壒閲忔帶鐏棩蹇楄褰曠粨鏉�
+         */
+
+        return resultList;
+
+    }
+
+    /**
+     * PLC璁剧疆蹇冭烦鏃堕棿
+     *
+     * @return com.sandu.ximon.dao.enums.DeviceRespStatusEnums
+     */
+    public List<Map<String, Object>> setHeartBeatTime(List<PlcControlParam> paramList) {
+        if (CollectionUtil.isEmpty(paramList)) {
+            throw new BusinessException("鍙傛暟涓嶈兘涓虹┖");
+        }
+
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        for (PlcControlParam param : paramList) {
+            A7PlcSettingHeartBeatTimeReqInnerFrame plcControlFrame = new A7PlcSettingHeartBeatTimeReqInnerFrame(param.getHeartBeatTime());
+            A7Frame a7Frame = new A7Frame(A7OrderEnum.REQUEST_PLC_DATA.getCode(), plcControlFrame);
+            Map<String, Object> map = new HashMap<>();
+            try {
+                map.put("deviceCode", param.getDeviceCode());
+                WrapResponseCommonFrame<A7PlcBrightnessRespInnerFrame> frame
+                        = MainBoardInvokeSyncService.getInstance().sendRRPC(param.getDeviceCode(), a7Frame, A7PlcBrightnessRespInnerFrame.class);
+                //瀛樺偍鎺у埗甯ф寚浠�
+                StoreOperationRecordsUtils.storeInnerFrameData(param.getDeviceCode(), "PLC甯�-璁剧疆PLC蹇冭烦鍖呴棿闅旀椂闂�", a7Frame, frame);
+
+                if (frame == null) {
+                    map.put("status", DeviceRespStatusEnums.OTHER_ERROR.getCode());
+                    resultList.add(map);
+                    continue;
+                }
+                String responseStatus = frame.getResponseInnerFrame().getResponseStatus();
+                int status = HexUtil.hexToInt(responseStatus);
+                map.put("status", status);
+                resultList.add(map);
+            } catch (BusinessException e) {
+                map.put("status", DeviceRespStatusEnums.OTHER_ERROR.getCode());
+                resultList.add(map);
+            }
+        }
+
+        /**
+         * 鏈嶅姟绔壒閲忔帶鐏棩蹇楄褰曞紑濮�
+         */
+        String content = "{PLC璁剧疆蹇冭烦鏃堕棿锛�" + paramList.toString()
+                + "锛� PLC璁剧疆蹇冭烦鏃堕棿缁撴灉锛�" + resultList.toString() + "}";
+        List<String> codeList = new ArrayList<>();
+        for (PlcControlParam bean : paramList) {
+            codeList.add(bean.getDeviceCode());
+        }
+        StoreOperationRecordsUtils.storeOperationData(codeList, null, "PLC璁剧疆蹇冭烦鏃堕棿", content);
+        /**
+         * 鏈嶅姟绔壒閲忔帶鐏棩蹇楄褰曠粨鏉�
+         */
+
+        return resultList;
+
+    }
+
+    /**
+     * PLC 鏌ヨ蹇冭烦鏃堕棿
+     *
+     * @return com.sandu.ximon.dao.enums.DeviceRespStatusEnums
+     */
+    public List<Map<String, Object>> queryHeartBeatTime(List<PlcControlParam> paramList) {
+        if (CollectionUtil.isEmpty(paramList)) {
+            throw new BusinessException("鍙傛暟涓嶈兘涓虹┖");
+        }
+
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        for (PlcControlParam param : paramList) {
+            A7PlcQueryHeartBeatTimeReqInnerFrame plcControlFrame = new A7PlcQueryHeartBeatTimeReqInnerFrame();
+            A7Frame a7Frame = new A7Frame(A7OrderEnum.REQUEST_PLC_DATA.getCode(), plcControlFrame);
+            Map<String, Object> map = new HashMap<>();
+            try {
+                map.put("deviceCode", param.getDeviceCode());
+                WrapResponseCommonFrame<A7PlcQueryHeartBeatTimeRespInnerFrame> frame
+                        = MainBoardInvokeSyncService.getInstance().sendRRPC(param.getDeviceCode(), a7Frame,  A7PlcQueryHeartBeatTimeRespInnerFrame.class);
+                //瀛樺偍鎺у埗甯ф寚浠�
+                StoreOperationRecordsUtils.storeInnerFrameData(param.getDeviceCode(), "PLC甯�-璁剧疆PLC蹇冭烦鍖呴棿闅旀椂闂�", a7Frame, frame);
+
+                if (frame == null) {
+                    map.put("status", DeviceRespStatusEnums.OTHER_ERROR.getCode());
+                    resultList.add(map);
+                    continue;
+                }
+                String time = frame.getResponseInnerFrame().getTime();
+                map.put("status", 0);
+                map.put("time",time);
+                resultList.add(map);
+            } catch (BusinessException e) {
+                map.put("status", DeviceRespStatusEnums.OTHER_ERROR.getCode());
+                resultList.add(map);
+            }
+        }
+
+        /**
+         * 鏈嶅姟绔壒閲忔帶鐏棩蹇楄褰曞紑濮�
+         */
+        String content = "{PLC鏌ヨ蹇冭烦鏃堕棿锛�" + paramList.toString()
+                + "锛� PLC鏌ヨ蹇冭烦鏃堕棿缁撴灉锛�" + resultList.toString() + "}";
+        List<String> codeList = new ArrayList<>();
+        for (PlcControlParam bean : paramList) {
+            codeList.add(bean.getDeviceCode());
+        }
+        StoreOperationRecordsUtils.storeOperationData(codeList, null, "PLC鏌ヨ蹇冭烦鏃堕棿", content);
+        /**
+         * 鏈嶅姟绔壒閲忔帶鐏棩蹇楄褰曠粨鏉�
+         */
+
+        return resultList;
+
+    }
+
+    /**
+     * PLC 鏌ヨ蹇冭烦鍖�
+     *
+     * @return com.sandu.ximon.dao.enums.DeviceRespStatusEnums
+     */
+    public List<Map<String, Object>> queryHeartBeatData(List<PlcControlParam> paramList) {
+        if (CollectionUtil.isEmpty(paramList)) {
+            throw new BusinessException("鍙傛暟涓嶈兘涓虹┖");
+        }
+
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        for (PlcControlParam param : paramList) {
+            A7PlcQueryHeartBeatDataReqInnerFrame plcControlFrame = new A7PlcQueryHeartBeatDataReqInnerFrame();
+            A7Frame a7Frame = new A7Frame(A7OrderEnum.REQUEST_PLC_DATA.getCode(), plcControlFrame);
+            Map<String, Object> map = new HashMap<>();
+            try {
+                map.put("deviceCode", param.getDeviceCode());
+                WrapResponseCommonFrame<A7PlcQueryHeartBeatDataRespInnerFrame> frame
+                        = MainBoardInvokeSyncService.getInstance().sendRRPC(param.getDeviceCode(), a7Frame,  A7PlcQueryHeartBeatDataRespInnerFrame.class);
+
+                if (frame == null) {
+                    map.put("status", DeviceRespStatusEnums.OTHER_ERROR.getCode());
+                    resultList.add(map);
+                    continue;
+                }
+                String data = JSON.toJSONString(frame.getResponseInnerFrame().getHeartbeatReportInnerFrame().getHeartBeatDataPackage());
+                map.put("status", 0);
+                map.put("heartBeatData",data);
+                resultList.add(map);
+            } catch (BusinessException e) {
+                map.put("status", DeviceRespStatusEnums.OTHER_ERROR.getCode());
+                resultList.add(map);
+            }
+        }
+
+
+
+        return resultList;
+
+    }
+
+
+    /**
+     * PLC 鏌ヨ鐗堟湰
+     *
+     * @return com.sandu.ximon.dao.enums.DeviceRespStatusEnums
+     */
+    public List<Map<String, Object>> queryVersion(List<PlcControlParam> paramList) {
+        if (CollectionUtil.isEmpty(paramList)) {
+            throw new BusinessException("鍙傛暟涓嶈兘涓虹┖");
+        }
+
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        for (PlcControlParam param : paramList) {
+            A7PlcQueryVersionReqInnerFrame plcControlFrame = new A7PlcQueryVersionReqInnerFrame();
+            A7Frame a7Frame = new A7Frame(A7OrderEnum.REQUEST_PLC_DATA.getCode(), plcControlFrame);
+            Map<String, Object> map = new HashMap<>();
+            try {
+                map.put("deviceCode", param.getDeviceCode());
+                WrapResponseCommonFrame<A7PlcQueryVersionRespInnerFrame> frame
+                        = MainBoardInvokeSyncService.getInstance().sendRRPC(param.getDeviceCode(), a7Frame,  A7PlcQueryVersionRespInnerFrame.class);
+
+                if (frame == null) {
+                    map.put("status", DeviceRespStatusEnums.OTHER_ERROR.getCode());
+                    resultList.add(map);
+                    continue;
+                }
+                map.put("status", 0);
+                map.put("hardwareVersion",frame.getResponseInnerFrame().getHardwareVersionDouble());
+                map.put("softwareVersion",frame.getResponseInnerFrame().getSoftwareVersionDouble());
+
+                resultList.add(map);
+            } catch (BusinessException e) {
+                map.put("status", DeviceRespStatusEnums.OTHER_ERROR.getCode());
+                resultList.add(map);
+            }
+        }
+
+        return resultList;
+
+    }
+
+
+    /**
+     * PLC閲嶅惎
+     *
+     * @return com.sandu.ximon.dao.enums.DeviceRespStatusEnums
+     */
+    public List<Map<String, Object>> reboot(List<PlcControlParam> paramList) {
+        if (CollectionUtil.isEmpty(paramList)) {
+            throw new BusinessException("鍙傛暟涓嶈兘涓虹┖");
+        }
+
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        for (PlcControlParam param : paramList) {
+            A7PlcRebootReqInnerFrame plcControlFrame = new A7PlcRebootReqInnerFrame();
+            A7Frame a7Frame = new A7Frame(A7OrderEnum.REQUEST_PLC_DATA.getCode(), plcControlFrame);
+            Map<String, Object> map = new HashMap<>();
+            try {
+                map.put("deviceCode", param.getDeviceCode());
+                WrapResponseCommonFrame<A7PlcBrightnessRespInnerFrame> frame
+                        = MainBoardInvokeSyncService.getInstance().sendRRPC(param.getDeviceCode(), a7Frame, A7PlcBrightnessRespInnerFrame.class);
+                //瀛樺偍鎺у埗甯ф寚浠�
+                StoreOperationRecordsUtils.storeInnerFrameData(param.getDeviceCode(), "PLC甯�-璁剧疆PLC閲嶅惎", a7Frame, frame);
+
+                if (frame == null) {
+                    map.put("status", DeviceRespStatusEnums.OTHER_ERROR.getCode());
+                    resultList.add(map);
+                    continue;
+                }
+                String responseStatus = frame.getResponseInnerFrame().getResponseStatus();
+                int status = HexUtil.hexToInt(responseStatus);
+                map.put("status", status);
+                resultList.add(map);
+            } catch (BusinessException e) {
+                map.put("status", DeviceRespStatusEnums.OTHER_ERROR.getCode());
+                resultList.add(map);
+            }
+        }
+
+        /**
+         * 鏈嶅姟绔壒閲忔帶鐏棩蹇楄褰曞紑濮�
+         */
+        String content = "{PLC閲嶅惎锛�" + paramList.toString()
+                + "锛� PLC閲嶅惎锛�" + resultList.toString() + "}";
+        List<String> codeList = new ArrayList<>();
+        for (PlcControlParam bean : paramList) {
+            codeList.add(bean.getDeviceCode());
+        }
+        StoreOperationRecordsUtils.storeOperationData(codeList, null, "PLC閲嶅惎", content);
+        /**
+         * 鏈嶅姟绔壒閲忔帶鐏棩蹇楄褰曠粨鏉�
+         */
+
+        return resultList;
+
+    }
+
+
+    /**
+     * PLC鎭㈠鍑哄巶璁剧疆
+     *
+     * @return com.sandu.ximon.dao.enums.DeviceRespStatusEnums
+     */
+    public List<Map<String, Object>> reset(List<PlcControlParam> paramList) {
+        if (CollectionUtil.isEmpty(paramList)) {
+            throw new BusinessException("鍙傛暟涓嶈兘涓虹┖");
+        }
+
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        for (PlcControlParam param : paramList) {
+            A7PlcResetReqInnerFrame plcControlFrame = new A7PlcResetReqInnerFrame();
+            A7Frame a7Frame = new A7Frame(A7OrderEnum.REQUEST_PLC_DATA.getCode(), plcControlFrame);
+            Map<String, Object> map = new HashMap<>();
+            try {
+                map.put("deviceCode", param.getDeviceCode());
+                WrapResponseCommonFrame<A7PlcResetRespInnerFrame> frame
+                        = MainBoardInvokeSyncService.getInstance().sendRRPC(param.getDeviceCode(), a7Frame, A7PlcResetRespInnerFrame.class);
+                //瀛樺偍鎺у埗甯ф寚浠�
+                StoreOperationRecordsUtils.storeInnerFrameData(param.getDeviceCode(), "PLC甯�-璁剧疆PLC鎭㈠鍑哄巶璁剧疆", a7Frame, frame);
+
+                if (frame == null) {
+                    map.put("status", DeviceRespStatusEnums.OTHER_ERROR.getCode());
+                    resultList.add(map);
+                    continue;
+                }
+
+                String responseStatus = frame.getResponseInnerFrame().getResponseStatus();
+                int status = HexUtil.hexToInt(responseStatus);
+
+                IRequestFrame iRequestFrame = FrameBuilder.builderA2().innerFrame(new EmptyRequestInnerFrame()).orderType(A2OrderEnum.REQUEST_MAIN_BOARD_RESET.getCode()).build();
+                CommonFrame rebootFrame = MainBoardInvokeSyncService.getInstance().sendRRPC(param.getDeviceCode(), iRequestFrame);
+
+                boolean b = false;
+
+                if (!"00".equals(rebootFrame.getPayload())) {
+                    map.put("status", DeviceRespStatusEnums.OTHER_ERROR.getCode());
+                    resultList.add(map);
+                    continue;
+                }
+
+                map.put("status", status);
+                resultList.add(map);
+            } catch (BusinessException e) {
+                map.put("status", DeviceRespStatusEnums.OTHER_ERROR.getCode());
+                resultList.add(map);
+            }
+        }
+
+        /**
+         * 鏈嶅姟绔壒閲忔帶鐏棩蹇楄褰曞紑濮�
+         */
+        String content = "{PLC鎭㈠鍑哄巶璁剧疆锛�" + paramList.toString()
+                + "锛� PLC鎭㈠鍑哄巶璁剧疆锛�" + resultList.toString() + "}";
+        List<String> codeList = new ArrayList<>();
+        for (PlcControlParam bean : paramList) {
+            codeList.add(bean.getDeviceCode());
+        }
+        StoreOperationRecordsUtils.storeOperationData(codeList, null, "PLC鎭㈠鍑哄巶璁剧疆", content);
+        /**
+         * 鏈嶅姟绔壒閲忔帶鐏棩蹇楄褰曠粨鏉�
+         */
+
+        return resultList;
+
+    }
+
+
+    /**
+     * 鑾峰彇鐢ㄦ埛鎵�鏈夌殑璁惧鐮�
+     */
+    public CommonPage<String> listDeviceCode(int pageNo, int pageSize, String keyword, String deviceCode, String orderBy) {
+        List<String> list;
+        if (SecurityUtils.getClientId() != null) {
+            PageHelper.startPage(pageNo, pageSize);
+            list = baseMapper.listCode(SecurityUtils.getUserId(), keyword, deviceCode);
+        } else {
+
+            PageHelper.startPage(pageNo, pageSize, orderBy);
+            list = baseMapper.listCode(null, keyword, deviceCode);
+        }
+
+        return CommonPage.restPage(list);
+    }
+
+    public void timeSynchronizationInitiative(String deviceCode, String destinationAddress) {
+        Plc plc = getPlc(deviceCode);
+        if (plc == null) {
+            log.error("PLC涓诲姩鍚屾鏃堕棿璇锋眰寮傚父锛孭LC淇℃伅涓嶅瓨鍦紒");
+            return;
+        }
+        SetCalendar(plc.getPlcId(), destinationAddress);
+
+    }
+    /**
+     * 璁剧疆鏃ュ巻锛堝悓蹇冭烦鍖呬腑鐨�6瀛楄妭鏃ユ湡鏃堕棿锛�
+     *
+     * @return
+     */
+    public String SetCalendar(Long plcId, String address) {
+        Calendar cal = Calendar.getInstance();
+        //鑾峰彇褰撳墠鏃堕棿
+        int year = cal.get(Calendar.YEAR);
+        int month = cal.get(Calendar.MONTH);
+        int day = cal.get(Calendar.DATE);
+        int hour = cal.get(Calendar.HOUR_OF_DAY);
+        int min = cal.get(Calendar.MINUTE);
+        int sec = cal.get(Calendar.SECOND);
+
+
+        Plc one = getById(plcId);
+        if (one == null) {
+            System.out.println("plc涓嶅瓨鍦紒");
+        }
+
+        A7PlcSetCalendarReqInnerFrame setCalendarReqInnerFrame =
+                new A7PlcSetCalendarReqInnerFrame(address, year % 100, month + 1, day, hour, min, sec);
+
+        A7Frame a7Frame = new A7Frame(A5OrderEnum.REQUEST_LIGHT_DATA.getCode(), setCalendarReqInnerFrame);
+        System.out.println(a7Frame + "            -----A7Frame");
+
+        CommonFrame commonFrame;
+
+        commonFrame = MainBoardInvokeSyncService.getInstance().sendRRPC(one.getDeviceCode(), a7Frame);
+        StoreOperationRecordsUtils.storeInnerFrameData(one.getDeviceCode(), "PLC甯�-璁剧疆鏃ュ巻", a7Frame, commonFrame);
+
+        System.out.println(commonFrame + "            -----commonFrame");
+
+        A7PlcOperationReportInnerFrame operationReportInnerFrame = new A7PlcOperationReportInnerFrame().transformFrame(commonFrame.getPayload());
+        if (operationReportInnerFrame.isValidate()) {
+            return operationReportInnerFrame.getState();
+        } else {
+            throw new BusinessException("鏁版嵁鏍¢獙閿欒锛岃閲嶆柊璇锋眰");
+        }
+    }
+}
+
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcTaskPoleRelationService.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcTaskPoleRelationService.java
new file mode 100644
index 0000000..074c7ba
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcTaskPoleRelationService.java
@@ -0,0 +1,17 @@
+package com.sandu.ximon.admin.service;
+import com.sandu.common.service.impl.BaseServiceImpl;
+import com.sandu.ximon.dao.domain.PlcTaskPoleRelation;
+import com.sandu.ximon.dao.mapper.PlcTaskPoleRelationMapper;
+import org.springframework.stereotype.Service;
+
+/**
+ * plc浠诲姟鍜岀伅鏉嗗叧绯昏〃(PlcTaskPoleRelation)琛ㄦ湇鍔℃帴鍙�
+ *
+ * @author van
+ * @since 2022-12-19 16:54:14
+ */
+@Service
+public class PlcTaskPoleRelationService extends BaseServiceImpl<PlcTaskPoleRelationMapper, PlcTaskPoleRelation> {
+
+}
+
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcTaskService.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcTaskService.java
new file mode 100644
index 0000000..a7bd63a
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcTaskService.java
@@ -0,0 +1,909 @@
+package com.sandu.ximon.admin.service;
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.HexUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.github.pagehelper.Page;
+import com.github.pagehelper.PageHelper;
+import com.sandu.common.execption.BusinessException;
+import com.sandu.common.object.BaseConditionVO;
+import com.sandu.common.service.impl.BaseServiceImpl;
+import com.sandu.common.util.SpringContextHolder;
+import com.sandu.ximon.admin.dto.PlcTaskDto;
+import com.sandu.ximon.admin.dto.PlcTaskDto;
+import com.sandu.ximon.admin.dto.SingleLightOrderDto;
+import com.sandu.ximon.admin.manager.iot.frame.FrameBuilder;
+import com.sandu.ximon.admin.manager.iot.frame.IRequestFrame;
+import com.sandu.ximon.admin.manager.iot.frame.inner.request.A7PlcTimerReqInnerFrame;
+import com.sandu.ximon.admin.manager.iot.frame.inner.response.A7PlcTimerRespInnerFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.dto.WrapResponseCommonFrame;
+import com.sandu.ximon.admin.manager.iot.rrpc.enums.A7OrderEnum;
+import com.sandu.ximon.admin.manager.iot.rrpc.mainboard.MainBoardInvokeSyncService;
+import com.sandu.ximon.admin.manager.iot.rrpc.util.SupplementUtils;
+import com.sandu.ximon.admin.param.PlcTaskIssueParam;
+import com.sandu.ximon.admin.param.PlcTaskParam;
+import com.sandu.ximon.admin.security.SecurityUtils;
+import com.sandu.ximon.admin.utils.StoreOperationRecordsUtils;
+import com.sandu.ximon.admin.utils.TaskOrderUtil;
+import com.sandu.ximon.admin.vo.*;
+import com.sandu.ximon.dao.domain.*;
+import com.sandu.ximon.dao.enums.DeviceRespStatusEnums;
+import com.sandu.ximon.dao.enums.OrderByEnums;
+import com.sandu.ximon.dao.mapper.PlcTaskMapper;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * plc浠诲姟琛�(PlcTask)琛ㄦ湇鍔℃帴鍙�
+ *
+ * @author van
+ * @since 2022-12-19 16:53:41
+ */
+@Service
+@Slf4j
+@AllArgsConstructor
+public class PlcTaskService extends BaseServiceImpl<PlcTaskMapper,PlcTask> {
+
+    private final PoleService poleService;
+
+    private final ClientService clientService;
+
+    private final PlcTaskPoleRelationService plcTaskPoleRelationService;
+
+    private final PlcTaskMapper plcTaskMapper;
+
+    /**
+     * 鏍规嵁浠诲姟淇℃伅杞垚甯ц礋鑽�
+     *
+     * @return 璺伅瀹氭椂鍣ㄥ垪琛�
+     */
+    private String buildControlFramePayload(String openOrder, String closeOrder, String controlOrder, Integer week) {
+
+        // 娣诲姞寮�鐏畾鏃跺櫒
+        SingleLightOrderDto openLightOrder = TaskOrderUtil.parseLightOrder(openOrder);
+        SingleLightOrderDto closeLightOrder = TaskOrderUtil.parseLightOrder(closeOrder);
+        String[] controlOrderArray = StrUtil.split(controlOrder, PlcTaskParam.REQUEST_ORDER_LENGTH);
+        Integer[] weekArrays = TaskOrderUtil.parseLightCronWeek2List(week).toArray(new Integer[0]);
+        if (openLightOrder == null || closeLightOrder == null) {
+            throw new BusinessException("瑙f瀽PLC鍛戒护澶辫触");
+        }
+        if (ArrayUtil.isEmpty(weekArrays)) {
+            throw new BusinessException("璇疯缃槦鏈�");
+        }
+
+        StringBuilder sb = new StringBuilder();
+        String weekHex = SupplementUtils.suppleZero(HexUtil.toHex(week), 2);
+
+        // 鎷兼帴寮�鐏懡浠�
+        sb.append(weekHex);
+        sb.append(SupplementUtils.suppleZero(HexUtil.toHex(openLightOrder.getHour()), 2));
+        sb.append(SupplementUtils.suppleZero(HexUtil.toHex(openLightOrder.getMinute()), 2));
+        sb.append(SupplementUtils.suppleZero(HexUtil.toHex(openLightOrder.getBrightness()), 2));
+
+        // 鎷兼帴鍏崇伅鍛戒护
+        sb.append(weekHex);
+        sb.append(SupplementUtils.suppleZero(HexUtil.toHex(closeLightOrder.getHour()), 2));
+        sb.append(SupplementUtils.suppleZero(HexUtil.toHex(closeLightOrder.getMinute()), 2));
+        sb.append(SupplementUtils.suppleZero(HexUtil.toHex(closeLightOrder.getBrightness()), 2));
+
+        // 鎷兼帴浜害鎺х伅鍛戒护
+        for (String controlOrderStr : controlOrderArray) {
+            SingleLightOrderDto controlLightOrder = TaskOrderUtil.parseLightOrder(controlOrderStr);
+            if (controlLightOrder != null) {
+                sb.append(weekHex);
+                sb.append(SupplementUtils.suppleZero(HexUtil.toHex(controlLightOrder.getHour()), 2));
+                sb.append(SupplementUtils.suppleZero(HexUtil.toHex(controlLightOrder.getMinute()), 2));
+                sb.append(SupplementUtils.suppleZero(HexUtil.toHex(controlLightOrder.getBrightness()), 2));
+            }
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * 鐢ㄤ簬浠诲姟鏂板,涓嬪彂
+     *
+     * @param plcTask
+     * @param poleIdList
+     * @param framePayload
+     * @param plcAddress
+     * @return
+     */
+    private List<PlcTaskPoleRelation> sendControllerFrame(PlcTask plcTask, List<Long> poleIdList, String framePayload, String plcAddress) {
+        List<PlcTaskPoleRelation> plcTaskPoleRelationList = new ArrayList<>();
+        //鎴愬姛
+        List<PlcTaskPoleRelation> success = new ArrayList<>();
+        //澶辫触
+        List<PlcTaskPoleRelation> fail = new ArrayList<>();
+
+        Map map = new HashMap();
+
+        List<Pole> poles = poleService.listByIds(poleIdList);
+        if (CollectionUtil.isEmpty(poles)) {
+            return null;
+        }
+
+        for (Pole pole : poles) {
+            if (pole.getDeviceCode() == null || pole.getDeviceCode().equals("")) {
+                removeById(plcTask.getTaskId());
+                throw new BusinessException("缂栬緫鐨勭伅鏉嗘垨鍘熸湁浠诲姟鐨勭伅鏉嗕笉瀛樺湪mac,涓嶈兘涓嬪彂浠诲姟   璇锋鏌ョ伅鏉嗘槸鍚﹀瓨鍦≒LC");
+            }
+            PlcTaskPoleRelation plcTaskPoleRelation = new PlcTaskPoleRelation();
+            plcTaskPoleRelation.setPoleId(pole.getId());
+            plcTaskPoleRelation.setTaskId(plcTask.getTaskId());
+
+            // rrpc 鍙戠敓瀹氭椂鍛戒护
+            plcTaskPoleRelation.setDeviceCode(pole.getDeviceCode());
+            plcTaskPoleRelation.setPlcAddress(plcAddress);
+            // rrpc 鍙戠敓瀹氭椂鍛戒护
+            try {
+                A7PlcTimerRespInnerFrame a7PlcTimerRespInnerFrame = sendTimeRRpc(framePayload, pole.getDeviceCode(), plcAddress);
+                if (a7PlcTimerRespInnerFrame == null) {
+                    plcTaskPoleRelation.setIssueStatus(DeviceRespStatusEnums.OTHER_ERROR.getCode());
+                } else {
+                    plcTaskPoleRelation.setIssueStatus(HexUtil.hexToInt(a7PlcTimerRespInnerFrame.getResponseStatus()));
+                }
+            } catch (BusinessException e) {
+                e.printStackTrace();
+                plcTaskPoleRelation.setIssueStatus(DeviceRespStatusEnums.OTHER_ERROR.getCode());
+            }
+            plcTaskPoleRelationList.add(plcTaskPoleRelation);
+        }
+
+//        }
+        return plcTaskPoleRelationList;
+    }
+
+    /**
+     * 鍙戦�佺伅鎺ц姹�
+     *
+     * @param framePayload 鐏帶鍙傛暟
+     * @param deviceCode   璁惧鍚�
+     * @return 杩斿洖甯�
+     */
+    public A7PlcTimerRespInnerFrame sendTimeRRpc(String framePayload, String deviceCode, String plcAddress) {
+        IRequestFrame requestFrame = FrameBuilder.builderA7().innerFrame(new A7PlcTimerReqInnerFrame(framePayload, plcAddress)).orderType(A7OrderEnum.REQUEST_PLC_DATA.getCode()).build();
+        System.out.println(requestFrame + "          --------requestFrame");
+
+        WrapResponseCommonFrame<A7PlcTimerRespInnerFrame> responseCommonFrame = MainBoardInvokeSyncService.getInstance().sendRRPC(deviceCode, requestFrame, A7PlcTimerRespInnerFrame.class);
+        System.out.println(responseCommonFrame + "         -----------responseCommonFrame");
+        StoreOperationRecordsUtils.storeInnerFrameData(deviceCode, "PLC甯�-瀹氭椂", requestFrame, responseCommonFrame);
+        return Optional.ofNullable(responseCommonFrame).map(WrapResponseCommonFrame::getResponseInnerFrame).orElse(null);
+    }
+
+    /**
+     * 鐢ㄤ簬浠诲姟缂栬緫
+     *
+     * @param poleIdList
+     * @param framePayload
+     * @param plcAddress
+     * @return
+     */
+    private Map<String, List<PlcTaskPoleRelation>> sendControllerFrame(List<Long> poleIdList, String framePayload, String plcAddress) {
+
+        System.out.println("framePayload:" + framePayload);
+        List<PlcTaskPoleRelation> plcTaskPoleRelationList = new ArrayList<>();
+        //鎴愬姛
+        List<PlcTaskPoleRelation> success = new ArrayList<>();
+        //澶辫触
+        List<PlcTaskPoleRelation> fail = new ArrayList<>();
+
+        Map<String, List<PlcTaskPoleRelation>> map = new HashMap();
+
+        List<Pole> poles = poleService.listByIds(poleIdList);
+        if (CollectionUtil.isEmpty(poles)) {
+            return null;
+        }
+
+        for (Pole pole : poles) {
+            if (pole.getDeviceCode() == null || pole.getDeviceCode().equals("")) {
+                throw new BusinessException("缂栬緫鐨勭伅鏉嗘垨鍘熸湁浠诲姟鐨勭伅鏉嗕笉瀛樺湪mac,涓嶈兘涓嬪彂浠诲姟   璇锋鏌ョ伅鏉嗘槸鍚﹀瓨鍦≒LC");
+            }
+            PlcTaskPoleRelation plcTaskPoleRelation = new PlcTaskPoleRelation();
+            plcTaskPoleRelation.setPoleId(pole.getId());
+            //鍏崇郴琛ㄦ彃鍏ョ伅澶村湴鍧�
+            plcTaskPoleRelation.setPlcAddress(plcAddress);
+
+
+            // rrpc 鍙戠敓瀹氭椂鍛戒护
+            plcTaskPoleRelation.setPlcAddress(plcAddress);
+            plcTaskPoleRelation.setDeviceCode(pole.getDeviceCode());
+            // rrpc 鍙戠敓瀹氭椂鍛戒护
+            try {
+                A7PlcTimerRespInnerFrame a7PlcTimerRespInnerFrame = sendTimeRRpc(framePayload, pole.getDeviceCode(), plcAddress);
+                if (a7PlcTimerRespInnerFrame == null) {
+                    plcTaskPoleRelation.setIssueStatus(DeviceRespStatusEnums.OTHER_ERROR.getCode());
+                    fail.add(plcTaskPoleRelation);
+                } else {
+                    plcTaskPoleRelation.setIssueStatus(HexUtil.hexToInt(a7PlcTimerRespInnerFrame.getResponseStatus()));
+                    success.add(plcTaskPoleRelation);
+                }
+            } catch (BusinessException e) {
+                plcTaskPoleRelation.setIssueStatus(DeviceRespStatusEnums.OTHER_ERROR.getCode());
+                fail.add(plcTaskPoleRelation);
+            }
+            plcTaskPoleRelationList.add(plcTaskPoleRelation);
+        }
+
+        map.put("success", success);
+        map.put("fail", fail);
+        map.put("all", plcTaskPoleRelationList);
+        log.error("鍙戦�佹帶鍒跺櫒甯х粨鏋滐細{}", map);
+        return map;
+    }
+
+
+
+    /**
+     * 鏂板浠诲姟
+     *
+     * @param param
+     * @return
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public String AddPlcTask(PlcTaskParam param) {
+        if (StrUtil.length(param.getControlOrder()) % PlcTaskParam.REQUEST_ORDER_LENGTH != 0) {
+            throw new BusinessException("鐏帶鍛戒护鏍煎紡涓嶆纭�");
+        }
+
+        if (!"0001".equals(param.getPlcAddress())
+                && !"0002".equals(param.getPlcAddress())
+                    && !"0003".equals(param.getPlcAddress())) {
+            throw new BusinessException("鐏ご鍦板潃鏍煎紡涓嶆纭�");
+        }
+
+
+        int week = 0;
+        for (Integer w : param.getWeekList()) {
+            week |= w;
+        }
+
+        PlcTask newPlcTask = new PlcTask();
+        newPlcTask.setTaskName(param.getTaskName());
+
+        newPlcTask.setClientId(clientService.getClientId(SecurityUtils.getUserId()));
+        newPlcTask.setUserId(SecurityUtils.getUserId());
+
+        newPlcTask.setWeek(week);
+        newPlcTask.setCreateUser(SecurityUtils.getUsername());
+        newPlcTask.setControlOrder(param.getControlOrder());
+        newPlcTask.setOpenOrder(param.getOpenOrder());
+        newPlcTask.setCloseOrder(param.getCloseOrder());
+        newPlcTask.setPlcAdress(param.getPlcAddress());
+        newPlcTask.setUpdateTime(LocalDateTime.now());
+        newPlcTask.setFramePayload(buildControlFramePayload(param.getOpenOrder(), param.getCloseOrder(), param.getControlOrder(), week));
+
+        if (!save(newPlcTask)) {
+            throw new BusinessException("淇濆瓨PLC浠诲姟澶辫触");
+        }
+
+        List<String> poleCodeList = new ArrayList<>();
+        //浼犲叆鐨勭伅鏉唅d闆嗗悎
+        List<Long> poleIdList = new ArrayList<>();
+        //鍘婚噸
+        for (Long item : param.getPoleIdList()) {
+            if (!poleIdList.contains(item)) {
+                poleIdList.add(item);
+            }
+        }
+
+        if (CollectionUtil.isNotEmpty(poleIdList)) {
+            List<Pole> poleList = SpringContextHolder.getBean(PoleService.class).listByIds(poleIdList);
+            if (CollectionUtil.isNotEmpty(poleList)) {
+                poleCodeList = poleList.stream().map(Pole::getDeviceCode).collect(Collectors.toList());
+            }
+        }
+
+        String content = "{浠诲姟ID锛�" + newPlcTask.getTaskId() + "锛� 浠诲姟鍚嶏細" + newPlcTask.getTaskName() + "}锛寋鍐呭抚鎸囦护" + newPlcTask.getFramePayload() + "锛� 鐏潌ID锛�" + poleIdList.toString() + "锛� 鎺у埗鐨勭伅澶村湴鍧�锛�" + param.getPlcAddress() + " }";
+        StoreOperationRecordsUtils.storeOperationData(poleCodeList, null, "鏂板PLC浠诲姟", content);
+
+        //璁板綍杩欎簺鐏潌鍘熷厛鐨勪换鍔�
+        List<PlcTaskPoleRelation> oldPlcTaskStatusAndPoles = plcTaskPoleRelationService.list(Wrappers.lambdaQuery(PlcTaskPoleRelation.class)
+                .in(PlcTaskPoleRelation::getPoleId, poleIdList).eq(PlcTaskPoleRelation::getPlcAddress, param.getPlcAddress()));
+
+
+        List<PlcTaskPoleRelation> newPoleMap = new ArrayList<>();
+        if (!poleIdList.isEmpty()) {
+            //鏂扮伅鏉嗕笅鍙戞柊浠诲姟
+            newPoleMap = sendControllerFrame(newPlcTask, poleIdList, newPlcTask.getFramePayload(), param.getPlcAddress());
+
+        }
+
+        newPoleMap.forEach(
+                commend -> {
+                    //寮�鍏崇伅鏃堕棿
+                    commend.setSysScheduled(JSON.toJSONString(newPlcTask));
+                    System.out.println(commend.getIssueStatus() + "鐘舵��");
+                    if (commend.getIssueStatus() == 0) {
+                        //涓嬪彂鎴愬姛  鏇存柊绯荤粺瀹氭椂鍜岀‖浠跺畾鏃�
+                        commend.setDeviceScheduled(JSON.toJSONString(newPlcTask));
+                    } else {
+                        //涓嬪彂澶辫触  鏇存柊绯荤粺瀹氭椂  淇濈暀纭欢瀹氭椂 纭欢瀹氭椂
+//                        commend.setSysScheduled(s);
+                        oldPlcTaskStatusAndPoles.forEach(task -> {
+                            if (task.getPlcAddress().equals(commend.getPlcAddress()) && task.getDeviceCode().equals(commend.getDeviceCode())) {
+                                //鍚屼竴涓伅澶�
+                                commend.setDeviceScheduled(task.getDeviceScheduled());
+                            }
+                        });
+
+                    }
+                }
+        );
+
+        /**
+         * 涓嬪彂璺伅浠诲姟鏃ュ織璁板綍寮�濮�
+         */
+
+        String content1 = "{浠诲姟ID锛�" + newPlcTask.getTaskId() + "锛� 浠诲姟鍚嶏細" + newPlcTask.getTaskName() + "}," + " 鐏潌ID锛�" + poleIdList.toString() + " }";
+        StoreOperationRecordsUtils.storeOperationData(poleCodeList, null, "涓嬪彂PLC浠诲姟", content1);
+        /**
+         * 涓嬪彂璺伅浠诲姟鏃ュ織璁板綍缁撴潫
+         */
+
+
+        //鍒犻櫎鏃х殑鍏崇郴
+        plcTaskPoleRelationService.remove(Wrappers.lambdaQuery(PlcTaskPoleRelation.class)
+                .in(PlcTaskPoleRelation::getPoleId, poleIdList).eq(PlcTaskPoleRelation::getPlcAddress, newPlcTask.getPlcAdress()));
+
+
+        boolean b = true;
+        //淇濆瓨浠诲姟鍏崇郴
+        if (!newPoleMap.isEmpty()) {
+            b = plcTaskPoleRelationService.saveBatch(newPoleMap);
+        }
+
+        if (!b) {
+            //鎵�鏈夌伅鏉嗛兘涓嬪彂澶辫触 鏂板鐨勪换鍔′笉淇濈暀
+            removeById(newPlcTask);
+            throw new BusinessException("鎸囦护涓嬪彂澶辫触,璇锋鏌ョ伅鏉嗙姸鎬佸悗閲嶆柊鏂板浠诲姟");
+        } else {
+            return "浠诲姟鏂板鎴愬姛";
+        }
+    }
+
+
+    /**
+     * 缂栬緫璺伅浠诲姟
+     *
+     * @param taskId
+     * @param param
+     * @return
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public String newUpdatePlcTask(Long taskId, PlcTaskParam param) {
+        if (StrUtil.length(param.getControlOrder()) % PlcTaskParam.REQUEST_ORDER_LENGTH != 0) {
+            throw new BusinessException("鐏帶鍛戒护鏍煎紡涓嶆纭�");
+        }
+        if (!"0001".equals(param.getPlcAddress())
+                && !"0002".equals(param.getPlcAddress())
+                && !"0003".equals(param.getPlcAddress())) {
+            throw new BusinessException("鐏ご鍦板潃鏍煎紡涓嶆纭�");
+        }
+
+        PlcTask newPlcTask = getById(taskId);
+
+        if (newPlcTask == null) {
+            throw new BusinessException("鎵句笉鍒癙LC浠诲姟");
+        }
+
+
+        int week = 0;
+        for (Integer w : param.getWeekList()) {
+            week |= w;
+        }
+
+        newPlcTask.setTaskName(param.getTaskName());
+
+        newPlcTask.setClientId(clientService.getClientId(SecurityUtils.getUserId()));
+        newPlcTask.setUserId(SecurityUtils.getUserId());
+
+        newPlcTask.setWeek(week);
+        newPlcTask.setCreateUser(SecurityUtils.getUsername());
+        newPlcTask.setControlOrder(param.getControlOrder());
+        newPlcTask.setOpenOrder(param.getOpenOrder());
+        newPlcTask.setCloseOrder(param.getCloseOrder());
+        newPlcTask.setPlcAdress(param.getPlcAddress());
+        newPlcTask.setUpdateTime(LocalDateTime.now());
+        newPlcTask.setFramePayload(buildControlFramePayload(param.getOpenOrder(), param.getCloseOrder(), param.getControlOrder(), week));
+
+        updateById(newPlcTask);
+
+        //缂栬緫鍚庣伅鏉咺D闆嗗悎
+        List<Long> poleIdList = new ArrayList<>();
+        //鍘婚噸
+        for (Long item : param.getPoleIdList()) {
+            if (!poleIdList.contains(item)) {
+                poleIdList.add(item);
+            }
+        }
+        //璁板綍浠诲姟缂栬緫鍣ㄥ墠鐏潌ID闆嗗悎
+//        List<PlcTaskStatusAndPole> oldPlcTaskStatusAndPoles = plcTaskPoleRelationService.listPoleAndStatusIdByTaskId(taskId);
+        List<PlcTaskPoleRelation> oldPlcTaskStatusAndPoles = plcTaskPoleRelationService.
+                list(Wrappers.lambdaQuery(PlcTaskPoleRelation.class).eq(PlcTaskPoleRelation::getTaskId, taskId));
+        List<Long> oldList = oldPlcTaskStatusAndPoles.stream().
+                map(PlcTaskPoleRelation::getPoleId).collect(Collectors.toList());
+
+        //鍒ゆ柇poleIdList涓槸鍚︽湁鏃х殑鐏潌ID    (鐩存帴涓嬪彂)
+        List<Long> newPoleIdList = poleIdList.stream().filter(poleId -> !oldList.contains(poleId)).collect(Collectors.toList());
+        //鍒ゆ柇poleIdList涓槸鍚︽湁鏂扮殑鐏潌ID    (瑕嗙洊鎿嶄綔)
+        List<Long> oldPoleIdList = poleIdList.stream().filter(poleId -> oldList.contains(poleId)).collect(Collectors.toList());
+
+
+        //oldList涓湁鐨勭伅鏉咺D锛屼絾鏄痯oleIdList涓病鏈� (鍏崇伅鎿嶄綔)
+        List<Long> closeLight = oldList.stream().filter(poleId -> !poleIdList.contains(poleId)).collect(Collectors.toList());
+
+
+        //鍙栧嚭瑕嗙洊鎿嶄綔鐨勫叧绯讳俊鎭�
+        //璁板綍杩欎簺鐏潌鍘熷厛鐨勪换鍔�
+        List<PlcTaskPoleRelation> oldRelation = new ArrayList<>();
+
+        if (CollectionUtil.isNotEmpty(oldPoleIdList)) {
+            List<Long> oldRelationList = new ArrayList<>();
+            oldRelationList.addAll(oldPoleIdList);
+            oldRelationList.addAll(closeLight);
+            oldRelation = plcTaskPoleRelationService.list(Wrappers.lambdaQuery(PlcTaskPoleRelation.class).in(PlcTaskPoleRelation::getPoleId, oldRelationList)
+                    .ne(PlcTaskPoleRelation::getTaskId, taskId).eq(PlcTaskPoleRelation::getPlcAddress, param.getPlcAddress()));
+        }
+
+        //鍙栧嚭浠诲姟涓師鏈夌殑浠诲姟淇℃伅
+        List<PlcTaskPoleRelation> relations = plcTaskPoleRelationService.list(Wrappers.lambdaQuery(PlcTaskPoleRelation.class)
+                .eq(PlcTaskPoleRelation::getTaskId, taskId).eq(PlcTaskPoleRelation::getPlcAddress, param.getPlcAddress()));
+
+        relations.addAll(oldRelation);
+
+        List<PlcTaskPoleRelation> newPoleAll = new ArrayList<>();
+        List<PlcTaskPoleRelation> newPoleSuccess = new ArrayList<>();
+        List<PlcTaskPoleRelation> newPoleFail = new ArrayList<>();
+        if (CollectionUtil.isNotEmpty(newPoleIdList)) {
+            //鏂扮伅鏉嗕笅鍙戞柊浠诲姟
+            Map<String, List<PlcTaskPoleRelation>> newPoleMap = sendControllerFrame(newPoleIdList, newPlcTask.getFramePayload(), param.getPlcAddress());
+
+            if (newPoleMap != null) {
+                //newPoleAll闆嗗悎鍚庨潰鐢ㄤ簬瀛樺偍鍏崇郴琛�
+                newPoleAll = newPoleMap.getOrDefault("all", new ArrayList<>());
+                newPoleSuccess = newPoleMap.getOrDefault("success", new ArrayList<>());
+                newPoleFail = newPoleMap.getOrDefault("fail", new ArrayList<>());
+            }
+        }
+
+        List<PlcTaskPoleRelation> oldPoleFail = new ArrayList<>();
+        List<PlcTaskPoleRelation> oldPoleSuccess = new ArrayList<>();
+        if (CollectionUtil.isNotEmpty(oldPoleIdList)) {
+            //瑕嗙洊鎿嶄綔鐏潌
+            Map<String, List<PlcTaskPoleRelation>> oldPoleMap = sendControllerFrame(oldPoleIdList, newPlcTask.getFramePayload(), param.getPlcAddress());
+            if (oldPoleMap != null) {
+                oldPoleFail = oldPoleMap.getOrDefault("fail", new ArrayList<>());
+                oldPoleSuccess = oldPoleMap.getOrDefault("success", new ArrayList<>());
+            }
+        }
+
+
+        List<PlcTaskPoleRelation> closePoleFail = new ArrayList<>();
+        List<PlcTaskPoleRelation> closePoleSuccess = new ArrayList<>();
+        System.out.println(closeLight + "closeLight");
+        if (CollectionUtil.isNotEmpty(closeLight) && closeLight != null && closeLight.get(0) != null) {
+            //娓呴櫎甯ф寚浠�
+            String framePayloadClose = "";
+            //鍏崇伅鎿嶄綔鐏潌
+            Map<String, List<PlcTaskPoleRelation>> closePoleMap = sendControllerFrame(closeLight, framePayloadClose, param.getPlcAddress());
+            if (closePoleMap != null) {
+                closePoleFail = closePoleMap.getOrDefault("fail", new ArrayList<>());
+                closePoleSuccess = closePoleMap.getOrDefault("success", new ArrayList<>());
+            }
+        }
+
+
+        /**
+         * 缂栬緫璺伅浠诲姟鏃ュ織璁板綍寮�濮�
+         */
+        List<String> poleCodeList = new ArrayList<>();
+        if (CollectionUtil.isNotEmpty(poleIdList)) {
+            List<Pole> poleList = SpringContextHolder.getBean(PoleService.class).listByIds(poleIdList);
+            if (CollectionUtil.isNotEmpty(poleList)) {
+                poleCodeList = poleList.stream().map(Pole::getDeviceCode).collect(Collectors.toList());
+            }
+        }
+        String content = "{浠诲姟ID锛�" + newPlcTask.getTaskId() + "锛� 浠诲姟鍚嶏細" + newPlcTask.getTaskName() + "}锛寋鍐呭抚鎸囦护" + newPlcTask.getFramePayload() + "锛� 鐏潌ID锛�" + poleIdList.toString() + "锛� 鎺у埗鐨勭伅澶村湴鍧�锛�" + param.getPlcAddress() + " }";
+        StoreOperationRecordsUtils.storeOperationData(poleCodeList, null, "缂栬緫PLC浠诲姟", content);
+        /**
+         * 缂栬緫璺伅浠诲姟鏃ュ織璁板綍缁撴潫
+         */
+
+
+        List<PlcTaskPoleRelation> all = new ArrayList<>();
+        all.addAll(newPoleSuccess);
+        all.addAll(newPoleFail);
+        all.addAll(oldPoleSuccess);
+        all.addAll(oldPoleFail);
+
+
+        if (closePoleFail.size() != 0) {
+            List<PlcTaskPoleRelation> colesFail = new ArrayList<>();
+            //鍘熸潵浠诲姟涓湰韬氨涓嬪彂澶辫触鐨勪换鍔�  鍗崇‖浠跺畾鏃朵负绌�    缂栬緫鍚庤繘琛屽叧鐏搷浣�   鍙洿鎺ュ墧闄や换鍔″叧绯�
+            closePoleFail.forEach(
+                    close -> {
+                        relations.forEach(
+                                task -> {
+                                    System.out.println(task.getPlcAddress().equals(close.getPlcAddress()) + "   addressResult");
+                                    System.out.println(close.getPlcAddress() + "   close.getPlcAddress()");
+                                    if (task.getPlcAddress().equals(close.getPlcAddress()) && task.getDeviceCode().equals(close.getDeviceCode())
+                                            && task.getDeviceScheduled() != null && !task.getDeviceScheduled().isEmpty()) {
+                                        colesFail.add(close);
+                                    }
+                                }
+                        );
+                        all.addAll(colesFail);
+                    }
+            );
+
+        }
+
+
+        if (!all.isEmpty()) {
+            List<PlcTaskPoleRelation> finalOldRelation = relations;
+            all.forEach(
+                    commend -> {
+                        // 鏇存柊绯荤粺瀹氭椂
+                        commend.setSysScheduled(JSON.toJSONString(newPlcTask));
+                        commend.setTaskId(taskId);
+                        // 鍏堣缃‖浠跺畾鏃朵负涓婃鐨勭‖浠跺畾鏃�   涓嶈鎴愬姛澶辫触
+                        finalOldRelation.forEach(task -> {
+                            if (task.getPlcAddress().equals(commend.getPlcAddress()) && task.getDeviceCode().equals(commend.getDeviceCode())) {
+                                //鍚屼竴涓伅澶�
+                                commend.setDeviceScheduled(task.getDeviceScheduled());
+                                if (commend.getIssueStatus() == 0) {
+                                    //涓嬪彂鎴愬姛  鏇存柊绯荤粺瀹氭椂鍜岀‖浠跺畾鏃�
+                                    commend.setDeviceScheduled(JSON.toJSONString(newPlcTask));
+                                }
+
+                            }
+                        });
+
+                    }
+            );
+        }
+        boolean b = true;
+
+        //缂栬緫鍓嶅悗鎵�鏈夌殑鐏潌ID闆嗗悎
+        poleIdList.addAll(oldList);
+        //鍘婚噸
+        List<Long> collect = poleIdList.stream().distinct().collect(Collectors.toList());
+        if (!collect.isEmpty()) {
+            plcTaskPoleRelationService.remove(Wrappers.lambdaQuery(PlcTaskPoleRelation.class)
+                    .in(PlcTaskPoleRelation::getPoleId, collect).eq(PlcTaskPoleRelation::getPlcAddress, newPlcTask.getPlcAdress()));
+
+        }
+
+
+        if (!all.isEmpty()) {
+            b = plcTaskPoleRelationService.saveBatch(all);
+        }
+
+
+        /**
+         * 涓嬪彂璺伅浠诲姟鏃ュ織璁板綍寮�濮�
+         */
+        String content1 = "{浠诲姟ID锛�" + newPlcTask.getTaskId() + "锛� 浠诲姟鍚嶏細" + newPlcTask.getTaskName() + "}," + " 鐏潌ID锛�" + poleCodeList.toString() + " }";
+        StoreOperationRecordsUtils.storeOperationData(poleCodeList, null, "涓嬪彂璺伅浠诲姟", content1);
+        /**
+         * 涓嬪彂璺伅浠诲姟鏃ュ織璁板綍缁撴潫
+         */
+
+        if (b) {
+            return "缂栬緫鎴愬姛";
+        } else {
+            return "缂栬緫澶辫触";
+        }
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    public String delPlcTask(Long taskId) {
+        PlcTask byId = getById(taskId);
+        if (byId == null) {
+            throw new BusinessException("鎵句笉鍒颁换鍔′俊鎭�");
+        }
+
+        //鍙栧嚭浠诲姟鍏崇郴
+        List<PlcTaskPoleRelation> relations = plcTaskPoleRelationService.list(Wrappers.lambdaQuery(PlcTaskPoleRelation.class).eq(PlcTaskPoleRelation::getTaskId, taskId));
+
+        //鍙栧嚭鐏潌id
+        List<Long> poleIds = relations.stream().map(PlcTaskPoleRelation::getPoleId).distinct().collect(Collectors.toList());
+
+        if (poleIds != null && poleIds.size() > 0) {
+            //瀛樺湪浠诲姟鍏崇郴   涓嬪彂娓呴櫎浠诲姟鎸囦护
+            Map<String, List<PlcTaskPoleRelation>> ffff = sendControllerFrame(poleIds, "", byId.getPlcAdress());
+
+            if (ffff == null) {
+                throw new BusinessException("鍒犻櫎澶辫触");
+            }
+
+            /**
+             * 鍒犻櫎鎺х伅浠诲姟鏃ュ織璁板綍寮�濮�
+             */
+            String content = "{鎺х伅浠诲姟id锛�" + taskId + " }";
+            StoreOperationRecordsUtils.storeOperationData(null, null, "鍒犻櫎鎺х伅浠诲姟", content);
+            /**
+             * 鍒犻櫎鎺х伅浠诲姟鏃ュ織璁板綍缁撴潫
+             */
+            if (ffff.get("fail").size() == 0) {
+                //鍏ㄩ儴娓呴櫎鎴愬姛  鍒犻櫎鍏ㄩ儴浠诲姟鍏崇郴
+                plcTaskPoleRelationService.remove(Wrappers.lambdaQuery(PlcTaskPoleRelation.class).eq(PlcTaskPoleRelation::getTaskId, taskId));
+                //鍒犻櫎浠诲姟
+                removeById(taskId);
+                return "浠诲姟鍒犻櫎鎴愬姛";
+            } else if (ffff.get("success").size() != ffff.get("all").size()) {
+                //閮ㄥ垎鎴愬姛  鍒犻櫎鎴愬姛閮ㄥ垎鐨勫叧绯�  淇濈暀浠诲姟
+                List<PlcTaskPoleRelation> relations1 = ffff.get("success");
+                if (relations1 != null && relations1.size() > 0) {
+                    relations1.forEach(plcTaskPoleRelation -> {
+                        plcTaskPoleRelationService.remove(Wrappers.lambdaUpdate(PlcTaskPoleRelation.class)
+                                .eq(PlcTaskPoleRelation::getPoleId, plcTaskPoleRelation.getPoleId()).eq(PlcTaskPoleRelation::getTaskId, taskId));
+                    });
+                }
+                return "閮ㄥ垎浠诲姟鍒犻櫎鎴愬姛,娓呴櫎浠诲姟澶辫触鐨勪换鍔″強鏁版嵁淇濈暀!";
+            } else if (ffff.get("fail").size() == ffff.get("all").size()) {
+                //鍏ㄩ儴澶辫触  淇濈暀浠诲姟
+                return "浠诲姟鍒犻櫎澶辫触 ,璇锋鏌ョ‖浠惰澶�!";
+            } else {
+                return "浠诲姟鍒犻櫎澶辫触,鏈煡閿欒绫诲瀷!";
+            }
+        } else {
+            //涓嶅瓨鍦ㄤ换鍔″叧绯�    绌轰换鍔$洿鎺ュ垹闄�
+            removeById(taskId);
+            return "浠诲姟鍒犻櫎鎴愬姛";
+        }
+    }
+
+    /**
+     * 涓嬪彂鍗曚釜鐏潌鐨勪换鍔�
+     */
+    public boolean issuePlcTask(PlcTaskIssueParam param) {
+
+        PlcTaskPoleRelation relation = plcTaskPoleRelationService.getOne(Wrappers.lambdaQuery(PlcTaskPoleRelation.class)
+                .eq(PlcTaskPoleRelation::getPoleId, param.getPoleId()).eq(PlcTaskPoleRelation::getTaskId, param.getTaskId()));
+
+        if (relation == null) {
+            throw new BusinessException("鎵句笉鍒颁换鍔″叧绯�,鏃犳硶琛ュ彂");
+        }
+        PlcTask plcTask = JSONObject.parseObject(relation.getSysScheduled(), PlcTask.class);
+//        PlcTask plcTask = getById(param.getTaskId());
+        if (plcTask == null) {
+            throw new BusinessException("鎵句笉鍒颁换鍔�");
+        }
+        //杞崲甯ф寚浠�
+        String framePayload = buildControlFramePayload(plcTask.getOpenOrder(), plcTask.getCloseOrder(), plcTask.getControlOrder(), plcTask.getWeek());
+        //鍙戦�乺rpc  寰楀埌鍙戦�佺粨鏋�
+        List<PlcTaskPoleRelation> plcTaskPoleRelationList = sendControllerFrame(plcTask, ListUtil.toList(param.getPoleId()), framePayload, plcTask.getPlcAdress());
+
+        /**
+         * 涓嬪彂璺伅浠诲姟鏃ュ織璁板綍寮�濮�
+         */
+        List<String> poleCodeList = new ArrayList<>();
+        List<Pole> list = SpringContextHolder.getBean(PoleService.class).list(Wrappers.lambdaQuery(Pole.class).eq(Pole::getId, param.getPoleId()));
+        if (CollectionUtil.isNotEmpty(list)) {
+            poleCodeList = list.stream().map(Pole::getDeviceCode).collect(Collectors.toList());
+        }
+        String content = "{浠诲姟ID锛�" + plcTask.getTaskId() + "锛� 浠诲姟鍚嶏細" + plcTask.getTaskName() + "}," + " 鐏潌ID锛�" + param.getPoleId() + " }";
+        StoreOperationRecordsUtils.storeOperationData(poleCodeList, null, "涓嬪彂PLC浠诲姟", content);
+        /**
+         * 涓嬪彂璺伅浠诲姟鏃ュ織璁板綍缁撴潫
+         */
+
+
+        if (CollectionUtil.isNotEmpty(plcTaskPoleRelationList)) {
+            PlcTaskPoleRelation plcTaskPoleRelation = plcTaskPoleRelationList.get(0);
+            if (plcTaskPoleRelation.getIssueStatus() == 0) {
+                //涓嬪彂鎴愬姛  鏇存柊纭欢瀹氭椂  杩斿洖鎴愬姛
+                relation.setDeviceScheduled(JSON.toJSONString(plcTaskPoleRelation));
+                plcTaskPoleRelationService.updateById(relation);
+                return true;
+            } else {
+                return false;
+            }
+        }
+        return false;
+    }
+
+
+    public Map checkTask(PlcTaskParam param) {
+        /**
+         * 閲嶅浠诲姟鐨勭伅澶�
+         */
+        String plcAddress = param.getPlcAddress();
+        List<Long> poleIdList = param.getPoleIdList();
+        List<PlcTaskPoleRelation> plcTaskPoleRelations = plcTaskPoleRelationService.list(Wrappers.lambdaQuery(PlcTaskPoleRelation.class)
+                .in(PlcTaskPoleRelation::getPoleId, poleIdList).eq(PlcTaskPoleRelation::getPlcAddress, plcAddress));
+        //閲嶅鐨勪换鍔d
+        List<Long> taskIds = plcTaskPoleRelations.stream().map(PlcTaskPoleRelation::getTaskId).collect(Collectors.toList());
+        //閲嶅鐨勭伅鏉唅d
+        List<Long> oldPoleIds = plcTaskPoleRelations.stream().map(PlcTaskPoleRelation::getPoleId).collect(Collectors.toList());
+        //鏈噸澶嶇殑鐏潌id
+        List<Long> finalOldPoleIds = oldPoleIds;
+        //鍙栧嚭瀛樺湪浜巔oleIdList鑰屼笉鍦╫ldPoleIds涓殑鐏潌
+        List<Long> newPoleIds = poleIdList.stream().filter(id -> !finalOldPoleIds.contains(id)).collect(Collectors.toList());
+
+        //閲嶅鍏冪礌鍙繚鐣欎竴涓�
+        taskIds = taskIds.stream().distinct().collect(Collectors.toList());
+        oldPoleIds = oldPoleIds.stream().distinct().collect(Collectors.toList());
+        newPoleIds = newPoleIds.stream().distinct().collect(Collectors.toList());
+        Map map = new HashMap();
+        if (!plcTaskPoleRelations.isEmpty()) {
+
+            map.put("result", "false");
+            map.put("newPoleIds", newPoleIds);
+            map.put("oldPoleIds", oldPoleIds);
+            map.put("taskIds", taskIds);
+        } else {
+            map.put("result", "true");
+            map.put("msg", "浠诲姟涓棤閲嶅鐏潌鍦板潃");
+        }
+        return map;
+    }
+
+
+    public List<PlcTaskDto> listPlcTask(BaseConditionVO conditionVO, String keyword, Integer order, Integer seq) {
+
+        //鎺掑簭瀛楁
+        String orderByResult = "task_id";
+        //姝e簭銆佸�掑彊
+        String orderBySeq = OrderByEnums.ASC.getCode();
+        if (order != null) {
+            switch (order) {
+                case 1:
+                    orderByResult = OrderByEnums.LIGHT_TASK_UPDATE_TIME.getCode();
+                    break;
+                default:
+            }
+        }
+        if (seq != null) {
+            switch (seq) {
+                case 1:
+                    orderBySeq = OrderByEnums.ASC.getCode();
+                    break;
+                case 2:
+                    orderBySeq = OrderByEnums.DESC.getCode();
+                    break;
+                default:
+                    break;
+            }
+        }
+        //鎺掑簭鏂瑰紡
+        String orderBy = orderByResult + " " + orderBySeq;
+
+        PageHelper.startPage(conditionVO.getPageNo(), conditionVO.getPageSize(), orderBy);
+        List<PlcTask> list = baseMapper.listTask(SecurityUtils.getClientId(), keyword, orderBy);
+
+
+        Page<PlcTaskDto> page = new Page<>();
+        BeanUtils.copyProperties(list, page);
+        for (PlcTask plcTask : list) {
+            PlcTaskDto plcTaskDto = new PlcTaskDto();
+            BeanUtils.copyProperties(plcTask, plcTaskDto);
+            plcTaskDto.setWeekList(TaskOrderUtil.parseLightWeek2List(plcTask.getWeek()));
+
+
+            //鍒ゆ柇鐏ご鏄惁瀛樺湪浠诲姟
+            List<PlcTaskPoleRelation> plcTaskPoleRelationList = plcTaskPoleRelationService.list(Wrappers.<PlcTaskPoleRelation>lambdaQuery().eq(PlcTaskPoleRelation::getTaskId, plcTask.getTaskId()));
+
+            //涓嬪彂鎴愬姛鐨勭伅鏉嗘暟閲�
+            Integer successCount = baseMapper.successCount(plcTaskDto.getTaskId());
+            ///浠诲姟涓�荤殑鐏潌鏁伴噺
+            Integer toTalCount = baseMapper.toTalCount(plcTaskDto.getTaskId());
+            if (successCount == null) {
+                successCount = 0;
+            }
+            if (toTalCount == null) {
+                toTalCount = 0;
+            }
+            if (toTalCount == 0) {
+                //浠诲姟涓病鏈夌伅鏉�
+                plcTaskDto.setSyncStatus("鏈悓姝�");
+            } else {
+                //浠诲姟涓湁鐏潌
+                if (successCount == 0) {
+                    //涓嬪彂鎴愬姛鏈�0
+                    plcTaskDto.setSyncStatus("鏈悓姝�");
+                } else if (successCount != 0 && successCount < toTalCount) {
+                    //瀛樺湪涓嬪彂鎴愬姛    浣嗗苟鏈叏閮ㄦ垚鍔�
+                    plcTaskDto.setSyncStatus("閮ㄥ垎鍚屾");
+                } else if (toTalCount.equals(successCount) && toTalCount != 0 && successCount != 0) {
+                    //鍏ㄩ儴鎴愬姛
+                    plcTaskDto.setSyncStatus("宸插悓姝�");
+                } else {
+                    //鏈煡绫诲瀷
+                    plcTaskDto.setSyncStatus("鍚屾鐘舵�佸嚭閿�");
+                }
+            }
+            page.add(plcTaskDto);
+        }
+        return page;
+    }
+
+    /**
+     * 鎵ц涓殑璺伅浠诲姟
+     *
+     * @return
+     */
+    public List<PlcTaskDto> listTask() {
+        Long clientId = SecurityUtils.getClientId();
+        List<PlcTask> plcTasks = plcTaskMapper.listPlcTask(clientId);
+        Page<PlcTaskDto> page = new Page<>();
+        BeanUtils.copyProperties(plcTasks, page);
+        for (PlcTask plcTask : plcTasks) {
+            PlcTaskDto plcTaskDto = new PlcTaskDto();
+            BeanUtils.copyProperties(plcTask, plcTaskDto);
+            plcTaskDto.setWeekList(TaskOrderUtil.parseLightWeek2List(plcTask.getWeek()));
+            page.add(plcTaskDto);
+        }
+        return page;
+    }
+
+    /**
+     * 浠诲姟璇︽儏
+     */
+    public Object detailPlcTask(Long taskId) {
+        PlcTask plcTask = getById(taskId);
+        if (plcTask == null) {
+            throw new BusinessException("鎵句笉鍒颁换鍔�");
+        }
+        PlcTaskInfoVO vo = new PlcTaskInfoVO();
+
+//        LightTaskDto plcTaskDto = new LightTaskDto();
+//        BeanUtils.copyProperties(plcTask, plcTaskDto);
+
+        plcTask.setWeekList(TaskOrderUtil.parseLightWeek2List(plcTask.getWeek()));
+
+        vo.setPlcTask(plcTask);
+        List<PlcTaskRelationVO> relations = new ArrayList<>();
+        List<PlcTaskPoleRelation> taskPoleRelations = plcTaskPoleRelationService.list(Wrappers.lambdaQuery(PlcTaskPoleRelation.class)
+                .eq(PlcTaskPoleRelation::getTaskId, taskId));
+        if (taskPoleRelations != null && !taskPoleRelations.isEmpty()) {
+            taskPoleRelations.forEach(
+                    relation -> {
+                        PlcTaskRelationVO plcTaskRelationVO = new PlcTaskRelationVO();
+                        plcTaskRelationVO.setPlcAddress(relation.getPlcAddress());
+                        plcTaskRelationVO.setIssueStatus(relation.getIssueStatus());
+                        plcTaskRelationVO.setPoleId(relation.getPoleId());
+                        Pole byId = poleService.getById(relation.getPoleId());
+                        if (byId != null) {
+                            plcTaskRelationVO.setPoleName(byId.getPoleName());
+                        }
+
+                        PlcTaskVO sys = JSONObject.parseObject(relation.getSysScheduled(), PlcTaskVO.class);
+                        sys.setWeekList(TaskOrderUtil.parseLightWeek2List(sys.getWeek()));
+                        plcTaskRelationVO.setSysScheduled(sys);
+
+                        PlcTaskVO device = JSONObject.parseObject(relation.getDeviceScheduled(), PlcTaskVO.class);
+                        if (device != null) {
+                            device.setWeekList(TaskOrderUtil.parseLightWeek2List(device.getWeek()));
+                            plcTaskRelationVO.setDeviceScheduled(device);
+                        }
+                        relations.add(plcTaskRelationVO);
+                    }
+            );
+
+            vo.setRelations(relations);
+        }
+
+//        List<LightTaskStatusAndPole> plcTaskStatusAndPoles = plcTaskPoleRelationService.listPoleAndStatusIdByTaskId(taskId);
+
+//        return MapUtil.builder().put("task", plcTask).put("poles", plcTaskStatusAndPoles).build();
+        return vo;
+    }
+
+
+
+}
+
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PoleBindingService.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PoleBindingService.java
index cc4a26d..300fcfc 100644
--- a/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PoleBindingService.java
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PoleBindingService.java
@@ -42,6 +42,9 @@
             case PoleBindingEnums.LIGHT:
                 size = SpringContextHolder.getBean(LightService.class).list(Wrappers.lambdaQuery(Light.class).eq(Light::getDeviceCode, param.getDeviceCode())).size();
                 break;
+            case PoleBindingEnums.PLC:
+                size = SpringContextHolder.getBean(PlcService.class).list(Wrappers.lambdaQuery(Plc.class).eq(Plc::getDeviceCode, param.getDeviceCode())).size();
+                break;
             case PoleBindingEnums.VONNOX:
                 size = SpringContextHolder.getBean(LedPlayerEntityService.class).list(Wrappers.lambdaQuery(LedPlayerEntity.class).eq(LedPlayerEntity::getSn, param.getDeviceCode())).size();
                 break;
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PoleService.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PoleService.java
index 7d542dc..56a361b 100644
--- a/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PoleService.java
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/service/PoleService.java
@@ -22,6 +22,7 @@
 import com.sandu.ximon.admin.manager.iot.frame.inner.report.A5C3HeartbeatReportInnerFrame;
 import com.sandu.ximon.admin.manager.iot.frame.inner.request.A1TernaryCodeReqInnerFrame;
 import com.sandu.ximon.admin.manager.iot.frame.inner.request.A5LightResetReqInnerFrame;
+import com.sandu.ximon.admin.manager.iot.frame.inner.request.A7PlcResetReqInnerFrame;
 import com.sandu.ximon.admin.manager.iot.frame.inner.request.EmptyRequestInnerFrame;
 import com.sandu.ximon.admin.manager.iot.frame.inner.response.A1DeviceMacRespInnerFrame;
 import com.sandu.ximon.admin.manager.iot.frame.inner.response.A1TernaryCodeRespInnerFrame;
@@ -45,6 +46,7 @@
 import com.sandu.ximon.dao.domain.*;
 import com.sandu.ximon.dao.enums.OrderByEnums;
 import com.sandu.ximon.dao.mapper.PoleMapper;
+import eu.bitwalker.useragentutils.DeviceType;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.RandomStringUtils;
@@ -885,11 +887,21 @@
         if (deviceName.isEmpty()) {
             throw new BusinessException("璇ョ伅鏉哅ac涓虹┖");
         }
-        IRequestFrame build = FrameBuilder.builderA5().orderType(A5OrderEnum.REQUEST_LIGHT_DATA.getCode()).innerFrame(new A5LightResetReqInnerFrame()).build();
+        Integer deviceType = byId.getDeviceType();
+
+        IRequestFrame build = null;
+        if (deviceType < 2){
+            build = FrameBuilder.builderA5().orderType(A5OrderEnum.REQUEST_LIGHT_DATA.getCode()).innerFrame(new A5LightResetReqInnerFrame()).build();
+        }
+        else if (deviceType == 2){
+            build = FrameBuilder.builderA7().orderType(A7OrderEnum.REQUEST_PLC_DATA.getCode()).innerFrame(new A7PlcResetReqInnerFrame()).build();
+
+        }
+
         CommonFrame commonFrame = MainBoardInvokeSyncService.getInstance().sendRRPC(deviceName, build);
+
         StoreOperationRecordsUtils.storeInnerFrameData(deviceName, "鐏潌鎭㈠鍑哄巶璁剧疆", build, commonFrame);
 
-        System.out.println(commonFrame.toString());
         IRequestFrame iRequestFrame = FrameBuilder.builderA2().innerFrame(new EmptyRequestInnerFrame()).orderType(A2OrderEnum.REQUEST_MAIN_BOARD_RESET.getCode()).build();
         CommonFrame rebootFrame = MainBoardInvokeSyncService.getInstance().sendRRPC(deviceName, iRequestFrame);
         StoreOperationRecordsUtils.storeInnerFrameData(deviceName, "鐏潌閲嶅惎", iRequestFrame, commonFrame);
@@ -1001,6 +1013,8 @@
             pole.setDeviceType(0);
         } else if ("01".equals(a1DeviceMacRespInnerFrame.getType())) {
             pole.setDeviceType(1);
+        } else if ("02".equals(a1DeviceMacRespInnerFrame.getType())) {
+            pole.setDeviceType(2);
         }
 
         pole.setPoleCode(generatePoleCode());
@@ -1008,12 +1022,24 @@
         boolean result = saveOrUpdate(pole);
 
         if (result) {
-            Light light = SpringContextHolder.getBean(LightService.class).getOne(Wrappers.lambdaQuery(Light.class).eq(Light::getDeviceCode, pole.getDeviceCode()).last("limit 1"));
-            if (light == null) {
-                light = new Light();
-                light.setDeviceCode(uniqueMac);
-                light.setLightCount(2);
-                SpringContextHolder.getBean(LightService.class).save(light);
+            if (pole.getDeviceType() < 2) {
+                Light light = SpringContextHolder.getBean(LightService.class).
+                        getOne(Wrappers.lambdaQuery(Light.class).eq(Light::getDeviceCode, pole.getDeviceCode()).last("limit 1"));
+                if (light == null) {
+                    light = new Light();
+                    light.setDeviceCode(uniqueMac);
+                    light.setLightCount(2);
+                    SpringContextHolder.getBean(LightService.class).save(light);
+                }
+            } else if (pole.getDeviceType() == 2) {
+                Plc plc = SpringContextHolder.getBean(PlcService.class).
+                        getOne(Wrappers.lambdaQuery(Plc.class).eq(Plc::getDeviceCode,pole.getDeviceCode()).last("limit 1"));
+                if (plc == null){
+                    plc = new Plc();
+                    plc.setDeviceCode(uniqueMac);
+                    plc.setPlcCount(3);
+                    SpringContextHolder.getBean(PlcService.class).save(plc);
+                }
             }
         }
 
@@ -1419,4 +1445,4 @@
 
     }
 
-}
\ No newline at end of file
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/utils/MybatisPlusUtil.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/utils/MybatisPlusUtil.java
new file mode 100644
index 0000000..7ca98bf
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/utils/MybatisPlusUtil.java
@@ -0,0 +1,89 @@
+package com.sandu.ximon.admin.utils;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import java.lang.reflect.Field;
+import com.baomidou.mybatisplus.annotation.TableField;
+
+/**
+ * MybatisPlus宸ュ叿绫�
+ *
+ * @author van
+ * @since 2022-12-16 10:54:58
+ */
+public class MybatisPlusUtil {
+
+    /**
+     * 瀵逛紶鍏ュ疄浣撳姩鎬佹嫾鎺ユ煡璇㈡潯浠�
+     *
+     * @param target 鏌ヨ瀹炰綋
+     * @param <T>    瀹炰綋绫诲瀷
+     * @return 杩斿洖鏌ヨ鏉′欢
+     */
+    public static <T> QueryWrapper<T> queryWrapperBuilder(T target) {
+
+        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
+        //鑾峰彇瀹炰綋鎵�鏈夊睘鎬ч泦鍚�
+        Field[] declaredFields = target.getClass().getDeclaredFields();
+        //閬嶅巻灞炴�ч泦鍚堬紝鑾峰彇灞炲瀷绫诲瀷鍜屽睘鎬у��
+        for (Field declaredField : declaredFields) {
+            declaredField.setAccessible(true);
+            //鑾峰彇灞炴�у悕
+            String fieldName = declaredField.getName();
+
+            //灞炴�у��
+            Object value = null;
+            try {
+                //鑾峰彇灞炴�у��
+                value = declaredField.get(target);
+            } catch (IllegalAccessException e) {
+                e.printStackTrace();
+            }
+            //鑾峰彇灞炴�х被鍨�
+            String simpleName = declaredField.getType().getSimpleName();
+
+            //鑾峰彇TableField娉ㄨВ瀵硅薄锛岀敤浜庡垽鏂瀛楁鏄惁鍦ㄦ暟鎹簱涓娇鐢ㄤ笅鍒掔嚎
+            TableField tableFieldAnnotation = declaredField.getAnnotation(TableField.class);
+
+            //濡傛灉鏄疭tring绫诲瀷锛屾嫾鎺ユā绯婃煡鎵炬潯浠讹紝鍚﹀垯鎷兼帴绛夊�兼煡鎵撅紝蹇界暐serialVersionUID灞炴��
+            if (simpleName.equals("String")) {
+                //鑻ュ瓨鍦╰ableField娉ㄨВ锛屽垯浣跨敤娉ㄨВ涓殑value浣滀负鏌ヨ鍒楀悕锛岃嫢涓嶅瓨鍦紝鍒欎娇鐢ㄥ睘鎬у悕浣滀负鍒楀悕
+                if(tableFieldAnnotation !=null){
+                    String annotationValue = tableFieldAnnotation.value();
+                    queryWrapper.like(value != null, annotationValue, value);
+                }else {
+                    queryWrapper.like(value != null, fieldName, value);
+                }
+
+            } else if (!fieldName.equals("serialVersionUID")) {
+                //鑻ュ瓨鍦╰ableField娉ㄨВ锛屽垯浣跨敤娉ㄨВ涓殑value浣滀负鏌ヨ鍒楀悕锛岃嫢涓嶅瓨鍦紝鍒欎娇鐢ㄥ睘鎬у悕浣滀负鍒楀悕
+                if(tableFieldAnnotation !=null){
+                    String annotationValue = tableFieldAnnotation.value();
+                    queryWrapper.eq(value != null, annotationValue, value);
+                }else {
+                    queryWrapper.eq(value != null, fieldName, value);
+                }
+            }
+        }
+        return queryWrapper;
+    }
+
+    /**
+     * @param c   闇�瑕佽幏寰楁煡璇㈡潯浠剁殑瀹炰綋瀵硅薄
+     * @param <E> 瀹炰綋瀵硅薄绫诲瀷
+     * @return LambdaQueryWrapper
+     */
+    public static <E> LambdaQueryWrapper<E> getLQWrapper(Class<E> c) {
+
+        return new LambdaQueryWrapper<>();
+    }
+
+    /**
+     * @param c   闇�瑕佽幏寰楁煡璇㈡潯浠剁殑瀹炰綋瀵硅薄
+     * @param <E> 瀹炰綋瀵硅薄绫诲瀷
+     * @return QueryWrapper
+     */
+    public static <E> QueryWrapper<E> getQWrapper(Class<E> c) {
+
+        return new QueryWrapper<>();
+    }
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/vo/PlcTaskInfoVO.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/vo/PlcTaskInfoVO.java
new file mode 100644
index 0000000..73f64b5
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/vo/PlcTaskInfoVO.java
@@ -0,0 +1,21 @@
+package com.sandu.ximon.admin.vo;
+
+import com.sandu.ximon.dao.domain.LightTask;
+import com.sandu.ximon.dao.domain.PlcTask;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author van
+ */
+@Data
+public class PlcTaskInfoVO {
+
+    /**
+     * 浠诲姟
+     */
+    private PlcTask plcTask;
+
+    private List<PlcTaskRelationVO> relations;
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/vo/PlcTaskRelationVO.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/vo/PlcTaskRelationVO.java
new file mode 100644
index 0000000..bb89553
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/vo/PlcTaskRelationVO.java
@@ -0,0 +1,32 @@
+package com.sandu.ximon.admin.vo;
+
+import lombok.Data;
+
+/**
+ * @author van
+ */
+@Data
+public class PlcTaskRelationVO {
+
+    private Long poleId;
+    private String poleName;
+
+
+    private String plcAddress;
+
+    /**
+     * 浠诲姟涓嬪彂鐘舵�侊紝0鎴愬姛锛�1鏍¢獙鐮侀敊璇紝2闀垮害閿欒锛�3鍐檉lash閿欒锛�255鍏朵粬閿欒
+     */
+    private Integer issueStatus;
+
+
+    /**
+     * 绯荤粺瀹氭椂
+     */
+    private PlcTaskVO sysScheduled;
+
+    /**
+     * 纭欢瀹氭椂
+     */
+    private PlcTaskVO deviceScheduled;
+}
diff --git a/ximon-admin/src/main/java/com/sandu/ximon/admin/vo/PlcTaskVO.java b/ximon-admin/src/main/java/com/sandu/ximon/admin/vo/PlcTaskVO.java
new file mode 100644
index 0000000..2acc959
--- /dev/null
+++ b/ximon-admin/src/main/java/com/sandu/ximon/admin/vo/PlcTaskVO.java
@@ -0,0 +1,52 @@
+package com.sandu.ximon.admin.vo;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author van
+ */
+@Data
+public class PlcTaskVO {
+
+    private Long taskId;
+
+
+    /**
+     * 浠诲姟鍚嶇О
+     */
+    private String taskName;
+
+    /**
+     * 鏄熸湡鍑狅紝浣嶈繍绠椾繚瀛橈紝1浠h〃鏄熸湡涓�锛�2鏄熸湡浜岋紝4鏄熸湡涓夛紝8鏄熸湡鍥涳紝16鏄熸湡浜旓紝32鏄熸湡鍏紝64鏄熸湡鏃�
+     */
+    @JsonIgnore
+    private Integer week;
+
+    private List<Integer> weekList;
+
+    /**
+     * 寮�鐏懡浠�
+     */
+    private String openOrder;
+
+    /**
+     * 鍏抽棴鐏懡浠�
+     */
+    private String closeOrder;
+
+    /**
+     * 鐏帶鍛戒护
+     */
+    private String controlOrder;
+
+
+    /**
+     * 鎺х伅鍦板潃
+     */
+    private String plcAdress;
+
+
+}
diff --git a/ximon-admin/src/main/resources/application-xm_local.yml b/ximon-admin/src/main/resources/application-xm_local.yml
new file mode 100644
index 0000000..060ab8c
--- /dev/null
+++ b/ximon-admin/src/main/resources/application-xm_local.yml
@@ -0,0 +1,129 @@
+spring:
+#  甯屾ⅵ鏈湴寮�鍙�
+  datasource:
+    # 鏁版嵁搴撶敤鎴峰悕
+    username: root
+    # 鏁版嵁搴撳瘑鐮�
+    password: zhxm2512209
+    url: jdbc:mysql://39.103.154.108:2512/xm_dev?useUnicode=true&autoReconnect=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai
+    type: com.alibaba.druid.pool.DruidDataSource
+    druid:
+      connection-init-sqls: set names utf8mb4
+      driver-class-name: com.mysql.cj.jdbc.Driver
+  redis:
+    host: 39.103.154.108
+    password: zhxm2512209
+    port: 6379
+    database: 0
+server:
+  port: 20017
+sandu:
+  jwt:
+    header: Authorization
+    # 浠ょ墝鍓嶇紑
+    token-start-with: Bearer
+    # 蹇呴』浣跨敤鏈�灏�88浣嶇殑Base64瀵硅浠ょ墝杩涜缂栫爜
+    base64-secret: U1GZNSKOH43V19GNIVE8HUYM9H86K657V1D66EAVSL9Q023J4JNWE44BNHCS6V9E66BPKF0KXUI5R1ZOYK2OWZZYALPD07JHOYUROL930UGJQUJDNAEYNTMUS27BHKTJEF9011DGGQ4QT9BN6CM2P9SY2VV2MZKJPCOW9YIGN0VJ
+    # 浠ょ墝杩囨湡鏃堕棿 姝ゅ鍗曚綅/姣 锛屽彲鍦ㄦ缃戠珯鐢熸垚 https://www.convertworld.com/zh-hans/time/milliseconds.html 1涓湀
+    token-validity-in-seconds: 2629800000
+    # 鍦ㄧ嚎鐢ㄦ埛key
+    online-key: online-token
+    # 鏄惁鍚姩redis缂撳瓨鐢ㄦ埛淇℃伅
+    cache-online: false
+    #************************鏈湴涓婁紶鏂囦欢閰嶇疆************************
+  upload:
+    #鏂囦欢鏈嶅姟鍣ㄨ矾寰�
+    upload-root-path: D:\file\
+    storage: local
+    #鏈嶅姟鍣ㄦ枃浠跺墠缂�
+    real-url: http://localhost/
+  common:
+    urlPrefix: http://localhost/
+  quartz:
+    enable: true
+
+# MQTT鐩戝惉
+listenter:
+  isOpen: true
+
+minio:
+  endpoint: 47.106.172.9
+  port: 9000
+  accessKey: minioadmin
+  secretKey: zhxm2512209
+  secure: false
+
+
+# led灞忓箷鏈嶅姟鍣ㄥ湴鍧�锛堟洿鏀归渶瑕佸悓鏃舵洿鏀癸級
+realtime-server:
+  #  command: http://101.132.131.91:8081/payload/
+  #  url: http://101.132.131.91:8081/
+  command: http://112.74.63.130:20018/command/
+  url: http://112.74.63.130:20018/
+
+
+server-conf:
+  ip: 127.0.0.1 # 47.106.172.9/101.132.131.91
+
+
+
+nova-conf:   #璇虹摝鍥炶皟
+  notify-url: http://39.103.154.108:20018/serv/vnnox/progress
+  screen-shot-notify-url: http://39.103.154.108:20018/serv/vnnox/screenshot
+  status-notify-url: http://39.103.154.108:20018/serv/vnnox/asyncStatus
+
+  #iot浜у搧绉橀挜
+iot:
+  access_key: LTAI4G27Af8MZEF55phdMQ4y
+  access_secret: KUc2yOtr7TRB4FuF5Wr0dWeTblbEuh
+
+#闃块噷浜憃ss閰嶇疆
+oss-conf:
+  end-point: oss-cn-shanghai.aliyuncs.com
+  key-id: LTAI5tPdpt5wvJyLipRijFSP
+  key-secret: 1ahYfCKd0yTddsUnuDLQzI23MLh4VQ
+  bucket-name: ximonsmart
+
+#鏂拌鐡�
+new-nova:
+  #渚濊禆鍦板潃
+  string-path: D:\file\novaWin\bin\viplexcore.dll
+  #鑺傜洰鐢熸垚璺緞
+  out-put-path: D:\file\temp
+new-nova-file:
+  upload:
+    #鏂囦欢鏈嶅姟鍣ㄨ矾寰�
+    upload-root-path: D:\file\
+    storage: local
+    #鏈嶅姟鍣ㄦ枃浠跺墠缂�
+    file-url: http://192.168.0.12:20017/file/
+    #璇虹摝鎴睆瀛樻斁璺緞   鏂囦欢澶瑰繀椤诲瓨鍦�  涓旀槸鏈嶅姟鍣ㄦ枃浠惰矾寰�(upload-root-path)涓嬬殑瀛愭枃浠跺す
+    screen-shot-path: D:\file\screenShot\
+
+
+
+customer:
+  mqtt:
+    broker: tcp://127.0.0.1:1883
+    clientList:
+      #瀹㈡埛绔疘D
+      - clientId: java_server_msg
+        #鐩戝惉涓婚
+        subscribeTopic: v1/devices/response/+
+        #鐢ㄦ埛鍚�
+        userName: server_admin
+        #瀵嗙爜
+        password: zhxm2512209
+        #涓嬪彂涓婚
+        publishTopic: v1/devices/request/
+      #鐩戝惉涓婁笅绾�
+      - clientId: java_server_status
+        #鐩戝惉涓婚
+        subscribeTopic: $SYS/brokers/+/clients/#
+        #鐢ㄦ埛鍚�
+        userName: server_admin
+        #瀵嗙爜
+        password: zhxm2512209
+        #涓嬪彂涓婚
+        publishTopic: v1/devices/request/
+
diff --git a/ximon-admin/src/main/resources/application.yml b/ximon-admin/src/main/resources/application.yml
index 0b58b1a..7bcbf06 100644
--- a/ximon-admin/src/main/resources/application.yml
+++ b/ximon-admin/src/main/resources/application.yml
@@ -1,6 +1,6 @@
 spring:
   profiles:
-    active: prod
+    active: xm_local
   jackson:
     date-format: yyyy-MM-dd HH:mm:ss
     time-zone: GMT+8
@@ -53,4 +53,4 @@
 
 #涓绘澘rrpc閫氫俊PRODUCT_KEY
 #rrpc:
-#  key: a1JsfPG4iKW
\ No newline at end of file
+#  key: a1JsfPG4iKW

--
Gitblit v1.9.3