当前位置: 首页 > news >正文

中州养老:华为云设备管理接口开发全流程

需求分析

点击同步数据时,要把华为云的数据拉取到我们的系统中

对于新增设备操作,实际上这些参数与华为云产品我们添加设备时的参数是一样的

表结构设计

E-R图

数据库字段

接口分析

对于设备中的数据,我们既要再IOT平台存储,又要在数据库中存储.之所以保存两份数据的原因:

IOT平台中只是维护了基础的设备信息,并没有跟业务数据进行绑定,比如,设备属于哪个位置,绑定了哪个老人。

对于我们要实现的功能,华为云提供了丰富的接口

环境集成

IOT平台目前已经给提供了完整的SDK,我们在conmon模块引入华为云的两个依赖

我们添加关于IOT的配置并修改

endpoint

测试客户端能否连接成功

package com.zzyl.test;import com.huaweicloud.sdk.iotda.v5.IoTDAClient;
import com.huaweicloud.sdk.iotda.v5.model.ListProductsRequest;
import com.huaweicloud.sdk.iotda.v5.model.ListProductsResponse;
import com.huaweicloud.sdk.iotda.v5.model.Page;
import com.huaweicloud.sdk.iotda.v5.model.ProductSummary;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.List;@SpringBootTest
public class IoTDeviceTest {@Autowiredprivate IoTDAClient client;/*** 查询公共实例下的所有产品* @throws Exception*/@Testpublic void selectProduceList() throws Exception {ListProductsRequest listProductsRequest = new ListProductsRequest();listProductsRequest.setLimit(50);ListProductsResponse response = client.listProducts(listProductsRequest);List<ProductSummary> products = response.getProducts();System.out.println(products);}}

功能开发

从物联网平台同步产品列表

Controller层就是一个简单的post请求

servic层,我们调用华为云的接口请求获得产品的列表存入到Redis中

 /*** 同步产品列表*/@Overridepublic void syncProductList(){//请求参数ListProductsRequest listProductsRequest=new ListProductsRequest();//设置条数listProductsRequest.setLimit(50);//发起请求ListProductsResponse response=client.listProducts(listProductsRequest);if(response.getHttpStatusCode()!=200){throw new BaseException("物联网接口 - 查询产品,同步失败");}//存储到redisredisTemplate.opsForValue().set(CacheConstants.IOT_ALL_PRODUCT_LIST,JSONUtil.toJsonStr(response.getProducts()));}

此时打开redis图形化界面,所有数据均已经存储到redis中

查询所有产品列表

Controller

从redis中查询数据并返回

/*** 查询所有产品列表** @return*/@Overridepublic List<ProductVo> allProduct(){//从redis中查询数据String jsonStr=redisTemplate.opsForValue().get(CacheConstants.IOT_ALL_PRODUCT_LIST);//如果数据为空,则返回一个空集合if(StringUtils.isEmpty(jsonStr)){return Collections.emptyList();}//解析数据,并返回return JSONUtil.toList(jsonStr,ProductVo.class);}

前后端联调查看结果

查询已经入住的老人列表

接口文档

对于分页查询接口,传入分页数量和每页数量

通过传入的状态作为mp的条件查询我们想要的姓名,年龄等

/*** 老人分页查询* @param status* @param pageNum* @param pageSize* @return*/@Overridepublic TableDataInfo pageQuery(Integer status,Integer pageNum,Integer pageSize){//分页查询老人数据//创建条件构建器LambdaQueryWrapper<Elder> queryWrapper=new LambdaQueryWrapper<>();//创建分页对象Page<Elder> page=new Page<>(pageNum,pageSize);//按照状态查询if(ObjectUtil.isNotNull(status)){queryWrapper.eq(Elder::getStatus,status);}//sql返回结果,只展示主键、名字、身份照号、床位编号queryWrapper.select(Elder::getId,Elder::getName,Elder::getIdCardNo,Elder::getBedNumber);//执行查询page=page(page,queryWrapper);//返回分页结果return getDataTable(page);}/*** 封装分页结果* @param page* @return*/private TableDataInfo getDataTable(Page<Elder> page){//封装分页结果TableDataInfo tableDataInfo=new TableDataInfo();tableDataInfo.setTotal(page.getTotal());tableDataInfo.setCode(HttpStatus.SUCCESS);tableDataInfo.setMsg("请求成功");tableDataInfo.setRows(page.getRecords());return tableDataInfo;}

注册设备

在Controller层,我们传入设备信息

service层的逻辑

/*** 注册设备* @param deviceDto*/@Overridepublic void registerDevice(DeviceDto deviceDto){//判断设备名称是否重复LambdaQueryWrapper<Device> queryWrapper=new LambdaQueryWrapper<>();queryWrapper.eq(Device::getDeviceName,deviceDto.getDeviceName());if(count(queryWrapper)>0){throw new BaseException("设备名称已存在,请重新输入");}//检验设备标识码是否重复LambdaQueryWrapper<Device> queryWrapperNodeId=new LambdaQueryWrapper<>();queryWrapperNodeId.eq(Device::getNodeId,deviceDto.getNodeId());if(count(queryWrapperNodeId)>0){throw new BaseException("设备标识码已存在,请重新输入");}//校验同一位置是否绑定了同一类产品LambdaQueryWrapper<Device> condition=new LambdaQueryWrapper<>();condition.eq(Device::getProductKey,deviceDto.getProductKey()).eq(Device::getLocationType,deviceDto.getLocationType()).eq(Device::getPhysicalLocationType,deviceDto.getPhysicalLocationType()).eq(Device::getBindingLocation,deviceDto.getBindingLocation());if(count(condition)>0){throw new BaseException("该老人/位置已绑定该产品,请重新选择");}//iot中新增设备AddDeviceRequest request=new AddDeviceRequest();AddDevice body=new AddDevice();body.withProductId(deviceDto.getProductKey());body.withDeviceName(deviceDto.getDeviceName());body.withNodeId(deviceDto.getNodeId());request.withBody(body);AuthInfo authInfo=new AuthInfo();//秘钥String secret=UUID.randomUUID().toString().replaceAll("-","");authInfo.withSecret(secret);body.setAuthInfo(authInfo);AddDeviceResponse response;try{response=client.addDevice(request);}catch(Exception e){e.printStackTrace();throw new BaseException("物联网接口 - 注册设备,调用失败");}//设备数据保存到数据库//属性拷贝Device device=BeanUtil.toBean(deviceDto,Device.class);//设备id、设备绑定状态device.setIotId(response.getDeviceId());//秘钥device.setSecret(secret);//在数据库中新增设备try{save(device);}catch(Exception e){throw new BaseException("同一个位置不能绑定同类型的产品");}}

测试

查看设备上报的数据

前端传入Controller层物联网设备的id

   /*** 获取设备详细信息*/@GetMapping("/{iotId}")@ApiOperation("获取设备详细信息")@ApiImplicitParams({@ApiImplicitParam(name = "iotId", value = "物联网设备id", required = true, dataTypeClass = String.class)})public AjaxResult getInfo(@PathVariable("iotId") String iotId){return success(deviceService.queryDeviceDetail(iotId));}/*** 查询设备上报数据*/@GetMapping("/queryServiceProperties/{iotId}")@ApiOperation("查询设备上报数据")@ApiImplicitParams({@ApiImplicitParam(name = "iotId", value = "物联网设备id", required = true, dataTypeClass = String.class)})public AjaxResult queryServiceProperties(@PathVariable("iotId") String iotId){AjaxResult ajaxResult=deviceService.queryServiceProperties(iotId);return ajaxResult;}

service层通过Controller层传入的iotId查询数据库中的设备信息,调用华为的物联网接口查询华为云中设备的实时信息,将数据封装到deviceVo中返回给前端

   /*** 查询设备详情** @return*/@Overridepublic DeviceDetailVo queryDeviceDetail(String iotId){//查询数据库Device device=getOne(Wrappers.<Device>lambdaQuery().eq(Device::getIotId,iotId));if(ObjectUtil.isEmpty(device)){return null;}//调用华为云物联网接口ShowDeviceRequest request=new ShowDeviceRequest();request.setDeviceId(iotId);ShowDeviceResponse response;try{response=client.showDevice(request);}catch(Exception e){log.info("物联网接口 - 查询设备详情,调用失败:{}",e.getMessage());throw new BaseException("物联网接口 - 查询设备详情,调用失败");}//属性拷贝DeviceDetailVo deviceVo=BeanUtil.toBean(device,DeviceDetailVo.class);deviceVo.setDeviceStatus(response.getStatus());String activeTimeStr=response.getActiveTime();if(StringUtils.isNotEmpty(activeTimeStr)){LocalDateTime activeTime=LocalDateTimeUtil.parse(activeTimeStr,DatePattern.UTC_MS_PATTERN);//日期时区转换activeTime=activeTime.atZone(ZoneId.from(ZoneOffset.UTC)).withZoneSameInstant(ZoneId.of("Asia/Shanghai")).toLocalDateTime();deviceVo.setActiveTime(activeTime);}return deviceVo;}/*** 查询设备上报数据** @param iotId* @return*/@Overridepublic AjaxResult queryServiceProperties(String iotId){ShowDeviceShadowRequest request=new ShowDeviceShadowRequest();request.setDeviceId(iotId);ShowDeviceShadowResponse response=client.showDeviceShadow(request);if(response.getHttpStatusCode()!=200){throw new BaseException("物联网接口 - 查询设备上报数据,调用失败");}List<DeviceShadowData> shadow=response.getShadow();if(CollUtil.isEmpty(shadow)){List<Object> emptyList=Collections.emptyList();return AjaxResult.success(emptyList);}//返回数据JSONObject jsonObject=JSONUtil.parseObj(shadow.get(0).getReported().getProperties());List<Map<String, Object>>list=new ArrayList<>();//处理上报时间日期LocalDateTime activeTime=LocalDateTimeUtil.parse(shadow.get(0).getReported().getEventTime(),"yyyyMMdd'T'HHmmss'Z'");//日期时区转换LocalDateTime eventTime=activeTime.atZone(ZoneId.from(ZoneOffset.UTC)).withZoneSameInstant(ZoneId.of("Asia/Shanghai")).toLocalDateTime();jsonObject.forEach((k,v)->{Map<String, Object> map=new HashMap<>();map.put("functionId",k);map.put("value",v);map.put("eventTime",eventTime);list.add(map);});return AjaxResult.success(list);}


文章转载自:

http://013e9otu.Lwmzp.cn
http://iRAq0kLV.Lwmzp.cn
http://4uEHfP5T.Lwmzp.cn
http://InvcgSQP.Lwmzp.cn
http://PhJ6lACS.Lwmzp.cn
http://HS1AGxjl.Lwmzp.cn
http://0mwxVydI.Lwmzp.cn
http://fK981Fpc.Lwmzp.cn
http://oaBkXOjT.Lwmzp.cn
http://u5b9zEZv.Lwmzp.cn
http://TjKLWdHR.Lwmzp.cn
http://gYCnnIrk.Lwmzp.cn
http://K5UHjzsR.Lwmzp.cn
http://ilR6n61L.Lwmzp.cn
http://sB7troor.Lwmzp.cn
http://KsfxeBeO.Lwmzp.cn
http://Ria3TVN4.Lwmzp.cn
http://4a5GiEVq.Lwmzp.cn
http://SGLMJway.Lwmzp.cn
http://s6FOqVLM.Lwmzp.cn
http://hMjANOJH.Lwmzp.cn
http://lBzciyX7.Lwmzp.cn
http://GhXhCHbe.Lwmzp.cn
http://yb8nzCvs.Lwmzp.cn
http://7v0rEX1d.Lwmzp.cn
http://BOk82gBE.Lwmzp.cn
http://QDl9YQqa.Lwmzp.cn
http://ZaM9JsRb.Lwmzp.cn
http://FoUgNNQu.Lwmzp.cn
http://gsAlAQ2h.Lwmzp.cn
http://www.dtcms.com/a/379221.html

相关文章:

  • 探讨图片以Base64存数据库的合理性
  • MoonBit 再次走进清华:张宏波受邀参加「思源计划」与「程序设计训练课」
  • RabbitMQ如何实现消息的持久化?
  • Crawlergo安装全流程
  • 完全背包问题 - 动态规划最优解法(Java实现)
  • 如何选择合适的双轴倾角传感器厂家提升水平监测准确性?
  • 洛谷PP5318 查找文献 (深度搜索与广度搜索)详解
  • 手机云服务是什么意思?
  • Linux 基础操作全攻略:从文件解压到服务器管理
  • web:ts的类类型
  • 初识StarRocks
  • linux常见的基础命令及其作用
  • 12 Prompt 模板化与参数化
  • 自动化车间无线安灯呼叫系统解决方案
  • Oracle APEX 如何运行页面时跳过登录页
  • list容器
  • Docker Compose:轻松管理多容器应用
  • 云蝠智能大模型呼叫新模型上线,拥抱AGI
  • 网站SEO内部优化一般包括哪些内容和方法
  • 18j621-3通风天窗图集pdf(免费高清版)
  • 以下是UniApp启动速度优化的深度方案
  • GoogLeNet实战:用PyTorch实现经典Inception模块
  • verilog中task的使用
  • SpringDoc OpenAPI集成spring boot3
  • 安卓13_ROM修改定制化-----安卓 13 系统 ROM 定制化与低版本系统的核心区别
  • yolo学习笔记02——yolo简介
  • OpenCV 开发 -- 图像算术运算
  • 字符串-43.字符串相乘-力扣(LeetCode)
  • java properties/反射基础
  • solidity的高阶语法4