diff --git a/AutoSprout-common/src/main/java/com/ruoyi/common/core/domain/onenet/DatapointValue.java b/AutoSprout-common/src/main/java/com/ruoyi/common/core/domain/onenet/DatapointValue.java index cc5d9f2..700eaa3 100644 --- a/AutoSprout-common/src/main/java/com/ruoyi/common/core/domain/onenet/DatapointValue.java +++ b/AutoSprout-common/src/main/java/com/ruoyi/common/core/domain/onenet/DatapointValue.java @@ -55,7 +55,7 @@ public class DatapointValue { //下次浇水时间 @Data - private class nextDs { + public static class nextDs { private int hour; private int min; private int sec; diff --git a/AutoSprout-watering/src/main/java/com/ruoyi/device/app/AppController.java b/AutoSprout-watering/src/main/java/com/ruoyi/device/app/AppController.java index 36d6c57..0a21f49 100644 --- a/AutoSprout-watering/src/main/java/com/ruoyi/device/app/AppController.java +++ b/AutoSprout-watering/src/main/java/com/ruoyi/device/app/AppController.java @@ -302,10 +302,11 @@ public class AppController extends BaseController * 删除定时器 */ @Log(title = "定时器", businessType = BusinessType.DELETE) - @DeleteMapping("/timer/{ids}") - public AjaxResult remove(@PathVariable Long[] ids) + @DeleteMapping("/timer/{deviceId}/{ids}") + public AjaxResult remove(@PathVariable Long deviceId,@PathVariable Long[] ids) { - return toAjax(asTimerService.deleteAsTimerByIds(ids)); + logger.info("删除定时器传参-----"+JSON.toJSONString(ids)); + return toAjax(asTimerService.deleteAsTimerByIds(deviceId,ids)); } diff --git a/AutoSprout-watering/src/main/java/com/ruoyi/device/controller/AsTimerController.java b/AutoSprout-watering/src/main/java/com/ruoyi/device/controller/AsTimerController.java index da4dd65..264afb1 100644 --- a/AutoSprout-watering/src/main/java/com/ruoyi/device/controller/AsTimerController.java +++ b/AutoSprout-watering/src/main/java/com/ruoyi/device/controller/AsTimerController.java @@ -2,6 +2,8 @@ package com.ruoyi.device.controller; import java.util.List; import javax.servlet.http.HttpServletResponse; + +import com.alibaba.fastjson2.JSON; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; @@ -23,7 +25,7 @@ import com.ruoyi.common.core.page.TableDataInfo; /** * 定时器Controller - * + * * @author 邱贞招 * @date 2024-03-18 */ @@ -91,14 +93,26 @@ public class AsTimerController extends BaseController return toAjax(asTimerService.updateAsTimer(asTimer)); } + /** + * 开关定时器 + */ + @Log(title = "开关定时器", businessType = BusinessType.UPDATE) + @PutMapping("/switch") + public AjaxResult isSwitch(@RequestBody AsTimer asTimer) + { + return toAjax(asTimerService.isSwitch(asTimer)); + } + + /** * 删除定时器 */ @PreAuthorize("@ss.hasPermi('device:timer:remove')") @Log(title = "定时器", businessType = BusinessType.DELETE) - @DeleteMapping("/{ids}") - public AjaxResult remove(@PathVariable Long[] ids) + @DeleteMapping("/{deviceId}/{ids}") + public AjaxResult remove(@PathVariable Long deviceId,@PathVariable Long[] ids) { - return toAjax(asTimerService.deleteAsTimerByIds(ids)); + logger.info("删除定时器传参-----"+ JSON.toJSONString(ids)); + return toAjax(asTimerService.deleteAsTimerByIds(deviceId,ids)); } } diff --git a/AutoSprout-watering/src/main/java/com/ruoyi/device/domain/AsTimer.java b/AutoSprout-watering/src/main/java/com/ruoyi/device/domain/AsTimer.java index b5cb7a9..7d7df4a 100644 --- a/AutoSprout-watering/src/main/java/com/ruoyi/device/domain/AsTimer.java +++ b/AutoSprout-watering/src/main/java/com/ruoyi/device/domain/AsTimer.java @@ -32,7 +32,7 @@ public class AsTimer extends BaseEntity private String mode; /** 定时器索引 */ - private Long index; + private Integer index; /** 启动时间 */ @Excel(name = "启动时间", width = 30, dateFormat = "HH:mm") diff --git a/AutoSprout-watering/src/main/java/com/ruoyi/device/service/IAsTimerService.java b/AutoSprout-watering/src/main/java/com/ruoyi/device/service/IAsTimerService.java index 8624aba..21e4a0b 100644 --- a/AutoSprout-watering/src/main/java/com/ruoyi/device/service/IAsTimerService.java +++ b/AutoSprout-watering/src/main/java/com/ruoyi/device/service/IAsTimerService.java @@ -2,6 +2,7 @@ package com.ruoyi.device.service; import java.util.List; import com.ruoyi.device.domain.AsTimer; +import org.springframework.web.bind.annotation.PathVariable; /** * 定时器Service接口 @@ -33,7 +34,7 @@ public interface IAsTimerService * @param asTimer 定时器 * @return 结果 */ - public int insertAsTimer(AsTimer asTimer); + public Boolean insertAsTimer(AsTimer asTimer); /** * 修改定时器 @@ -41,7 +42,7 @@ public interface IAsTimerService * @param asTimer 定时器 * @return 结果 */ - public int updateAsTimer(AsTimer asTimer); + public Boolean updateAsTimer(AsTimer asTimer); /** * 批量删除定时器 @@ -49,7 +50,7 @@ public interface IAsTimerService * @param ids 需要删除的定时器主键集合 * @return 结果 */ - public int deleteAsTimerByIds(Long[] ids); + public Boolean deleteAsTimerByIds(Long deviceId,Long[] ids); /** * 删除定时器信息 @@ -66,5 +67,5 @@ public interface IAsTimerService * @param asTimer 定时器 * @return 结果 */ - public int isSwitch(AsTimer asTimer); + public Boolean isSwitch(AsTimer asTimer); } diff --git a/AutoSprout-watering/src/main/java/com/ruoyi/device/service/impl/AsTimerServiceImpl.java b/AutoSprout-watering/src/main/java/com/ruoyi/device/service/impl/AsTimerServiceImpl.java index aafd324..2697c5d 100644 --- a/AutoSprout-watering/src/main/java/com/ruoyi/device/service/impl/AsTimerServiceImpl.java +++ b/AutoSprout-watering/src/main/java/com/ruoyi/device/service/impl/AsTimerServiceImpl.java @@ -17,6 +17,7 @@ import com.ruoyi.device.mapper.AsTimerMapper; import com.ruoyi.device.service.IAsDeviceService; import com.ruoyi.device.service.IAsTimerService; import lombok.SneakyThrows; +import org.apache.commons.lang3.ObjectUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @@ -36,8 +37,11 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * 定时器Service业务层处理 @@ -108,7 +112,7 @@ public class AsTimerServiceImpl implements IAsTimerService Boolean once = ds.getOnce(); asTimer1.setMode(once?"1":"2"); asTimer1.setDeviceId(asTimer.getDeviceId()); - asTimer1.setIndex((long)i); + asTimer1.setIndex(i); //将week将10进制转成2进制 asTimer1.setWeek(Integer.toBinaryString(ds.getWeek())); asTimer1.setIsSwitch(ds.getSw()); @@ -131,7 +135,7 @@ public class AsTimerServiceImpl implements IAsTimerService @SneakyThrows @Override @Transactional - public int insertAsTimer(AsTimer asTimer) + public Boolean insertAsTimer(AsTimer asTimer) { SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm"); Time sqlTime = new Time(timeFormat.parse(asTimer.getStartTimeStr()).getTime()); @@ -143,18 +147,44 @@ public class AsTimerServiceImpl implements IAsTimerService AsDevice device = asDeviceService.selectAsDeviceByDeviceId(deviceId); /**请求onenet获取到该设备的定时器列表*/ - List dsArray = getDs("add",asTimer, token, device); + DatapointValue.Ds ds = getDs("add",asTimer, token, device); /**向onenet发送编辑指令*/ - sendCommand(token, device, dsArray); - return asTimerMapper.insertAsTimer(asTimer); + sendCommand(token, device, ds); +// asTimerMapper.insertAsTimer(asTimer) + return Boolean.TRUE; } - private void sendCommand(String token, AsDevice device, List dsArray) { + private void sendCommand(String token, AsDevice device, DatapointValue.Ds ds) { /** 向onenet发送编辑指令 更新设备定时器*/ /** 1.获取参数*/ - String command = getTimerCommand(dsArray); - logger.info("IOT获取到下发命令:【{}】",command); + String command = getTimerCommand(ds); + logger.info("IOT获取到定时器下发命令:【{}】",command); + + /** 2.发送请求*/ + String deviceName = device.getMac();//mac地址就是产品名称 + String param2 = "device_name=" + deviceName + "&product_id=" + productId +"&timeout=" + timeout; + String sendUrl2 = iotUrl+ IotConstants.ADDS_COMMAND + "?"+param2; + + logger.info("IOT获取到Authorization:【{}】", token); + + String result2 = HttpUtils.sendPostWithToken(sendUrl2, command, token); + + /** 3.返回结果处理*/ + JSONObject paramsObj = JSON.parseObject(result2); + String code = paramsObj.getString("code"); + if (!HttpStatus.IOT_SUCCESS.equals(code)) + { + throw new ServiceException(code+"-----"+ IotUtil.formatMsg(code)); + } + logger.info("IOT请求调用结果:【{}】",result2); + } + + private void sendCommand(String token, AsDevice device, List ds) { + /** 向onenet发送编辑指令 更新设备定时器*/ + /** 1.获取参数*/ + String command = getTimerCommand(ds); + logger.info("IOT获取到定时器下发命令:【{}】",command); /** 2.发送请求*/ String deviceName = device.getMac();//mac地址就是产品名称 @@ -175,6 +205,39 @@ public class AsTimerServiceImpl implements IAsTimerService logger.info("IOT请求调用结果:【{}】",result2); } + /** + * 设置开关命令 + * + * @param token token + * @return 结果 + */ + private void sendSwitchCommand(String token, AsDevice device, DatapointValue.Ds ds) { + /** 向onenet发送编辑指令 更新设备定时器*/ + /** 1.获取参数*/ + StringBuilder command = new StringBuilder() + .append("sds").append(ds.getId()).append(IotConstants.COMMAND_SEPARATOR) + .append("sw").append(ds.getSw()?"1":"0").append(IotConstants.COMMAND_SEPARATOR); + logger.info("IOT设置开关下发命令:【{}】",command); + + /** 2.发送请求*/ + String deviceName = device.getMac();//mac地址就是产品名称 + String param2 = "device_name=" + deviceName + "&product_id=" + productId +"&timeout=" + timeout; + String sendUrl2 = iotUrl+ IotConstants.ADDS_COMMAND + "?"+param2; + + logger.info("IOT获取到Authorization:【{}】", token); + + String result2 = HttpUtils.sendPostWithToken(sendUrl2, command.toString(), token); + + /** 3.返回结果处理*/ + JSONObject paramsObj = JSON.parseObject(result2); + String code = paramsObj.getString("code"); + if (!HttpStatus.IOT_SUCCESS.equals(code)) + { + throw new ServiceException(code+"-----"+ IotUtil.formatMsg(code)); + } + logger.info("IOT请求调用结果:【{}】",result2); + } + /** * 请求onenet获取到该设备的定时器信息 * @@ -182,7 +245,7 @@ public class AsTimerServiceImpl implements IAsTimerService * @return 结果 */ @Nullable - private List getDs(String type, AsTimer asTimer, String token, AsDevice device) throws ParseException { + private DatapointValue.Ds getDs(String type, AsTimer asTimer, String token, AsDevice device) throws ParseException { /**1.请求onenet获取到该设备的定时器信息*/ String param = "device_name=" + device.getMac() + "&product_id=" + productId; String sendUrl = iotUrl+ IotConstants.ADDS_HISTORY_DATAPOINTS + "?"+param; @@ -196,30 +259,29 @@ public class AsTimerServiceImpl implements IAsTimerService Data data = dataPointRes.getData(); List datastreams = data.getDatastreams(); List dsArray = null; + DatapointValue.Ds ds = null; for (Datastream datastream: datastreams) { if(datastream.getId().equals("jj")){ List datapoints = datastream.getDatapoints(); for (Datapoint obj:datapoints) { DatapointValue value = JSONObject.parseObject(obj.getValue().toString(), DatapointValue.class); dsArray = value.getDsArray(); - DatapointValue.Ds ds = getDsItem(asTimer); + //清除无效的定时器 + dsArray = cleanInvalidDs(dsArray); + ds = getDsItem(asTimer); if("add".equals(type)){ //添加定时器 - dsArray.add(ds); + ds.setId(dsArray.size()); + ds.setSw(true); }else if("edit".equals(type)){ //编辑定时器 - for (int i = 0; i < dsArray.size(); i++) { - if(i == asTimer.getIndex() ){ - dsArray.remove(i); - dsArray.add(ds); - } - } + ds.setId(asTimer.getIndex()); } } } } logger.info("请求onenet获取到定时器列表【{}】",JSON.toJSON(dsArray)); - return dsArray; + return ds; } @@ -250,11 +312,26 @@ public class AsTimerServiceImpl implements IAsTimerService for (Datapoint obj:datapoints) { DatapointValue value = JSONObject.parseObject(obj.getValue().toString(), DatapointValue.class); dsArray = value.getDsArray(); - + logger.info("请求onenet获取到定时器列表(处理前)【{}】",JSON.toJSON(dsArray)); + dsArray = cleanInvalidDs(dsArray); } } } - logger.info("请求onenet获取到定时器列表【{}】",JSON.toJSON(dsArray)); + logger.info("请求onenet获取到定时器列表(处理后)【{}】",JSON.toJSON(dsArray)); + return dsArray; + } + + /** + * 清理无效的定时器 + * @param dsArray + * @return + */ + @NotNull + private List cleanInvalidDs(List dsArray) { + List filteredDsList = dsArray.stream() + .filter(ds -> ds.getWeek() != 0) + .collect(Collectors.toList()); + dsArray = new ArrayList<>(filteredDsList); return dsArray; } @@ -264,33 +341,86 @@ public class AsTimerServiceImpl implements IAsTimerService DatapointValue.Ds ds = new DatapointValue.Ds(); //将week(二进制)转成十进制 String week = asTimer.getWeek(); - ds.setWeek(Integer.parseInt(week, 2)); + if(StringUtils.isNotEmpty(week)){ + ds.setWeek(Integer.parseInt(week, 2)); + } //将startTimeStr(HH:mm)转成time提取小时、分钟、秒 - Date parse = new SimpleDateFormat("HH:mm").parse(asTimer.getStartTimeStr()); - Instant instant = parse.toInstant(); - LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); - //time提取出小时,分钟,秒 - ds.setHour(localDateTime.getHour()); - ds.setMin(localDateTime.getMinute()); - ds.setSec(asTimer.getWateringDuration()); + if(ObjectUtils.isNotEmpty(asTimer.getStartTimeStr())){ + Date parse = new SimpleDateFormat("HH:mm").parse(asTimer.getStartTimeStr()); + Instant instant = parse.toInstant(); + LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); + //time提取出小时,分钟,秒 + ds.setHour(localDateTime.getHour()); + ds.setMin(localDateTime.getMinute()); + } + if(ObjectUtils.isNotEmpty(asTimer.getWateringDuration())){ + ds.setSec(asTimer.getWateringDuration()); + } String mode = asTimer.getMode(); - ds.setOnce("1".equals(mode)?true:false); + if(StringUtils.isNotEmpty(mode)){ + ds.setOnce("1".equals(mode)?true:false); + } ds.setSw(asTimer.getIsSwitch()); + if(asTimer.getIndex()!=null){ + ds.setId(asTimer.getIndex()); + } return ds; } + /** + * 构建删除定时器 + * @param ids + * @return + */ + @NotNull + private List getDeleteDsItem(Long[] ids) { + List dsArry = new ArrayList<>(); + Arrays.stream(ids) // 将数组转换为Stream + .forEach(id -> { // 对Stream中的每个元素应用操作 + DatapointValue.Ds ds = new DatapointValue.Ds(); + ds.setWeek(0); + ds.setHour(0); + ds.setMin(0); + ds.setSec(0); + ds.setOnce(false); + ds.setSw(false); + ds.setId(id.intValue()); + dsArry.add(ds); + }); + return dsArry; + } + //拼接定时器命令 - private String getTimerCommand(List dsArray) { - if (dsArray == null || dsArray.size() == 0) + private String getTimerCommand(DatapointValue.Ds ds) { + if (ObjectUtils.isEmpty(ds)) { return ""; } StringBuilder command = null; - for (int i = 0; i < dsArray.size(); i++) { - DatapointValue.Ds ds = dsArray.get(i); + command = new StringBuilder() + .append("sds").append(ds.getId()).append(IotConstants.COMMAND_SEPARATOR) + .append("week").append(ds.getWeek()).append(IotConstants.COMMAND_SEPARATOR) + .append("hour").append(ds.getHour()).append(IotConstants.COMMAND_SEPARATOR) + .append("min").append(ds.getMin()).append(IotConstants.COMMAND_SEPARATOR) + .append("sec").append(ds.getSec()).append(IotConstants.COMMAND_SEPARATOR); + if(ds.getSw()!=null){ + command.append("sw").append(ds.getSw()?"1":"0").append(IotConstants.COMMAND_SEPARATOR); + } + if(ds.getOnce()!=null){ + command.append("once").append(ds.getOnce()?"1":"0").append(IotConstants.COMMAND_SEPARATOR); + } + return command.toString(); + } + //拼接定时器命令 + private String getTimerCommand(List dsArray) { + if (ObjectUtils.isEmpty(dsArray)) + { + return ""; + } + StringBuilder command = null; + for (DatapointValue.Ds ds :dsArray) { command = new StringBuilder() - .append("sds").append(i).append(IotConstants.COMMAND_SEPARATOR) - .append("once").append(ds.getOnce()?"1":"0").append(IotConstants.COMMAND_SEPARATOR) + .append("sds").append(ds.getId()).append(IotConstants.COMMAND_SEPARATOR) .append("week").append(ds.getWeek()).append(IotConstants.COMMAND_SEPARATOR) .append("hour").append(ds.getHour()).append(IotConstants.COMMAND_SEPARATOR) .append("min").append(ds.getMin()).append(IotConstants.COMMAND_SEPARATOR) @@ -298,7 +428,11 @@ public class AsTimerServiceImpl implements IAsTimerService if(ds.getSw()!=null){ command.append("sw").append(ds.getSw()?"1":"0").append(IotConstants.COMMAND_SEPARATOR); } + if(ds.getOnce()!=null){ + command.append("once").append(ds.getOnce()?"1":"0").append(IotConstants.COMMAND_SEPARATOR); + } } + return command.toString(); } @@ -310,7 +444,7 @@ public class AsTimerServiceImpl implements IAsTimerService */ @SneakyThrows @Override - public int updateAsTimer(AsTimer asTimer) + public Boolean updateAsTimer(AsTimer asTimer) { SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm"); Time sqlTime = new Time(timeFormat.parse(asTimer.getStartTimeStr()).getTime()); @@ -319,24 +453,31 @@ public class AsTimerServiceImpl implements IAsTimerService Long deviceId = asTimer.getDeviceId(); AsDevice device = asDeviceService.selectAsDeviceByDeviceId(deviceId); /** 请求onenet获取到该设备的定时器列表*/ - List dsArray = getDs("edit",asTimer, token, device); + DatapointValue.Ds ds = getDs("edit",asTimer, token, device); /** 根据定时器索引修改定时器 */ /**向onenet发送编辑指令*/ - sendCommand(token, device, dsArray); + sendCommand(token, device, ds); asTimer.setUpdateTime(DateUtils.getNowDate()); - return asTimerMapper.updateAsTimer(asTimer); +// asTimerMapper.updateAsTimer(asTimer) + return Boolean.TRUE; } /** * 批量删除定时器 * - * @param ids 需要删除的定时器主键 + * @param deviceId 设备id + * @param ids 定时器ids * @return 结果 */ + @SneakyThrows @Override - public int deleteAsTimerByIds(Long[] ids) + public Boolean deleteAsTimerByIds(Long deviceId,Long[] ids) { - return asTimerMapper.deleteAsTimerByIds(ids); + String token = Token.getToken(); + AsDevice device = asDeviceService.selectAsDeviceByDeviceId(deviceId); + List dsList = getDeleteDsItem(ids); + sendCommand(token, device, dsList); + return Boolean.TRUE; } /** @@ -356,9 +497,14 @@ public class AsTimerServiceImpl implements IAsTimerService * @param asTimer * @return */ + @SneakyThrows @Override - public int isSwitch(AsTimer asTimer) { - int i = asTimerMapper.updateAsTimer(asTimer); - return i; + public Boolean isSwitch(AsTimer asTimer) { + String token = Token.getToken(); + Long deviceId = asTimer.getDeviceId(); + AsDevice device = asDeviceService.selectAsDeviceByDeviceId(deviceId); + DatapointValue.Ds ds = getDsItem(asTimer); + sendSwitchCommand(token, device, ds); + return Boolean.TRUE; } } diff --git a/AutoSprout-watering/src/main/resources/mapper/device/AsWateringRecordMapper.xml b/AutoSprout-watering/src/main/resources/mapper/device/AsWateringRecordMapper.xml index 37b81e3..56c6294 100644 --- a/AutoSprout-watering/src/main/resources/mapper/device/AsWateringRecordMapper.xml +++ b/AutoSprout-watering/src/main/resources/mapper/device/AsWateringRecordMapper.xml @@ -27,6 +27,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and water_time = #{waterTime} + and device_id = #{deviceId} and start_mode = #{startMode} and spraying_time = #{sprayingTime} and pulse_mode = #{pulseMode}