@@ -111,4 +111,28 @@ public class GZLocationInterval { | |||
} | |||
return min; | |||
} | |||
public static int timeInterval(LocalDateTime time, List<GZLocationInterval> list){ | |||
int day = time.getDayOfWeek().getValue(); | |||
for (int i = 0; i < list.size(); i++) { | |||
GZLocationInterval interval = list.get(i); | |||
if(interval.getWeekDays().equals("*") || interval.getWeekDays().indexOf(String.valueOf(day)) > -1){ | |||
if(interval.getTimes().equals("*")){ | |||
return interval.getInterval(); | |||
}else{ | |||
int hour = Integer.parseInt(interval.getTimes().substring(0, 2)); | |||
int minute = Integer.parseInt(interval.getTimes().substring(2, 4)); | |||
LocalDateTime startTime = time.withHour(hour).withMinute(minute).withSecond(0); | |||
hour = Integer.parseInt(interval.getTimes().substring(4, 6)); | |||
minute = Integer.parseInt(interval.getTimes().substring(6, 8)); | |||
LocalDateTime endTime = time.withHour(hour).withMinute(minute).withSecond(0); | |||
if(time.isAfter(startTime) && time.isBefore(endTime)){ | |||
return interval.getInterval(); | |||
} | |||
} | |||
} | |||
} | |||
// 0表示 不用发送 | |||
return 0; | |||
} | |||
} |
@@ -1,6 +1,7 @@ | |||
package com.ssjl.zhaobiao.guizhou.quartz; | |||
import com.ssjl.zhaobiao.guizhou.quartz.job.GZHeartJob; | |||
import com.ssjl.zhaobiao.guizhou.quartz.job.GZLocationSend; | |||
import com.ssjl.zhaobiao.guizhou.quartz.job.GZSyncSetting; | |||
import org.quartz.*; | |||
import org.springframework.context.annotation.Bean; | |||
@@ -63,6 +64,25 @@ public class QuartzConfig { | |||
.build(); | |||
} | |||
@Bean | |||
public JobDetail gzLocationTask() { | |||
return JobBuilder.newJob(GZLocationSend.class) | |||
.withIdentity("gzLocationTask") | |||
.storeDurably() | |||
.build(); | |||
} | |||
@Bean | |||
public Trigger gzLocationTaskTrigger() { | |||
SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule() | |||
.withIntervalInSeconds(30) | |||
.repeatForever(); | |||
return TriggerBuilder.newTrigger() | |||
.forJob(gzLocationTask()) | |||
.withIdentity("gzLocationTask") | |||
.withSchedule(scheduleBuilder) | |||
.build(); | |||
} | |||
// @Bean | |||
// public JobDetail temperaturePushTask(){ | |||
// return JobBuilder.newJob(TemperaturePushJob.class) | |||
@@ -3,8 +3,12 @@ package com.ssjl.zhaobiao.guizhou.quartz.job; | |||
import com.alibaba.fastjson.JSON; | |||
import com.ssjl.zhaobiao.guizhou.entity.DianxinGzDeviceConfig; | |||
import com.ssjl.zhaobiao.guizhou.entity.GZMessage.GZLocationInterval; | |||
import com.ssjl.zhaobiao.guizhou.entity.IOT.Api.IotApiResponse; | |||
import com.ssjl.zhaobiao.guizhou.entity.IOTDevice; | |||
import com.ssjl.zhaobiao.guizhou.repository.DianxinGzDeviceConfigMapper; | |||
import com.ssjl.zhaobiao.guizhou.utils.IOTApiUtil; | |||
import com.ssjl.zhaobiao.guizhou.utils.LocationUtil; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.quartz.DisallowConcurrentExecution; | |||
import org.quartz.JobExecutionContext; | |||
@@ -13,6 +17,7 @@ import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.beans.factory.annotation.Value; | |||
import org.springframework.scheduling.quartz.QuartzJobBean; | |||
import java.time.LocalDateTime; | |||
import java.util.List; | |||
//此注解标记任务不并发,任务执行完后才开始下一次任务 | |||
@@ -22,6 +27,10 @@ public class GZLocationSend extends QuartzJobBean { | |||
@Autowired | |||
DianxinGzDeviceConfigMapper dianxinGzDeviceConfigMapper; | |||
@Autowired | |||
LocationUtil locationUtil; | |||
@Autowired | |||
IOTApiUtil iotApiUtil; | |||
@Value("${guizhou.device.testList}") | |||
String testList; | |||
@@ -29,15 +38,50 @@ public class GZLocationSend extends QuartzJobBean { | |||
@Override | |||
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { | |||
List<IOTDevice> deviceList = JSON.parseArray(testList, IOTDevice.class); | |||
LocalDateTime time = LocalDateTime.now(); | |||
for (int i = 0; i < deviceList.size(); i++) { | |||
IOTDevice device = deviceList.get(i); | |||
try{ | |||
// 找到记录的时间 | |||
// | |||
// 找到上次发送的时间 | |||
LocalDateTime lastTime = locationUtil.getTime(device.getImei()); | |||
if(lastTime == null){ | |||
lastTime = LocalDateTime.of(2020, 1 ,1,1,1); | |||
} | |||
DianxinGzDeviceConfig dianxinGzDeviceConfig = dianxinGzDeviceConfigMapper.selectByImei(device.getImei()); | |||
List<GZLocationInterval> intervalList = GZLocationInterval.build(dianxinGzDeviceConfig.getLocationInterval()); | |||
int interval = GZLocationInterval.timeInterval(time, intervalList); | |||
if(interval == 0){ | |||
// 不发送 | |||
continue; | |||
} | |||
// 按时间段设计,下次发送的时间 | |||
if(lastTime.plusMinutes(interval).isAfter(time)){ | |||
continue; | |||
} | |||
// 当前时间已达到,则发起即时定位,由于即时定位平台要等待定时数据,耗时很长,因而要开一条线程 | |||
getLocation(device.getImei()); | |||
// 更新发送时间 | |||
locationUtil.saveTime(device.getImei(), time); | |||
}catch (Exception e){ | |||
e.printStackTrace(); | |||
} | |||
} | |||
} | |||
private void getLocation(String imei){ | |||
Thread t = new Thread(new Runnable() { | |||
@Override | |||
public void run() { | |||
try { | |||
log.info(imei + ",发起即时定位" ); | |||
IotApiResponse rs = iotApiUtil.getLocationNow(imei); | |||
log.info(imei + ",即时定位返回:" + JSON.toJSONString(rs)); | |||
}catch (Exception e){ | |||
log.info(e.getMessage()); | |||
// e.printStackTrace(); | |||
} | |||
} | |||
}); | |||
t.start(); | |||
} | |||
} |
@@ -42,6 +42,10 @@ public class IOTApiUtil { | |||
return send("/api/Command/ActivateDevice", JSON.toJSONString(active), AuthTye.TOKEN); | |||
} | |||
public IotApiResponse getLocationNow(String imei) throws IOException { | |||
return get("/api/Command/Locate?serialNo="+imei, AuthTye.TOKEN); | |||
} | |||
private IotApiResponse send(String url ,String json, AuthTye authType) throws IOException { | |||
Headers headers; | |||
if(authType == AuthTye.TOKEN){ | |||
@@ -53,6 +57,17 @@ public class IOTApiUtil { | |||
return JSON.parseObject(rs, IotApiResponse.class); | |||
} | |||
public IotApiResponse get(String url, AuthTye authType) throws IOException { | |||
Headers headers; | |||
if(authType == AuthTye.TOKEN){ | |||
headers = new Headers.Builder().add("AuthToken", token).build(); | |||
}else{ | |||
headers = new Headers.Builder().add("AuthKey", key).build(); | |||
} | |||
String rs = httpUtil.get(apiUrl + url, headers); | |||
return JSON.parseObject(rs, IotApiResponse.class); | |||
} | |||
enum AuthTye{ | |||
TOKEN, | |||
KEY | |||
@@ -27,6 +27,16 @@ public class OkHttpUtil { | |||
} | |||
} | |||
public String get(String url, Headers headers) throws IOException { | |||
Request request = new Request.Builder() | |||
.url(url) | |||
.headers(headers) | |||
.build(); | |||
try (Response response = client.newCall(request).execute()) { | |||
return response.body().string(); | |||
} | |||
} | |||
public String postJson(String url, String json) throws IOException { | |||
RequestBody requestBody = RequestBody.create(json, JSON); | |||
Request request = new Request.Builder() | |||
@@ -40,15 +40,15 @@ netty.port=8888 | |||
# \u8D35\u5DDE\u7535\u4FE1\u53C2\u6570 | |||
guizhou.protocol=T01.4 | |||
#guizhou.factory=telpo | |||
#guizhou.device.model=TPS401 | |||
#guizhou.device.version=ACB_1001 | |||
#guizhou.device.testList= [{ "imei": "862622050253671","phone": "" },{ "imei": "862622050253358","phone": "" },{ "imei": "800115470000678","phone": "" }] | |||
guizhou.factory=telpo | |||
guizhou.device.model=TPS401 | |||
guizhou.device.version=ACB_1001 | |||
guizhou.device.testList= [{ "imei": "862622050253671","phone": "" },{ "imei": "862622050253358","phone": "" },{ "imei": "800115470000678","phone": "" }] | |||
guizhou.factory=zhizhong | |||
guizhou.device.model=RZL600 | |||
guizhou.device.version=RZL_2021 | |||
guizhou.device.testList= [{ "imei": "862622050654340","phone": "" },{ "imei": "862622050317740","phone": "" }] | |||
#guizhou.factory=zhizhong | |||
#guizhou.device.model=RZL600 | |||
#guizhou.device.version=RZL_2021 | |||
#guizhou.device.testList= [{ "imei": "862622050654340","phone": "" },{ "imei": "862622050317740","phone": "" }] | |||
#guizhou.factory=zhanneng | |||
#guizhou.device.model=TPE390 | |||