2021与蓝度共同重构项目,服务端
Van333
2022-12-29 727a69f859060093e685582fa10e5de82dcc138a
放假备份。完成集中控制器对接。
已修改15个文件
已添加66个文件
已删除1个文件
5591 ■■■■■ 文件已修改
dao/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/bo/PlcBo.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/bo/PlcReportDataBo.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/bo/PlcReportErrorBo.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/bo/PlcTaskNameIdBo.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/domain/Plc.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/domain/PlcReportData.java 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/domain/PlcReportError.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/domain/PlcTask.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/domain/PlcTaskPoleRelation.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/domain/PoleBinding.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/enums/MenuEnum.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/enums/OrderByEnums.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/enums/PoleBindingEnums.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/mapper/PlcMapper.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/mapper/PlcReportDataMapper.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/mapper/PlcReportErrorMapper.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/mapper/PlcTaskMapper.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/mapper/PlcTaskPoleRelationMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/resources/mapper/LedSFileMapper.xml 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/resources/mapper/PlcLightMapper.xml 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/resources/mapper/PlcReportDataMapper.xml 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/resources/mapper/PlcReportErrorMapper.xml 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/resources/mapper/PlcTaskDao.xml 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sandu-common/src/main/resources/logback-spring.xml 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcController.java 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcReportDataController.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcTaskController.java 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PlcTaskPoleRelationController.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/PoleController.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/dto/PlcTaskDto.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/amqp/AmqpMessageListener.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/amqp/processor/PlcDataProcessor.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/A7Frame.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/FrameBuilder.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcErrorCodeReportInnerFrame.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcHeartbeatReportInnerFrame.java 308 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcManualLightSwitchReportInnerFrame.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcOperationReportInnerFrame.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/report/A7PlcTimeSyncReportInnerFrame.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcBrightnessReqInnerFrame.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcCleanErrorCodeInnerFrame.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcQueryHeartBeatDataReqInnerFrame.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcQueryHeartBeatTimeReqInnerFrame.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcQueryVersionReqInnerFrame.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcRebootReqInnerFrame.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcResetReqInnerFrame.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcSetCalendarReqInnerFrame.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcSettingHeartBeatTimeReqInnerFrame.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/request/A7PlcTimerReqInnerFrame.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A1DeviceMacRespInnerFrame.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcBrightnessRespInnerFrame.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcQueryHeartBeatDataRespInnerFrame.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcQueryHeartBeatTimeRespInnerFrame.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcQueryVersionRespInnerFrame.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcResetRespInnerFrame.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcRespInnerFrame.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/frame/inner/response/A7PlcTimerRespInnerFrame.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/A7OrderEnum.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/A7PlcDataEnum.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/A7PlcReportEnum.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/FunctionCodeEnum.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/manager/iot/rrpc/enums/PlcErrorEnum.java 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcControlParam.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcRemarkParam.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcTaskDelParam.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcTaskIssueParam.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/param/PlcTaskParam.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcReportDataService.java 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcReportErrorService.java 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcService.java 647 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcTaskPoleRelationService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/service/PlcTaskService.java 909 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/service/PoleBindingService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/service/PoleService.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/utils/MybatisPlusUtil.java 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/vo/PlcTaskInfoVO.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/vo/PlcTaskRelationVO.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/vo/PlcTaskVO.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/resources/application-xm_local.yml 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
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>
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;
}
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;
}
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;
}
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;
}
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;
}
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;
    //正向有功总电量
    @ApiModelProperty("正向有功总电量")
    @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;
}
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;
}
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代表星期一,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;
}
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写flash错误,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;
}
dao/src/main/java/com/sandu/ximon/dao/domain/PoleBinding.java
@@ -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;
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;
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"),
    /**
     * å……电桩列表
dao/src/main/java/com/sandu/ximon/dao/enums/PoleBindingEnums.java
@@ -64,4 +64,9 @@
     * å†œè€•
     */
    public static final String ATMOSPHERIC_NONG_GENG = "11";
    /*
    * plc
    * */
    public static final String PLC = "13";
}
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> {
/**
* æ‰¹é‡æ–°å¢žæ•°æ®ï¼ˆMyBatis原生foreach方法)
*
* @param entities List<Plc> å®žä¾‹å¯¹è±¡åˆ—表
* @return å½±å“è¡Œæ•°
*/
int insertBatch(@Param("entities") List<Plc> entities);
/**
* æ‰¹é‡æ–°å¢žæˆ–按主键更新数据(MyBatis原生foreach方法)
*
* @param entities List<Plc> å®žä¾‹å¯¹è±¡åˆ—表
* @return å½±å“è¡Œæ•°
* @throws org.springframework.jdbc.BadSqlGrammarException å…¥å‚是空List的时候会抛SQL语句错误的异常,请自行校验入参
*/
int insertOrUpdateBatch(@Param("entities") List<Plc> entities);
    List<PlcBo> listPlc(Long clientId, String keyword);
    /**
     * èŽ·å–ç”¨æˆ·æ‰€æ‹¥æœ‰çš„ç¯æ†ä¸Šçš„è·¯ç¯code
     *
     * @param userId
     * @return
     */
    List<String> listCode(Long userId, String keyword, String deviceCode);
}
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);
}
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);
}
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);
}
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> {
}
dao/src/main/resources/mapper/LedSFileMapper.xml
ÎļþÒÑɾ³ý
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>
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>
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>
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>
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>
    <!-- ç”Ÿäº§çŽ¯å¢ƒ. æ—¥å¿—级别为WARN且写日志文件-->
    <springProfile name="prod,docker">
    <springProfile name="prod,docker,xm_lj">
        <root level="warn">
            <appender-ref ref="STDOUT"/>
            <appender-ref ref="ASYNC"/>
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>
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);
    }
}
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;
}
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));
    }
}
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));
    }
}
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());
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;
}
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,8 +106,12 @@
        if (frame == null) {
            return;
        }
        log.info("处理订阅");
        log.info(frame.toString());
//        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);
@@ -125,5 +124,14 @@
        } 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);
            }
        }
    }
}
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);
                }
            }
        }
    }
}
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;
    }
}
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("找不到符合条件的请求帧");
        }
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;
    }
}
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) {
        //  é•¿åº¦ä¸ä¸€è‡´æ—¶ï¼Œè¿”回null
        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> {
        //  å¹´RTC 1
        private Integer year;
        //  æœˆRTC 1
        private Integer month;
        //  æ—¥RTC 1
        private Integer day;
        //  æ—¶RTC 1
        private Integer hour;
        //  åˆ†RTC 1
        private Integer min;
        //  ç§’RTC 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;
        //正向有功总电量
        //@ApiModelProperty("正向有功总电量")
       // @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),得到正确数值
         * ä¼ å…¥16进制的温度,类型为String
         * å¦‚F500
         */
        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;
        }
    }
}
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;
    }
}
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) {        //  é•¿åº¦ä¸ä¸€è‡´æ—¶ï¼Œè¿”回null
        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 = "写Flash失败错误";
                break;
            case "FF":
                State = "其他错误";
                break;
            default:
                State = "未知错误";
        }
        return State;
    }
}
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;
    }
}
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());
    }
}
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());
    }
}
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());
    }
}
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());
    }
}
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());
    }
}
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());
    }
}
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());
    }
}
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);
    }
}
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());
    }
}
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());
    }
}
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代表MQTT串口,01代表CAT1
     * 1字节 è®¾å¤‡ç±»åž‹ è®¾å¤‡ç±»åž‹00代表MQTT串口,01代表CAT1,02代表PLC
     */
    private String type;
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
    }
}
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;
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    é›†ä¸­çº¿æŽ§å™¨EEPROM故障
3    é›†ä¸­çº¿æŽ§å™¨RTC故障
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    é›†ä¸­çº¿æŽ§å™¨EEPROM故障
        3    é›†ä¸­çº¿æŽ§å™¨RTC故障
        4    A相失压
        5    A相欠压    æ— ç”µæµ
        6    A相过压    ç¼ºç›¸
        7    A相失流    ç”µæµåå‘
        8    A相过流
        9    A相过载*/
    E0(1,"网络不稳定/4G信号弱"),
    E1(2,"设备温度过高"),
    E2(2<<1,"集中线控器EEPROM故障"),
    E3(2<<2,"集中线控器RTC故障"),
    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;
    }
}
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;
}
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;
}
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;
}
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;
}
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代表星期一,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;
}
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);
    /**
     * ä¿å­˜ä¸ŠæŠ¥çš„PLC心跳数据
     *
     * @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";
        //正序、倒叙
        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("系统中不存在该plc");
        }
        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;
    }
}
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;
        //为null的话是超管
        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);
        }
    }
}
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";
        //正序、倒叙
        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("找不到PLC");
        }
        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, "服务端批量PLC控灯", 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主动同步时间请求异常,PLC信息不存在!");
            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("数据校验错误,请重新请求");
        }
    }
}
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> {
}
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("解析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,不能下发任务   è¯·æ£€æŸ¥ç¯æ†æ˜¯å¦å­˜åœ¨PLC");
            }
            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,不能下发任务   è¯·æ£€æŸ¥ç¯æ†æ˜¯å¦å­˜åœ¨PLC");
            }
            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<>();
        //传入的灯杆id集合
        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("找不到PLC任务");
        }
        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);
        //编辑后灯杆ID集合
        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中有的灯杆ID,但是poleIdList中没有 (关灯操作)
        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());
        //发送rrpc  å¾—到发送结果
        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));
        //重复的任务id
        List<Long> taskIds = plcTaskPoleRelations.stream().map(PlcTaskPoleRelation::getTaskId).collect(Collectors.toList());
        //重复的灯杆id
        List<Long> oldPoleIds = plcTaskPoleRelations.stream().map(PlcTaskPoleRelation::getPoleId).collect(Collectors.toList());
        //未重复的灯杆id
        List<Long> finalOldPoleIds = oldPoleIds;
        //取出存在于poleIdList而不在oldPoleIds中的灯杆
        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";
        //正序、倒叙
        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;
    }
}
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;
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("该灯杆Mac为空");
        }
        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,13 +1022,25 @@
        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 (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);
                }
            }
        }
        /**
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);
            //如果是String类型,拼接模糊查找条件,否则拼接等值查找,忽略serialVersionUID属性
            if (simpleName.equals("String")) {
                //若存在tableField注解,则使用注解中的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")) {
                //若存在tableField注解,则使用注解中的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<>();
    }
}
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;
}
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写flash错误,255其他错误
     */
    private Integer issueStatus;
    /**
     * ç³»ç»Ÿå®šæ—¶
     */
    private PlcTaskVO sysScheduled;
    /**
     * ç¡¬ä»¶å®šæ—¶
     */
    private PlcTaskVO deviceScheduled;
}
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代表星期一,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;
}
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
#阿里云oss配置
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:
      #客户端ID
      - 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/
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