| | |
| | | package com.flightfeather.uav.lightshare.service.impl |
| | | |
| | | import com.flightfeather.uav.common.utils.DateUtil |
| | | import com.flightfeather.uav.dataprocess.ElectricDailyAnalysis |
| | | import com.flightfeather.uav.domain.entity.CompanyDevice |
| | | import com.flightfeather.uav.domain.entity.ElectricMinuteValue |
| | | import com.flightfeather.uav.domain.entity.toAirData |
| | | import com.flightfeather.uav.domain.mapper.CompanyDeviceMapper |
| | | import com.flightfeather.uav.domain.mapper.ElectricMinuteValueMapper |
| | | import com.flightfeather.uav.lightshare.bean.BaseResponse |
| | | import com.flightfeather.uav.lightshare.bean.DataHead |
| | | import com.flightfeather.uav.lightshare.bean.* |
| | | import com.flightfeather.uav.lightshare.eunm.ElectricityType |
| | | import com.flightfeather.uav.lightshare.service.ElectricityService |
| | | import com.flightfeather.uav.socket.bean.AirData |
| | | import com.github.pagehelper.PageHelper |
| | | import org.springframework.format.annotation.DateTimeFormat |
| | | import org.springframework.stereotype.Service |
| | | import tk.mybatis.mapper.entity.Example |
| | | import java.text.SimpleDateFormat |
| | | import java.time.LocalDate |
| | | import java.time.LocalDateTime |
| | | import java.time.ZoneId |
| | | import java.time.format.DateTimeFormatter |
| | | import java.time.format.DateTimeParseException |
| | | import kotlin.math.round |
| | | |
| | | @Service |
| | | class ElectricityServiceImpl(private val electricMinuteValueMapper: ElectricMinuteValueMapper) : ElectricityService { |
| | | class ElectricityServiceImpl( |
| | | private val electricMinuteValueMapper: ElectricMinuteValueMapper, private val companyDeviceMapper: CompanyDeviceMapper |
| | | ) : ElectricityService { |
| | | |
| | | private var dateFormatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss") |
| | | private var dateFormatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm") |
| | | private var dateFormatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") |
| | | |
| | | override fun getMinuteData( |
| | | deviceCode: String, startTime: String?, |
| | | endTime: String?, page: Int?, perPage: Int? |
| | | ): BaseResponse<List<ElectricMinuteValue>> { |
| | | override fun getMinuteData(deviceCode: String, startTime: String?, endTime: String?, page: Int?, perPage: Int?): BaseResponse<List<ElectricMinuteValue>> { |
| | | val perP = perPage ?: 60 |
| | | val p = page ?: 1 |
| | | val sTime = startTime?.let { dateFormatter.parse(it) } |
| | |
| | | sTime?.let { andGreaterThanOrEqualTo("mvDataTime", it) } |
| | | eTime?.let { andLessThanOrEqualTo("mvDataTime", it) } |
| | | } |
| | | orderBy("mvDataTime") |
| | | orderBy("mvDataTime").apply { |
| | | // 当请求接口不传递起始时间,默认获取最新的数据 |
| | | if (startTime == null && endTime == null) { |
| | | desc() |
| | | } |
| | | } |
| | | }).forEach { |
| | | it?.let { result.add(it) } |
| | | } |
| | | if (startTime == null && endTime == null) { |
| | | result.reverse() |
| | | } |
| | | return BaseResponse(true, head = DataHead(pageInfo.pageNum, pageInfo.pages), data = result) |
| | | } |
| | | |
| | | override fun getMinuteData2(deviceCode: String, startTime: String?, endTime: String?, page: Int?, perPage: Int?): BaseResponse<List<DataVo>> { |
| | | val result = mutableListOf<DataVo>() |
| | | getMinuteData(deviceCode, startTime, endTime, page, perPage).run { |
| | | data?.forEach { |
| | | result.add(DataVo( |
| | | DateUtil.instance.dateToString(it.mvDataTime, DateUtil.DateStyle.YYYY_MM_DD_HH_MM_SS), |
| | | it.mvStatCode, |
| | | it.toAirData() |
| | | )) |
| | | } |
| | | return BaseResponse(success, head = head, data = result) |
| | | } |
| | | } |
| | | |
| | | override fun getByCompany(cId: String): BaseResponse<List<ElectricMinuteValue>> { |
| | | val result = mutableListOf<ElectricMinuteValue>() |
| | | companyDeviceMapper.selectByExample(Example(CompanyDevice::class.java).apply { |
| | | createCriteria().andEqualTo("cdCompanyId", cId) |
| | | }).forEach { |
| | | val p = PageHelper.startPage<ElectricMinuteValue>(1, 1) |
| | | electricMinuteValueMapper.selectByExample(Example(ElectricMinuteValue::class.java).apply { |
| | | createCriteria().andEqualTo("mvStatCode", it?.cdDeviceCode) |
| | | orderBy("mvDataTime").desc() |
| | | })?.let { |
| | | if (it.isNotEmpty()) { |
| | | it[0]?.let {e-> result.add(e) } |
| | | } |
| | | } |
| | | } |
| | | |
| | | return BaseResponse(true, data = result) |
| | | } |
| | | |
| | | override fun getElectricityInfo(cId: String, startTime: String?, endTime: String?, page: Int?, perPage: Int?): BaseResponse<List<ElectricVo>> { |
| | | val perP = perPage ?: 60 |
| | | val p = page ?: 1 |
| | | val sTime = startTime?.let { dateFormatter.parse(it) } |
| | | val eTime = endTime?.let { dateFormatter.parse(it) } |
| | | val result = mutableListOf<ElectricVo>() |
| | | val deviceCodeList = companyDeviceMapper.selectByExample(Example(CompanyDevice::class.java).apply { |
| | | createCriteria().andEqualTo("cdCompanyId", cId) |
| | | }) |
| | | //产线风机 |
| | | var d1: CompanyDevice? = null |
| | | //废气净化装置 |
| | | var d2: CompanyDevice? = null |
| | | |
| | | deviceCodeList.forEach { |
| | | if (it?.cdType == ElectricityType.ProductionLine.value) { |
| | | d1 = it |
| | | }else if (it?.cdType == ElectricityType.Purify.value) { |
| | | d2 = it |
| | | } |
| | | } |
| | | |
| | | var pageInfo = PageHelper.startPage<ElectricMinuteValue>(p, perP) |
| | | val dataList1 = electricMinuteValueMapper.selectByExample(Example(ElectricMinuteValue::class.java).apply { |
| | | createCriteria().andEqualTo("mvStatCode", d1?.cdDeviceCode) |
| | | .apply { |
| | | sTime?.let { andGreaterThanOrEqualTo("mvDataTime", it) } |
| | | eTime?.let { andLessThanOrEqualTo("mvDataTime", it) } |
| | | } |
| | | orderBy("mvDataTime").apply { |
| | | // 当请求接口不传递起始时间,默认获取最新的数据 |
| | | if (startTime == null && endTime == null) { |
| | | desc() |
| | | } |
| | | } |
| | | }) |
| | | if (startTime == null && endTime == null) { |
| | | dataList1.reverse() |
| | | } |
| | | if (dataList1.isEmpty()) return BaseResponse(true, data = result) |
| | | |
| | | // pageInfo = PageHelper.startPage<ElectricMinuteValue>(p, perP) |
| | | val dataList2 = electricMinuteValueMapper.selectByExample(Example(ElectricMinuteValue::class.java).apply { |
| | | createCriteria().andEqualTo("mvStatCode", d2?.cdDeviceCode) |
| | | .apply { |
| | | andGreaterThanOrEqualTo("mvDataTime", sTime ?: dataList1[0].mvDataTime) |
| | | eTime?.let { andLessThanOrEqualTo("mvDataTime", it) } |
| | | } |
| | | orderBy("mvDataTime").apply { |
| | | // 当请求接口不传递起始时间,默认获取最新的数据 |
| | | if (startTime == null && endTime == null) { |
| | | desc() |
| | | } |
| | | } |
| | | }) |
| | | if (startTime == null && endTime == null) { |
| | | dataList2.reverse() |
| | | } |
| | | |
| | | // FIXME: 2021/11/5 返回结果需要根据两台设备的数据始末时间,选取最长的两个始末时间 |
| | | val sT = if (dataList1.isEmpty() && dataList2.isNotEmpty()) { |
| | | dataList2[0]?.mvDataTime |
| | | }else if (dataList1.isNotEmpty() && dataList2.isEmpty()) { |
| | | dataList1[0]?.mvDataTime |
| | | } else if (dataList1.isNotEmpty() && dataList2.isNotEmpty()) { |
| | | if (dataList1[0]?.mvDataTime?.after(dataList2[0]?.mvDataTime) == true) { |
| | | dataList2[0]?.mvDataTime |
| | | } else { |
| | | dataList1[0]?.mvDataTime |
| | | } |
| | | } else { |
| | | null |
| | | } |
| | | val eT = if (dataList1.isEmpty() && dataList2.isNotEmpty()) { |
| | | dataList2.last()?.mvDataTime |
| | | }else if (dataList1.isNotEmpty() && dataList2.isEmpty()) { |
| | | dataList1.last()?.mvDataTime |
| | | } else if (dataList1.isNotEmpty() && dataList2.isNotEmpty()) { |
| | | if (dataList1.last()?.mvDataTime?.after(dataList2.last()?.mvDataTime) == true) { |
| | | dataList1.last()?.mvDataTime |
| | | } else { |
| | | dataList2.last()?.mvDataTime |
| | | } |
| | | } else { |
| | | null |
| | | } |
| | | |
| | | if (sT == null || eT == null) { |
| | | return BaseResponse(true, data = result) |
| | | } |
| | | |
| | | var lsT = LocalDateTime.ofInstant(sT.toInstant(), ZoneId.systemDefault()).withSecond(0) |
| | | val leT = LocalDateTime.ofInstant(eT.toInstant(), ZoneId.systemDefault()).withSecond(0) |
| | | |
| | | // 根据两台设备的最长起始时间,计算其中每一分钟的对应均值 |
| | | while (!lsT.isAfter(leT)) { |
| | | // FIXME: 2021/11/22 此处由于前端设备的采样时间不标准 ,采样周期并不是严格的1分钟,导致采样时间有时会缺少1分钟的数据 |
| | | // FIXME: 2021/11/22 因此,当某一分钟该设备数据轮空时,采用前一个数据作为填充 |
| | | val data1 = if (dataList1.isNotEmpty()) dataList1[0] else null |
| | | val t1 = data1?.let { LocalDateTime.ofInstant(it.mvDataTime?.toInstant(), ZoneId.systemDefault()).withSecond(0) } |
| | | val data2 = if (dataList2.isNotEmpty()) dataList2[0] else null |
| | | val t2 = data2?.let { LocalDateTime.ofInstant(it.mvDataTime?.toInstant(), ZoneId.systemDefault()).withSecond(0) } |
| | | if ((data1 == null || !lsT.isEqual(t1)) |
| | | && (data2 == null || !lsT.isEqual(t2)) |
| | | ) { |
| | | |
| | | } else { |
| | | // 两台设备的数据根据时间合并为一个结构体 |
| | | val vo = ElectricVo(lsT.format(dateFormatter2)) |
| | | if (data1 == null || !lsT.isEqual(t1)) { |
| | | result.lastOrNull()?.let { |
| | | vo.apply { |
| | | d1eA = it.d1eA |
| | | d1eB = it.d1eB |
| | | d1eC = it.d1eC |
| | | d1Status = it.d1Status |
| | | d1StatusName = it.d1StatusName |
| | | d1Avg = it.d1Avg |
| | | } |
| | | } |
| | | } else { |
| | | vo.apply { |
| | | d1eA = data1.mvElectricityA ?: .0 |
| | | d1eB = data1.mvElectricityB ?: .0 |
| | | d1eC = data1.mvElectricityC ?: .0 |
| | | val s = ElectricDailyAnalysis.getStatus(data1, d1) |
| | | d1Status = s.first |
| | | d1StatusName = s.second |
| | | d1Avg = s.third |
| | | } |
| | | dataList1.removeAt(0) |
| | | } |
| | | |
| | | if (data2 == null || !lsT.isEqual(t2)) { |
| | | result.lastOrNull()?.let { |
| | | vo.apply { |
| | | d2eA = it.d2eA |
| | | d2eB = it.d2eB |
| | | d2eC = it.d2eC |
| | | d2Status = it.d2Status |
| | | d2StatusName = it.d2StatusName |
| | | d2Avg = it.d2Avg |
| | | } |
| | | } |
| | | } else { |
| | | vo.apply { |
| | | d2eA = data2.mvElectricityA ?: .0 |
| | | d2eB = data2.mvElectricityB ?: .0 |
| | | d2eC = data2.mvElectricityC ?: .0 |
| | | val s = ElectricDailyAnalysis.getStatus(data2, d2) |
| | | d2Status = s.first |
| | | d2StatusName = s.second |
| | | d2Avg = s.third |
| | | } |
| | | dataList2.removeAt(0) |
| | | } |
| | | |
| | | result.add(vo) |
| | | } |
| | | // if (dataList1.isNotEmpty()) { |
| | | // val d = dataList1[0] |
| | | // val t = LocalDateTime.ofInstant(d?.mvDataTime?.toInstant(), ZoneId.systemDefault()).withSecond(0) |
| | | // if (lsT.isEqual(t)) { |
| | | // vo.apply { |
| | | // d1eA = d?.mvElectricityA ?: .0 |
| | | // d1eB = d?.mvElectricityB ?: .0 |
| | | // d1eC = d?.mvElectricityC ?: .0 |
| | | // val s = ElectricDailyAnalysis.getStatus(d, d1) |
| | | // d1Status = s.first |
| | | // d1StatusName = s.second |
| | | // d1Avg = s.third |
| | | // } |
| | | // dataList1.removeAt(0) |
| | | // } else { |
| | | // result.lastOrNull()?.let { |
| | | // vo.apply { |
| | | // d1eA = it.d1eA |
| | | // d1eB = it.d1eB |
| | | // d1eC = it.d1eC |
| | | // d1Status = it.d1Status |
| | | // d1StatusName = it.d1StatusName |
| | | // d1Avg = it.d1Avg |
| | | // } |
| | | // } |
| | | // } |
| | | // } else { |
| | | // result.lastOrNull()?.let { |
| | | // vo.apply { |
| | | // d1eA = it.d1eA |
| | | // d1eB = it.d1eB |
| | | // d1eC = it.d1eC |
| | | // d1Status = it.d1Status |
| | | // d1StatusName = it.d1StatusName |
| | | // d1Avg = it.d1Avg |
| | | // } |
| | | // } |
| | | // } |
| | | // if (dataList2.isNotEmpty()) { |
| | | // val d = dataList2[0] |
| | | // val t = LocalDateTime.ofInstant(d?.mvDataTime?.toInstant(), ZoneId.systemDefault()).withSecond(0) |
| | | // if (lsT.isEqual(t)) { |
| | | // vo.apply { |
| | | // d2eA = d?.mvElectricityA ?: .0 |
| | | // d2eB = d?.mvElectricityB ?: .0 |
| | | // d2eC = d?.mvElectricityC ?: .0 |
| | | // val s = ElectricDailyAnalysis.getStatus(d, d2) |
| | | // d2Status = s.first |
| | | // d2StatusName = s.second |
| | | // d2Avg = s.third |
| | | // } |
| | | // dataList2.removeAt(0) |
| | | // } else { |
| | | // result.lastOrNull()?.let { |
| | | // vo.apply { |
| | | // d2eA = it.d2eA |
| | | // d2eB = it.d2eB |
| | | // d2eC = it.d2eC |
| | | // d2Status = it.d2Status |
| | | // d2StatusName = it.d2StatusName |
| | | // d2Avg = it.d2Avg |
| | | // } |
| | | // } |
| | | // } |
| | | // } else { |
| | | // result.lastOrNull()?.let { |
| | | // vo.apply { |
| | | // d2eA = it.d2eA |
| | | // d2eB = it.d2eB |
| | | // d2eC = it.d2eC |
| | | // d2Status = it.d2Status |
| | | // d2StatusName = it.d2StatusName |
| | | // d2Avg = it.d2Avg |
| | | // } |
| | | // } |
| | | // } |
| | | |
| | | lsT = lsT.plusMinutes(1) |
| | | } |
| | | |
| | | return BaseResponse(true, head = DataHead(pageInfo.pageNum, pageInfo.pages), data = result) |
| | | } |
| | | |
| | | override fun dailyAnalysis(cId: String, startTime: String?, endTime: String?): BaseResponse<List<ElectricDailyInfo>> { |
| | | // 根据企业id获取对应设备 |
| | | val devices = companyDeviceMapper.selectByExample(Example(CompanyDevice::class.java).apply { |
| | | createCriteria().andEqualTo("cdCompanyId", cId) |
| | | }) |
| | | val deviceCodeList = mutableListOf<String>() |
| | | devices.forEach { it?.let { deviceCodeList.add(it.cdDeviceCode) }} |
| | | |
| | | val st:LocalDateTime |
| | | val et:LocalDateTime |
| | | // 当没有开始或结束时间时,使用最新一条数据时间的当天作为统计时间 |
| | | if (startTime == null || endTime == null) { |
| | | val em = electricMinuteValueMapper.selectOneByExample(Example(ElectricMinuteValue::class.java).apply { |
| | | createCriteria().andIn("mvStatCode", deviceCodeList) |
| | | orderBy("mvDataTime").desc() |
| | | }) |
| | | val dataTime = LocalDateTime.ofInstant(em?.mvDataTime?.toInstant(), ZoneId.systemDefault()) |
| | | st = dataTime.withHour(0).withMinute(0).withSecond(0) |
| | | et = dataTime.withHour(23).withMinute(59).withSecond(59) |
| | | } |
| | | // 当有开始结束时间时,判断格式是否正确 |
| | | else { |
| | | try { |
| | | st = LocalDateTime.parse("$startTime 00:00:00", dateFormatter3) |
| | | et = LocalDateTime.parse("$endTime 23:59:59", dateFormatter3) |
| | | } catch (e: DateTimeParseException) { |
| | | return BaseResponse(false, "时间格式错误,应为yyyy-MM-dd") |
| | | } |
| | | } |
| | | |
| | | val dataList = electricMinuteValueMapper.selectByExample(Example(ElectricMinuteValue::class.java).apply { |
| | | createCriteria().andIn("mvStatCode", deviceCodeList) |
| | | .andBetween("mvDataTime", st, et) |
| | | orderBy("mvDataTime") |
| | | }) |
| | | val result = ElectricDailyAnalysis.analysis(devices, dataList) |
| | | |
| | | return BaseResponse(true, data = result) |
| | | } |
| | | } |