opt:西门子优化
This commit is contained in:
@@ -94,7 +94,13 @@ public class NDCAgvServiceImpl implements NDCAgvService {
|
||||
//如果起始点在PS15起始点位区间、终点也在PS15终点区间,则使用PS15,type=2其他情况,type =1
|
||||
StorageCell startStorageCell = storageCellService.getByCode(inst.getStart_point_code());
|
||||
StorageCell endStorageCell = storageCellService.getByCode(inst.getNext_point_code());
|
||||
if ((null != startStorageCell && null != endStorageCell)
|
||||
if(null != startStorageCell && null != endStorageCell
|
||||
&& "small".equals(inst.getCar_type())){
|
||||
inst.setCar_type("1");
|
||||
startAddress = deviceService.queryEndAddressBydeviceCode(inst.getStart_point_code());
|
||||
nextAddress = deviceService.queryAddressBydeviceCode(inst.getNext_point_code());
|
||||
}
|
||||
else if ((null != startStorageCell && null != endStorageCell)
|
||||
&& (("start".equals(inst.getCar_type()) && "2".equals(startStorageCell.getCar_type()))
|
||||
|| "end".equals(inst.getCar_type()) && "2".equals(endStorageCell.getCar_type())
|
||||
|| "new_car".equals(startStorageCell.getRemark())
|
||||
|
||||
@@ -13,5 +13,7 @@ public interface AcsAgvUsageRecordMapper extends BaseMapper<AcsAgvUsageRecord> {
|
||||
|
||||
AcsAgvUsageRecord selectActiveByDeviceCode(@Param("deviceCode") String deviceCode);
|
||||
|
||||
AcsAgvUsageRecord selectActiveByInstructionCode(@Param("instructionCode") String instructionCode);
|
||||
|
||||
List<AcsAgvUsageRecord> selectByDeviceCodeAndDate(@Param("deviceCode") String deviceCode, @Param("workDate") Date workDate);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,15 @@
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="selectActiveByInstructionCode" resultMap="BaseResultMap">
|
||||
SELECT * FROM acs_agv_usage_record
|
||||
WHERE instruction_code = #{instructionCode}
|
||||
AND status = '0'
|
||||
AND is_active = '1'
|
||||
ORDER BY start_time DESC
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="selectByDeviceCodeAndDate" resultMap="BaseResultMap">
|
||||
SELECT * FROM acs_agv_usage_record
|
||||
WHERE device_code = #{deviceCode}
|
||||
|
||||
@@ -83,4 +83,12 @@ public class AgvUsageController {
|
||||
agvUsageService.endWork(deviceCode, taskCode, instructionCode);
|
||||
return new ResponseEntity<>("success", HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/monthly")
|
||||
@Log("获取月度AGV使用率统计")
|
||||
@ApiOperation("获取月度AGV使用率统计")
|
||||
public ResponseEntity<Object> getMonthlyStatistics() {
|
||||
List<Map<String, Object>> result = agvUsageService.getMonthlyAgvUsageRate();
|
||||
return new ResponseEntity<>(result, HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,4 +22,6 @@ public interface AcsAgvUsageService {
|
||||
List<Map<String, Object>> getAgvUsageRate(Date startDate, Date endDate);
|
||||
|
||||
Map<String, Object> getAgvRealtimeStatus();
|
||||
|
||||
List<Map<String, Object>> getMonthlyAgvUsageRate();
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import cn.hutool.core.util.IdUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.nl.acs.agv_usage.domain.AcsAgvDailyStatistics;
|
||||
import org.nl.acs.agv_usage.domain.AcsAgvUsageRecord;
|
||||
import org.nl.acs.agv_usage.mapper.AcsAgvDailyStatisticsMapper;
|
||||
@@ -37,36 +38,58 @@ public class AcsAgvUsageServiceImpl implements AcsAgvUsageService {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void startWork(String deviceCode, String deviceName, String taskCode, String instructionCode) {
|
||||
AcsAgvUsageRecord existingRecord = usageRecordMapper.selectActiveByDeviceCode(deviceCode);
|
||||
if (existingRecord != null) {
|
||||
log.warn("AGV {} 已有工作中的记录,先结束上一条记录", deviceCode);
|
||||
endWork(deviceCode, existingRecord.getTask_code(), existingRecord.getInstruction_code());
|
||||
if(StringUtils.isBlank(instructionCode)) {
|
||||
log.warn("指令号为空,无法开始工作记录");
|
||||
return;
|
||||
}
|
||||
|
||||
AcsAgvUsageRecord record = new AcsAgvUsageRecord();
|
||||
record.setId(IdUtil.simpleUUID());
|
||||
record.setDevice_code(deviceCode);
|
||||
record.setDevice_name(deviceName);
|
||||
record.setTask_code(taskCode);
|
||||
record.setInstruction_code(instructionCode);
|
||||
record.setStart_time(new Date());
|
||||
record.setWork_date(new Date());
|
||||
record.setStatus("0");
|
||||
record.setWork_duration(0L);
|
||||
record.setIs_active("1");
|
||||
record.setCreate_time(new Date());
|
||||
record.setUpdate_time(new Date());
|
||||
|
||||
usageRecordMapper.insert(record);
|
||||
log.info("AGV {} 开始工作,任务号: {}, 指令号: {}", deviceCode, taskCode, instructionCode);
|
||||
AcsAgvUsageRecord existingRecord = usageRecordMapper.selectActiveByInstructionCode(instructionCode);
|
||||
if (existingRecord != null) {
|
||||
// 如果记录已存在,更新车号和设备名称
|
||||
if (StringUtils.isNotBlank(deviceCode)) {
|
||||
existingRecord.setDevice_code(deviceCode);
|
||||
existingRecord.setDevice_name(deviceName);
|
||||
existingRecord.setUpdate_time(new Date());
|
||||
usageRecordMapper.updateById(existingRecord);
|
||||
log.info("AGV {} 工作记录已更新,任务号: {}, 指令号: {}", deviceCode, taskCode, instructionCode);
|
||||
}
|
||||
} else {
|
||||
// 创建新记录
|
||||
AcsAgvUsageRecord record = new AcsAgvUsageRecord();
|
||||
record.setId(IdUtil.simpleUUID());
|
||||
record.setDevice_code(deviceCode);
|
||||
record.setDevice_name(deviceName);
|
||||
record.setTask_code(taskCode);
|
||||
record.setInstruction_code(instructionCode);
|
||||
record.setStart_time(new Date());
|
||||
record.setWork_date(new Date());
|
||||
record.setStatus("0");
|
||||
record.setWork_duration(0L);
|
||||
record.setIs_active("1");
|
||||
record.setCreate_time(new Date());
|
||||
record.setUpdate_time(new Date());
|
||||
usageRecordMapper.insert(record);
|
||||
log.info("AGV 工作记录已创建,任务号: {}, 指令号: {}", taskCode, instructionCode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void endWork(String deviceCode, String taskCode, String instructionCode) {
|
||||
AcsAgvUsageRecord record = usageRecordMapper.selectActiveByDeviceCode(deviceCode);
|
||||
AcsAgvUsageRecord record = null;
|
||||
|
||||
// 优先根据设备号查找记录
|
||||
if (StringUtils.isNotBlank(deviceCode)) {
|
||||
record = usageRecordMapper.selectActiveByDeviceCode(deviceCode);
|
||||
}
|
||||
|
||||
// 如果根据设备号找不到,且指令号不为空,根据指令号查找
|
||||
if (record == null && StringUtils.isNotBlank(instructionCode)) {
|
||||
record = usageRecordMapper.selectActiveByInstructionCode(instructionCode);
|
||||
}
|
||||
|
||||
if (record == null) {
|
||||
log.warn("AGV {} 没有找到工作中的记录", deviceCode);
|
||||
log.warn("未找到工作中的记录,设备号: {}, 指令号: {}", deviceCode, instructionCode);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -80,9 +103,12 @@ public class AcsAgvUsageServiceImpl implements AcsAgvUsageService {
|
||||
|
||||
usageRecordMapper.updateById(record);
|
||||
|
||||
updateDailyStatistics(deviceCode, record.getWork_date());
|
||||
// 只有当设备号不为空时,才更新每日统计
|
||||
if (StringUtils.isNotBlank(record.getDevice_code())) {
|
||||
updateDailyStatistics(record.getDevice_code(), record.getWork_date());
|
||||
}
|
||||
|
||||
log.info("AGV {} 结束工作,任务号: {}, 工作时长: {}秒", deviceCode, taskCode, workDuration);
|
||||
log.info("AGV {} 结束工作,任务号: {}, 工作时长: {}秒", record.getDevice_code(), taskCode, workDuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -107,13 +133,27 @@ public class AcsAgvUsageServiceImpl implements AcsAgvUsageService {
|
||||
|
||||
AcsAgvDailyStatistics existingStats = dailyStatisticsMapper.selectByDeviceCodeAndDate(deviceCode, workDate);
|
||||
|
||||
long totalIdleDuration = DAY_SECONDS - totalWorkDuration;
|
||||
// 计算总时长:如果是当天,使用当天0点到当前时间的差值;否则使用24小时
|
||||
long totalDuration;
|
||||
Date today = new Date();
|
||||
Date workDateStart = DateUtil.beginOfDay(workDate);
|
||||
Date todayStart = DateUtil.beginOfDay(today);
|
||||
|
||||
if (workDateStart.equals(todayStart)) {
|
||||
// 当天,计算0点到当前时间的差值
|
||||
totalDuration = (System.currentTimeMillis() - workDateStart.getTime()) / 1000;
|
||||
} else {
|
||||
// 非当天,使用24小时
|
||||
totalDuration = DAY_SECONDS;
|
||||
}
|
||||
|
||||
long totalIdleDuration = totalDuration - totalWorkDuration;
|
||||
if (totalIdleDuration < 0) {
|
||||
totalIdleDuration = 0;
|
||||
}
|
||||
|
||||
BigDecimal usageRate = BigDecimal.valueOf(totalWorkDuration)
|
||||
.divide(BigDecimal.valueOf(DAY_SECONDS), 4, RoundingMode.HALF_UP)
|
||||
.divide(BigDecimal.valueOf(totalDuration), 4, RoundingMode.HALF_UP)
|
||||
.multiply(BigDecimal.valueOf(100))
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
|
||||
@@ -218,4 +258,66 @@ public class AcsAgvUsageServiceImpl implements AcsAgvUsageService {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> getMonthlyAgvUsageRate() {
|
||||
// 获取所有每日统计数据
|
||||
List<AcsAgvDailyStatistics> statistics = dailyStatisticsMapper.selectList(null);
|
||||
|
||||
// 按月份分组
|
||||
Map<String, Map<String, Object>> monthlyStatsMap = new LinkedHashMap<>();
|
||||
|
||||
for (AcsAgvDailyStatistics stat : statistics) {
|
||||
Date workDate = stat.getWork_date();
|
||||
String month = DateUtil.format(workDate, "yyyy-MM");
|
||||
|
||||
if (!monthlyStatsMap.containsKey(month)) {
|
||||
Map<String, Object> monthlyData = new HashMap<>();
|
||||
monthlyData.put("month", month);
|
||||
monthlyData.put("totalWorkDuration", 0L);
|
||||
monthlyData.put("totalTaskCount", 0);
|
||||
monthlyData.put("usageRateSum", BigDecimal.ZERO);
|
||||
monthlyData.put("dayCount", 0);
|
||||
monthlyData.put("maxUsageRate", BigDecimal.ZERO);
|
||||
monthlyData.put("minUsageRate", BigDecimal.valueOf(100));
|
||||
monthlyStatsMap.put(month, monthlyData);
|
||||
}
|
||||
|
||||
Map<String, Object> monthlyData = monthlyStatsMap.get(month);
|
||||
monthlyData.put("totalWorkDuration", (Long) monthlyData.get("totalWorkDuration") + stat.getTotal_work_duration());
|
||||
monthlyData.put("totalTaskCount", (Integer) monthlyData.get("totalTaskCount") + stat.getTask_count());
|
||||
monthlyData.put("usageRateSum", ((BigDecimal) monthlyData.get("usageRateSum")).add(stat.getUsage_rate()));
|
||||
monthlyData.put("dayCount", (Integer) monthlyData.get("dayCount") + 1);
|
||||
|
||||
// 更新最高和最低使用率
|
||||
BigDecimal usageRate = stat.getUsage_rate();
|
||||
if (usageRate.compareTo((BigDecimal) monthlyData.get("maxUsageRate")) > 0) {
|
||||
monthlyData.put("maxUsageRate", usageRate);
|
||||
}
|
||||
if (usageRate.compareTo((BigDecimal) monthlyData.get("minUsageRate")) < 0) {
|
||||
monthlyData.put("minUsageRate", usageRate);
|
||||
}
|
||||
}
|
||||
|
||||
// 计算月度平均使用率并整理结果
|
||||
List<Map<String, Object>> result = new ArrayList<>();
|
||||
for (Map<String, Object> monthlyData : monthlyStatsMap.values()) {
|
||||
int dayCount = (Integer) monthlyData.get("dayCount");
|
||||
if (dayCount > 0) {
|
||||
BigDecimal avgUsageRate = ((BigDecimal) monthlyData.get("usageRateSum"))
|
||||
.divide(BigDecimal.valueOf(dayCount), 2, RoundingMode.HALF_UP);
|
||||
monthlyData.put("avgUsageRate", avgUsageRate);
|
||||
} else {
|
||||
monthlyData.put("avgUsageRate", BigDecimal.ZERO);
|
||||
}
|
||||
monthlyData.remove("usageRateSum");
|
||||
monthlyData.remove("dayCount");
|
||||
result.add(monthlyData);
|
||||
}
|
||||
|
||||
// 按月份降序排序
|
||||
result.sort((a, b) -> b.get("month").toString().compareTo(a.get("month").toString()));
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,7 +302,7 @@ public class OneNDCSocketConnectionAutoRun extends AbstractAutoRunnable {
|
||||
} else {
|
||||
//上报异常信息
|
||||
//(不需要WCS反馈)
|
||||
if (phase == 0x70 || phase == 0x71 || phase == 0x72 || phase == 0x73 || phase == 0x74) {
|
||||
if (phase == 0x70 || phase == 0x71 || phase == 0x72 || phase == 0x73 || phase == 0x74 || phase == 0x67 || phase == 0x68) {
|
||||
device = deviceAppService.findDeviceByCode("agv" + Integer.toString(agvaddr));
|
||||
} else {
|
||||
device = deviceAppService.findDeviceByCode("agv" + Integer.toString(arr[20]));
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.nl.acs.task.domain.Task;
|
||||
import org.nl.acs.task.service.TaskService;
|
||||
import org.nl.acs.task.service.dto.TaskDto;
|
||||
import org.nl.acs.task.service.impl.TaskServiceImpl;
|
||||
import org.nl.common.utils.AlarmUtil;
|
||||
import org.nl.common.utils.ThrowableUtil;
|
||||
import org.nl.system.service.dict.ISysDictService;
|
||||
import org.nl.system.service.dict.dao.Dict;
|
||||
@@ -136,14 +137,55 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
|
||||
|
||||
if (phase == 0x67) {
|
||||
//故障信息
|
||||
if (arr[18] * 256 + arr[19] == 0) {
|
||||
// if (arr[18] * 256 + arr[19] == 0) {
|
||||
|
||||
// }
|
||||
// FeedBackTaskStatusRequest request = new FeedBackTaskStatusRequest();
|
||||
// request.setDevice_code(this.device_code);
|
||||
// request.setState("故障");
|
||||
// acsToWmsService.notify(request);
|
||||
// data = NDCAgvService.sendAgvOneModeInst(phase, index, 0, 0, 0, 0, 0);
|
||||
|
||||
// 更新AGV状态
|
||||
try {
|
||||
log.info("接收到phase=0x67的情况:ikey {}", ikey);
|
||||
String agvDeviceCode = "agv" + agvaddr;
|
||||
String agvDeviceName = this.device_code;
|
||||
Device agvDevice = deviceAppService.findDeviceByCode(agvDeviceCode);
|
||||
if (agvDevice != null) {
|
||||
agvDeviceName = agvDevice.getDevice_name();
|
||||
}
|
||||
|
||||
if (ikey == 0) {
|
||||
agvAlarmService.updateAgvStatus(agvDeviceCode, agvDeviceName, 2,"正常", x, y, angle, electric_qty);
|
||||
} else {
|
||||
agvAlarmService.updateAgvStatus(agvDeviceCode, agvDeviceName, 6,
|
||||
AlarmUtil.parseAlarm(Integer.toHexString(ikey),phase), x, y, angle, electric_qty);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("AGV状态更新失败: {}", e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
else if (phase == 0x68) {
|
||||
// 更新AGV状态
|
||||
try {
|
||||
log.info("接收到phase=0x68的情况:ikey {}", ikey);
|
||||
String agvDeviceCode = "agv" + agvaddr;
|
||||
String agvDeviceName = this.device_code;
|
||||
Device agvDevice = deviceAppService.findDeviceByCode(agvDeviceCode);
|
||||
if (agvDevice != null) {
|
||||
agvDeviceName = agvDevice.getDevice_name();
|
||||
}
|
||||
if (ikey == 0) {
|
||||
agvAlarmService.updateAgvStatus(agvDeviceCode, agvDeviceName, 2,"正常", x, y, angle, electric_qty);
|
||||
} else {
|
||||
agvAlarmService.updateAgvStatus(agvDeviceCode, agvDeviceName, 6,
|
||||
AlarmUtil.parseAlarm(Integer.toHexString(ikey),phase), x, y, angle, electric_qty);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("AGV状态更新失败: {}", e.getMessage());
|
||||
}
|
||||
FeedBackTaskStatusRequest request = new FeedBackTaskStatusRequest();
|
||||
request.setDevice_code(this.device_code);
|
||||
request.setState("故障");
|
||||
acsToWmsService.notify(request);
|
||||
data = NDCAgvService.sendAgvOneModeInst(phase, index, 0, 0, 0, 0, 0);
|
||||
}
|
||||
TaskDto task = new TaskDto();
|
||||
|
||||
@@ -151,7 +193,17 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
|
||||
task = taskService.findById(inst.getTask_id());
|
||||
}
|
||||
|
||||
|
||||
//接到任务,因为无法判断是哪辆车 先不处理
|
||||
if (phase == 0x01) {
|
||||
// AGV使用率统计 - 开始工作
|
||||
try {
|
||||
String agvDeviceCode = null;
|
||||
String agvDeviceName = null;
|
||||
agvUsageService.startWork(agvDeviceCode, agvDeviceName, inst.getTask_code(), inst.getInstruction_code());
|
||||
} catch (Exception e) {
|
||||
log.error("AGV使用率统计-开始工作失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
//分配 车id
|
||||
//(不需要WCS反馈)
|
||||
if (phase == 0x02) {
|
||||
@@ -621,35 +673,6 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
|
||||
} else if (phase == 0x74) {
|
||||
//三色灯状态
|
||||
status = ikey;
|
||||
|
||||
// 更新AGV状态
|
||||
try {
|
||||
String agvDeviceCode = "agv" + agvaddr;
|
||||
String agvDeviceName = this.device_code;
|
||||
Device agvDevice = deviceAppService.findDeviceByCode(agvDeviceCode);
|
||||
if (agvDevice != null) {
|
||||
agvDeviceName = agvDevice.getDevice_name();
|
||||
}
|
||||
String statusStr = "正常";
|
||||
if (status == 1) {
|
||||
statusStr = "关机";
|
||||
} else if (status == 2) {
|
||||
statusStr = "运行中";
|
||||
}else if (status == 3) {
|
||||
statusStr = "交通管制";
|
||||
}else if (status == 4) {
|
||||
statusStr = "任务等待";
|
||||
}else if (status == 5) {
|
||||
statusStr = "充电中";
|
||||
}else if (status == 6) {
|
||||
statusStr = "故障中";
|
||||
}else if (status == 7) {
|
||||
statusStr = "低电量";
|
||||
}
|
||||
agvAlarmService.updateAgvStatus(agvDeviceCode, agvDeviceName, status,statusStr, x, y, angle, electric_qty);
|
||||
} catch (Exception e) {
|
||||
log.error("AGV状态更新失败: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
if (!ObjectUtil.isEmpty(data)) {
|
||||
logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data);
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package org.nl.common.utils;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AlarmUtil {
|
||||
private static final String[] ALARM_67 = {
|
||||
"货叉光电报警", // 0
|
||||
"安全避障报警", // 1
|
||||
"触边/防撞报警", // 2
|
||||
"导航激光报警", // 3
|
||||
"急停按钮触发", // 4
|
||||
"载货状态改变", // 5
|
||||
"需要复位", // 6
|
||||
"没有操作码", // 7
|
||||
"取货时无货", // 8
|
||||
"取货前有货", // 9
|
||||
"放货前无货", //10
|
||||
"放货完有货", //11
|
||||
"充电异常", //12
|
||||
"超出安全区域", //13
|
||||
"货叉太高或太低" //14
|
||||
};
|
||||
|
||||
private static final String[] ALARM_68 = {
|
||||
"车轮打滑", // 0
|
||||
"手动模式", // 1
|
||||
"没有定位", // 2
|
||||
"车辆不在系统中", // 3
|
||||
"正在充电", // 4
|
||||
"转向编码器同步失败",// 5
|
||||
"货叉左右限位未触发" // 6
|
||||
};
|
||||
public static String parseAlarm(String hexStr, int phase) {
|
||||
if (hexStr == null || StringUtils.isBlank(hexStr) || hexStr.length() > 4) {
|
||||
throw new IllegalArgumentException("十六进制字符串无效");
|
||||
}
|
||||
if (0x67 != phase && 0x68 != phase) {
|
||||
throw new IllegalArgumentException("phase只能是67或68");
|
||||
}
|
||||
|
||||
// 1. 直接转16位二进制,保留所有前导0
|
||||
int value = Integer.parseInt(hexStr.trim(), 16);
|
||||
String binary = String.format("%16s", Integer.toBinaryString(value)).replace(' ', '0');
|
||||
|
||||
List<String> res = new ArrayList<>();
|
||||
|
||||
if (0x67 == phase) {
|
||||
// 核心:遍历16位,从左到右 = 位1 ~ 位15,最后一位=位0
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (binary.charAt(i) == '1') {
|
||||
int bit;
|
||||
if (i == 15) {
|
||||
bit = 0; // 最后一位 = 第0位
|
||||
} else {
|
||||
bit = i + 1; // 左边第i位 = 第(i+1)位
|
||||
}
|
||||
|
||||
if (bit < ALARM_67.length) {
|
||||
res.add(ALARM_67[bit]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 68模式 8位
|
||||
String bin8 = String.format("%8s", Integer.toBinaryString(value)).replace(' ', '0');
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (bin8.charAt(i) == '1') {
|
||||
int bit = (i == 7) ? 0 : (i + 1);
|
||||
if (bit < ALARM_68.length) {
|
||||
res.add(ALARM_68[bit]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return String.join(",", res);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user