Showing
8 changed files
with
696 additions
and
48 deletions
| @@ -7,37 +7,35 @@ import com.alibaba.fastjson.TypeReference; | @@ -7,37 +7,35 @@ import com.alibaba.fastjson.TypeReference; | ||
| 7 | import com.iot.scheduler.model.DeviceToken; | 7 | import com.iot.scheduler.model.DeviceToken; |
| 8 | import com.iot.scheduler.model.QxDeviceInfo; | 8 | import com.iot.scheduler.model.QxDeviceInfo; |
| 9 | import com.iot.scheduler.model.QxDeviceInfoDetail; | 9 | import com.iot.scheduler.model.QxDeviceInfoDetail; |
| 10 | +import com.iot.scheduler.utils.SqlTypedValueUtils; | ||
| 11 | +import com.zaxxer.hikari.HikariConfig; | ||
| 12 | +import com.zaxxer.hikari.HikariDataSource; | ||
| 10 | import jakarta.annotation.Resource; | 13 | import jakarta.annotation.Resource; |
| 11 | import lombok.extern.slf4j.Slf4j; | 14 | import lombok.extern.slf4j.Slf4j; |
| 12 | import org.apache.commons.lang3.StringUtils; | 15 | import org.apache.commons.lang3.StringUtils; |
| 13 | import org.apache.http.Consts; | 16 | import org.apache.http.Consts; |
| 14 | import org.apache.http.HttpEntity; | 17 | import org.apache.http.HttpEntity; |
| 15 | import org.apache.http.client.methods.CloseableHttpResponse; | 18 | import org.apache.http.client.methods.CloseableHttpResponse; |
| 16 | -import org.apache.http.client.methods.HttpGet; | ||
| 17 | import org.apache.http.client.methods.HttpPost; | 19 | import org.apache.http.client.methods.HttpPost; |
| 18 | import org.apache.http.entity.ContentType; | 20 | import org.apache.http.entity.ContentType; |
| 19 | import org.apache.http.entity.StringEntity; | 21 | import org.apache.http.entity.StringEntity; |
| 20 | import org.apache.http.impl.client.CloseableHttpClient; | 22 | import org.apache.http.impl.client.CloseableHttpClient; |
| 21 | import org.apache.http.impl.client.HttpClients; | 23 | import org.apache.http.impl.client.HttpClients; |
| 22 | import org.apache.http.message.BasicHeader; | 24 | import org.apache.http.message.BasicHeader; |
| 23 | -import org.apache.http.util.EntityUtils; | ||
| 24 | import org.springframework.beans.factory.annotation.Value; | 25 | import org.springframework.beans.factory.annotation.Value; |
| 25 | import org.springframework.data.redis.core.RedisTemplate; | 26 | import org.springframework.data.redis.core.RedisTemplate; |
| 26 | import org.springframework.stereotype.Service; | 27 | import org.springframework.stereotype.Service; |
| 27 | import org.springframework.util.CollectionUtils; | 28 | import org.springframework.util.CollectionUtils; |
| 28 | -import org.springframework.util.LinkedMultiValueMap; | ||
| 29 | -import org.springframework.util.MultiValueMap; | ||
| 30 | -import org.springframework.web.util.UriComponentsBuilder; | ||
| 31 | 29 | ||
| 32 | import java.io.ByteArrayOutputStream; | 30 | import java.io.ByteArrayOutputStream; |
| 33 | import java.io.IOException; | 31 | import java.io.IOException; |
| 34 | import java.io.InputStream; | 32 | import java.io.InputStream; |
| 35 | -import java.text.SimpleDateFormat; | 33 | +import java.sql.*; |
| 36 | import java.util.*; | 34 | import java.util.*; |
| 37 | -import java.util.concurrent.TimeUnit; | 35 | +import java.util.Date; |
| 38 | 36 | ||
| 39 | /** | 37 | /** |
| 40 | - * 双龙应用数据同步 | 38 | + * 国宏应用数据同步 |
| 41 | */ | 39 | */ |
| 42 | @Slf4j | 40 | @Slf4j |
| 43 | @Service | 41 | @Service |
| @@ -61,6 +59,16 @@ public class GhDevicePullService { | @@ -61,6 +59,16 @@ public class GhDevicePullService { | ||
| 61 | private String iotDeviceDetailUrl; | 59 | private String iotDeviceDetailUrl; |
| 62 | 60 | ||
| 63 | 61 | ||
| 62 | + @Value("${hn.third.jdbcUrl:jdbc:postgresql://106.15.73.210:5433/thingskit}") | ||
| 63 | + private String jdbcUrl; | ||
| 64 | + | ||
| 65 | + @Value("${hn.third.jdbcUserName:postgres}") | ||
| 66 | + private String jdbcUserName; | ||
| 67 | + | ||
| 68 | + @Value("${hn.third.jdbcPassword:postgres}") | ||
| 69 | + private String jdbcPassword; | ||
| 70 | + | ||
| 71 | + | ||
| 64 | @Resource | 72 | @Resource |
| 65 | private RedisTemplate<String, String> redisTemplate; | 73 | private RedisTemplate<String, String> redisTemplate; |
| 66 | 74 | ||
| @@ -72,7 +80,7 @@ public class GhDevicePullService { | @@ -72,7 +80,7 @@ public class GhDevicePullService { | ||
| 72 | for (Object o : deviceInfoList) { | 80 | for (Object o : deviceInfoList) { |
| 73 | JSONObject deviceInfoJson = (JSONObject) o; | 81 | JSONObject deviceInfoJson = (JSONObject) o; |
| 74 | QxDeviceInfo qxDeviceInfo = new QxDeviceInfo(); | 82 | QxDeviceInfo qxDeviceInfo = new QxDeviceInfo(); |
| 75 | - qxDeviceInfo.setDeviceType("DIRECT_CONNECTION"); | 83 | + qxDeviceInfo.setDeviceType("SENSOR"); |
| 76 | qxDeviceInfo.setTransportType("DEFAULT"); | 84 | qxDeviceInfo.setTransportType("DEFAULT"); |
| 77 | qxDeviceInfo.setOrganizationId(iotOrganizeId); | 85 | qxDeviceInfo.setOrganizationId(iotOrganizeId); |
| 78 | qxDeviceInfo.setDeviceProfileId(iotDeviceProfileId); | 86 | qxDeviceInfo.setDeviceProfileId(iotDeviceProfileId); |
| @@ -110,20 +118,30 @@ public class GhDevicePullService { | @@ -110,20 +118,30 @@ public class GhDevicePullService { | ||
| 110 | case 1: | 118 | case 1: |
| 111 | qxDeviceInfoDetail.setStatus("ERROR"); | 119 | qxDeviceInfoDetail.setStatus("ERROR"); |
| 112 | qxDeviceInfoDetail.setAlarm(true); | 120 | qxDeviceInfoDetail.setAlarm(true); |
| 121 | + //先从缓存里面拿token信息 | ||
| 122 | + String totalCapacity = getTotalCapacity("gh_total_capacity_" + dtuSn, 0D); | ||
| 123 | + qxDeviceInfoDetail.setCumulativeOutput(Double.valueOf(totalCapacity)); | ||
| 113 | break; | 124 | break; |
| 114 | case 2: | 125 | case 2: |
| 115 | qxDeviceInfoDetail.setStatus("STAND"); | 126 | qxDeviceInfoDetail.setStatus("STAND"); |
| 127 | + //先从缓存里面拿token信息 | ||
| 128 | + totalCapacity = getTotalCapacity("gh_total_capacity_" + dtuSn, 0D); | ||
| 129 | + qxDeviceInfoDetail.setCumulativeOutput(Double.valueOf(totalCapacity)); | ||
| 116 | break; | 130 | break; |
| 117 | case 3: | 131 | case 3: |
| 118 | qxDeviceInfoDetail.setStatus("RUN"); | 132 | qxDeviceInfoDetail.setStatus("RUN"); |
| 119 | //先从缓存里面拿token信息 | 133 | //先从缓存里面拿token信息 |
| 120 | - String totalCapacity = getTotalCapacity("gh_total_capacity_" + dtuSn); | 134 | + totalCapacity = getTotalCapacity("gh_total_capacity_" + dtuSn, 200D); |
| 121 | qxDeviceInfoDetail.setCumulativeOutput(Double.valueOf(totalCapacity)); | 135 | qxDeviceInfoDetail.setCumulativeOutput(Double.valueOf(totalCapacity)); |
| 136 | + qxDeviceInfoDetail.setCapacity(200D); | ||
| 122 | break; | 137 | break; |
| 123 | default: | 138 | default: |
| 124 | continue; | 139 | continue; |
| 125 | } | 140 | } |
| 126 | 141 | ||
| 142 | + if (lampState == 0) { | ||
| 143 | + continue; | ||
| 144 | + } | ||
| 127 | 145 | ||
| 128 | qxDeviceInfoDetail.setStartTime(new Date()); | 146 | qxDeviceInfoDetail.setStartTime(new Date()); |
| 129 | qxDeviceInfoDetail.setDtuSn(dtuSn); | 147 | qxDeviceInfoDetail.setDtuSn(dtuSn); |
| @@ -171,13 +189,122 @@ public class GhDevicePullService { | @@ -171,13 +189,122 @@ public class GhDevicePullService { | ||
| 171 | } | 189 | } |
| 172 | 190 | ||
| 173 | private JSONArray getDeviceInfo() { | 191 | private JSONArray getDeviceInfo() { |
| 192 | + Connection connection = null; | ||
| 193 | + PreparedStatement statement = null; | ||
| 194 | + ResultSet resultSet = null; | ||
| 195 | + HikariDataSource dataSource = null; | ||
| 196 | + List<Object> resultList = new ArrayList<>(); | ||
| 197 | + | ||
| 198 | + log.info("开始连接数据库,URL: {}", jdbcUrl); | ||
| 199 | + | ||
| 200 | + try { | ||
| 201 | + HikariConfig config = new HikariConfig(); | ||
| 202 | + config.setJdbcUrl(jdbcUrl); | ||
| 203 | + config.setUsername(jdbcUserName); | ||
| 204 | + config.setPassword(jdbcPassword); | ||
| 205 | + config.setDriverClassName("org.postgresql.Driver"); | ||
| 206 | + config.setMaximumPoolSize(5); | ||
| 207 | + config.setMinimumIdle(5); | ||
| 208 | + config.setConnectionTimeout(60000); | ||
| 209 | + config.setConnectionTestQuery("SELECT 1"); | ||
| 210 | + | ||
| 211 | + dataSource = new HikariDataSource(config); | ||
| 212 | + log.info("Hikari连接池配置完成"); | ||
| 213 | + | ||
| 214 | + connection = dataSource.getConnection(); | ||
| 215 | + log.info("数据库连接成功"); | ||
| 216 | + | ||
| 217 | + String selectSql = "SELECT\n" + | ||
| 218 | + "de.name,\n" + | ||
| 219 | + "dc.credentials_id,\n" + | ||
| 220 | + "CASE\n" + | ||
| 221 | + " WHEN ak2.long_v IS NULL OR (ak.bool_v = FALSE AND ak2.long_v IS NOT NULL) THEN 'OFF'\n" + | ||
| 222 | + " WHEN tkl.long_v = 1 THEN 'ERROR'\n" + | ||
| 223 | + " WHEN tkl2.long_v = 1 THEN 'STAND'\n" + | ||
| 224 | + " WHEN tkl3.long_v = 1 THEN 'RUN'\n" + | ||
| 225 | + " ELSE 'OFF'\n" + | ||
| 226 | + " END AS status \n" + | ||
| 227 | + "FROM device de \n" + | ||
| 228 | + "LEFT JOIN ts_kv_latest tkl on de.id = tkl.entity_id AND tkl.key = '64'\n" + | ||
| 229 | + "LEFT JOIN ts_kv_latest tkl2 on de.id = tkl2.entity_id AND tkl2.key = '535'\n" + | ||
| 230 | + "LEFT JOIN ts_kv_latest tkl3 on de.id = tkl3.entity_id AND tkl3.key = '534'\n" + | ||
| 231 | + "LEFT JOIN attribute_kv ak ON de.id = ak.entity_id AND ak.entity_type = 'DEVICE' AND ak.attribute_key = 'active'\n" + | ||
| 232 | + "LEFT JOIN attribute_kv ak2 ON de.id = ak2.entity_id AND ak2.entity_type = 'DEVICE' AND ak2.attribute_key = 'lastActivityTime'\n" + | ||
| 233 | + "LEFT JOIN device_credentials dc ON de.id = dc.device_id\n" + | ||
| 234 | + "WHERE de.organization_id = '875a4841-c7f2-4e2c-88a2-ea62d4642132'\n" + | ||
| 235 | + "AND de.device_profile_id = '1f2183a0-0562-11f1-9cb8-e3376d1e7978'\n"; | ||
| 236 | + | ||
| 237 | + statement = connection.prepareStatement(selectSql); | ||
| 238 | + log.info("执行SQL查询: {}", selectSql); | ||
| 239 | + | ||
| 240 | + resultSet = statement.executeQuery(); | ||
| 241 | + ResultSetMetaData metaData = resultSet.getMetaData(); | ||
| 242 | + int columnCount = metaData.getColumnCount(); | ||
| 243 | + log.info("查询结果集元数据获取成功,共{}列", columnCount); | ||
| 244 | + | ||
| 245 | + int rowCount = 0; | ||
| 246 | + while (resultSet.next()) { | ||
| 247 | + List<Object> result = new ArrayList<>(columnCount); | ||
| 248 | + for (int index = 1; index <= columnCount; index++) { | ||
| 249 | + int columnType = metaData.getColumnType(index); | ||
| 250 | + Object value = SqlTypedValueUtils.getTypedValue(resultSet, index, columnType); | ||
| 251 | + result.add(value); | ||
| 252 | + } | ||
| 253 | + resultList.add(result); | ||
| 254 | + rowCount++; | ||
| 255 | + | ||
| 256 | + // 每处理1000行记录一次日志 | ||
| 257 | + if (rowCount % 1000 == 0) { | ||
| 258 | + log.info("已处理{}行数据", rowCount); | ||
| 259 | + } | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + log.info("数据查询完成,共获取{}行数据", rowCount); | ||
| 263 | + | ||
| 264 | + } catch (SQLException e) { | ||
| 265 | + log.error("数据库操作异常,URL: {}, 用户名: {}", jdbcUrl, jdbcUserName, e); | ||
| 266 | + } catch (Exception e) { | ||
| 267 | + log.error("初始化数据库连接或查询数据时发生异常", e); | ||
| 268 | + } finally { | ||
| 269 | + // 释放资源 | ||
| 270 | + try { | ||
| 271 | + if (resultSet != null) resultSet.close(); | ||
| 272 | + if (statement != null) statement.close(); | ||
| 273 | + if (connection != null) connection.close(); | ||
| 274 | + log.info("数据库连接资源已释放"); | ||
| 275 | + } catch (SQLException e) { | ||
| 276 | + log.error("关闭数据库资源时发生异常", e); | ||
| 277 | + } | ||
| 278 | + | ||
| 279 | + if (dataSource != null) { | ||
| 280 | + try { | ||
| 281 | + dataSource.close(); | ||
| 282 | + log.info("HikariDataSource连接池已关闭"); | ||
| 283 | + } catch (Exception e) { | ||
| 284 | + log.error("关闭HikariDataSource连接池时发生异常", e); | ||
| 285 | + } | ||
| 286 | + } | ||
| 287 | + } | ||
| 288 | + | ||
| 289 | + log.info("数据库操作完成,返回{}条记录", resultList.size()); | ||
| 174 | JSONArray jsonArray = new JSONArray(); | 290 | JSONArray jsonArray = new JSONArray(); |
| 175 | - List<JSONObject> jsonObjectList = new ArrayList<>(13); | ||
| 176 | - for (int index = 1; index < 14; index++) { | 291 | + List<JSONObject> jsonObjectList = new ArrayList<>(resultList.size()); |
| 292 | + for (Object result : resultList) { | ||
| 293 | + List<Object> dataList = (ArrayList) result; | ||
| 177 | Map<String, Object> map = new HashMap<>(3); | 294 | Map<String, Object> map = new HashMap<>(3); |
| 178 | - map.put("deviceName", "无纺布机组" + index); | ||
| 179 | - map.put("dtuSn", "AGH20260123" + String.format("%03d", index)); | ||
| 180 | - map.put("lampState", 3); | 295 | + map.put("deviceName", dataList.get(0)); |
| 296 | + map.put("dtuSn", dataList.get(1)); | ||
| 297 | + String status = dataList.get(2).toString(); | ||
| 298 | + if ("OFF".equals(status)) { | ||
| 299 | + map.put("lampState", 0); | ||
| 300 | + } else if ("ERROR".equals(status)) { | ||
| 301 | + map.put("lampState", 1); | ||
| 302 | + } else if ("STAND".equals(status)) { | ||
| 303 | + map.put("lampState", 2); | ||
| 304 | + } else if ("RUN".equals(status)) { | ||
| 305 | + map.put("lampState", 3); | ||
| 306 | + } | ||
| 307 | + | ||
| 181 | JSONObject jsonObject = new JSONObject(); | 308 | JSONObject jsonObject = new JSONObject(); |
| 182 | jsonObject.putAll(map); | 309 | jsonObject.putAll(map); |
| 183 | jsonObjectList.add(jsonObject); | 310 | jsonObjectList.add(jsonObject); |
| @@ -185,11 +312,26 @@ public class GhDevicePullService { | @@ -185,11 +312,26 @@ public class GhDevicePullService { | ||
| 185 | 312 | ||
| 186 | jsonArray.addAll(jsonObjectList); | 313 | jsonArray.addAll(jsonObjectList); |
| 187 | return jsonArray; | 314 | return jsonArray; |
| 315 | + | ||
| 316 | +// JSONArray jsonArray = new JSONArray(); | ||
| 317 | +// List<JSONObject> jsonObjectList = new ArrayList<>(13); | ||
| 318 | +// for (int index = 1; index < 14; index++) { | ||
| 319 | +// Map<String, Object> map = new HashMap<>(3); | ||
| 320 | +// map.put("deviceName", "无纺布机组" + index); | ||
| 321 | +// map.put("dtuSn", "AGH20260123" + String.format("%03d", index)); | ||
| 322 | +// map.put("lampState", 3); | ||
| 323 | +// JSONObject jsonObject = new JSONObject(); | ||
| 324 | +// jsonObject.putAll(map); | ||
| 325 | +// jsonObjectList.add(jsonObject); | ||
| 326 | +// } | ||
| 327 | +// | ||
| 328 | +// jsonArray.addAll(jsonObjectList); | ||
| 329 | +// return jsonArray; | ||
| 188 | } | 330 | } |
| 189 | 331 | ||
| 190 | - private String getTotalCapacity(String key) { | 332 | + |
| 333 | + private String getTotalCapacity(String key, Double production) { | ||
| 191 | String totalCapacity = redisTemplate.opsForValue().get(key); | 334 | String totalCapacity = redisTemplate.opsForValue().get(key); |
| 192 | - Double production = 100D; | ||
| 193 | Double totalCapacityD = 0D; | 335 | Double totalCapacityD = 0D; |
| 194 | if (StringUtils.isEmpty(totalCapacity)) { | 336 | if (StringUtils.isEmpty(totalCapacity)) { |
| 195 | totalCapacityD = production; | 337 | totalCapacityD = production; |
| @@ -124,10 +124,10 @@ public class HnDeviceReportService { | @@ -124,10 +124,10 @@ public class HnDeviceReportService { | ||
| 124 | boolean sendResult = sendReportDevice(reportDevice); | 124 | boolean sendResult = sendReportDevice(reportDevice); |
| 125 | if (sendResult) { | 125 | if (sendResult) { |
| 126 | successCount++; | 126 | successCount++; |
| 127 | - log.info("设备[{}]数据上报成功", deviceId); | 127 | +// log.info("设备[{}]数据上报成功", deviceId); |
| 128 | } else { | 128 | } else { |
| 129 | failCount++; | 129 | failCount++; |
| 130 | - log.error("设备[{}]数据上报失败", deviceId); | 130 | +// log.error("设备[{}]数据上报失败", deviceId); |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | } catch (Exception e) { | 133 | } catch (Exception e) { |
| @@ -151,19 +151,26 @@ public class ShDevicePullService { | @@ -151,19 +151,26 @@ public class ShDevicePullService { | ||
| 151 | switch (lampState) { | 151 | switch (lampState) { |
| 152 | case 0: | 152 | case 0: |
| 153 | qxDeviceInfoDetail.setStatus("OFF"); | 153 | qxDeviceInfoDetail.setStatus("OFF"); |
| 154 | + String totalCapacity = getTotalCapacity("total_capacity_" + dtuSn, 0D); | ||
| 155 | + qxDeviceInfoDetail.setCumulativeOutput(Double.valueOf(totalCapacity)); | ||
| 154 | break; | 156 | break; |
| 155 | case 1: | 157 | case 1: |
| 156 | qxDeviceInfoDetail.setStatus("ERROR"); | 158 | qxDeviceInfoDetail.setStatus("ERROR"); |
| 157 | qxDeviceInfoDetail.setAlarm(true); | 159 | qxDeviceInfoDetail.setAlarm(true); |
| 160 | + totalCapacity = getTotalCapacity("total_capacity_" + dtuSn, 0D); | ||
| 161 | + qxDeviceInfoDetail.setCumulativeOutput(Double.valueOf(totalCapacity)); | ||
| 158 | break; | 162 | break; |
| 159 | case 2: | 163 | case 2: |
| 160 | qxDeviceInfoDetail.setStatus("STAND"); | 164 | qxDeviceInfoDetail.setStatus("STAND"); |
| 165 | + totalCapacity = getTotalCapacity("total_capacity_" + dtuSn, 0D); | ||
| 166 | + qxDeviceInfoDetail.setCumulativeOutput(Double.valueOf(totalCapacity)); | ||
| 161 | break; | 167 | break; |
| 162 | case 3: | 168 | case 3: |
| 163 | qxDeviceInfoDetail.setStatus("RUN"); | 169 | qxDeviceInfoDetail.setStatus("RUN"); |
| 164 | //先从缓存里面拿token信息 | 170 | //先从缓存里面拿token信息 |
| 165 | - String totalCapacity = getTotalCapacity("total_capacity_" + dtuSn, highSpeed); | 171 | + totalCapacity = getTotalCapacity("total_capacity_" + dtuSn, highSpeed ? 120D : 90D); |
| 166 | qxDeviceInfoDetail.setCumulativeOutput(Double.valueOf(totalCapacity)); | 172 | qxDeviceInfoDetail.setCumulativeOutput(Double.valueOf(totalCapacity)); |
| 173 | + qxDeviceInfoDetail.setCapacity(highSpeed ? 120D : 90D); | ||
| 167 | break; | 174 | break; |
| 168 | default: | 175 | default: |
| 169 | continue; | 176 | continue; |
| @@ -225,9 +232,8 @@ public class ShDevicePullService { | @@ -225,9 +232,8 @@ public class ShDevicePullService { | ||
| 225 | } | 232 | } |
| 226 | } | 233 | } |
| 227 | 234 | ||
| 228 | - private String getTotalCapacity(String key, boolean highSpeedDevice) { | 235 | + private String getTotalCapacity(String key, Double production) { |
| 229 | String totalCapacity = redisTemplate.opsForValue().get(key); | 236 | String totalCapacity = redisTemplate.opsForValue().get(key); |
| 230 | - Double production = highSpeedDevice ? 120D : 90D; | ||
| 231 | Double totalCapacityD = 0D; | 237 | Double totalCapacityD = 0D; |
| 232 | if (StringUtils.isEmpty(totalCapacity)) { | 238 | if (StringUtils.isEmpty(totalCapacity)) { |
| 233 | totalCapacityD = production; | 239 | totalCapacityD = production; |
| @@ -7,6 +7,9 @@ import com.alibaba.fastjson.TypeReference; | @@ -7,6 +7,9 @@ import com.alibaba.fastjson.TypeReference; | ||
| 7 | import com.iot.scheduler.model.DeviceToken; | 7 | import com.iot.scheduler.model.DeviceToken; |
| 8 | import com.iot.scheduler.model.QxDeviceInfo; | 8 | import com.iot.scheduler.model.QxDeviceInfo; |
| 9 | import com.iot.scheduler.model.QxDeviceInfoDetail; | 9 | import com.iot.scheduler.model.QxDeviceInfoDetail; |
| 10 | +import com.iot.scheduler.utils.SqlTypedValueUtils; | ||
| 11 | +import com.zaxxer.hikari.HikariConfig; | ||
| 12 | +import com.zaxxer.hikari.HikariDataSource; | ||
| 10 | import jakarta.annotation.Resource; | 13 | import jakarta.annotation.Resource; |
| 11 | import lombok.extern.slf4j.Slf4j; | 14 | import lombok.extern.slf4j.Slf4j; |
| 12 | import org.apache.commons.lang3.StringUtils; | 15 | import org.apache.commons.lang3.StringUtils; |
| @@ -27,11 +30,12 @@ import org.springframework.util.CollectionUtils; | @@ -27,11 +30,12 @@ import org.springframework.util.CollectionUtils; | ||
| 27 | import java.io.ByteArrayOutputStream; | 30 | import java.io.ByteArrayOutputStream; |
| 28 | import java.io.IOException; | 31 | import java.io.IOException; |
| 29 | import java.io.InputStream; | 32 | import java.io.InputStream; |
| 30 | -import java.time.LocalTime; | 33 | +import java.sql.*; |
| 31 | import java.util.*; | 34 | import java.util.*; |
| 35 | +import java.util.Date; | ||
| 32 | 36 | ||
| 33 | /** | 37 | /** |
| 34 | - * 双龙应用数据同步 | 38 | + * 盛华纸业应用数据同步 |
| 35 | */ | 39 | */ |
| 36 | @Slf4j | 40 | @Slf4j |
| 37 | @Service | 41 | @Service |
| @@ -54,19 +58,29 @@ public class ShzzDevicePullService { | @@ -54,19 +58,29 @@ public class ShzzDevicePullService { | ||
| 54 | @Value("${shzz.iot.detailUrl}") | 58 | @Value("${shzz.iot.detailUrl}") |
| 55 | private String iotDeviceDetailUrl; | 59 | private String iotDeviceDetailUrl; |
| 56 | 60 | ||
| 61 | + @Value("${hn.third.jdbcUrl:jdbc:postgresql://106.15.73.210:5433/thingskit}") | ||
| 62 | + private String jdbcUrl; | ||
| 63 | + | ||
| 64 | + @Value("${hn.third.jdbcUserName:postgres}") | ||
| 65 | + private String jdbcUserName; | ||
| 66 | + | ||
| 67 | + @Value("${hn.third.jdbcPassword:postgres}") | ||
| 68 | + private String jdbcPassword; | ||
| 57 | 69 | ||
| 58 | @Resource | 70 | @Resource |
| 59 | private RedisTemplate<String, String> redisTemplate; | 71 | private RedisTemplate<String, String> redisTemplate; |
| 60 | 72 | ||
| 61 | public void pullDeviceAndPushToIot() { | 73 | public void pullDeviceAndPushToIot() { |
| 62 | JSONArray deviceInfoList = getDeviceInfo(); | 74 | JSONArray deviceInfoList = getDeviceInfo(); |
| 75 | + JSONArray deviceInfoList2 = getDeviceInfo2(); | ||
| 76 | + deviceInfoList.addAll(deviceInfoList2); | ||
| 63 | List<QxDeviceInfo> qxDeviceInfos = new ArrayList<>(); | 77 | List<QxDeviceInfo> qxDeviceInfos = new ArrayList<>(); |
| 64 | List<QxDeviceInfoDetail> qxAddDeviceInfoDetails = new ArrayList<>(); | 78 | List<QxDeviceInfoDetail> qxAddDeviceInfoDetails = new ArrayList<>(); |
| 65 | Map<String, QxDeviceInfoDetail> qxDeviceInfoDetailMap = new HashMap<>(); | 79 | Map<String, QxDeviceInfoDetail> qxDeviceInfoDetailMap = new HashMap<>(); |
| 66 | for (Object o : deviceInfoList) { | 80 | for (Object o : deviceInfoList) { |
| 67 | JSONObject deviceInfoJson = (JSONObject) o; | 81 | JSONObject deviceInfoJson = (JSONObject) o; |
| 68 | QxDeviceInfo qxDeviceInfo = new QxDeviceInfo(); | 82 | QxDeviceInfo qxDeviceInfo = new QxDeviceInfo(); |
| 69 | - qxDeviceInfo.setDeviceType("DIRECT_CONNECTION"); | 83 | + qxDeviceInfo.setDeviceType("SENSOR"); |
| 70 | qxDeviceInfo.setTransportType("DEFAULT"); | 84 | qxDeviceInfo.setTransportType("DEFAULT"); |
| 71 | qxDeviceInfo.setOrganizationId(iotOrganizeId); | 85 | qxDeviceInfo.setOrganizationId(iotOrganizeId); |
| 72 | qxDeviceInfo.setDeviceProfileId(iotDeviceProfileId); | 86 | qxDeviceInfo.setDeviceProfileId(iotDeviceProfileId); |
| @@ -104,20 +118,28 @@ public class ShzzDevicePullService { | @@ -104,20 +118,28 @@ public class ShzzDevicePullService { | ||
| 104 | case 1: | 118 | case 1: |
| 105 | qxDeviceInfoDetail.setStatus("ERROR"); | 119 | qxDeviceInfoDetail.setStatus("ERROR"); |
| 106 | qxDeviceInfoDetail.setAlarm(true); | 120 | qxDeviceInfoDetail.setAlarm(true); |
| 121 | + String totalCapacity = getTotalCapacity("gh_total_capacity_" + dtuSn, 0D); | ||
| 122 | + qxDeviceInfoDetail.setCumulativeOutput(Double.valueOf(totalCapacity)); | ||
| 107 | break; | 123 | break; |
| 108 | case 2: | 124 | case 2: |
| 109 | qxDeviceInfoDetail.setStatus("STAND"); | 125 | qxDeviceInfoDetail.setStatus("STAND"); |
| 126 | + totalCapacity = getTotalCapacity("gh_total_capacity_" + dtuSn, 0D); | ||
| 127 | + qxDeviceInfoDetail.setCumulativeOutput(Double.valueOf(totalCapacity)); | ||
| 110 | break; | 128 | break; |
| 111 | case 3: | 129 | case 3: |
| 112 | qxDeviceInfoDetail.setStatus("RUN"); | 130 | qxDeviceInfoDetail.setStatus("RUN"); |
| 113 | //先从缓存里面拿token信息 | 131 | //先从缓存里面拿token信息 |
| 114 | - String totalCapacity = getTotalCapacity("gh_total_capacity_" + dtuSn, deviceInfoJson.getDouble("production")); | 132 | + totalCapacity = getTotalCapacity("gh_total_capacity_" + dtuSn, deviceInfoJson.getDouble("production")); |
| 115 | qxDeviceInfoDetail.setCumulativeOutput(Double.valueOf(totalCapacity)); | 133 | qxDeviceInfoDetail.setCumulativeOutput(Double.valueOf(totalCapacity)); |
| 134 | + qxDeviceInfoDetail.setCapacity(deviceInfoJson.getDouble("production")); | ||
| 116 | break; | 135 | break; |
| 117 | default: | 136 | default: |
| 118 | continue; | 137 | continue; |
| 119 | } | 138 | } |
| 120 | 139 | ||
| 140 | + if (lampState == 0) { | ||
| 141 | + continue; | ||
| 142 | + } | ||
| 121 | 143 | ||
| 122 | qxDeviceInfoDetail.setStartTime(new Date()); | 144 | qxDeviceInfoDetail.setStartTime(new Date()); |
| 123 | qxDeviceInfoDetail.setDtuSn(dtuSn); | 145 | qxDeviceInfoDetail.setDtuSn(dtuSn); |
| @@ -164,7 +186,304 @@ public class ShzzDevicePullService { | @@ -164,7 +186,304 @@ public class ShzzDevicePullService { | ||
| 164 | } | 186 | } |
| 165 | } | 187 | } |
| 166 | 188 | ||
| 189 | + private JSONArray getDeviceInfo2() { | ||
| 190 | + Connection connection = null; | ||
| 191 | + PreparedStatement statement = null; | ||
| 192 | + PreparedStatement tsKvStatement = null; | ||
| 193 | + ResultSet resultSet = null; | ||
| 194 | + ResultSet tsKvResultSet = null; | ||
| 195 | + HikariDataSource dataSource = null; | ||
| 196 | + List<Object> resultList = new ArrayList<>(); | ||
| 197 | + | ||
| 198 | + log.info("开始连接数据库2,URL: {}", jdbcUrl); | ||
| 199 | + | ||
| 200 | + try { | ||
| 201 | + HikariConfig config = new HikariConfig(); | ||
| 202 | + config.setJdbcUrl(jdbcUrl); | ||
| 203 | + config.setUsername(jdbcUserName); | ||
| 204 | + config.setPassword(jdbcPassword); | ||
| 205 | + config.setDriverClassName("org.postgresql.Driver"); | ||
| 206 | + config.setMaximumPoolSize(5); | ||
| 207 | + config.setMinimumIdle(5); | ||
| 208 | + config.setConnectionTimeout(60000); | ||
| 209 | + config.setConnectionTestQuery("SELECT 1"); | ||
| 210 | + | ||
| 211 | + dataSource = new HikariDataSource(config); | ||
| 212 | + log.info("Hikari连接池配置完成2"); | ||
| 213 | + | ||
| 214 | + connection = dataSource.getConnection(); | ||
| 215 | + log.info("数据库连接成功2"); | ||
| 216 | + | ||
| 217 | + String selectSql = "SELECT\n" + | ||
| 218 | + "de.id,\n" + | ||
| 219 | + "de.name,\n" + | ||
| 220 | + "dc.credentials_id,\n" + | ||
| 221 | + "CASE\n" + | ||
| 222 | + " WHEN ak2.long_v IS NULL OR (ak.bool_v = FALSE AND ak2.long_v IS NOT NULL) THEN 'OFF'\n" + | ||
| 223 | + " WHEN tkl.long_v = 1 THEN 'ERROR'\n" + | ||
| 224 | + " ELSE 'RUN'\n" + | ||
| 225 | + " END AS status \n" + | ||
| 226 | + "FROM device de \n" + | ||
| 227 | + "LEFT JOIN ts_kv_latest tkl on de.id = tkl.entity_id AND tkl.key = '528'\n" + | ||
| 228 | + "LEFT JOIN attribute_kv ak ON de.id = ak.entity_id AND ak.entity_type = 'DEVICE' AND ak.attribute_key = 'active'\n" + | ||
| 229 | + "LEFT JOIN attribute_kv ak2 ON de.id = ak2.entity_id AND ak2.entity_type = 'DEVICE' AND ak2.attribute_key = 'lastActivityTime'\n" + | ||
| 230 | + "LEFT JOIN device_credentials dc ON de.id = dc.device_id\n" + | ||
| 231 | + "WHERE de.organization_id = '3304ebd5-71ae-448a-91a2-e3b4d6ae258a'\n" + | ||
| 232 | + "AND de.device_profile_id = '63042200-02fe-11f1-9cb8-e3376d1e7978'\n"; | ||
| 233 | + | ||
| 234 | + statement = connection.prepareStatement(selectSql); | ||
| 235 | + log.info("执行SQL查询2: {}", selectSql); | ||
| 236 | + | ||
| 237 | + resultSet = statement.executeQuery(); | ||
| 238 | + ResultSetMetaData metaData = resultSet.getMetaData(); | ||
| 239 | + int columnCount = metaData.getColumnCount(); | ||
| 240 | + log.info("查询结果集元数据获取成功2,共{}列", columnCount); | ||
| 241 | + | ||
| 242 | + int rowCount = 0; | ||
| 243 | + while (resultSet.next()) { | ||
| 244 | + List<Object> result = new ArrayList<>(columnCount); | ||
| 245 | + for (int index = 1; index <= columnCount; index++) { | ||
| 246 | + int columnType = metaData.getColumnType(index); | ||
| 247 | + Object value = SqlTypedValueUtils.getTypedValue(resultSet, index, columnType); | ||
| 248 | + result.add(value); | ||
| 249 | + } | ||
| 250 | + | ||
| 251 | + // 处理状态为RUN的设备,进行二次验证 | ||
| 252 | + if (result.size() >= 4 && "RUN".equals(result.get(3))) { | ||
| 253 | + String deviceId = result.get(0).toString(); | ||
| 254 | + String deviceName = result.get(1).toString(); | ||
| 255 | + | ||
| 256 | + // 查询该设备最近两条key='531'的数据 | ||
| 257 | + String tsKvSql = "SELECT str_v FROM ts_kv " + | ||
| 258 | + "WHERE entity_id = ? AND key = '531' " + | ||
| 259 | + "ORDER BY ts DESC LIMIT 2"; | ||
| 260 | + | ||
| 261 | + tsKvStatement = connection.prepareStatement(tsKvSql); | ||
| 262 | + tsKvStatement.setString(1, deviceId); | ||
| 263 | + tsKvResultSet = tsKvStatement.executeQuery(); | ||
| 264 | + | ||
| 265 | + List<String> strVValues = new ArrayList<>(2); | ||
| 266 | + while (tsKvResultSet.next()) { | ||
| 267 | + strVValues.add(tsKvResultSet.getString("long_v")); | ||
| 268 | + } | ||
| 269 | + | ||
| 270 | + // 如果查询到两条数据且值不同,才认为是真正的RUN状态 | ||
| 271 | + // 否则改为STAND状态 | ||
| 272 | + if (strVValues.size() < 2 || | ||
| 273 | + (strVValues.size() == 2 && strVValues.get(0).equals(strVValues.get(1)))) { | ||
| 274 | + result.set(3, "STAND"); | ||
| 275 | + log.debug("设备{}状态由RUN修正为STAND,long_v值: {}", deviceName, strVValues); | ||
| 276 | + } else { | ||
| 277 | + log.debug("设备{}确认为RUN状态,最近两个long_v值不同: {} 和 {}", | ||
| 278 | + deviceName, strVValues.get(0), strVValues.get(1)); | ||
| 279 | + } | ||
| 280 | + | ||
| 281 | + // 关闭ts_kv查询的相关资源 | ||
| 282 | + if (tsKvResultSet != null) { | ||
| 283 | + tsKvResultSet.close(); | ||
| 284 | + tsKvResultSet = null; | ||
| 285 | + } | ||
| 286 | + if (tsKvStatement != null) { | ||
| 287 | + tsKvStatement.close(); | ||
| 288 | + tsKvStatement = null; | ||
| 289 | + } | ||
| 290 | + } | ||
| 291 | + | ||
| 292 | + resultList.add(result); | ||
| 293 | + rowCount++; | ||
| 294 | + | ||
| 295 | + // 每处理100行记录一次日志 | ||
| 296 | + if (rowCount % 100 == 0) { | ||
| 297 | + log.info("已处理{}行数据", rowCount); | ||
| 298 | + } | ||
| 299 | + } | ||
| 300 | + | ||
| 301 | + log.info("数据查询完成,共获取{}行数据", rowCount); | ||
| 302 | + | ||
| 303 | + } catch (SQLException e) { | ||
| 304 | + log.error("数据库操作异常,URL: {}, 用户名: {}", jdbcUrl, jdbcUserName, e); | ||
| 305 | + } catch (Exception e) { | ||
| 306 | + log.error("初始化数据库连接或查询数据时发生异常", e); | ||
| 307 | + } finally { | ||
| 308 | + // 释放资源 | ||
| 309 | + try { | ||
| 310 | + if (tsKvResultSet != null) tsKvResultSet.close(); | ||
| 311 | + if (tsKvStatement != null) tsKvStatement.close(); | ||
| 312 | + if (resultSet != null) resultSet.close(); | ||
| 313 | + if (statement != null) statement.close(); | ||
| 314 | + if (connection != null) connection.close(); | ||
| 315 | + log.info("数据库连接资源已释放"); | ||
| 316 | + } catch (SQLException e) { | ||
| 317 | + log.error("关闭数据库资源时发生异常", e); | ||
| 318 | + } | ||
| 319 | + | ||
| 320 | + if (dataSource != null) { | ||
| 321 | + try { | ||
| 322 | + dataSource.close(); | ||
| 323 | + log.info("HikariDataSource连接池已关闭"); | ||
| 324 | + } catch (Exception e) { | ||
| 325 | + log.error("关闭HikariDataSource连接池时发生异常", e); | ||
| 326 | + } | ||
| 327 | + } | ||
| 328 | + } | ||
| 329 | + | ||
| 330 | + log.info("数据库操作完成,返回{}条记录", resultList.size()); | ||
| 331 | + List<String> deviceNameList = Arrays.asList( | ||
| 332 | + "新发现KSJ-160智能纸杯机7oz-1", "新发现KSJ-160智能纸杯机7oz-2", "新发现KSJ-160智能纸杯机6.5oz", "新发现KSJ-160智能纸杯机8oz-1", | ||
| 333 | + "新发现KSJ-160智能纸杯机8oz-2", "新发现PJJ-III型纸容器品检机6.5oz/7oz", "新发现PJJ-III型纸容器品检机7.5oz/8oz", | ||
| 334 | + "新发现PJJ-I-02型纸容器品检机7.5oz/8oz", "新发现PJJ-I-02型纸容器品检机7.5oz/12oz", "新发现KSJ-160智能快速纸杯机7.5oz-1", | ||
| 335 | + "新发现KSJ-160智能快速纸杯机7.5oz-2", "新发现KSJ-160智能快速纸杯机12oz", "智能中速纸杯机JBZ-22D-1", | ||
| 336 | + "智能中速纸杯机JBZ-22D-2", "智能中速纸杯机JBZ-22D-3", "智能中速纸杯机JBZ-22D-4", "智能中速纸杯机JBZ-22D-5", "智能中速纸杯机JBZ-22D-6", | ||
| 337 | + "智能中速纸杯机JBZ-22D-7", "智能中速纸杯机JBZ-22D-8", "智能中速纸杯机JBZ-22D-9", "智能中速纸杯机JBZ-22S-1", "智能中速纸杯机JBZ-22S-2", | ||
| 338 | + "高速智能纸杯机DEBAO-100S", "纸机杯XC-L12齿轮340-B型-1", "纸机杯XC-L12齿轮340-B型-2", "中速外贴机SM100-KT490(12oz)", | ||
| 339 | + "中速外贴机SM100-KT491(4oz)", "中速外贴机SM100-KY373", "中速外贴机SM100-KT489(16oz)", "外贴机8oz", "外贴机12oz", "模切机1", | ||
| 340 | + "模切机2", "模切机3", "模切机4", "模切机5"); | ||
| 341 | + | ||
| 342 | + JSONArray jsonArray = new JSONArray(); | ||
| 343 | + List<JSONObject> jsonObjectList = new ArrayList<>(resultList.size()); | ||
| 344 | + for (Object result : resultList) { | ||
| 345 | + List<Object> dataList = (ArrayList) result; | ||
| 346 | + int index = deviceNameList.indexOf(dataList.get(1)); // 注意:现在name在索引1位置 | ||
| 347 | + | ||
| 348 | + Map<String, Object> map = new HashMap<>(3); | ||
| 349 | + map.put("deviceName", dataList.get(1)); | ||
| 350 | + map.put("dtuSn", dataList.get(2)); | ||
| 351 | + | ||
| 352 | + String status = dataList.get(3).toString(); | ||
| 353 | + if ("OFF".equals(status)) { | ||
| 354 | + map.put("lampState", 0); | ||
| 355 | + } else if ("ERROR".equals(status)) { | ||
| 356 | + map.put("lampState", 1); | ||
| 357 | + } else if ("STAND".equals(status)) { | ||
| 358 | + map.put("lampState", 2); | ||
| 359 | + } else if ("RUN".equals(status)) { | ||
| 360 | + map.put("lampState", 3); | ||
| 361 | + } | ||
| 362 | + | ||
| 363 | + if (index < 11) { | ||
| 364 | + map.put("production", 130D); | ||
| 365 | + } else if (index == 11) { | ||
| 366 | + map.put("production", 120D); | ||
| 367 | + } else if (index < 23) { | ||
| 368 | + map.put("production", 80D); | ||
| 369 | + } else if (index == 23) { | ||
| 370 | + map.put("production", 110D); | ||
| 371 | + } else if (index < 26) { | ||
| 372 | + map.put("production", 50D); | ||
| 373 | + } else if (index < 30) { | ||
| 374 | + map.put("production", 120D); | ||
| 375 | + } else { | ||
| 376 | + map.put("production", 80D); | ||
| 377 | + } | ||
| 378 | + | ||
| 379 | + JSONObject jsonObject = new JSONObject(); | ||
| 380 | + jsonObject.putAll(map); | ||
| 381 | + jsonObjectList.add(jsonObject); | ||
| 382 | + } | ||
| 383 | + | ||
| 384 | + jsonArray.addAll(jsonObjectList); | ||
| 385 | + return jsonArray; | ||
| 386 | + } | ||
| 387 | + | ||
| 167 | private JSONArray getDeviceInfo() { | 388 | private JSONArray getDeviceInfo() { |
| 389 | + Connection connection = null; | ||
| 390 | + PreparedStatement statement = null; | ||
| 391 | + ResultSet resultSet = null; | ||
| 392 | + HikariDataSource dataSource = null; | ||
| 393 | + List<Object> resultList = new ArrayList<>(); | ||
| 394 | + | ||
| 395 | + log.info("开始连接数据库,URL: {}", jdbcUrl); | ||
| 396 | + | ||
| 397 | + try { | ||
| 398 | + HikariConfig config = new HikariConfig(); | ||
| 399 | + config.setJdbcUrl(jdbcUrl); | ||
| 400 | + config.setUsername(jdbcUserName); | ||
| 401 | + config.setPassword(jdbcPassword); | ||
| 402 | + config.setDriverClassName("org.postgresql.Driver"); | ||
| 403 | + config.setMaximumPoolSize(5); | ||
| 404 | + config.setMinimumIdle(5); | ||
| 405 | + config.setConnectionTimeout(60000); | ||
| 406 | + config.setConnectionTestQuery("SELECT 1"); | ||
| 407 | + | ||
| 408 | + dataSource = new HikariDataSource(config); | ||
| 409 | + log.info("Hikari连接池配置完成"); | ||
| 410 | + | ||
| 411 | + connection = dataSource.getConnection(); | ||
| 412 | + log.info("数据库连接成功"); | ||
| 413 | + | ||
| 414 | + String selectSql = "SELECT\n" + | ||
| 415 | + "de.name,\n" + | ||
| 416 | + "dc.credentials_id,\n" + | ||
| 417 | + "CASE\n" + | ||
| 418 | + " WHEN ak2.long_v IS NULL OR (ak.bool_v = FALSE AND ak2.long_v IS NOT NULL) THEN 'OFF'\n" + | ||
| 419 | + " WHEN tkl.long_v = 1 THEN 'ERROR'\n" + | ||
| 420 | + " WHEN tkl2.long_v = 1 THEN 'STAND'\n" + | ||
| 421 | + " WHEN tkl3.long_v = 1 THEN 'RUN'\n" + | ||
| 422 | + " ELSE 'OFF'\n" + | ||
| 423 | + " END AS status \n" + | ||
| 424 | + "FROM device de \n" + | ||
| 425 | + "LEFT JOIN ts_kv_latest tkl on de.id = tkl.entity_id AND tkl.key = '64'\n" + | ||
| 426 | + "LEFT JOIN ts_kv_latest tkl2 on de.id = tkl2.entity_id AND tkl2.key = '535'\n" + | ||
| 427 | + "LEFT JOIN ts_kv_latest tkl3 on de.id = tkl3.entity_id AND tkl3.key = '534'\n" + | ||
| 428 | + "LEFT JOIN attribute_kv ak ON de.id = ak.entity_id AND ak.entity_type = 'DEVICE' AND ak.attribute_key = 'active'\n" + | ||
| 429 | + "LEFT JOIN attribute_kv ak2 ON de.id = ak2.entity_id AND ak2.entity_type = 'DEVICE' AND ak2.attribute_key = 'lastActivityTime'\n" + | ||
| 430 | + "LEFT JOIN device_credentials dc ON de.id = dc.device_id\n" + | ||
| 431 | + "WHERE de.organization_id = '3304ebd5-71ae-448a-91a2-e3b4d6ae258a'\n" + | ||
| 432 | + "AND de.device_profile_id = '1f2183a0-0562-11f1-9cb8-e3376d1e7978'\n"; | ||
| 433 | + | ||
| 434 | + statement = connection.prepareStatement(selectSql); | ||
| 435 | + log.info("执行SQL查询: {}", selectSql); | ||
| 436 | + | ||
| 437 | + resultSet = statement.executeQuery(); | ||
| 438 | + ResultSetMetaData metaData = resultSet.getMetaData(); | ||
| 439 | + int columnCount = metaData.getColumnCount(); | ||
| 440 | + log.info("查询结果集元数据获取成功,共{}列", columnCount); | ||
| 441 | + | ||
| 442 | + int rowCount = 0; | ||
| 443 | + while (resultSet.next()) { | ||
| 444 | + List<Object> result = new ArrayList<>(columnCount); | ||
| 445 | + for (int index = 1; index <= columnCount; index++) { | ||
| 446 | + int columnType = metaData.getColumnType(index); | ||
| 447 | + Object value = SqlTypedValueUtils.getTypedValue(resultSet, index, columnType); | ||
| 448 | + result.add(value); | ||
| 449 | + } | ||
| 450 | + resultList.add(result); | ||
| 451 | + rowCount++; | ||
| 452 | + | ||
| 453 | + // 每处理1000行记录一次日志 | ||
| 454 | + if (rowCount % 1000 == 0) { | ||
| 455 | + log.info("已处理{}行数据", rowCount); | ||
| 456 | + } | ||
| 457 | + } | ||
| 458 | + | ||
| 459 | + log.info("数据查询完成,共获取{}行数据", rowCount); | ||
| 460 | + | ||
| 461 | + } catch (SQLException e) { | ||
| 462 | + log.error("数据库操作异常,URL: {}, 用户名: {}", jdbcUrl, jdbcUserName, e); | ||
| 463 | + } catch (Exception e) { | ||
| 464 | + log.error("初始化数据库连接或查询数据时发生异常", e); | ||
| 465 | + } finally { | ||
| 466 | + // 释放资源 | ||
| 467 | + try { | ||
| 468 | + if (resultSet != null) resultSet.close(); | ||
| 469 | + if (statement != null) statement.close(); | ||
| 470 | + if (connection != null) connection.close(); | ||
| 471 | + log.info("数据库连接资源已释放"); | ||
| 472 | + } catch (SQLException e) { | ||
| 473 | + log.error("关闭数据库资源时发生异常", e); | ||
| 474 | + } | ||
| 475 | + | ||
| 476 | + if (dataSource != null) { | ||
| 477 | + try { | ||
| 478 | + dataSource.close(); | ||
| 479 | + log.info("HikariDataSource连接池已关闭"); | ||
| 480 | + } catch (Exception e) { | ||
| 481 | + log.error("关闭HikariDataSource连接池时发生异常", e); | ||
| 482 | + } | ||
| 483 | + } | ||
| 484 | + } | ||
| 485 | + | ||
| 486 | + log.info("数据库操作完成,返回{}条记录", resultList.size()); | ||
| 168 | List<String> deviceNameList = Arrays.asList( | 487 | List<String> deviceNameList = Arrays.asList( |
| 169 | "新发现KSJ-160智能纸杯机7oz-1", "新发现KSJ-160智能纸杯机7oz-2", "新发现KSJ-160智能纸杯机6.5oz", "新发现KSJ-160智能纸杯机8oz-1", | 488 | "新发现KSJ-160智能纸杯机7oz-1", "新发现KSJ-160智能纸杯机7oz-2", "新发现KSJ-160智能纸杯机6.5oz", "新发现KSJ-160智能纸杯机8oz-1", |
| 170 | "新发现KSJ-160智能纸杯机8oz-2", "新发现PJJ-III型纸容器品检机6.5oz/7oz", "新发现PJJ-III型纸容器品检机7.5oz/8oz", | 489 | "新发现KSJ-160智能纸杯机8oz-2", "新发现PJJ-III型纸容器品检机6.5oz/7oz", "新发现PJJ-III型纸容器品检机7.5oz/8oz", |
| @@ -175,19 +494,26 @@ public class ShzzDevicePullService { | @@ -175,19 +494,26 @@ public class ShzzDevicePullService { | ||
| 175 | "高速智能纸杯机DEBAO-100S", "纸机杯XC-L12齿轮340-B型-1", "纸机杯XC-L12齿轮340-B型-2", "中速外贴机SM100-KT490(12oz)", | 494 | "高速智能纸杯机DEBAO-100S", "纸机杯XC-L12齿轮340-B型-1", "纸机杯XC-L12齿轮340-B型-2", "中速外贴机SM100-KT490(12oz)", |
| 176 | "中速外贴机SM100-KT491(4oz)", "中速外贴机SM100-KY373", "中速外贴机SM100-KT489(16oz)", "外贴机8oz", "外贴机12oz", "模切机1", | 495 | "中速外贴机SM100-KT491(4oz)", "中速外贴机SM100-KY373", "中速外贴机SM100-KT489(16oz)", "外贴机8oz", "外贴机12oz", "模切机1", |
| 177 | "模切机2", "模切机3", "模切机4", "模切机5"); | 496 | "模切机2", "模切机3", "模切机4", "模切机5"); |
| 497 | + | ||
| 178 | JSONArray jsonArray = new JSONArray(); | 498 | JSONArray jsonArray = new JSONArray(); |
| 179 | - List<JSONObject> jsonObjectList = new ArrayList<>(38); | ||
| 180 | - LocalTime currentTime = LocalTime.now(); | ||
| 181 | - LocalTime startTime = LocalTime.of(8, 0, 0); // 08:00:00 | ||
| 182 | - LocalTime endTime = LocalTime.of(18, 0, 0); // 18:00:00 | ||
| 183 | - boolean isWithinRange = | ||
| 184 | - !currentTime.isBefore(startTime) && | ||
| 185 | - currentTime.isBefore(endTime); | ||
| 186 | - for (int index = 0; index < deviceNameList.size(); index++) { | 499 | + List<JSONObject> jsonObjectList = new ArrayList<>(resultList.size()); |
| 500 | + for (Object result : resultList) { | ||
| 501 | + List<Object> dataList = (ArrayList) result; | ||
| 502 | + int index = deviceNameList.indexOf(dataList.get(0)); | ||
| 187 | Map<String, Object> map = new HashMap<>(3); | 503 | Map<String, Object> map = new HashMap<>(3); |
| 188 | - map.put("deviceName", deviceNameList.get(index)); | ||
| 189 | - map.put("dtuSn", "SGH20250123" + String.format("%03d", index)); | ||
| 190 | - map.put("lampState", isWithinRange ? 3 : 0); | 504 | + map.put("deviceName", dataList.get(0)); |
| 505 | + map.put("dtuSn", dataList.get(1)); | ||
| 506 | + String status = dataList.get(2).toString(); | ||
| 507 | + if ("OFF".equals(status)) { | ||
| 508 | + map.put("lampState", 0); | ||
| 509 | + } else if ("ERROR".equals(status)) { | ||
| 510 | + map.put("lampState", 1); | ||
| 511 | + } else if ("STAND".equals(status)) { | ||
| 512 | + map.put("lampState", 2); | ||
| 513 | + } else if ("RUN".equals(status)) { | ||
| 514 | + map.put("lampState", 3); | ||
| 515 | + } | ||
| 516 | + | ||
| 191 | if (index < 11) { | 517 | if (index < 11) { |
| 192 | map.put("production", 130D); | 518 | map.put("production", 130D); |
| 193 | } else if (index == 11) { | 519 | } else if (index == 11) { |
| @@ -203,6 +529,7 @@ public class ShzzDevicePullService { | @@ -203,6 +529,7 @@ public class ShzzDevicePullService { | ||
| 203 | } else { | 529 | } else { |
| 204 | map.put("production", 80D); | 530 | map.put("production", 80D); |
| 205 | } | 531 | } |
| 532 | + | ||
| 206 | JSONObject jsonObject = new JSONObject(); | 533 | JSONObject jsonObject = new JSONObject(); |
| 207 | jsonObject.putAll(map); | 534 | jsonObject.putAll(map); |
| 208 | jsonObjectList.add(jsonObject); | 535 | jsonObjectList.add(jsonObject); |
| @@ -210,6 +537,43 @@ public class ShzzDevicePullService { | @@ -210,6 +537,43 @@ public class ShzzDevicePullService { | ||
| 210 | 537 | ||
| 211 | jsonArray.addAll(jsonObjectList); | 538 | jsonArray.addAll(jsonObjectList); |
| 212 | return jsonArray; | 539 | return jsonArray; |
| 540 | + | ||
| 541 | + | ||
| 542 | +// JSONArray jsonArray = new JSONArray(); | ||
| 543 | +// List<JSONObject> jsonObjectList = new ArrayList<>(38); | ||
| 544 | +// LocalTime currentTime = LocalTime.now(); | ||
| 545 | +// LocalTime startTime = LocalTime.of(8, 0, 0); // 08:00:00 | ||
| 546 | +// LocalTime endTime = LocalTime.of(18, 0, 0); // 18:00:00 | ||
| 547 | +// boolean isWithinRange = | ||
| 548 | +// !currentTime.isBefore(startTime) && | ||
| 549 | +// currentTime.isBefore(endTime); | ||
| 550 | +// for (int index = 0; index < deviceNameList.size(); index++) { | ||
| 551 | +// Map<String, Object> map = new HashMap<>(3); | ||
| 552 | +// map.put("deviceName", deviceNameList.get(index)); | ||
| 553 | +// map.put("dtuSn", "SGH20250123" + String.format("%03d", index)); | ||
| 554 | +// map.put("lampState", isWithinRange ? 3 : 0); | ||
| 555 | +// if (index < 11) { | ||
| 556 | +// map.put("production", 130D); | ||
| 557 | +// } else if (index == 11) { | ||
| 558 | +// map.put("production", 120D); | ||
| 559 | +// } else if (index < 23) { | ||
| 560 | +// map.put("production", 80D); | ||
| 561 | +// } else if (index == 23) { | ||
| 562 | +// map.put("production", 110D); | ||
| 563 | +// } else if (index < 26) { | ||
| 564 | +// map.put("production", 50D); | ||
| 565 | +// } else if (index < 30) { | ||
| 566 | +// map.put("production", 120D); | ||
| 567 | +// } else { | ||
| 568 | +// map.put("production", 80D); | ||
| 569 | +// } | ||
| 570 | +// JSONObject jsonObject = new JSONObject(); | ||
| 571 | +// jsonObject.putAll(map); | ||
| 572 | +// jsonObjectList.add(jsonObject); | ||
| 573 | +// } | ||
| 574 | +// | ||
| 575 | +// jsonArray.addAll(jsonObjectList); | ||
| 576 | +// return jsonArray; | ||
| 213 | } | 577 | } |
| 214 | 578 | ||
| 215 | private String getTotalCapacity(String key, Double production) { | 579 | private String getTotalCapacity(String key, Double production) { |
| @@ -151,19 +151,29 @@ public class SlDevicePullService { | @@ -151,19 +151,29 @@ public class SlDevicePullService { | ||
| 151 | switch (lampState) { | 151 | switch (lampState) { |
| 152 | case 0: | 152 | case 0: |
| 153 | qxDeviceInfoDetail.setStatus("OFF"); | 153 | qxDeviceInfoDetail.setStatus("OFF"); |
| 154 | + //先从缓存里面拿token信息 | ||
| 155 | + String totalCapacity = getTotalCapacity("total_capacity_" + dtuSn, 0D); | ||
| 156 | + qxDeviceInfoDetail.setCumulativeOutput(Double.valueOf(totalCapacity)); | ||
| 154 | break; | 157 | break; |
| 155 | case 1: | 158 | case 1: |
| 156 | qxDeviceInfoDetail.setStatus("ERROR"); | 159 | qxDeviceInfoDetail.setStatus("ERROR"); |
| 157 | qxDeviceInfoDetail.setAlarm(true); | 160 | qxDeviceInfoDetail.setAlarm(true); |
| 161 | + //先从缓存里面拿token信息 | ||
| 162 | + totalCapacity = getTotalCapacity("total_capacity_" + dtuSn, 0D); | ||
| 163 | + qxDeviceInfoDetail.setCumulativeOutput(Double.valueOf(totalCapacity)); | ||
| 158 | break; | 164 | break; |
| 159 | case 2: | 165 | case 2: |
| 160 | qxDeviceInfoDetail.setStatus("STAND"); | 166 | qxDeviceInfoDetail.setStatus("STAND"); |
| 167 | + //先从缓存里面拿token信息 | ||
| 168 | + totalCapacity = getTotalCapacity("total_capacity_" + dtuSn, 0D); | ||
| 169 | + qxDeviceInfoDetail.setCumulativeOutput(Double.valueOf(totalCapacity)); | ||
| 161 | break; | 170 | break; |
| 162 | case 3: | 171 | case 3: |
| 163 | qxDeviceInfoDetail.setStatus("RUN"); | 172 | qxDeviceInfoDetail.setStatus("RUN"); |
| 164 | //先从缓存里面拿token信息 | 173 | //先从缓存里面拿token信息 |
| 165 | - String totalCapacity = getTotalCapacity("total_capacity_" + dtuSn, highSpeed); | 174 | + totalCapacity = getTotalCapacity("total_capacity_" + dtuSn, highSpeed ? 120D : 100D); |
| 166 | qxDeviceInfoDetail.setCumulativeOutput(Double.valueOf(totalCapacity)); | 175 | qxDeviceInfoDetail.setCumulativeOutput(Double.valueOf(totalCapacity)); |
| 176 | + qxDeviceInfoDetail.setCapacity(highSpeed ? 120D : 100D); | ||
| 167 | break; | 177 | break; |
| 168 | default: | 178 | default: |
| 169 | continue; | 179 | continue; |
| @@ -225,9 +235,8 @@ public class SlDevicePullService { | @@ -225,9 +235,8 @@ public class SlDevicePullService { | ||
| 225 | } | 235 | } |
| 226 | } | 236 | } |
| 227 | 237 | ||
| 228 | - private String getTotalCapacity(String key, boolean highSpeedDevice) { | 238 | + private String getTotalCapacity(String key, Double production) { |
| 229 | String totalCapacity = redisTemplate.opsForValue().get(key); | 239 | String totalCapacity = redisTemplate.opsForValue().get(key); |
| 230 | - Double production = highSpeedDevice ? 120D : 100D; | ||
| 231 | Double totalCapacityD = 0D; | 240 | Double totalCapacityD = 0D; |
| 232 | if (StringUtils.isEmpty(totalCapacity)) { | 241 | if (StringUtils.isEmpty(totalCapacity)) { |
| 233 | totalCapacityD = production; | 242 | totalCapacityD = production; |
| 1 | +package com.iot.scheduler.utils; | ||
| 2 | + | ||
| 3 | +import lombok.extern.slf4j.Slf4j; | ||
| 4 | + | ||
| 5 | +import java.sql.*; | ||
| 6 | + | ||
| 7 | +@Slf4j | ||
| 8 | +public class SqlTypedValueUtils { | ||
| 9 | + | ||
| 10 | + public static Object getTypedValue(ResultSet rs, int index, int sqlType) throws SQLException { | ||
| 11 | + Object value; | ||
| 12 | + | ||
| 13 | + try { | ||
| 14 | + switch (sqlType) { | ||
| 15 | + case Types.BIT: | ||
| 16 | + case Types.BOOLEAN: | ||
| 17 | + value = rs.getBoolean(index); | ||
| 18 | + return rs.wasNull() ? null : value; | ||
| 19 | + | ||
| 20 | + case Types.TINYINT: | ||
| 21 | + case Types.SMALLINT: | ||
| 22 | + case Types.INTEGER: | ||
| 23 | + value = rs.getInt(index); | ||
| 24 | + return rs.wasNull() ? null : value; | ||
| 25 | + | ||
| 26 | + case Types.BIGINT: | ||
| 27 | + value = rs.getLong(index); | ||
| 28 | + return rs.wasNull() ? null : value; | ||
| 29 | + | ||
| 30 | + case Types.FLOAT: | ||
| 31 | + case Types.REAL: | ||
| 32 | + value = rs.getFloat(index); | ||
| 33 | + return rs.wasNull() ? null : value; | ||
| 34 | + | ||
| 35 | + case Types.DOUBLE: | ||
| 36 | + value = rs.getDouble(index); | ||
| 37 | + return rs.wasNull() ? null : value; | ||
| 38 | + | ||
| 39 | + case Types.NUMERIC: | ||
| 40 | + case Types.DECIMAL: | ||
| 41 | + value = rs.getBigDecimal(index); | ||
| 42 | + return rs.wasNull() ? null : value; | ||
| 43 | + | ||
| 44 | + case Types.CHAR: | ||
| 45 | + case Types.VARCHAR: | ||
| 46 | + case Types.LONGVARCHAR: | ||
| 47 | + case Types.NCHAR: | ||
| 48 | + case Types.NVARCHAR: | ||
| 49 | + case Types.LONGNVARCHAR: | ||
| 50 | + value = rs.getString(index); | ||
| 51 | + return rs.wasNull() ? null : value; | ||
| 52 | + | ||
| 53 | + case Types.DATE: | ||
| 54 | + Date date = rs.getDate(index); | ||
| 55 | + return date != null ? date.toLocalDate() : null; | ||
| 56 | + | ||
| 57 | + case Types.TIME: | ||
| 58 | + Time time = rs.getTime(index); | ||
| 59 | + return time != null ? time.toLocalTime() : null; | ||
| 60 | + | ||
| 61 | + case Types.TIMESTAMP: | ||
| 62 | + Timestamp timestamp = rs.getTimestamp(index); | ||
| 63 | + return timestamp != null ? timestamp.toLocalDateTime() : null; | ||
| 64 | + | ||
| 65 | + case Types.BINARY: | ||
| 66 | + case Types.VARBINARY: | ||
| 67 | + case Types.LONGVARBINARY: | ||
| 68 | + value = rs.getBytes(index); | ||
| 69 | + return rs.wasNull() ? null : value; | ||
| 70 | + | ||
| 71 | + case Types.BLOB: | ||
| 72 | + value = rs.getBlob(index); | ||
| 73 | + return rs.wasNull() ? null : value; | ||
| 74 | + | ||
| 75 | + case Types.CLOB: | ||
| 76 | + value = rs.getClob(index); | ||
| 77 | + return rs.wasNull() ? null : value; | ||
| 78 | + | ||
| 79 | + default: | ||
| 80 | + value = rs.getObject(index); | ||
| 81 | + return rs.wasNull() ? null : value; | ||
| 82 | + } | ||
| 83 | + } catch (SQLException e) { | ||
| 84 | + log.error("获取结果集第{}列数据时发生异常,数据类型: {}", index, sqlType, e); | ||
| 85 | + throw e; | ||
| 86 | + } | ||
| 87 | + } | ||
| 88 | +} |
| @@ -36,8 +36,8 @@ public class ChizhouZoneScheduler extends AbstractZoneScheduler { | @@ -36,8 +36,8 @@ public class ChizhouZoneScheduler extends AbstractZoneScheduler { | ||
| 36 | log.info("[{}] Simulating pulling devices...", getZoneName()); | 36 | log.info("[{}] Simulating pulling devices...", getZoneName()); |
| 37 | shDevicePullService.pullDeviceAndPushToIot(); | 37 | shDevicePullService.pullDeviceAndPushToIot(); |
| 38 | slDevicePullService.pullDeviceAndPushToIot(); | 38 | slDevicePullService.pullDeviceAndPushToIot(); |
| 39 | -// ghDevicePullService.pullDeviceAndPushToIot(); | ||
| 40 | -// shzzDevicePullService.pullDeviceAndPushToIot(); | 39 | + ghDevicePullService.pullDeviceAndPushToIot(); |
| 40 | + shzzDevicePullService.pullDeviceAndPushToIot(); | ||
| 41 | Thread.sleep(1000); | 41 | Thread.sleep(1000); |
| 42 | } catch (Exception e) { | 42 | } catch (Exception e) { |
| 43 | logError(taskName, e); | 43 | logError(taskName, e); |
| @@ -49,8 +49,8 @@ hn: | @@ -49,8 +49,8 @@ hn: | ||
| 49 | jdbcPassword: "postgres" | 49 | jdbcPassword: "postgres" |
| 50 | selectSql: "SELECT | 50 | selectSql: "SELECT |
| 51 | dc.credentials_id AS sn, | 51 | dc.credentials_id AS sn, |
| 52 | - tkl1.str_v, | ||
| 53 | - tkl2.dbl_v | 52 | + tkl1.str_v AS status, |
| 53 | + tkl2.dbl_v AS cumulativeOutput | ||
| 54 | FROM | 54 | FROM |
| 55 | device de | 55 | device de |
| 56 | LEFT JOIN device_credentials dc on de.id = dc.device_id | 56 | LEFT JOIN device_credentials dc on de.id = dc.device_id |
| @@ -61,10 +61,49 @@ hn: | @@ -61,10 +61,49 @@ hn: | ||
| 61 | WHERE | 61 | WHERE |
| 62 | de.organization_id IN( | 62 | de.organization_id IN( |
| 63 | 'f82530a0-93e4-4aeb-9339-f5b6d1127840', | 63 | 'f82530a0-93e4-4aeb-9339-f5b6d1127840', |
| 64 | - '752a7621-b59b-477c-b15e-e06d412e02d5', | ||
| 65 | - '3304ebd5-71ae-448a-91a2-e3b4d6ae258a', | ||
| 66 | - '875a4841-c7f2-4e2c-88a2-ea62d4642132' | ||
| 67 | - );" | 64 | + '752a7621-b59b-477c-b15e-e06d412e02d5' |
| 65 | + ) | ||
| 66 | + UNION all | ||
| 67 | + | ||
| 68 | +SELECT | ||
| 69 | +dc.credentials_id AS sn, | ||
| 70 | +CASE | ||
| 71 | + WHEN ak2.long_v IS NULL OR (ak.bool_v = FALSE AND ak2.long_v IS NOT NULL) THEN 'OFF' | ||
| 72 | + WHEN tkl.long_v = 1 THEN 'ERROR' | ||
| 73 | + WHEN tkl2.long_v = 1 THEN 'STAND' | ||
| 74 | + WHEN tkl3.long_v = 1 THEN 'RUN' | ||
| 75 | + ELSE 'OFF' | ||
| 76 | + END AS status, | ||
| 77 | +tkl4.dbl_v AS cumulativeOutput | ||
| 78 | +FROM device de | ||
| 79 | +LEFT JOIN ts_kv_latest tkl on de.id = tkl.entity_id AND tkl.key = '64' | ||
| 80 | +LEFT JOIN ts_kv_latest tkl2 on de.id = tkl2.entity_id AND tkl2.key = '535' | ||
| 81 | +LEFT JOIN ts_kv_latest tkl3 on de.id = tkl3.entity_id AND tkl3.key = '534' | ||
| 82 | +LEFT JOIN ts_kv_latest tkl4 ON de.id = tkl4.entity_id AND tkl4.key = '175' | ||
| 83 | +LEFT JOIN attribute_kv ak ON de.id = ak.entity_id AND ak.entity_type = 'DEVICE' AND ak.attribute_key = 'active' | ||
| 84 | +LEFT JOIN attribute_kv ak2 ON de.id = ak2.entity_id AND ak2.entity_type = 'DEVICE' AND ak2.attribute_key = 'lastActivityTime' | ||
| 85 | +LEFT JOIN device_credentials dc ON de.id = dc.device_id | ||
| 86 | +WHERE (de.organization_id = '875a4841-c7f2-4e2c-88a2-ea62d4642132' or de.organization_id = '3304ebd5-71ae-448a-91a2-e3b4d6ae258a') | ||
| 87 | +AND de.device_profile_id = '1f2183a0-0562-11f1-9cb8-e3376d1e7978' | ||
| 88 | +UNION ALL | ||
| 89 | +SELECT | ||
| 90 | +dc.credentials_id, | ||
| 91 | +CASE | ||
| 92 | + WHEN ak2.long_v IS NULL OR (ak.bool_v = FALSE AND ak2.long_v IS NOT NULL) THEN 'OFF' | ||
| 93 | + WHEN tkl.str_v = 'ERROR' THEN 'ERROR' | ||
| 94 | + WHEN tkl.str_v = 'STAND' THEN 'STAND' | ||
| 95 | + ELSE 'RUN' | ||
| 96 | + END AS status, | ||
| 97 | +tkl2.dbl_v AS cumulativeOutput | ||
| 98 | +FROM device de | ||
| 99 | +LEFT JOIN ts_kv_latest tkl on de.id = tkl.entity_id AND tkl.key = '61' | ||
| 100 | +LEFT JOIN ts_kv_latest tkl2 ON de.id = tkl2.entity_id AND tkl2.key = '175' | ||
| 101 | +LEFT JOIN attribute_kv ak ON de.id = ak.entity_id AND ak.entity_type = 'DEVICE' AND ak.attribute_key = 'active' | ||
| 102 | +LEFT JOIN attribute_kv ak2 ON de.id = ak2.entity_id AND ak2.entity_type = 'DEVICE' AND ak2.attribute_key = 'lastActivityTime' | ||
| 103 | +LEFT JOIN device_credentials dc ON de.id = dc.device_id | ||
| 104 | +WHERE de.organization_id = '3304ebd5-71ae-448a-91a2-e3b4d6ae258a' | ||
| 105 | +AND de.device_profile_id = '63042200-02fe-11f1-9cb8-e3376d1e7978'" | ||
| 106 | + | ||
| 68 | hnhsq: | 107 | hnhsq: |
| 69 | third: | 108 | third: |
| 70 | reportUrl: "http://58.243.79.51:31357/mainApi/formEngine/formData/batchAddOrUpate" | 109 | reportUrl: "http://58.243.79.51:31357/mainApi/formEngine/formData/batchAddOrUpate" |