| | |
| | | import org.yzh.protocol.commons.transform.AttributeConverter; |
| | | import org.yzh.protocol.commons.transform.AttributeConverterYue; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.Map; |
| | | |
| | |
| | | package org.yzh.web.endpoint; |
| | | package com.doumee.jtt808.web.endpoint; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import io.github.yezhihao.netmc.core.annotation.Async; |
| | |
| | | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| | | </properties> |
| | | |
| | | |
| | | </project> |
| | |
| | | import java.text.DateFormatSymbols; |
| | | import java.text.ParseException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDateTime; |
| | | import java.time.ZoneId; |
| | | import java.time.ZonedDateTime; |
| | | import java.util.Date; |
| | | import java.util.*; |
| | | |
| | |
| | | |
| | | public DateUtil() { |
| | | } |
| | | public static Date getDateFromLocalDateTime( LocalDateTime localDateTime) { |
| | | try { |
| | | ZoneId zoneId = ZoneId.systemDefault(); // è·åç³»ç»é»è®¤æ¶åº |
| | | ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId); // 转æ¢ä¸ºå¸¦æ¶åºçæ¥ææ¶é´ |
| | | Date date = Date.from(zonedDateTime.toInstant()); // 转æ¢ä¸ºDate |
| | | return date; |
| | | }catch (Exception e){ |
| | | |
| | | } |
| | | return null; |
| | | |
| | | } |
| | | public static Date StringToDate2(String DATE) { |
| | | if(StringUtils.isBlank(DATE)){ |
| | | return null; |
| | |
| | | /** |
| | | * åå§å微信å°ç¨åºæ¯ä» |
| | | */ |
| | | public void load_wxPayService() |
| | | { |
| | | Config config = |
| | | new RSAAutoCertificateConfig.Builder() |
| | | .merchantId(wxPayProperties.getMchId()) |
| | | .privateKeyFromPath(wxPayProperties.getPrivateKeyPath()) |
| | | .merchantSerialNumber(wxPayProperties.getSerialNumer()) |
| | | .apiV3Key(wxPayProperties.getApiV3Key()) |
| | | .build(); |
| | | this.wxPayService = new JsapiService.Builder().config(config).build(); |
| | | public void load_wxPayService() { |
| | | try { |
| | | Config config = |
| | | new RSAAutoCertificateConfig.Builder() |
| | | .merchantId(wxPayProperties.getMchId()) |
| | | .privateKeyFromPath(wxPayProperties.getPrivateKeyPath()) |
| | | .merchantSerialNumber(wxPayProperties.getSerialNumer()) |
| | | .apiV3Key(wxPayProperties.getApiV3Key()) |
| | | .build(); |
| | | this.wxPayService = new JsapiService.Builder().config(config).build(); |
| | | |
| | | this.jsapiExtService = new JsapiServiceExtension.Builder().config(config).build(); |
| | | this.refundService = new RefundService.Builder().config(config).build(); |
| | | this.billDownloadService = new BillDownloadService.Builder().config(config).build();; |
| | | this.jsapiExtService = new JsapiServiceExtension.Builder().config(config).build(); |
| | | this.refundService = new RefundService.Builder().config(config).build(); |
| | | this.billDownloadService = new BillDownloadService.Builder().config(config).build(); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | |
| | | } |
| | | } |
| | | /** |
| | | * åå§å微信å°ç¨åºæ¯ä» |
| | |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.Data; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | |
| | | @ExcelColumn(name="") |
| | | //@JsonFormat(pattern = "yyyy-MM-dd") |
| | | private Date soldoutDate; |
| | | @ApiModelProperty(value = "车è¾ç±»å 0èªè¡è½¦ 1çµè½¦") |
| | | @ExcelColumn(name="车è¾ç±»å 0èªè¡è½¦ 1çµè½¦") |
| | | private Integer type; |
| | | @ApiModelProperty(value = "æè¿çº¬åº¦") |
| | | @ExcelColumn(name="æè¿çº¬åº¦") |
| | | private BigDecimal latitude; |
| | | @ApiModelProperty(value = "æè¿ç»åº¦") |
| | | @ExcelColumn(name="æè¿ç»åº¦") |
| | | private BigDecimal longitude; |
| | | @ApiModelProperty(value = "çµè½¦æ§å¶å¨SNç ") |
| | | @ExcelColumn(name="çµè½¦æ§å¶å¨SNç ") |
| | | private String deviceSn; |
| | | @ApiModelProperty(value = "å½åçµåå¼") |
| | | @ExcelColumn(name="å½åçµåå¼") |
| | | private BigDecimal voltage; |
| | | @ApiModelProperty(value = "æåå¿è·³æ¶é´") |
| | | @ExcelColumn(name="æåå¿è·³æ¶é´") |
| | | private Date heartDate; |
| | | @ApiModelProperty(value = "ç»ç«¯é讯å°å") |
| | | @ExcelColumn(name="ç»ç«¯é讯å°å") |
| | | private String remoteAddress; |
| | | @ApiModelProperty(value = "æè¿å®ä½å°å") |
| | | @ExcelColumn(name="æè¿å®ä½å°å") |
| | | private String location; |
| | | |
| | | } |
| | |
| | | |
| | | PageData<Bikes> findJoinPage(PageWrap<Bikes> pageWrap); |
| | | |
| | | void updateByJtt( Bikes m); |
| | | } |
| | |
| | | public Bikes findById(String id) { |
| | | return bikesMapper.selectById(id); |
| | | } |
| | | @Override |
| | | public void updateByJtt( Bikes m){ |
| | | if(StringUtils.isBlank(m.getDeviceSn() )){ |
| | | return; |
| | | } |
| | | Bikes bikes = bikesJoinMapper.selectOne(new MPJLambdaWrapper<Bikes>() |
| | | .eq(Bikes::getDeviceSn,String.format("%012s",m.getDeviceSn())) |
| | | .eq(Bikes::getIsdeleted,Constants.ZERO) |
| | | .eq(Bikes::getType,Constants.ONE) |
| | | .last("limit 1")); |
| | | if(bikes == null){ |
| | | return; |
| | | } |
| | | bikesJoinMapper.update(null,new UpdateWrapper<Bikes>().lambda() |
| | | .set(m.getLatitude()!=null,Bikes::getLatitude,m.getLatitude()) |
| | | .set(m.getVoltage()!=null,Bikes::getVoltage,m.getVoltage()) |
| | | .set(m.getLongitude()!=null,Bikes::getLongitude,m.getLongitude()) |
| | | .set(m.getHeartDate()!=null,Bikes::getHeartDate,m.getHeartDate()) |
| | | .eq(Bikes::getId,bikes.getId())); |
| | | } |
| | | |
| | | @Override |
| | | public Bikes findOne(Bikes bikes) { |
| | |
| | | @EnableAsync |
| | | @MapperScan("com.doumee.dao") |
| | | public class InterfaceApplication { |
| | | |
| | | public static void main(String[] args) { |
| | | System.setProperty("com.zaxxer.hikari.aliveBypassWindowMs", "2000"); |
| | | ApplicationContext context = SpringApplication.run(InterfaceApplication.class); |
| | | context.getEnvironment(); |
| | | } |
| | |
| | | .build() |
| | | .globalOperationParameters(this.getParameterList()); |
| | | } |
| | | @Bean |
| | | public Docket getDocket4() { |
| | | return new Docket(DocumentationType.SWAGGER_2) |
| | | .apiInfo(this.getApiInfo()).groupName("ãJTT808æ¥å£APIã") |
| | | .host(host) |
| | | .select() |
| | | .apis( basePackage("com.doumee.jtt808.web")) |
| | | // 设置éè¦è¢«æ«æçç±»ï¼è¿é设置为添å äº@Api注解çç±» |
| | | // .apis(RequestHandlerSelectors.withClassAnnotation(Api.class)) |
| | | .paths(PathSelectors.any()) |
| | | .build() |
| | | .globalOperationParameters(this.getParameterList()); |
| | | } |
| | | |
| | | private List<Parameter> getParameterList() { |
| | | ParameterBuilder tokenPar = new ParameterBuilder(); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.t808; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
| | | import io.github.yezhihao.protostar.annotation.Field; |
| | | import io.github.yezhihao.protostar.annotation.Message; |
| | | import lombok.Data; |
| | | import org.yzh.protocol.basics.JTMessage; |
| | | import org.yzh.protocol.commons.JT808; |
| | | import org.yzh.protocol.commons.transform.AttributeConverter; |
| | | import org.yzh.protocol.commons.transform.AttributeConverterYue; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author yezhihao |
| | | * https://gitee.com/yezhihao/jt808-server |
| | | */ |
| | | @JsonIgnoreProperties({"attributes", |
| | | "alarmList", |
| | | "dateTime", |
| | | "messageId", |
| | | "properties", |
| | | "protocolVersion", |
| | | "clientId", "serialNo", |
| | | "packageTotal", "packageNo", |
| | | "verified", |
| | | "bodyLength", |
| | | "encryption", |
| | | "subpackage", |
| | | "version", |
| | | "reserved"}) |
| | | @Message(JT808.ä½ç½®ä¿¡æ¯æ±æ¥) |
| | | @Data |
| | | public class T0200 extends JTMessage { |
| | | |
| | | @Field(length = 4, desc = "æ¥è¦æ å¿") |
| | | private int warnBit; |
| | | @Field(length = 4, desc = "ç¶æ") |
| | | private int statusBit; |
| | | @Field(length = 4, desc = "纬度") |
| | | private int latitude; |
| | | @Field(length = 4, desc = "ç»åº¦") |
| | | private int longitude; |
| | | @Field(length = 2, desc = "é«ç¨(ç±³)") |
| | | private int altitude; |
| | | @Field(length = 2, desc = "é度(1/10å
¬éæ¯å°æ¶)") |
| | | private int speed; |
| | | @Field(length = 2, desc = "æ¹å") |
| | | private int direction; |
| | | // @Field(length = 6, charset = "BCD", desc = "æ¶é´(YYMMDDHHMMSS)") |
| | | // private LocalDateTime deviceTime; |
| | | @Field(length = 6, charset = "BCD", desc = "æ¶é´(YYYY-MM-DDTHH-mm-ss)") |
| | | private LocalDateTime deviceTime; |
| | | @Field(converter = AttributeConverter.class, desc = "ä½ç½®éå ä¿¡æ¯", version = {-1, 0}) |
| | | @Field(converter = AttributeConverterYue.class, desc = "ä½ç½®éå ä¿¡æ¯(粤æ )", version = 1) |
| | | private Map<Integer, Object> attributes; |
| | | |
| | | public int getWarnBit() { |
| | | return warnBit; |
| | | } |
| | | |
| | | public void setWarnBit(int warnBit) { |
| | | this.warnBit = warnBit; |
| | | } |
| | | |
| | | public int getStatusBit() { |
| | | return statusBit; |
| | | } |
| | | |
| | | public void setStatusBit(int statusBit) { |
| | | this.statusBit = statusBit; |
| | | } |
| | | |
| | | public int getLatitude() { |
| | | return latitude; |
| | | } |
| | | |
| | | public void setLatitude(int latitude) { |
| | | this.latitude = latitude; |
| | | } |
| | | |
| | | public int getLongitude() { |
| | | return longitude; |
| | | } |
| | | |
| | | public void setLongitude(int longitude) { |
| | | this.longitude = longitude; |
| | | } |
| | | |
| | | public int getAltitude() { |
| | | return altitude; |
| | | } |
| | | |
| | | public void setAltitude(int altitude) { |
| | | this.altitude = altitude; |
| | | } |
| | | |
| | | public int getSpeed() { |
| | | return speed; |
| | | } |
| | | |
| | | public void setSpeed(int speed) { |
| | | this.speed = speed; |
| | | } |
| | | |
| | | public int getDirection() { |
| | | return direction; |
| | | } |
| | | |
| | | public void setDirection(int direction) { |
| | | this.direction = direction; |
| | | } |
| | | |
| | | public LocalDateTime getDeviceTime() { |
| | | return deviceTime; |
| | | } |
| | | |
| | | public void setDeviceTime(LocalDateTime deviceTime) { |
| | | this.deviceTime = deviceTime; |
| | | } |
| | | |
| | | |
| | | public int getAttributeInt(int key) { |
| | | if (attributes != null) { |
| | | Integer value = (Integer) attributes.get(key); |
| | | if (value != null) { |
| | | return value; |
| | | } |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | public long getAttributeLong(int key) { |
| | | if (attributes != null) { |
| | | Long value = (Long) attributes.get(key); |
| | | if (value != null) { |
| | | return value; |
| | | } |
| | | } |
| | | return 0L; |
| | | } |
| | | |
| | | private boolean updated; |
| | | private double lng; |
| | | private double lat; |
| | | private float speedKph; |
| | | |
| | | @Override |
| | | public boolean transform() { |
| | | if (deviceTime == null) |
| | | return false; |
| | | lng = longitude / 1000000d; |
| | | lat = latitude / 1000000d; |
| | | speedKph = speed / 10f; |
| | | return true; |
| | | } |
| | | |
| | | |
| | | public boolean updated() { |
| | | return updated || !(updated = true); |
| | | } |
| | | |
| | | public double getLng() { |
| | | return lng; |
| | | } |
| | | |
| | | public double getLat() { |
| | | return lat; |
| | | } |
| | | |
| | | public float getSpeedKph() { |
| | | return speedKph; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | StringBuilder sb = toStringHead(); |
| | | sb.append("T0200{deviceTime=").append(deviceTime); |
| | | sb.append(",longitude=").append(longitude); |
| | | sb.append(",latitude=").append(latitude); |
| | | sb.append(",altitude=").append(altitude); |
| | | sb.append(",speed=").append(speed); |
| | | sb.append(",direction=").append(direction); |
| | | sb.append(",warnBit=").append(Integer.toBinaryString(warnBit)); |
| | | sb.append(",statusBit=").append(Integer.toBinaryString(statusBit)); |
| | | sb.append(",attributes=").append(attributes); |
| | | sb.append('}'); |
| | | return sb.toString(); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.t808; |
| | | |
| | | import io.github.yezhihao.netmc.core.model.Response; |
| | | import io.github.yezhihao.protostar.annotation.Field; |
| | | import io.github.yezhihao.protostar.annotation.MergeSuperclass; |
| | | import io.github.yezhihao.protostar.annotation.Message; |
| | | import org.yzh.protocol.commons.JT808; |
| | | import org.yzh.protocol.t808.T0200; |
| | | |
| | | /** |
| | | * @author yezhihao |
| | | * https://gitee.com/yezhihao/jt808-server |
| | | */ |
| | | @MergeSuperclass |
| | | @Message({JT808.ä½ç½®ä¿¡æ¯æ¥è¯¢åºç, JT808.è½¦è¾æ§å¶åºç}) |
| | | public class T0201_0500 extends T0200 implements Response { |
| | | |
| | | @Field(length = 2, desc = "åºçæµæ°´å·") |
| | | private int responseSerialNo; |
| | | |
| | | @Override |
| | | public int getResponseSerialNo() { |
| | | return responseSerialNo; |
| | | } |
| | | |
| | | public void setResponseSerialNo(int responseSerialNo) { |
| | | this.responseSerialNo = responseSerialNo; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.t808; |
| | | |
| | | import io.github.yezhihao.protostar.annotation.Field; |
| | | import io.github.yezhihao.protostar.annotation.Message; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import org.yzh.commons.model.APICodes; |
| | | import org.yzh.commons.model.APIException; |
| | | import org.yzh.protocol.basics.JTMessage; |
| | | import org.yzh.protocol.commons.JT808; |
| | | |
| | | import java.util.Base64; |
| | | |
| | | /** |
| | | * @author yezhihao |
| | | * https://gitee.com/yezhihao/jt808-server |
| | | */ |
| | | @Message({JT808.å¹³å°RSAå
¬é¥, JT808.ç»ç«¯RSAå
¬é¥}) |
| | | public class T0A00_8A00 extends JTMessage { |
| | | |
| | | @Field(length = 4, desc = "RSAå
¬é¥{e,n}ä¸çe") |
| | | private int e; |
| | | @Field(length = 128, desc = "RSAå
¬é¥{e,n}ä¸çn") |
| | | private byte[] n; |
| | | |
| | | public T0A00_8A00() { |
| | | } |
| | | |
| | | public T0A00_8A00(int e, byte[] n) { |
| | | this.e = e; |
| | | this.n = n; |
| | | } |
| | | |
| | | public int getE() { |
| | | return e; |
| | | } |
| | | |
| | | public void setE(int e) { |
| | | this.e = e; |
| | | } |
| | | |
| | | public byte[] getN() { |
| | | return n; |
| | | } |
| | | |
| | | public void setN(byte[] n) { |
| | | this.n = n; |
| | | } |
| | | |
| | | @Schema(description = "n(BASE64ç¼ç )") |
| | | private String nBase64; |
| | | |
| | | public String getnBase64() { |
| | | return nBase64; |
| | | } |
| | | |
| | | public void setnBase64(String nBase64) { |
| | | this.nBase64 = nBase64; |
| | | } |
| | | |
| | | public T0A00_8A00 build() { |
| | | byte[] src = Base64.getDecoder().decode(n); |
| | | if (src.length == 129) { |
| | | byte[] dest = new byte[128]; |
| | | System.arraycopy(src, 1, dest, 0, 128); |
| | | src = dest; |
| | | } |
| | | if (src.length != 128) |
| | | throw new APIException(APICodes.InvalidParameter, "e length is not 128"); |
| | | this.n = src; |
| | | return this; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.t808; |
| | | |
| | | import io.github.yezhihao.netmc.util.AdapterMap; |
| | | import io.github.yezhihao.protostar.annotation.Field; |
| | | import io.github.yezhihao.protostar.annotation.Message; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import org.yzh.protocol.basics.JTMessage; |
| | | import org.yzh.protocol.commons.JT808; |
| | | import org.yzh.protocol.commons.transform.ParameterConverter; |
| | | import org.yzh.protocol.commons.transform.parameter.*; |
| | | |
| | | import java.util.Map; |
| | | import java.util.TreeMap; |
| | | import java.util.function.Function; |
| | | |
| | | /** |
| | | * @author yezhihao |
| | | * https://gitee.com/yezhihao/jt808-server |
| | | */ |
| | | @Message(JT808.设置ç»ç«¯åæ°) |
| | | public class T8103 extends JTMessage { |
| | | |
| | | @Field(length = 1, desc = "åæ°æ»æ°") |
| | | private int total; |
| | | @Field(desc = "忰项å表", converter = ParameterConverter.class) |
| | | private Map<Integer, Object> parameters; |
| | | |
| | | public T8103() { |
| | | } |
| | | |
| | | public T8103(Map<Integer, Object> parameters) { |
| | | this.parameters = parameters; |
| | | this.total = parameters.size(); |
| | | } |
| | | |
| | | public int getTotal() { |
| | | return total; |
| | | } |
| | | |
| | | public void setTotal(int total) { |
| | | this.total = total; |
| | | } |
| | | |
| | | public Map<Integer, Object> getParameters() { |
| | | return parameters; |
| | | } |
| | | |
| | | public void setParameters(Map<Integer, Object> parameters) { |
| | | this.parameters = parameters; |
| | | this.total = parameters.size(); |
| | | } |
| | | |
| | | public T8103 addParameter(Integer key, Object value) { |
| | | if (parameters == null) |
| | | parameters = new TreeMap(); |
| | | parameters.put(key, value); |
| | | total = parameters.size(); |
| | | return this; |
| | | } |
| | | |
| | | @Schema(description = "æ°å¼ååæ°å表(BYTEãWORD)") |
| | | private Map<Integer, Integer> parametersInt; |
| | | @Schema(description = "æ°å¼ååæ°å表(DWORDãQWORD)") |
| | | private Map<Integer, String> parametersLong; |
| | | @Schema(description = "å符ååæ°å表") |
| | | private Map<Integer, String> parametersStr; |
| | | @Schema(description = "å¾ååææ¥è¦åæ°è®¾ç½®(1078)") |
| | | private ParamImageIdentifyAlarm paramImageIdentifyAlarm; |
| | | @Schema(description = "ç¹æ®æ¥è¦å½ååæ°è®¾ç½®(1078)") |
| | | private ParamVideoSpecialAlarm paramVideoSpecialAlarm; |
| | | @Schema(description = "é³è§é¢ééå表设置(1078)") |
| | | private ParamChannels paramChannels; |
| | | @Schema(description = "ç»ç«¯ä¼ç å¤é模å¼è®¾ç½®æ°æ®æ ¼å¼(1078)") |
| | | private ParamSleepWake paramSleepWake; |
| | | @Schema(description = "é³è§é¢åæ°è®¾ç½®(1078)") |
| | | private ParamVideo paramVideo; |
| | | @Schema(description = "åç¬è§é¢ééåæ°è®¾ç½®(1078)") |
| | | private ParamVideoSingle paramVideoSingle; |
| | | @Schema(description = "ç²åºçæµç³»ç»åæ°(èæ )") |
| | | private ParamBSD paramBSD; |
| | | @Schema(description = "èåçæµç³»ç»åæ°(èæ )") |
| | | private ParamTPMS paramTPMS; |
| | | @Schema(description = "驾驶åç¶æçæµç³»ç»åæ°(èæ )") |
| | | private ParamDSM paramDSM; |
| | | @Schema(description = "é«çº§é©¾é©¶è¾
å©ç³»ç»åæ°(èæ )") |
| | | private ParamADAS paramADAS; |
| | | |
| | | public Map<Integer, Integer> getParametersInt() { |
| | | return parametersInt; |
| | | } |
| | | |
| | | public void setParametersInt(Map<Integer, Integer> parametersInt) { |
| | | this.parametersInt = parametersInt; |
| | | } |
| | | |
| | | public Map<Integer, String> getParametersLong() { |
| | | return parametersLong; |
| | | } |
| | | |
| | | public void setParametersLong(Map<Integer, String> parametersLong) { |
| | | this.parametersLong = parametersLong; |
| | | } |
| | | |
| | | public Map<Integer, String> getParametersStr() { |
| | | return parametersStr; |
| | | } |
| | | |
| | | public void setParametersStr(Map<Integer, String> parametersStr) { |
| | | this.parametersStr = parametersStr; |
| | | } |
| | | |
| | | public ParamADAS getParamADAS() { |
| | | return paramADAS; |
| | | } |
| | | |
| | | public void setParamADAS(ParamADAS paramADAS) { |
| | | this.paramADAS = paramADAS; |
| | | } |
| | | |
| | | public ParamBSD getParamBSD() { |
| | | return paramBSD; |
| | | } |
| | | |
| | | public void setParamBSD(ParamBSD paramBSD) { |
| | | this.paramBSD = paramBSD; |
| | | } |
| | | |
| | | public ParamChannels getParamChannels() { |
| | | return paramChannels; |
| | | } |
| | | |
| | | public void setParamChannels(ParamChannels paramChannels) { |
| | | this.paramChannels = paramChannels; |
| | | } |
| | | |
| | | public ParamDSM getParamDSM() { |
| | | return paramDSM; |
| | | } |
| | | |
| | | public void setParamDSM(ParamDSM paramDSM) { |
| | | this.paramDSM = paramDSM; |
| | | } |
| | | |
| | | public ParamImageIdentifyAlarm getParamImageIdentifyAlarm() { |
| | | return paramImageIdentifyAlarm; |
| | | } |
| | | |
| | | public void setParamImageIdentifyAlarm(ParamImageIdentifyAlarm paramImageIdentifyAlarm) { |
| | | this.paramImageIdentifyAlarm = paramImageIdentifyAlarm; |
| | | } |
| | | |
| | | public ParamSleepWake getParamSleepWake() { |
| | | return paramSleepWake; |
| | | } |
| | | |
| | | public void setParamSleepWake(ParamSleepWake paramSleepWake) { |
| | | this.paramSleepWake = paramSleepWake; |
| | | } |
| | | |
| | | public ParamTPMS getParamTPMS() { |
| | | return paramTPMS; |
| | | } |
| | | |
| | | public void setParamTPMS(ParamTPMS paramTPMS) { |
| | | this.paramTPMS = paramTPMS; |
| | | } |
| | | |
| | | public ParamVideo getParamVideo() { |
| | | return paramVideo; |
| | | } |
| | | |
| | | public void setParamVideo(ParamVideo paramVideo) { |
| | | this.paramVideo = paramVideo; |
| | | } |
| | | |
| | | public ParamVideoSingle getParamVideoSingle() { |
| | | return paramVideoSingle; |
| | | } |
| | | |
| | | public void setParamVideoSingle(ParamVideoSingle paramVideoSingle) { |
| | | this.paramVideoSingle = paramVideoSingle; |
| | | } |
| | | |
| | | public ParamVideoSpecialAlarm getParamVideoSpecialAlarm() { |
| | | return paramVideoSpecialAlarm; |
| | | } |
| | | |
| | | public void setParamVideoSpecialAlarm(ParamVideoSpecialAlarm paramVideoSpecialAlarm) { |
| | | this.paramVideoSpecialAlarm = paramVideoSpecialAlarm; |
| | | } |
| | | |
| | | public T8103 build() { |
| | | Map<Integer, Object> map = new TreeMap<>(); |
| | | |
| | | if (parametersInt != null && !parametersInt.isEmpty()) |
| | | map.putAll(parametersInt); |
| | | |
| | | if (parametersLong != null && !parametersLong.isEmpty()) |
| | | map.putAll(new AdapterMap(parametersLong, (Function<String, Long>) Long::parseLong)); |
| | | |
| | | if (parametersStr != null && !parametersStr.isEmpty()) |
| | | map.putAll(parametersStr); |
| | | |
| | | if (paramADAS != null) |
| | | map.put(paramADAS.key, paramADAS); |
| | | if (paramBSD != null) |
| | | map.put(paramBSD.key, paramBSD); |
| | | if (paramChannels != null) |
| | | map.put(paramChannels.key, paramChannels); |
| | | if (paramDSM != null) |
| | | map.put(paramDSM.key, paramDSM); |
| | | if (paramImageIdentifyAlarm != null) |
| | | map.put(paramImageIdentifyAlarm.key, paramImageIdentifyAlarm); |
| | | if (paramSleepWake != null) |
| | | map.put(paramSleepWake.key, paramSleepWake); |
| | | if (paramTPMS != null) |
| | | map.put(paramTPMS.key, paramTPMS); |
| | | if (paramVideo != null) |
| | | map.put(paramVideo.key, paramVideo); |
| | | if (paramVideoSingle != null) |
| | | map.put(paramVideoSingle.key, paramVideoSingle); |
| | | if (paramVideoSpecialAlarm != null) |
| | | map.put(paramVideoSpecialAlarm.key, paramVideoSpecialAlarm); |
| | | |
| | | this.total = map.size(); |
| | | this.parameters = map; |
| | | return this; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.t808; |
| | | |
| | | import io.github.yezhihao.protostar.annotation.Field; |
| | | import io.github.yezhihao.protostar.annotation.Message; |
| | | import io.github.yezhihao.protostar.util.KeyValuePair; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import org.yzh.protocol.basics.JTMessage; |
| | | import org.yzh.protocol.commons.JT808; |
| | | import org.yzh.protocol.commons.transform.PassthroughConverter; |
| | | import org.yzh.protocol.commons.transform.passthrough.PeripheralStatus; |
| | | import org.yzh.protocol.commons.transform.passthrough.PeripheralSystem; |
| | | |
| | | /** |
| | | * @author yezhihao |
| | | * https://gitee.com/yezhihao/jt808-server |
| | | */ |
| | | @Message(JT808.æ°æ®ä¸è¡éä¼ ) |
| | | public class T8900 extends JTMessage { |
| | | |
| | | /** GNSS模å详ç»å®ä½æ°æ® */ |
| | | public static final int GNSSLocation = 0x00; |
| | | /** éè·¯è¿è¾è¯ICå¡ä¿¡æ¯ä¸ä¼ æ¶æ¯ä¸º64Byte,ä¸ä¼ æ¶æ¯ä¸º24Byte,éè·¯è¿è¾è¯ICå¡è®¤è¯éä¼ è¶
æ¶æ¶é´ä¸º30s.è¶
æ¶å,ä¸éå */ |
| | | public static final int ICCardInfo = 0x0B; |
| | | /** 串å£1éä¼ æ¶æ¯ */ |
| | | public static final int SerialPortOne = 0x41; |
| | | /** 串å£2éä¼ æ¶æ¯ */ |
| | | public static final int SerialPortTow = 0x42; |
| | | /** ç¨æ·èªå®ä¹éä¼ 0xF0~0xFF */ |
| | | public static final int Custom = 0xF0; |
| | | |
| | | @Field(desc = "éä¼ æ¶æ¯", converter = PassthroughConverter.class) |
| | | private KeyValuePair<Integer, Object> message; |
| | | |
| | | public T8900() { |
| | | } |
| | | |
| | | public T8900(KeyValuePair<Integer, Object> message) { |
| | | this.message = message; |
| | | } |
| | | |
| | | public KeyValuePair<Integer, Object> getMessage() { |
| | | return message; |
| | | } |
| | | |
| | | public void setMessage(KeyValuePair<Integer, Object> message) { |
| | | this.message = message; |
| | | } |
| | | |
| | | @Schema(description = "ç¶ææ¥è¯¢(å¤è®¾ç¶æä¿¡æ¯ï¼å¤è®¾å·¥ä½ç¶æãè®¾å¤æ¥è¦ä¿¡æ¯)") |
| | | private PeripheralStatus peripheralStatus; |
| | | |
| | | @Schema(description = "ä¿¡æ¯æ¥è¯¢(å¤è®¾ä¼ æå¨çåºæ¬ä¿¡æ¯ï¼å
¬å¸ä¿¡æ¯ã产å代ç ãçæ¬å·ãå¤è®¾IDã客æ·ä»£ç )") |
| | | private PeripheralSystem peripheralSystem; |
| | | |
| | | public PeripheralStatus getPeripheralStatus() { |
| | | return peripheralStatus; |
| | | } |
| | | |
| | | public void setPeripheralStatus(PeripheralStatus peripheralStatus) { |
| | | this.peripheralStatus = peripheralStatus; |
| | | } |
| | | |
| | | public PeripheralSystem getPeripheralSystem() { |
| | | return peripheralSystem; |
| | | } |
| | | |
| | | public void setPeripheralSystem(PeripheralSystem peripheralSystem) { |
| | | this.peripheralSystem = peripheralSystem; |
| | | } |
| | | |
| | | public T8900 build() { |
| | | KeyValuePair<Integer, Object> message = new KeyValuePair<>(); |
| | | |
| | | if (peripheralStatus != null) { |
| | | message.setKey(PeripheralStatus.key); |
| | | message.setValue(peripheralStatus); |
| | | |
| | | } else if (peripheralSystem != null) { |
| | | message.setKey(PeripheralSystem.key); |
| | | message.setValue(peripheralSystem); |
| | | } |
| | | this.message = message; |
| | | return this; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.config; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonInclude.Include; |
| | | import com.fasterxml.jackson.core.JsonGenerator; |
| | | import com.fasterxml.jackson.databind.DeserializationFeature; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.fasterxml.jackson.databind.SerializationFeature; |
| | | import com.fasterxml.jackson.databind.module.SimpleModule; |
| | | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; |
| | | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; |
| | | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; |
| | | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; |
| | | import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; |
| | | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; |
| | | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; |
| | | import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; |
| | | import com.github.benmanes.caffeine.cache.Caffeine; |
| | | import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; |
| | | import org.springframework.cache.CacheManager; |
| | | import org.springframework.cache.caffeine.CaffeineCacheManager; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.yzh.commons.util.DateUtils; |
| | | |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.time.LocalTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | @Configuration |
| | | public class BeanConfig { |
| | | |
| | | @Bean |
| | | public CacheManager cacheManager() { |
| | | CaffeineCacheManager manager = new CaffeineCacheManager(); |
| | | manager.setCaffeine(Caffeine.newBuilder() |
| | | .maximumSize(500L) |
| | | .expireAfterWrite(30, TimeUnit.MINUTES)); |
| | | return manager; |
| | | } |
| | | |
| | | @Bean |
| | | public Jackson2ObjectMapperBuilderCustomizer customizeJackson2ObjectMapper() { |
| | | return builder -> { |
| | | SimpleModule longModule = new SimpleModule(); |
| | | longModule.addSerializer(Long.TYPE, ToStringSerializer.instance); |
| | | longModule.addSerializer(Long.class, ToStringSerializer.instance); |
| | | |
| | | JavaTimeModule timeModule = new JavaTimeModule(); |
| | | timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateUtils.DATE_TIME_FORMATTER)); |
| | | timeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateUtils.DATE_TIME_FORMATTER)); |
| | | timeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ISO_LOCAL_DATE)); |
| | | timeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ISO_LOCAL_DATE)); |
| | | timeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ISO_LOCAL_TIME)); |
| | | timeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ISO_LOCAL_TIME)); |
| | | |
| | | builder.modules(longModule, timeModule); |
| | | ObjectMapper mapper = new ObjectMapper(); |
| | | mapper.configure(SerializationFeature.FAIL_ON_SELF_REFERENCES, true);//忽ç¥å¾ªç¯å¼ç¨ |
| | | // mapper.configure(SerializationFeature.WRITE_SELF_REFERENCES_AS_NULL, true);//循ç¯å¼ç¨åå
¥null |
| | | mapper.setSerializationInclusion(Include.NON_NULL); |
| | | mapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true); |
| | | mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); |
| | | mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); |
| | | mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);// å
¼å®¹é«å¾·å°å¾api |
| | | builder.configure(mapper); |
| | | }; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.config; |
| | | |
| | | import io.github.yezhihao.netmc.core.HandlerMapping; |
| | | import io.github.yezhihao.netmc.core.SpringHandlerMapping; |
| | | import io.github.yezhihao.netmc.session.SessionListener; |
| | | import io.github.yezhihao.netmc.session.SessionManager; |
| | | import io.github.yezhihao.protostar.SchemaManager; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.yzh.protocol.codec.DataFrameMessageDecoder; |
| | | import org.yzh.protocol.codec.JTMessageAdapter; |
| | | import org.yzh.protocol.codec.JTMessageEncoder; |
| | | import org.yzh.protocol.codec.MultiPacketDecoder; |
| | | import com.doumee.jtt808.web.endpoint.JTHandlerInterceptor; |
| | | import com.doumee.jtt808.web.endpoint.JTMultiPacketListener; |
| | | import com.doumee.jtt808.web.endpoint.JTSessionListener; |
| | | import com.doumee.jtt808.web.model.enums.SessionKey; |
| | | |
| | | @Configuration |
| | | public class JTBeanConfig { |
| | | |
| | | @Bean |
| | | public HandlerMapping handlerMapping() { |
| | | return new SpringHandlerMapping(); |
| | | } |
| | | |
| | | @Bean |
| | | public JTHandlerInterceptor handlerInterceptor() { |
| | | return new JTHandlerInterceptor(); |
| | | } |
| | | |
| | | @Bean |
| | | public SessionListener sessionListener() { |
| | | return new JTSessionListener(); |
| | | } |
| | | |
| | | @Bean |
| | | public SessionManager sessionManager(SessionListener sessionListener) { |
| | | return new SessionManager(SessionKey.class, sessionListener); |
| | | } |
| | | |
| | | @Bean |
| | | public SchemaManager schemaManager() { |
| | | return new SchemaManager("org.yzh.protocol"); |
| | | } |
| | | |
| | | @Bean |
| | | public JTMessageAdapter messageAdapter(SchemaManager schemaManager) { |
| | | JTMessageEncoder encoder = new JTMessageEncoder(schemaManager); |
| | | MultiPacketDecoder decoder = new MultiPacketDecoder(schemaManager, new JTMultiPacketListener(10)); |
| | | return new WebLogAdapter(encoder, decoder); |
| | | } |
| | | |
| | | @Bean |
| | | public JTMessageAdapter alarmFileMessageAdapter(SchemaManager schemaManager) { |
| | | JTMessageEncoder encoder = new JTMessageEncoder(schemaManager); |
| | | DataFrameMessageDecoder decoder = new DataFrameMessageDecoder(schemaManager, new byte[]{0x30, 0x31, 0x63, 0x64}); |
| | | return new WebLogAdapter(encoder, decoder); |
| | | } |
| | | |
| | | @Bean |
| | | public MultiPacketDecoder multiPacketDecoder(SchemaManager schemaManager) { |
| | | return new MultiPacketDecoder(schemaManager); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.config; |
| | | |
| | | import io.github.yezhihao.netmc.NettyConfig; |
| | | import io.github.yezhihao.netmc.Server; |
| | | import io.github.yezhihao.netmc.codec.Delimiter; |
| | | import io.github.yezhihao.netmc.codec.LengthField; |
| | | import io.github.yezhihao.netmc.core.HandlerMapping; |
| | | import io.github.yezhihao.netmc.session.SessionManager; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.core.annotation.Order; |
| | | import org.yzh.protocol.codec.JTMessageAdapter; |
| | | import com.doumee.jtt808.web.endpoint.JTHandlerInterceptor; |
| | | |
| | | @Order(Integer.MIN_VALUE) |
| | | @Configuration |
| | | @ConditionalOnProperty(value = "jt-server.jt808.enable", havingValue = "true") |
| | | public class JTConfig { |
| | | |
| | | private final JTMessageAdapter messageAdapter; |
| | | private final HandlerMapping handlerMapping; |
| | | private final JTHandlerInterceptor handlerInterceptor; |
| | | private final SessionManager sessionManager; |
| | | |
| | | public JTConfig(JTMessageAdapter messageAdapter, HandlerMapping handlerMapping, JTHandlerInterceptor handlerInterceptor, SessionManager sessionManager) { |
| | | this.messageAdapter = messageAdapter; |
| | | this.handlerMapping = handlerMapping; |
| | | this.handlerInterceptor = handlerInterceptor; |
| | | this.sessionManager = sessionManager; |
| | | } |
| | | |
| | | @ConditionalOnProperty(value = "jt-server.jt808.port.tcp") |
| | | @Bean(initMethod = "start", destroyMethod = "stop") |
| | | public Server jt808TCPServer(@Value("${jt-server.jt808.port.tcp}") int port) { |
| | | return NettyConfig.custom() |
| | | //å¿è·³è¶
æ¶(ç§) |
| | | .setIdleStateTime(180, 0, 0) |
| | | .setPort(port) |
| | | //æ è¯ä½[2] + æ¶æ¯å¤´[21] + æ¶æ¯ä½[1023 * 2(转ä¹é¢ç)] + æ ¡éªç [1] + æ è¯ä½[2] |
| | | .setMaxFrameLength(2 + 21 + 1023 * 3 + 1 + 2) |
| | | .setDelimiters(new Delimiter(new byte[]{0x7e}, false)) |
| | | .setDecoder(messageAdapter) |
| | | .setEncoder(messageAdapter) |
| | | .setHandlerMapping(handlerMapping) |
| | | .setHandlerInterceptor(handlerInterceptor) |
| | | .setSessionManager(sessionManager) |
| | | .setName("808-TCP") |
| | | .build(); |
| | | } |
| | | |
| | | @ConditionalOnProperty(value = "jt-server.jt808.port.udp") |
| | | @Bean(initMethod = "start", destroyMethod = "stop") |
| | | public Server jt808UDPServer(@Value("${jt-server.jt808.port.udp}") int port) { |
| | | return NettyConfig.custom() |
| | | .setPort(port) |
| | | .setDelimiters(new Delimiter(new byte[]{0x7e}, false)) |
| | | .setDecoder(messageAdapter) |
| | | .setEncoder(messageAdapter) |
| | | .setHandlerMapping(handlerMapping) |
| | | .setHandlerInterceptor(handlerInterceptor) |
| | | .setSessionManager(sessionManager) |
| | | .setName("808-UDP") |
| | | .setEnableUDP(true) |
| | | .build(); |
| | | } |
| | | |
| | | @ConditionalOnProperty(value = "jt-server.alarm-file.enable", havingValue = "true") |
| | | @Bean(initMethod = "start", destroyMethod = "stop") |
| | | public Server alarmFileServer(@Value("${jt-server.alarm-file.port}") int port, JTMessageAdapter alarmFileMessageAdapter) { |
| | | return NettyConfig.custom() |
| | | .setPort(port) |
| | | .setMaxFrameLength(2 + 21 + 1023 * 2 + 1 + 2) |
| | | .setLengthField(new LengthField(new byte[]{0x30, 0x31, 0x63, 0x64}, 1024 * 65, 58, 4)) |
| | | .setDelimiters(new Delimiter(new byte[]{0x7e}, false)) |
| | | .setDecoder(alarmFileMessageAdapter) |
| | | .setEncoder(alarmFileMessageAdapter) |
| | | .setHandlerMapping(handlerMapping) |
| | | .setHandlerInterceptor(handlerInterceptor) |
| | | .setName("AlarmFile") |
| | | .build(); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.config; |
| | | |
| | | import io.github.yezhihao.netmc.session.Session; |
| | | import io.github.yezhihao.protostar.SchemaManager; |
| | | import io.netty.buffer.ByteBuf; |
| | | import io.netty.buffer.ByteBufUtil; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.http.codec.ServerSentEvent; |
| | | import org.yzh.protocol.basics.JTMessage; |
| | | import org.yzh.protocol.codec.JTMessageAdapter; |
| | | import org.yzh.protocol.codec.JTMessageDecoder; |
| | | import org.yzh.protocol.codec.JTMessageEncoder; |
| | | import org.yzh.protocol.commons.JT808; |
| | | import reactor.core.publisher.FluxSink; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | |
| | | public class WebLogAdapter extends JTMessageAdapter { |
| | | |
| | | protected static final Logger log = LoggerFactory.getLogger(WebLogAdapter.class); |
| | | |
| | | public static final HashMap<String, Set<FluxSink<Object>>> clientIds = new HashMap<>(); |
| | | public static final HashSet<Integer> ignoreMsgs = new HashSet<>(); |
| | | |
| | | static { |
| | | ignoreMsgs.add(JT808.å®ä½æ°æ®æ¹éä¸ä¼ ); |
| | | } |
| | | |
| | | public WebLogAdapter(SchemaManager schemaManager) { |
| | | super(schemaManager); |
| | | } |
| | | |
| | | public WebLogAdapter(JTMessageEncoder messageEncoder, JTMessageDecoder messageDecoder) { |
| | | super(messageEncoder, messageDecoder); |
| | | } |
| | | |
| | | @Override |
| | | public void encodeLog(Session session, JTMessage message, ByteBuf output) { |
| | | Set<FluxSink<Object>> emitters = clientIds.get(message.getClientId()); |
| | | if (emitters != null) { |
| | | ServerSentEvent<Object> event = ServerSentEvent.builder().event(message.getClientId()) |
| | | .data(message + "hex:" + ByteBufUtil.hexDump(output, 0, output.writerIndex())).build(); |
| | | for (FluxSink<Object> emitter : emitters) { |
| | | emitter.next(event); |
| | | } |
| | | } |
| | | if ((!ignoreMsgs.contains(message.getMessageId())) && (emitters != null || clientIds.isEmpty())) |
| | | super.encodeLog(session, message, output); |
| | | } |
| | | |
| | | @Override |
| | | public void decodeLog(Session session, JTMessage message, ByteBuf input) { |
| | | if (message != null) { |
| | | Set<FluxSink<Object>> emitters = clientIds.get(message.getClientId()); |
| | | if (emitters != null) { |
| | | ServerSentEvent<Object> event = ServerSentEvent.builder().event(message.getClientId()) |
| | | .data(message + "hex:" + ByteBufUtil.hexDump(input, 0, input.writerIndex())).build(); |
| | | for (FluxSink<Object> emitter : emitters) { |
| | | emitter.next(event); |
| | | } |
| | | } |
| | | if (!ignoreMsgs.contains(message.getMessageId()) && (emitters != null || clientIds.isEmpty())) |
| | | super.decodeLog(session, message, input); |
| | | |
| | | if (!message.isVerified()) |
| | | log.error("<<<<<æ ¡éªç é误session={},payload={}", session, ByteBufUtil.hexDump(input, 0, input.writerIndex())); |
| | | } |
| | | } |
| | | |
| | | public static void clearMessage() { |
| | | synchronized (ignoreMsgs) { |
| | | ignoreMsgs.clear(); |
| | | } |
| | | } |
| | | |
| | | public static void addMessage(int messageId) { |
| | | if (!ignoreMsgs.contains(messageId)) { |
| | | synchronized (ignoreMsgs) { |
| | | ignoreMsgs.add(messageId); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public static void removeMessage(int messageId) { |
| | | if (ignoreMsgs.contains(messageId)) { |
| | | synchronized (ignoreMsgs) { |
| | | ignoreMsgs.remove(messageId); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public static void clearClient() { |
| | | synchronized (clientIds) { |
| | | clientIds.clear(); |
| | | } |
| | | } |
| | | |
| | | public static void addClient(String clientId, FluxSink<Object> emitter) { |
| | | synchronized (clientIds) { |
| | | clientIds.computeIfAbsent(clientId, k -> new HashSet<>()).add(emitter); |
| | | } |
| | | } |
| | | |
| | | public static void removeClient(String clientId, FluxSink<Object> emitter) { |
| | | synchronized (clientIds) { |
| | | Set<FluxSink<Object>> emitters = clientIds.get(clientId); |
| | | if (emitters != null) { |
| | | emitters.remove(emitter); |
| | | if (emitters.isEmpty()) { |
| | | clientIds.remove(clientId); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.config; |
| | | |
| | | import org.springframework.boot.web.servlet.FilterRegistrationBean; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.core.Ordered; |
| | | import org.springframework.web.cors.CorsConfiguration; |
| | | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; |
| | | import org.springframework.web.filter.CorsFilter; |
| | | import org.springframework.web.servlet.config.annotation.CorsRegistry; |
| | | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; |
| | | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; |
| | | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
| | | |
| | | /** |
| | | * @author yezhihao |
| | | * https://gitee.com/yezhihao/jt808-server |
| | | */ |
| | | //@Configuration |
| | | public class WebMvcConfig implements WebMvcConfigurer { |
| | | |
| | | @Override |
| | | public void addResourceHandlers(ResourceHandlerRegistry registry) { |
| | | } |
| | | |
| | | @Override |
| | | public void addInterceptors(InterceptorRegistry registry) { |
| | | } |
| | | |
| | | @Override |
| | | public void addCorsMappings(CorsRegistry registry) { |
| | | // registry.addMapping("/**").combine(corsConfig()); |
| | | registry.addMapping("/**").allowedOrigins(CorsConfiguration.ALL) |
| | | .allowCredentials(true) |
| | | .allowedMethods(CorsConfiguration.ALL) |
| | | .maxAge(3600L) |
| | | .allowedHeaders(CorsConfiguration.ALL); |
| | | } |
| | | |
| | | @Bean |
| | | public FilterRegistrationBean<CorsFilter> corsFilter() { |
| | | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); |
| | | source.registerCorsConfiguration("/**", corsConfig()); |
| | | |
| | | FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source)); |
| | | bean.setOrder(Ordered.HIGHEST_PRECEDENCE); |
| | | return bean; |
| | | } |
| | | |
| | | @Bean |
| | | public CorsConfiguration corsConfig() { |
| | | CorsConfiguration config = new CorsConfiguration(); |
| | | // config.addAllowedOriginPattern(CorsConfiguration.ALL); |
| | | config.addAllowedOrigin(CorsConfiguration.ALL); |
| | | config.addAllowedMethod(CorsConfiguration.ALL); |
| | | config.addAllowedHeader(CorsConfiguration.ALL); |
| | | config.setAllowCredentials(true); |
| | | config.setMaxAge(3600L); |
| | | return config; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.controller; |
| | | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.dao.DuplicateKeyException; |
| | | import org.springframework.http.converter.HttpMessageNotReadableException; |
| | | import org.springframework.validation.BindException; |
| | | import org.springframework.validation.FieldError; |
| | | import org.springframework.web.HttpMediaTypeException; |
| | | import org.springframework.web.HttpRequestMethodNotSupportedException; |
| | | import org.springframework.web.bind.MissingServletRequestParameterException; |
| | | import org.springframework.web.bind.annotation.ExceptionHandler; |
| | | import org.springframework.web.bind.annotation.RestControllerAdvice; |
| | | import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; |
| | | import org.yzh.commons.model.APICodes; |
| | | import org.yzh.commons.model.APIException; |
| | | import org.yzh.commons.model.APIResult; |
| | | |
| | | import java.sql.SQLException; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | |
| | | @RestControllerAdvice |
| | | public class ExceptionController { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(ExceptionController.class); |
| | | |
| | | private static final Pattern compile = Pattern.compile("'\\w*'"); |
| | | |
| | | @ExceptionHandler(Exception.class) |
| | | public APIResult<?> onException(Exception e) { |
| | | log.error("ç³»ç»å¼å¸¸", e); |
| | | return new APIResult<>(e); |
| | | } |
| | | |
| | | @ExceptionHandler(APIException.class) |
| | | public APIResult<?> onAPIException(APIException e) { |
| | | return new APIResult<>(e); |
| | | } |
| | | |
| | | @ExceptionHandler(SQLException.class) |
| | | public APIResult<?> onSQLException(SQLException e) { |
| | | String message = e.getMessage(); |
| | | if (message.endsWith("have a default value")) |
| | | return new APIResult<>(APICodes.MissingParameter, e); |
| | | log.warn("ç³»ç»å¼å¸¸:", e); |
| | | return new APIResult<>(e); |
| | | } |
| | | |
| | | @ExceptionHandler(DuplicateKeyException.class) |
| | | public APIResult<?> onDuplicateKeyException(DuplicateKeyException e) { |
| | | Matcher matcher = compile.matcher(e.getCause().getMessage()); |
| | | List<String> values = new ArrayList<>(4); |
| | | while (matcher.find()) |
| | | values.add(matcher.group()); |
| | | |
| | | int size = values.size(); |
| | | int len = size < 2 ? size : (size / 2); |
| | | |
| | | StringBuilder sb = new StringBuilder(20); |
| | | sb.append("å·²åå¨çå·ç :"); |
| | | |
| | | for (int i = 0; i < len; i++) |
| | | sb.append(values.get(i)).append(','); |
| | | return new APIResult<>(APICodes.InvalidParameter, sb.substring(0, sb.length() - 1)); |
| | | } |
| | | |
| | | @ExceptionHandler(IllegalArgumentException.class) |
| | | public APIResult<?> onIllegalArgumentException(IllegalArgumentException e) { |
| | | log.warn("ç³»ç»å¼å¸¸:", e); |
| | | return new APIResult<>(APICodes.InvalidParameter, e.getMessage()); |
| | | } |
| | | |
| | | @ExceptionHandler(HttpMessageNotReadableException.class) |
| | | public APIResult<?> onHttpMessageNotReadableException(HttpMessageNotReadableException e) { |
| | | log.warn("ç³»ç»å¼å¸¸:", e); |
| | | return new APIResult<>(APICodes.TypeMismatch, e); |
| | | } |
| | | |
| | | @ExceptionHandler(BindException.class) |
| | | public APIResult<?> onBindException(BindException e) { |
| | | List<FieldError> fieldErrors = e.getFieldErrors(); |
| | | StringBuilder sb = new StringBuilder(); |
| | | for (FieldError fieldError : fieldErrors) |
| | | sb.append(fieldError.getField()).append(fieldError.getDefaultMessage()); |
| | | return new APIResult<>(APICodes.MissingParameter, sb.toString()); |
| | | } |
| | | |
| | | @ExceptionHandler(HttpMediaTypeException.class) |
| | | public APIResult<?> onHttpMediaTypeException(HttpMediaTypeException e) { |
| | | log.warn("ç³»ç»å¼å¸¸:", e); |
| | | return new APIResult<>(APICodes.NotSupportedType, e.getMessage()); |
| | | } |
| | | |
| | | @ExceptionHandler(HttpRequestMethodNotSupportedException.class) |
| | | public APIResult<?> onHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) { |
| | | return new APIResult<>(APICodes.NotImplemented); |
| | | } |
| | | |
| | | @ExceptionHandler(MissingServletRequestParameterException.class) |
| | | public APIResult<?> onMissingServletRequestParameterException(MissingServletRequestParameterException e) { |
| | | return new APIResult<>(APICodes.MissingParameter, ":" + e.getParameterName()); |
| | | } |
| | | |
| | | @ExceptionHandler(MethodArgumentTypeMismatchException.class) |
| | | public APIResult<?> onMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e) { |
| | | return new APIResult<>(APICodes.TypeMismatch, ":" + e.getName() + "=" + e.getValue(), e.getMessage()); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.controller; |
| | | |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | import org.yzh.commons.model.APIResult; |
| | | import org.yzh.protocol.basics.JTMessage; |
| | | import org.yzh.protocol.commons.JT1078; |
| | | import org.yzh.protocol.jsatl12.T9208; |
| | | import org.yzh.protocol.t1078.*; |
| | | import org.yzh.protocol.t808.T0001; |
| | | import com.doumee.jtt808.web.endpoint.MessageManager; |
| | | import reactor.core.publisher.Mono; |
| | | |
| | | @RestController |
| | | @RequestMapping("device") |
| | | @Api(tags = "JTT1078éä¿¡æ¥å£") |
| | | public class JT1078Controller { |
| | | |
| | | @Autowired |
| | | private MessageManager messageManager; |
| | | |
| | | @Operation(summary = "9003 æ¥è¯¢ç»ç«¯é³è§é¢å±æ§") |
| | | @PostMapping("9003") |
| | | public Mono<APIResult<T1003>> T9003(@RequestBody JTMessage request) { |
| | | return messageManager.requestR(request.messageId(JT1078.æ¥è¯¢ç»ç«¯é³è§é¢å±æ§), T1003.class); |
| | | } |
| | | |
| | | @Operation(summary = "9101 宿¶é³è§é¢ä¼ è¾è¯·æ±") |
| | | @PostMapping("9101") |
| | | public Mono<APIResult<T0001>> T9101(@RequestBody T9101 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "9102 é³è§é¢å®æ¶ä¼ è¾æ§å¶") |
| | | @PostMapping("9102") |
| | | public Mono<APIResult<T0001>> T9102(@RequestBody T9102 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "9201 å¹³å°ä¸åè¿ç¨å½ååæ¾è¯·æ±") |
| | | @PostMapping("9201") |
| | | public Mono<APIResult<T1205>> T9201(@RequestBody T9201 request) { |
| | | return messageManager.requestR(request, T1205.class); |
| | | } |
| | | |
| | | @Operation(summary = "9202 å¹³å°ä¸åè¿ç¨å½ååæ¾æ§å¶") |
| | | @PostMapping("9202") |
| | | public Mono<APIResult<T0001>> T9202(@RequestBody T9202 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "9205 æ¥è¯¢èµæºå表") |
| | | @PostMapping("9205") |
| | | public Mono<APIResult<T1205>> T9205(@RequestBody T9205 request) { |
| | | return messageManager.requestR(request, T1205.class); |
| | | } |
| | | |
| | | @Operation(summary = "9206 æä»¶ä¸ä¼ æä»¤") |
| | | @PostMapping("9206") |
| | | public Mono<APIResult<T0001>> T9206(@RequestBody T9206 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "9207 æä»¶ä¸ä¼ æ§å¶") |
| | | @PostMapping("9207") |
| | | public Mono<APIResult<T0001>> T9207(@RequestBody T9207 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "9208 æ¥è¦éä»¶ä¸ä¼ æä»¤(èæ )") |
| | | @PostMapping("9208") |
| | | public Mono<APIResult<T0001>> T9208(@RequestBody T9208 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "9301 äºå°æè½¬") |
| | | @PostMapping("9301") |
| | | public Mono<APIResult<T0001>> T9301(@RequestBody T9301 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "9302 äºå°è°æ´ç¦è·æ§å¶") |
| | | @PostMapping("9302") |
| | | public Mono<APIResult<T0001>> T9302(@RequestBody T9302 request) { |
| | | return messageManager.requestR(request.messageId(JT1078.äºå°è°æ´ç¦è·æ§å¶), T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "9303 äºå°è°æ´å
åæ§å¶") |
| | | @PostMapping("9303") |
| | | public Mono<APIResult<T0001>> T9303(@RequestBody T9302 request) { |
| | | return messageManager.requestR(request.messageId(JT1078.äºå°è°æ´å
åæ§å¶), T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "9304 äºå°é¨å·æ§å¶") |
| | | @PostMapping("9304") |
| | | public Mono<APIResult<T0001>> T9304(@RequestBody T9302 request) { |
| | | return messageManager.requestR(request.messageId(JT1078.äºå°é¨å·æ§å¶), T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "9305 红å¤è¡¥å
æ§å¶") |
| | | @PostMapping("9305") |
| | | public Mono<APIResult<T0001>> T9305(@RequestBody T9302 request) { |
| | | return messageManager.requestR(request.messageId(JT1078.红å¤è¡¥å
æ§å¶), T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "9306 äºå°ååæ§å¶") |
| | | @PostMapping("9306") |
| | | public Mono<APIResult<T0001>> T9306(@RequestBody T9302 request) { |
| | | return messageManager.requestR(request.messageId(JT1078.äºå°ååæ§å¶), T0001.class); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.controller; |
| | | |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | import org.yzh.commons.model.APIResult; |
| | | import org.yzh.protocol.basics.JTMessage; |
| | | import org.yzh.protocol.commons.JT808; |
| | | import org.yzh.protocol.t808.*; |
| | | import com.doumee.jtt808.web.endpoint.MessageManager; |
| | | import reactor.core.publisher.Mono; |
| | | |
| | | @RestController |
| | | @RequestMapping("jtt808/device") |
| | | @Api(tags = "JTT808éä¿¡æ¥å£") |
| | | public class JT808Controller { |
| | | |
| | | @Autowired |
| | | private MessageManager messageManager; |
| | | |
| | | @Operation(summary = "8103 设置ç»ç«¯åæ°") |
| | | @PostMapping("8103") |
| | | public Mono<APIResult<T0001>> T8103(@RequestBody com.doumee.jtt808.t808.T8103 request) { |
| | | return messageManager.requestR(request.build(), T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8104 æ¥è¯¢ç»ç«¯åæ°") |
| | | @PostMapping("8104") |
| | | public Mono<APIResult<T0104>> T8104(@RequestBody JTMessage request) { |
| | | return messageManager.requestR(request.messageId(JT808.æ¥è¯¢ç»ç«¯åæ°), T0104.class); |
| | | } |
| | | |
| | | @Operation(summary = "8106 æ¥è¯¢æå®ç»ç«¯åæ°") |
| | | @PostMapping("8106") |
| | | public Mono<APIResult<T0104>> T8106(@RequestBody T8106 request) { |
| | | return messageManager.requestR(request, T0104.class); |
| | | } |
| | | |
| | | @Operation(summary = "8105 ç»ç«¯æ§å¶") |
| | | @PostMapping("8105") |
| | | public Mono<APIResult<T0001>> T8105(@RequestBody T8105 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8107 æ¥è¯¢ç»ç«¯å±æ§") |
| | | @PostMapping("8107") |
| | | public Mono<APIResult<T0107>> T8107(@RequestBody JTMessage request) { |
| | | return messageManager.requestR(request.messageId(JT808.æ¥è¯¢ç»ç«¯å±æ§), T0107.class); |
| | | } |
| | | |
| | | @Operation(summary = "8201 ä½ç½®ä¿¡æ¯æ¥è¯¢") |
| | | @PostMapping("8201") |
| | | public Mono<APIResult<T0201_0500>> T8201(@RequestBody JTMessage request) { |
| | | return messageManager.requestR(request.messageId(JT808.ä½ç½®ä¿¡æ¯æ¥è¯¢), T0201_0500.class); |
| | | } |
| | | |
| | | @Operation(summary = "8202 临æ¶ä½ç½®è·è¸ªæ§å¶") |
| | | @PostMapping("8202") |
| | | public Mono<APIResult<T0001>> T8202(@RequestBody T8202 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8203 人工确认æ¥è¦æ¶æ¯") |
| | | @PostMapping("8203") |
| | | public Mono<APIResult<T0001>> T8203(@RequestBody T8203 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8204 æå¡å¨åç»ç«¯åèµ·é¾è·¯æ£æµè¯·æ±") |
| | | @PostMapping("8204") |
| | | public Mono<APIResult<T0001>> T8204(@RequestBody JTMessage request) { |
| | | return messageManager.requestR(request.messageId(JT808.æå¡å¨åç»ç«¯åèµ·é¾è·¯æ£æµè¯·æ±), T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8300 ææ¬ä¿¡æ¯ä¸å") |
| | | @PostMapping("8300") |
| | | public Mono<APIResult<T0001>> T8300(@RequestBody T8300 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8301 äºä»¶è®¾ç½®") |
| | | @PostMapping("8301") |
| | | public Mono<APIResult<T0001>> T8301(@RequestBody T8301 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8302 æé®ä¸å") |
| | | @PostMapping("8302") |
| | | public Mono<APIResult<T0001>> T8302(@RequestBody T8302 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8303 ä¿¡æ¯ç¹æèå设置") |
| | | @PostMapping("8303") |
| | | public Mono<APIResult<T0001>> T8303(@RequestBody T8303 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8304 ä¿¡æ¯æå¡") |
| | | @PostMapping("8304") |
| | | public Mono<APIResult<T0001>> T8304(@RequestBody T8304 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8400 çµè¯åæ¨") |
| | | @PostMapping("8400") |
| | | public Mono<APIResult<T0001>> T8400(@RequestBody T8400 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8401 设置çµè¯æ¬") |
| | | @PostMapping("8401") |
| | | public Mono<APIResult<T0001>> T8401(@RequestBody T8401 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8500 è½¦è¾æ§å¶") |
| | | @PostMapping("8500") |
| | | public Mono<APIResult<T0201_0500>> T8500(@RequestBody T8500 request) { |
| | | return messageManager.requestR(request, T0201_0500.class); |
| | | } |
| | | |
| | | @Operation(summary = "8600 设置åå½¢åºå") |
| | | @PostMapping("8600") |
| | | public Mono<APIResult<T0001>> T8600(@RequestBody T8600 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8601 å é¤åå½¢åºå") |
| | | @PostMapping("8601") |
| | | public Mono<APIResult<T0001>> T8601(@RequestBody T8601 request) { |
| | | return messageManager.requestR(request.messageId(JT808.å é¤åå½¢åºå), T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8602 设置ç©å½¢åºå") |
| | | @PostMapping("8602") |
| | | public Mono<APIResult<T0001>> T8602(@RequestBody T8602 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8603 å é¤ç©å½¢åºå") |
| | | @PostMapping("8603") |
| | | public Mono<APIResult<T0001>> T8603(@RequestBody T8601 request) { |
| | | return messageManager.requestR(request.messageId(JT808.å é¤ç©å½¢åºå), T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8604 设置å¤è¾¹å½¢åºå") |
| | | @PostMapping("8604") |
| | | public Mono<APIResult<T0001>> T8604(@RequestBody T8604 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8605 å é¤å¤è¾¹å½¢åºå") |
| | | @PostMapping("8605") |
| | | public Mono<APIResult<T0001>> T8605(@RequestBody T8601 request) { |
| | | return messageManager.requestR(request.messageId(JT808.å é¤å¤è¾¹å½¢åºå), T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8606 设置路线") |
| | | @PostMapping("8606") |
| | | public Mono<APIResult<T0001>> T8606(@RequestBody T8606 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8607 å é¤è·¯çº¿") |
| | | @PostMapping("8607") |
| | | public Mono<APIResult<T0001>> T8607(@RequestBody T8601 request) { |
| | | return messageManager.requestR(request.messageId(JT808.å é¤è·¯çº¿), T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8608 æ¥è¯¢åºåæçº¿è·¯æ°æ®") |
| | | @PostMapping("8608") |
| | | public Mono<APIResult<T0608>> T8608(@RequestBody T8608 request) { |
| | | return messageManager.requestR(request, T0608.class); |
| | | } |
| | | |
| | | @Operation(summary = "8700 è¡é©¶è®°å½ä»ªæ°æ®ééå½ä»¤") |
| | | @PostMapping("8700") |
| | | public Mono<APIResult<T0001>> T8700(@RequestBody JTMessage request) { |
| | | return messageManager.requestR(request.messageId(JT808.è¡é©¶è®°å½ä»ªæ°æ®ééå½ä»¤), T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8701 è¡é©¶è®°å½ä»ªåæ°ä¸ä¼ å½ä»¤") |
| | | @PostMapping("8701") |
| | | public Mono<APIResult<T0001>> T8701(@RequestBody T8701 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8702 䏿¥é©¾é©¶å身份信æ¯è¯·æ±") |
| | | @PostMapping("8702") |
| | | public Mono<APIResult<T0702>> T8702(@RequestBody JTMessage request) { |
| | | return messageManager.requestR(request.messageId(JT808.䏿¥é©¾é©¶å身份信æ¯è¯·æ±), T0702.class); |
| | | } |
| | | |
| | | @Operation(summary = "8801 æå头ç«å³ææå½ä»¤") |
| | | @PostMapping("8801") |
| | | public Mono<APIResult<T0805>> T8801(@RequestBody T8801 request) { |
| | | return messageManager.requestR(request, T0805.class); |
| | | } |
| | | |
| | | @Operation(summary = "8802 åå¨å¤åªä½æ°æ®æ£ç´¢") |
| | | @PostMapping("8802") |
| | | public Mono<APIResult<T0802>> T8802(@RequestBody T8802 request) { |
| | | return messageManager.requestR(request, T0802.class); |
| | | } |
| | | |
| | | @Operation(summary = "8803 åå¨å¤åªä½æ°æ®ä¸ä¼ ") |
| | | @PostMapping("8803") |
| | | public Mono<APIResult<T0001>> T8803(@RequestBody T8803 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8804 å½é³å¼å§å½ä»¤") |
| | | @PostMapping("8804") |
| | | public Mono<APIResult<T0001>> T8804(@RequestBody T8804 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8805 åæ¡åå¨å¤åªä½æ°æ®æ£ç´¢ä¸ä¼ å½ä»¤") |
| | | @PostMapping("8805") |
| | | public Mono<APIResult<T0001>> T8805(@RequestBody T8805 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8108 ä¸åç»ç«¯å级å
") |
| | | @PostMapping("8108") |
| | | public Mono<APIResult<T0001>> T8108(@RequestBody T8108 request) { |
| | | return messageManager.requestR(request, T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8900 æ°æ®ä¸è¡éä¼ ") |
| | | @PostMapping("8900") |
| | | public Mono<APIResult<T0001>> T8900(@RequestBody com.doumee.jtt808.t808.T8900 request) { |
| | | return messageManager.requestR(request.build(), T0001.class); |
| | | } |
| | | |
| | | @Operation(summary = "8A00 å¹³å°RSAå
¬é¥") |
| | | @PostMapping("8A00") |
| | | public Mono<APIResult<T0A00_8A00>> T8A00(@RequestBody com.doumee.jtt808.t808.T0A00_8A00 request) { |
| | | return messageManager.requestR(request.build(), T0A00_8A00.class); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.controller; |
| | | |
| | | import io.github.yezhihao.netmc.session.Session; |
| | | import io.github.yezhihao.netmc.session.SessionManager; |
| | | import io.github.yezhihao.netmc.util.AdapterCollection; |
| | | import io.github.yezhihao.protostar.util.Explain; |
| | | import io.netty.buffer.ByteBuf; |
| | | import io.netty.buffer.ByteBufUtil; |
| | | import io.netty.buffer.Unpooled; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.yzh.commons.model.APIResult; |
| | | import org.yzh.protocol.codec.JTMessageDecoder; |
| | | import com.doumee.jtt808.web.config.WebLogAdapter; |
| | | import com.doumee.jtt808.web.model.entity.DeviceDO; |
| | | import com.doumee.jtt808.web.model.enums.SessionKey; |
| | | import reactor.core.publisher.Flux; |
| | | import reactor.core.publisher.FluxSink; |
| | | import reactor.core.publisher.Mono; |
| | | |
| | | import javax.servlet.http.HttpSession; |
| | | import java.time.Duration; |
| | | import java.util.Collection; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | |
| | | @RestController |
| | | @RequestMapping |
| | | @Api(tags = "å
¶ä»éä¿¡æ¥å£") |
| | | public class OtherController { |
| | | |
| | | @Autowired |
| | | private SessionManager sessionManager; |
| | | @Autowired |
| | | private JTMessageDecoder decoder; |
| | | |
| | | @Operation(summary = "ç»ç«¯å®æ¶ä¿¡æ¯æ¥è¯¢") |
| | | @GetMapping("device/all") |
| | | public APIResult<Collection<Session>> all() { |
| | | Collection<Session> all = sessionManager.all(); |
| | | return APIResult.ok(all); |
| | | } |
| | | |
| | | @Operation(summary = "è·å¾å½åææå¨çº¿è®¾å¤ä¿¡æ¯") |
| | | @GetMapping("device/option") |
| | | public APIResult<Collection<DeviceDO>> getClientId(HttpSession httpSession) { |
| | | AdapterCollection<Session, DeviceDO> result = new AdapterCollection<>(sessionManager.all(), session -> { |
| | | DeviceDO device = SessionKey.getDevice(session); |
| | | if (device != null) |
| | | return device; |
| | | return new DeviceDO().mobileNo(session.getClientId()); |
| | | }); |
| | | return APIResult.ok(result); |
| | | } |
| | | |
| | | @Operation(summary = "设å¤è®¢é
") |
| | | @PostMapping(value = "device/sse", produces = MediaType.TEXT_PLAIN_VALUE) |
| | | public String sseSub(HttpSession httpSession, @RequestParam String clientId, @RequestParam boolean sub) { |
| | | FluxSink<Object> emitter = (FluxSink<Object>) httpSession.getAttribute("emitter"); |
| | | if (emitter == null) { |
| | | return "0"; |
| | | } |
| | | if (sub) { |
| | | WebLogAdapter.addClient(clientId, emitter); |
| | | ((Set<String>) httpSession.getAttribute("clientIds")).add(clientId); |
| | | } else { |
| | | WebLogAdapter.removeClient(clientId, emitter); |
| | | ((Set<String>) httpSession.getAttribute("clientIds")).remove(clientId); |
| | | } |
| | | return "1"; |
| | | } |
| | | |
| | | @Operation(summary = "设å¤çæ§") |
| | | @GetMapping(value = "device/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE) |
| | | public Flux<Object> sseConnect(HttpSession httpSession, String clientId) { |
| | | return Flux.create(emitter -> { |
| | | Set<String> clientIds = new HashSet<>(); |
| | | if (clientId != null) { |
| | | WebLogAdapter.addClient(clientId, emitter); |
| | | clientIds.add(clientId); |
| | | } |
| | | httpSession.setAttribute("clientIds", clientIds); |
| | | httpSession.setAttribute("emitter", emitter); |
| | | emitter.onDispose(() -> clientIds.forEach(id -> WebLogAdapter.removeClient(id, emitter))); |
| | | }); |
| | | } |
| | | |
| | | @Operation(summary = "808åè®®åæå·¥å
·") |
| | | @RequestMapping(value = "message/explain", method = {RequestMethod.POST, RequestMethod.GET}) |
| | | public String decode(@Parameter(description = "16è¿å¶æ¥æ") @RequestParam String hex) { |
| | | Explain explain = new Explain(); |
| | | hex = hex.replace(" ", ""); |
| | | String[] lines = hex.split("\n"); |
| | | for (String line : lines) { |
| | | String[] msgs = line.split("7e7e"); |
| | | for (String msg : msgs) { |
| | | ByteBuf byteBuf = Unpooled.wrappedBuffer(ByteBufUtil.decodeHexDump(msg)); |
| | | decoder.decode(byteBuf, explain); |
| | | } |
| | | } |
| | | return explain.toString(); |
| | | } |
| | | |
| | | @Operation(summary = "åå§æ¶æ¯åé") |
| | | @PostMapping("device/raw") |
| | | public Mono<String> postRaw(@Parameter(description = "ç»ç«¯ææºå·") @RequestParam String clientId, |
| | | @Parameter(description = "16è¿å¶æ¥æ") @RequestParam String message) { |
| | | Session session = sessionManager.get(clientId); |
| | | if (session != null) { |
| | | ByteBuf byteBuf = Unpooled.wrappedBuffer(ByteBufUtil.decodeHexDump(message)); |
| | | |
| | | return session.notify(byteBuf).map(unused -> "success") |
| | | .timeout(Duration.ofSeconds(10), Mono.just("timeout")) |
| | | .onErrorResume(throwable -> Mono.just("fail")); |
| | | } |
| | | return Mono.just("offline"); |
| | | } |
| | | |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.endpoint; |
| | | |
| | | import com.github.benmanes.caffeine.cache.Cache; |
| | | import com.github.benmanes.caffeine.cache.Caffeine; |
| | | import io.github.yezhihao.netmc.core.annotation.Endpoint; |
| | | import io.github.yezhihao.netmc.core.annotation.Mapping; |
| | | import io.github.yezhihao.netmc.session.Session; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | import org.yzh.protocol.commons.JSATL12; |
| | | import org.yzh.protocol.jsatl12.DataPacket; |
| | | import org.yzh.protocol.jsatl12.T1210; |
| | | import org.yzh.protocol.jsatl12.T1211; |
| | | import org.yzh.protocol.jsatl12.T9212; |
| | | import com.doumee.jtt808.web.service.FileService; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | @Endpoint |
| | | @Component |
| | | public class JSATL12Endpoint { |
| | | |
| | | @Autowired |
| | | private FileService fileService; |
| | | |
| | | private final Cache<String, Map<String, T1210.Item>> cache = Caffeine.newBuilder().expireAfterAccess(20, TimeUnit.MINUTES).build(); |
| | | |
| | | @Mapping(types = JSATL12.æ¥è¦éä»¶ä¿¡æ¯æ¶æ¯, desc = "æ¥è¦éä»¶ä¿¡æ¯æ¶æ¯") |
| | | public void alarmFileInfoList(T1210 message, Session session) { |
| | | session.register(message.getDeviceId(), message); |
| | | |
| | | List<T1210.Item> items = message.getItems(); |
| | | if (items == null) return; |
| | | |
| | | Map<String, T1210.Item> fileInfos = cache.get(message.getClientId(), s -> new HashMap<>((int) (items.size() / 0.75) + 1)); |
| | | |
| | | for (T1210.Item item : items) |
| | | fileInfos.put(item.getName(), item.parent(message)); |
| | | fileService.createDir(message); |
| | | } |
| | | |
| | | @Mapping(types = JSATL12.æä»¶ä¿¡æ¯ä¸ä¼ , desc = "æä»¶ä¿¡æ¯ä¸ä¼ ") |
| | | public void alarmFileInfo(T1211 message, Session session) { |
| | | if (!session.isRegistered()) session.register(message); |
| | | } |
| | | |
| | | @Mapping(types = JSATL12.æä»¶æ°æ®ä¸ä¼ , desc = "æä»¶æ°æ®ä¸ä¼ ") |
| | | public Object alarmFile(DataPacket dataPacket, Session session) { |
| | | Map<String, T1210.Item> fileInfos = cache.getIfPresent(session.getClientId()); |
| | | if (fileInfos != null) { |
| | | |
| | | T1210.Item fileInfo = fileInfos.get(dataPacket.getName().trim()); |
| | | if (fileInfo != null) { |
| | | |
| | | if (dataPacket.getOffset() == 0 && dataPacket.getLength() >= fileInfo.getSize()) { |
| | | fileService.writeFileSingle(fileInfo.parent(), dataPacket); |
| | | } else { |
| | | fileService.writeFile(fileInfo.parent(), dataPacket); |
| | | } |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | @Mapping(types = JSATL12.æä»¶ä¸ä¼ å®ææ¶æ¯, desc = "æä»¶ä¸ä¼ å®ææ¶æ¯") |
| | | public T9212 alarmFileComplete(T1211 message) { |
| | | Map<String, T1210.Item> fileInfos = cache.getIfPresent(message.getClientId()); |
| | | T1210.Item fileInfo = fileInfos.get(message.getName()); |
| | | T9212 result = new T9212(); |
| | | result.setName(message.getName()); |
| | | result.setType(message.getType()); |
| | | |
| | | int[] items = fileService.checkFile(fileInfo.parent(), message); |
| | | if (items == null) { |
| | | fileInfos.remove(message.getName()); |
| | | if (fileInfos.isEmpty()) { |
| | | cache.invalidate(message.getClientId()); |
| | | } |
| | | result.setResult(0); |
| | | } else { |
| | | result.setItems(items); |
| | | result.setResult(1); |
| | | } |
| | | return result; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.endpoint; |
| | | |
| | | import io.github.yezhihao.netmc.core.annotation.Endpoint; |
| | | import io.github.yezhihao.netmc.core.annotation.Mapping; |
| | | import io.github.yezhihao.netmc.session.Session; |
| | | import org.springframework.stereotype.Component; |
| | | import org.yzh.protocol.t1078.T1003; |
| | | import org.yzh.protocol.t1078.T1005; |
| | | import org.yzh.protocol.t1078.T1205; |
| | | import org.yzh.protocol.t1078.T1206; |
| | | |
| | | import static org.yzh.protocol.commons.JT1078.*; |
| | | |
| | | @Endpoint |
| | | @Component |
| | | public class JT1078Endpoint { |
| | | |
| | | @Mapping(types = ç»ç«¯ä¸ä¼ é³è§é¢èµæºå表, desc = "ç»ç«¯ä¸ä¼ é³è§é¢èµæºå表") |
| | | public void T1205(T1205 message, Session session) { |
| | | session.response(message); |
| | | } |
| | | |
| | | @Mapping(types = ç»ç«¯ä¸ä¼ é³è§é¢å±æ§, desc = "ç»ç«¯ä¸ä¼ é³è§é¢å±æ§") |
| | | public void T1003(T1003 message, Session session) { |
| | | session.response(message); |
| | | } |
| | | |
| | | @Mapping(types = æä»¶ä¸ä¼ 宿éç¥, desc = "æä»¶ä¸ä¼ 宿éç¥") |
| | | public void T1206(T1206 message, Session session) { |
| | | session.response(message); |
| | | } |
| | | |
| | | @Mapping(types = ç»ç«¯ä¸ä¼ ä¹å®¢æµé, desc = "ç»ç«¯ä¸ä¼ ä¹å®¢æµé") |
| | | public void T1005(T1005 message, Session session) { |
| | | |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.endpoint; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.doumee.core.utils.DateUtil; |
| | | import com.doumee.dao.business.model.Bikes; |
| | | import com.doumee.service.business.BikesService; |
| | | import io.github.yezhihao.netmc.core.annotation.Async; |
| | | import io.github.yezhihao.netmc.core.annotation.AsyncBatch; |
| | | import io.github.yezhihao.netmc.core.annotation.Endpoint; |
| | | import io.github.yezhihao.netmc.core.annotation.Mapping; |
| | | import io.github.yezhihao.netmc.session.Session; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | import org.yzh.protocol.basics.JTMessage; |
| | | import org.yzh.protocol.commons.JT808; |
| | | import org.yzh.protocol.commons.transform.AttributeKey; |
| | | import org.yzh.protocol.commons.transform.attribute.Battery; |
| | | import org.yzh.protocol.t808.*; |
| | | import com.doumee.jtt808.web.model.entity.DeviceDO; |
| | | import com.doumee.jtt808.web.model.enums.SessionKey; |
| | | import com.doumee.jtt808.web.service.FileService; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.time.ZoneOffset; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | import static org.yzh.protocol.commons.JT808.*; |
| | | |
| | | @Endpoint |
| | | @Component |
| | | public class JT808Endpoint { |
| | | |
| | | @Autowired |
| | | private BikesService bikesService; |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(JT808Endpoint.class); |
| | | |
| | | @Autowired |
| | | private FileService fileService; |
| | | |
| | | @Mapping(types = ç»ç«¯éç¨åºç, desc = "ç»ç«¯éç¨åºç") |
| | | public Object T0001(T0001 message, Session session) { |
| | | session.response(message); |
| | | return null; |
| | | } |
| | | |
| | | @Mapping(types = ç»ç«¯å¿è·³, desc = "ç»ç«¯å¿è·³") |
| | | public void T0002(JTMessage message, Session session) { |
| | | log.info("ç»ç«¯å¿è·³========={}", JSONObject.toJSONString(message)); |
| | | } |
| | | |
| | | @Mapping(types = ç»ç«¯æ³¨é, desc = "ç»ç«¯æ³¨é") |
| | | public void T0003(JTMessage message, Session session) { |
| | | session.invalidate(); |
| | | } |
| | | |
| | | @Mapping(types = æ¥è¯¢æå¡å¨æ¶é´, desc = "æ¥è¯¢æå¡å¨æ¶é´") |
| | | public T8004 T0004(JTMessage message, Session session) { |
| | | T8004 result = new T8004(LocalDateTime.now(ZoneOffset.UTC)); |
| | | return result; |
| | | } |
| | | |
| | | @Mapping(types = ç»ç«¯è¡¥ä¼ åå
请æ±, desc = "ç»ç«¯è¡¥ä¼ åå
请æ±") |
| | | public void T8003(T8003 message, Session session) { |
| | | } |
| | | @Mapping(types = ç»ç«¯æ ¡æ¶è¯·æ±ä¸è¡, desc = "ç»ç«¯æ ¡æ¶è¯·æ±ä¸è¡") |
| | | public void T0F01(JTMessage message, Session session) { |
| | | } |
| | | |
| | | @Mapping(types = ç»ç«¯æ³¨å, desc = "ç»ç«¯æ³¨å") |
| | | public T8100 T0100(T0100 message, Session session) { |
| | | session.register(message); |
| | | DeviceDO device = new DeviceDO(); |
| | | device.setProtocolVersion(message.getProtocolVersion()); |
| | | device.setMobileNo(message.getClientId()); |
| | | device.setDeviceId(message.getDeviceId()); |
| | | device.setPlateNo(message.getPlateNo()); |
| | | session.setAttribute(SessionKey.Device, device); |
| | | T8100 result = new T8100(); |
| | | result.setResponseSerialNo(message.getSerialNo()); |
| | | result.setToken(message.getDeviceId() + "," + message.getPlateNo()); |
| | | result.setResultCode(T8100.Success); |
| | | return result; |
| | | } |
| | | |
| | | @Mapping(types = ç»ç«¯é´æ, desc = "ç»ç«¯é´æ") |
| | | public T0001 T0102(T0102 message, Session session) { |
| | | session.register(message); |
| | | DeviceDO device = new DeviceDO(); |
| | | String[] token = message.getToken().split(","); |
| | | device.setProtocolVersion(message.getProtocolVersion()); |
| | | device.setMobileNo(message.getClientId()); |
| | | device.setDeviceId(token[0]); |
| | | if (token.length > 1) |
| | | device.setPlateNo(token[1]); |
| | | session.setAttribute(SessionKey.Device, device); |
| | | |
| | | T0001 result = new T0001(); |
| | | result.setResponseSerialNo(message.getSerialNo()); |
| | | result.setResponseMessageId(message.getMessageId()); |
| | | result.setResultCode(T0001.Success); |
| | | return result; |
| | | } |
| | | |
| | | @Mapping(types = æ¥è¯¢ç»ç«¯åæ°åºç, desc = "æ¥è¯¢ç»ç«¯åæ°åºç") |
| | | public void T0104(T0104 message, Session session) { |
| | | session.response(message); |
| | | } |
| | | |
| | | @Mapping(types = æ¥è¯¢ç»ç«¯å±æ§åºç, desc = "æ¥è¯¢ç»ç«¯å±æ§åºç") |
| | | public void T0107(T0107 message, Session session) { |
| | | log.info("æ¥è¯¢ç»ç«¯å±æ§åºç========={}", JSONObject.toJSONString(message)); |
| | | session.response(message); |
| | | } |
| | | |
| | | @Mapping(types = ç»ç«¯åçº§ç»æéç¥, desc = "ç»ç«¯åçº§ç»æéç¥") |
| | | public void T0108(T0108 message, Session session) { |
| | | } |
| | | |
| | | /** |
| | | * 弿¥æ¹éå¤ç |
| | | * poolSizeï¼åèæ°æ®åºCPUæ ¸å¿æ°é |
| | | * maxElementsï¼æå¤§ç´¯ç§¯4000æ¡è®°å½å¤ç䏿¬¡ |
| | | * maxWaitï¼æå¤§çå¾
æ¶é´1ç§ |
| | | */ |
| | | @AsyncBatch(poolSize = 2, maxElements = 4000, maxWait = 1000) |
| | | @Mapping(types = ä½ç½®ä¿¡æ¯æ±æ¥, desc = "ä½ç½®ä¿¡æ¯æ±æ¥") |
| | | public void T0200(List<T0200> list) { |
| | | for(T0200 m : list){ |
| | | Bikes bike = new Bikes(); |
| | | bike.setDeviceSn(m.getClientId()); |
| | | if(m.getLatitude()!=0){ |
| | | bike.setLatitude(new BigDecimal(m.getLatitude()).divide(new BigDecimal(1000000),2,BigDecimal.ROUND_HALF_UP)); |
| | | } |
| | | if(m.getLongitude()!=0){ |
| | | bike.setLongitude(new BigDecimal(m.getLongitude()).divide(new BigDecimal(1000000),2,BigDecimal.ROUND_HALF_UP)); |
| | | } |
| | | bike.setHeartDate(DateUtil.getDateFromLocalDateTime(m.getDeviceTime())); |
| | | if(m.getAttributes()!=null ){ |
| | | Battery battery= (Battery) m.getAttributes().get(AttributeKey.Battery); |
| | | if(battery !=null && battery.getVoltage()!=null){ |
| | | bike.setVoltage(new BigDecimal(battery.getVoltage())); |
| | | } |
| | | } |
| | | bikesService.updateByJtt(bike); |
| | | } |
| | | System.out.println(JSONObject.toJSONString(list) |
| | | ); |
| | | } |
| | | |
| | | @Mapping(types = å®ä½æ°æ®æ¹éä¸ä¼ , desc = "å®ä½æ°æ®æ¹éä¸ä¼ ") |
| | | public void T0704(T0704 message) { |
| | | } |
| | | public static String bcd2String(byte[] bytes) { |
| | | StringBuilder temp = new StringBuilder(bytes.length * 2); |
| | | for (int i = 0; i < bytes.length; i++) { |
| | | // é«åä½ |
| | | temp.append((bytes[i] & 0xf0) >>> 4); |
| | | // ä½åä½ |
| | | temp.append(bytes[i] & 0x0f); |
| | | } |
| | | return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp.toString().substring(1) : temp.toString(); |
| | | } |
| | | |
| | | @Mapping(types = {ä½ç½®ä¿¡æ¯æ¥è¯¢åºç, è½¦è¾æ§å¶åºç}, desc = "ä½ç½®ä¿¡æ¯æ¥è¯¢åºç/è½¦è¾æ§å¶åºç") |
| | | public void T0201_0500(T0201_0500 message, Session session) { |
| | | session.response(message); |
| | | } |
| | | |
| | | @Mapping(types = äºä»¶æ¥å, desc = "äºä»¶æ¥å") |
| | | public void T0301(T0301 message, Session session) { |
| | | } |
| | | |
| | | @Mapping(types = æé®åºç, desc = "æé®åºç") |
| | | public void T0302(T0302 message, Session session) { |
| | | } |
| | | |
| | | @Mapping(types = ä¿¡æ¯ç¹æ_åæ¶, desc = "ä¿¡æ¯ç¹æ/åæ¶") |
| | | public void T0303(T0303 message, Session session) { |
| | | } |
| | | |
| | | @Mapping(types = æ¥è¯¢åºåæçº¿è·¯æ°æ®åºç, desc = "æ¥è¯¢åºåæçº¿è·¯æ°æ®åºç") |
| | | public void T0608(T0608 message, Session session) { |
| | | session.response(message); |
| | | } |
| | | |
| | | @Mapping(types = è¡é©¶è®°å½æ°æ®ä¸ä¼ , desc = "è¡é©¶è®°å½ä»ªæ°æ®ä¸ä¼ ") |
| | | public void T0700(T0700 message, Session session) { |
| | | session.response(message); |
| | | } |
| | | |
| | | @Mapping(types = çµåè¿å䏿¥, desc = "çµåè¿å䏿¥") |
| | | public void T0701(JTMessage message, Session session) { |
| | | } |
| | | |
| | | @Mapping(types = 驾驶å身份信æ¯éé䏿¥, desc = "驾驶å身份信æ¯éé䏿¥") |
| | | public void T0702(T0702 message, Session session) { |
| | | session.response(message); |
| | | } |
| | | |
| | | @Mapping(types = CANæ»çº¿æ°æ®ä¸ä¼ , desc = "CANæ»çº¿æ°æ®ä¸ä¼ ") |
| | | public void T0705(T0705 message, Session session) { |
| | | } |
| | | |
| | | @Mapping(types = å¤åªä½äºä»¶ä¿¡æ¯ä¸ä¼ , desc = "å¤åªä½äºä»¶ä¿¡æ¯ä¸ä¼ ") |
| | | public void T0800(T0800 message, Session session) { |
| | | } |
| | | |
| | | @Async |
| | | @Mapping(types = å¤åªä½æ°æ®ä¸ä¼ , desc = "å¤åªä½æ°æ®ä¸ä¼ ") |
| | | public JTMessage T0801(T0801 message, Session session) { |
| | | if (message.getPacket() == null) { |
| | | T0001 result = new T0001(); |
| | | result.copyBy(message); |
| | | result.setMessageId(JT808.å¹³å°éç¨åºç); |
| | | result.setSerialNo(session.nextSerialNo()); |
| | | |
| | | result.setResponseSerialNo(message.getSerialNo()); |
| | | result.setResponseMessageId(message.getMessageId()); |
| | | result.setResultCode(T0001.Success); |
| | | return result; |
| | | } |
| | | fileService.saveMediaFile(message); |
| | | T8800 result = new T8800(); |
| | | result.setMediaId(message.getId()); |
| | | return result; |
| | | } |
| | | |
| | | @Mapping(types = åå¨å¤åªä½æ°æ®æ£ç´¢åºç, desc = "åå¨å¤åªä½æ°æ®æ£ç´¢åºç") |
| | | public void T0802(T0802 message, Session session) { |
| | | session.response(message); |
| | | } |
| | | |
| | | @Mapping(types = æå头ç«å³ææå½ä»¤åºç, desc = "æå头ç«å³ææå½ä»¤åºç") |
| | | public void T0805(T0805 message, Session session) { |
| | | session.response(message); |
| | | } |
| | | |
| | | @Mapping(types = æ°æ®ä¸è¡éä¼ , desc = "æ°æ®ä¸è¡éä¼ ") |
| | | public void T0900(T0900 message, Session session) { |
| | | } |
| | | |
| | | @Mapping(types = æ°æ®åç¼©ä¸æ¥, desc = "æ°æ®åç¼©ä¸æ¥") |
| | | public void T0901(T0901 message, Session session) { |
| | | } |
| | | |
| | | @Mapping(types = ç»ç«¯RSAå
¬é¥, desc = "ç»ç«¯RSAå
¬é¥") |
| | | public void T0A00(T0A00_8A00 message, Session session) { |
| | | session.response(message); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.endpoint; |
| | | |
| | | import io.github.yezhihao.netmc.core.HandlerInterceptor; |
| | | import io.github.yezhihao.netmc.session.Session; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.yzh.protocol.basics.JTMessage; |
| | | import org.yzh.protocol.commons.JT808; |
| | | import org.yzh.protocol.commons.transform.AttributeKey; |
| | | import org.yzh.protocol.commons.transform.attribute.Battery; |
| | | import org.yzh.protocol.t808.T0001; |
| | | import org.yzh.protocol.t808.T0200; |
| | | import com.doumee.jtt808.web.model.entity.DeviceDO; |
| | | import com.doumee.jtt808.web.model.enums.SessionKey; |
| | | |
| | | public class JTHandlerInterceptor implements HandlerInterceptor<JTMessage> { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(JTHandlerInterceptor.class); |
| | | |
| | | /** æªæ¾å°å¯¹åºçHandle */ |
| | | @Override |
| | | public JTMessage notSupported(JTMessage request, Session session) { |
| | | T0001 response = new T0001(); |
| | | response.copyBy(request); |
| | | response.setMessageId(JT808.å¹³å°éç¨åºç); |
| | | response.setSerialNo(session.nextSerialNo()); |
| | | |
| | | response.setResponseSerialNo(request.getSerialNo()); |
| | | response.setResponseMessageId(request.getMessageId()); |
| | | response.setResultCode(T0001.NotSupport); |
| | | |
| | | log.info("{}\n<<<<-æªè¯å«çæ¶æ¯{}\n>>>>-{}", session, request, response); |
| | | return response; |
| | | } |
| | | |
| | | |
| | | /** è°ç¨ä¹åï¼è¿åå¼ä¸ºvoidç */ |
| | | @Override |
| | | public JTMessage successful(JTMessage request, Session session) { |
| | | T0001 response = new T0001(); |
| | | response.copyBy(request); |
| | | response.setMessageId(JT808.å¹³å°éç¨åºç); |
| | | response.setSerialNo(session.nextSerialNo()); |
| | | |
| | | response.setResponseSerialNo(request.getSerialNo()); |
| | | response.setResponseMessageId(request.getMessageId()); |
| | | response.setResultCode(T0001.Success); |
| | | log.info(session.getId()); |
| | | // log.info("{}\n<<<<-{}\n>>>>-{}", session, request, response); |
| | | return response; |
| | | } |
| | | |
| | | /** è°ç¨ä¹åæåºå¼å¸¸ç */ |
| | | @Override |
| | | public JTMessage exceptional(JTMessage request, Session session, Exception e) { |
| | | T0001 response = new T0001(); |
| | | response.copyBy(request); |
| | | response.setMessageId(JT808.å¹³å°éç¨åºç); |
| | | response.setSerialNo(session.nextSerialNo()); |
| | | |
| | | response.setResponseSerialNo(request.getSerialNo()); |
| | | response.setResponseMessageId(request.getMessageId()); |
| | | response.setResultCode(T0001.Failure); |
| | | |
| | | log.warn(session + "\n<<<<-" + request + "\n>>>>-" + response + '\n', e); |
| | | return response; |
| | | } |
| | | |
| | | /** è°ç¨ä¹å */ |
| | | @Override |
| | | public boolean beforeHandle(JTMessage request, Session session) { |
| | | int messageId = request.getMessageId(); |
| | | if (messageId == JT808.ç»ç«¯æ³¨å || messageId == JT808.ç»ç«¯é´æ) |
| | | return true; |
| | | boolean transform = request.transform(); |
| | | if (messageId == JT808.ä½ç½®ä¿¡æ¯æ±æ¥) { |
| | | DeviceDO device = SessionKey.getDevice(session); |
| | | if (device != null){ |
| | | device.setLocation((T0200) request); |
| | | if(device.getLocation()!=null && device.getLocation().getAttributes()!=null ){ |
| | | Battery battery= (Battery) device.getLocation().getAttributes().get(AttributeKey.Battery); |
| | | if(battery !=null){ |
| | | device.setBatteryVoltage(battery.getVoltage()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return transform; |
| | | } |
| | | if (!session.isRegistered()) { |
| | | log.info("{}æªæ³¨åç设å¤<<<<-{}", session, request); |
| | | return true; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** è°ç¨ä¹å */ |
| | | @Override |
| | | public void afterHandle(JTMessage request, JTMessage response, Session session) { |
| | | if (response != null) { |
| | | response.copyBy(request); |
| | | response.setSerialNo(session.nextSerialNo()); |
| | | |
| | | if (response.getMessageId() == 0) { |
| | | response.setMessageId(response.reflectMessageId()); |
| | | } |
| | | } |
| | | // log.info("{}\n<<<<-{}\n>>>>-{}", session, request, response); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.endpoint; |
| | | |
| | | import io.github.yezhihao.netmc.session.Session; |
| | | import org.yzh.protocol.codec.MultiPacket; |
| | | import org.yzh.protocol.codec.MultiPacketListener; |
| | | import org.yzh.protocol.commons.JT808; |
| | | import org.yzh.protocol.t808.T8003; |
| | | |
| | | import java.util.List; |
| | | |
| | | public class JTMultiPacketListener extends MultiPacketListener { |
| | | |
| | | public JTMultiPacketListener(int timeout) { |
| | | super(timeout); |
| | | } |
| | | |
| | | @Override |
| | | public boolean receiveTimeout(MultiPacket multiPacket) { |
| | | int retryCount = multiPacket.getRetryCount(); |
| | | if (retryCount > 5) |
| | | return false; |
| | | |
| | | T8003 request = new T8003(); |
| | | request.setMessageId(JT808.æå¡å¨è¡¥ä¼ åå
请æ±); |
| | | request.copyBy(multiPacket.getFirstPacket()); |
| | | request.setResponseSerialNo(multiPacket.getSerialNo()); |
| | | List<Integer> notArrived = multiPacket.getNotArrived(); |
| | | short[] idList = new short[notArrived.size()]; |
| | | for (int i = 0; i < idList.length; i++) { |
| | | idList[i] = notArrived.get(i).shortValue(); |
| | | } |
| | | request.setId(idList); |
| | | Session session = multiPacket.getFirstPacket().getSession(); |
| | | if (session != null) { |
| | | session.notify(request).block(); |
| | | multiPacket.addRetryCount(1); |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.endpoint; |
| | | |
| | | import io.github.yezhihao.netmc.core.model.Message; |
| | | import io.github.yezhihao.netmc.session.Session; |
| | | import io.github.yezhihao.netmc.session.SessionListener; |
| | | import org.yzh.protocol.basics.JTMessage; |
| | | import com.doumee.jtt808.web.model.entity.DeviceDO; |
| | | import com.doumee.jtt808.web.model.enums.SessionKey; |
| | | |
| | | import java.util.function.BiConsumer; |
| | | |
| | | public class JTSessionListener implements SessionListener { |
| | | |
| | | /** |
| | | * ä¸è¡æ¶æ¯æ¦æªå¨ |
| | | */ |
| | | private static final BiConsumer<Session, Message> requestInterceptor = (session, message) -> { |
| | | JTMessage request = (JTMessage) message; |
| | | request.setClientId(session.getClientId()); |
| | | request.setSerialNo(session.nextSerialNo()); |
| | | |
| | | if (request.getMessageId() == 0) { |
| | | request.setMessageId(request.reflectMessageId()); |
| | | } |
| | | |
| | | DeviceDO device = SessionKey.getDevice(session); |
| | | if (device != null) { |
| | | int protocolVersion = device.getProtocolVersion(); |
| | | if (protocolVersion > 0) { |
| | | request.setVersion(true); |
| | | request.setProtocolVersion(protocolVersion); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * 设å¤è¿æ¥ |
| | | */ |
| | | @Override |
| | | public void sessionCreated(Session session) { |
| | | session.requestInterceptor(requestInterceptor); |
| | | } |
| | | |
| | | /** |
| | | * è®¾å¤æ³¨å |
| | | */ |
| | | @Override |
| | | public void sessionRegistered(Session session) { |
| | | } |
| | | |
| | | /** |
| | | * 设å¤ç¦»çº¿ |
| | | */ |
| | | @Override |
| | | public void sessionDestroyed(Session session) { |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.endpoint; |
| | | |
| | | import io.github.yezhihao.netmc.session.Session; |
| | | import io.github.yezhihao.netmc.session.SessionManager; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.stereotype.Component; |
| | | import org.yzh.commons.model.APIException; |
| | | import org.yzh.commons.model.APIResult; |
| | | import org.yzh.protocol.basics.JTMessage; |
| | | import reactor.core.publisher.Mono; |
| | | |
| | | import java.time.Duration; |
| | | |
| | | /** |
| | | * @author yezhihao |
| | | * https://gitee.com/yezhihao/jt808-server |
| | | */ |
| | | @Component |
| | | public class MessageManager { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(MessageManager.class); |
| | | |
| | | private static final Mono<Void> NEVER = Mono.never(); |
| | | private static final Mono OFFLINE_EXCEPTION = Mono.error(new APIException(4000, "离线ç客æ·ç«¯ï¼è¯·æ£æ¥è®¾å¤æ¯å¦æ³¨åæè
é´æï¼")); |
| | | private static final Mono OFFLINE_RESULT = Mono.just(new APIResult<>(4000, "离线ç客æ·ç«¯ï¼è¯·æ£æ¥è®¾å¤æ¯å¦æ³¨åæè
é´æï¼")); |
| | | private static final Mono SENDFAIL_RESULT = Mono.just(new APIResult<>(4001, "æ¶æ¯åé失败")); |
| | | private static final Mono TIMEOUT_RESULT = Mono.just(new APIResult<>(4002, "æ¶æ¯åéæå,客æ·ç«¯ååºè¶
æ¶ï¼è³äºè®¾å¤ä¸ºä»ä¹ä¸åºçï¼è¯·è系设å¤ååï¼")); |
| | | |
| | | private SessionManager sessionManager; |
| | | |
| | | public MessageManager(SessionManager sessionManager) { |
| | | this.sessionManager = sessionManager; |
| | | } |
| | | |
| | | public Mono<Void> notifyR(String sessionId, JTMessage request) { |
| | | Session session = sessionManager.get(sessionId); |
| | | if (session == null) |
| | | return OFFLINE_EXCEPTION; |
| | | |
| | | return session.notify(request); |
| | | } |
| | | |
| | | public Mono<Void> notify(String sessionId, JTMessage request) { |
| | | Session session = sessionManager.get(sessionId); |
| | | if (session == null) |
| | | return NEVER; |
| | | |
| | | return session.notify(request); |
| | | } |
| | | |
| | | public <T> Mono<APIResult<T>> requestR(String sessionId, JTMessage request, Class<T> responseClass) { |
| | | Session session = sessionManager.get(sessionId); |
| | | if (session == null) |
| | | return OFFLINE_RESULT; |
| | | |
| | | return session.request(request, responseClass) |
| | | .map(message -> APIResult.ok(message)) |
| | | .timeout(Duration.ofSeconds(10), TIMEOUT_RESULT) |
| | | .onErrorResume(e -> { |
| | | log.warn("æ¶æ¯åé失败", e); |
| | | return SENDFAIL_RESULT; |
| | | }); |
| | | } |
| | | |
| | | public <T> Mono<APIResult<T>> requestR(JTMessage request, Class<T> responseClass) { |
| | | Session session = sessionManager.get(request.getClientId()); |
| | | if (session == null) |
| | | return OFFLINE_RESULT; |
| | | |
| | | return session.request(request, responseClass) |
| | | .map(message -> APIResult.ok(message) |
| | | ) |
| | | .timeout(Duration.ofSeconds(10), TIMEOUT_RESULT) |
| | | .onErrorResume(e -> { |
| | | log.warn("æ¶æ¯åé失败", e); |
| | | return SENDFAIL_RESULT; |
| | | }); |
| | | } |
| | | |
| | | public <T> Mono<T> request(String sessionId, JTMessage request, Class<T> responseClass, long timeout) { |
| | | return request(sessionId, request, responseClass).timeout(Duration.ofMillis(timeout)); |
| | | } |
| | | |
| | | public <T> Mono<T> request(String sessionId, JTMessage request, Class<T> responseClass) { |
| | | Session session = sessionManager.get(sessionId); |
| | | if (session == null) |
| | | return OFFLINE_EXCEPTION; |
| | | |
| | | return session.request(request, responseClass); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.model.entity; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import org.yzh.protocol.t808.T0200; |
| | | |
| | | import java.util.Objects; |
| | | |
| | | @Data |
| | | public class DeviceDO { |
| | | |
| | | @Schema(description = "设å¤id") |
| | | private String deviceId; |
| | | @Schema(description = "è®¾å¤ææºå·") |
| | | private String mobileNo; |
| | | @Schema(description = "车çå·") |
| | | private String plateNo; |
| | | @Schema(description = "æºæid") |
| | | protected int agencyId; |
| | | @Schema(description = "叿ºid") |
| | | protected int driverId; |
| | | @Schema(description = "åè®®çæ¬å·") |
| | | private int protocolVersion; |
| | | @Schema(description = "çµæ± çµå") |
| | | private Float batteryVoltage; |
| | | @Schema(description = "宿¶ç¶æ") |
| | | private T0200 location; |
| | | |
| | | public DeviceDO() { |
| | | } |
| | | |
| | | public String getDeviceId() { |
| | | return deviceId; |
| | | } |
| | | |
| | | public void setDeviceId(String deviceId) { |
| | | this.deviceId = deviceId; |
| | | } |
| | | |
| | | public String getMobileNo() { |
| | | return mobileNo; |
| | | } |
| | | |
| | | public void setMobileNo(String mobileNo) { |
| | | this.mobileNo = mobileNo; |
| | | } |
| | | |
| | | public String getPlateNo() { |
| | | return plateNo; |
| | | } |
| | | |
| | | public void setPlateNo(String plateNo) { |
| | | this.plateNo = plateNo; |
| | | } |
| | | |
| | | public int getProtocolVersion() { |
| | | return protocolVersion; |
| | | } |
| | | |
| | | public void setProtocolVersion(int protocolVersion) { |
| | | this.protocolVersion = protocolVersion; |
| | | } |
| | | |
| | | public T0200 getLocation() { |
| | | return location; |
| | | } |
| | | |
| | | public void setLocation(T0200 location) { |
| | | this.location = location; |
| | | } |
| | | |
| | | public DeviceDO mobileNo(String mobileNo) { |
| | | this.mobileNo = mobileNo; |
| | | return this; |
| | | } |
| | | |
| | | @Override |
| | | public boolean equals(Object that) { |
| | | if (this == that) { |
| | | return true; |
| | | } |
| | | if (that == null) { |
| | | return false; |
| | | } |
| | | if (getClass() != that.getClass()) { |
| | | return false; |
| | | } |
| | | DeviceDO other = (DeviceDO) that; |
| | | return Objects.equals(this.deviceId, other.deviceId); |
| | | } |
| | | |
| | | @Override |
| | | public int hashCode() { |
| | | return ((deviceId == null) ? 0 : deviceId.hashCode()); |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | final StringBuilder sb = new StringBuilder(256); |
| | | sb.append("DeviceDO{deviceId=").append(deviceId); |
| | | sb.append(", mobileNo=").append(mobileNo); |
| | | sb.append(", plateNo=").append(plateNo); |
| | | sb.append(", protocolVersion=").append(protocolVersion); |
| | | sb.append('}'); |
| | | return sb.toString(); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.model.enums; |
| | | |
| | | import io.github.yezhihao.netmc.session.Session; |
| | | import com.doumee.jtt808.web.model.entity.DeviceDO; |
| | | |
| | | /** |
| | | * @author yezhihao |
| | | * https://gitee.com/yezhihao/jt808-server |
| | | */ |
| | | public enum SessionKey { |
| | | |
| | | Device; |
| | | |
| | | public static DeviceDO getDevice(Session session) { |
| | | return (DeviceDO) session.getAttribute(Device); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.model.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import org.yzh.protocol.commons.Charsets; |
| | | |
| | | import java.io.*; |
| | | import java.time.LocalDate; |
| | | |
| | | import static io.github.yezhihao.protostar.util.DateTool.BCD; |
| | | |
| | | /** |
| | | * @author yezhihao |
| | | * https://gitee.com/yezhihao/jt808-server |
| | | */ |
| | | public class DeviceInfo { |
| | | |
| | | @Schema(description = "ç¾åæ¥æ") |
| | | protected LocalDate issuedAt; |
| | | @Schema(description = "é¢çåæ®µ") |
| | | protected byte reserved; |
| | | @Schema(description = "设å¤id") |
| | | protected String deviceId; |
| | | |
| | | public DeviceInfo() { |
| | | } |
| | | |
| | | public DeviceInfo(byte[] bytes) { |
| | | formBytes(bytes); |
| | | } |
| | | |
| | | public DeviceInfo(String deviceId, LocalDate issuedAt) { |
| | | this.deviceId = deviceId; |
| | | this.issuedAt = issuedAt; |
| | | } |
| | | |
| | | public LocalDate getIssuedAt() { |
| | | return issuedAt; |
| | | } |
| | | |
| | | public void setIssuedAt(LocalDate issuedAt) { |
| | | this.issuedAt = issuedAt; |
| | | } |
| | | |
| | | public byte getReserved() { |
| | | return reserved; |
| | | } |
| | | |
| | | public void setReserved(byte reserved) { |
| | | this.reserved = reserved; |
| | | } |
| | | |
| | | public String getDeviceId() { |
| | | return deviceId; |
| | | } |
| | | |
| | | public void setDeviceId(String deviceId) { |
| | | this.deviceId = deviceId; |
| | | } |
| | | |
| | | public DeviceInfo formBytes(byte[] bytes) { |
| | | try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes); |
| | | DataInputStream dis = new DataInputStream(bis)) { |
| | | |
| | | byte[] temp; |
| | | dis.read(temp = new byte[3]); |
| | | this.issuedAt = BCD.toDate(temp); |
| | | this.reserved = dis.readByte(); |
| | | int len = dis.readUnsignedByte(); |
| | | dis.read(temp = new byte[len]); |
| | | this.deviceId = new String(temp, Charsets.GBK); |
| | | |
| | | return this; |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | public byte[] toBytes() { |
| | | try (ByteArrayOutputStream bos = new ByteArrayOutputStream(32); |
| | | DataOutputStream dos = new DataOutputStream(bos)) { |
| | | |
| | | dos.write(BCD.from(issuedAt)); |
| | | dos.writeByte(reserved); |
| | | byte[] bytes = deviceId.getBytes(Charsets.GBK); |
| | | dos.writeByte(bytes.length); |
| | | dos.write(bytes); |
| | | |
| | | return bos.toByteArray(); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | final StringBuilder sb = new StringBuilder("DeviceInfo{"); |
| | | sb.append("issuedAt=").append(issuedAt); |
| | | sb.append(", reserved=").append(reserved); |
| | | sb.append(", deviceId=").append(deviceId); |
| | | sb.append('}'); |
| | | return sb.toString(); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.doumee.jtt808.web.service; |
| | | |
| | | import io.netty.buffer.ByteBuf; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Service; |
| | | import org.yzh.commons.util.DateUtils; |
| | | import org.yzh.commons.util.IOUtils; |
| | | import org.yzh.commons.util.StrUtils; |
| | | import org.yzh.protocol.jsatl12.DataPacket; |
| | | import org.yzh.protocol.jsatl12.T1210; |
| | | import org.yzh.protocol.jsatl12.T1211; |
| | | import org.yzh.protocol.t808.T0200; |
| | | import org.yzh.protocol.t808.T0801; |
| | | import com.doumee.jtt808.web.model.entity.DeviceDO; |
| | | import com.doumee.jtt808.web.model.enums.SessionKey; |
| | | |
| | | import java.io.*; |
| | | import java.nio.ByteBuffer; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.Comparator; |
| | | import java.util.List; |
| | | |
| | | |
| | | @Service |
| | | public class FileService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(FileService.class.getSimpleName()); |
| | | |
| | | private static final Comparator<long[]> comparator = Comparator.comparingLong((long[] a) -> a[0]).thenComparingLong(a -> a[1]); |
| | | |
| | | @Value("${jt-server.alarm-file.path}") |
| | | private String workDirPath; |
| | | |
| | | @Value("${jt-server.jt808.media-file.path}") |
| | | private String mediaFileRoot; |
| | | |
| | | private String getDir(T1210 alarmId) { |
| | | StringBuilder sb = new StringBuilder(80); |
| | | sb.append(workDirPath).append('/'); |
| | | sb.append(alarmId.getClientId()).append('_'); |
| | | DateUtils.yyMMddHHmmss.formatTo(alarmId.getDateTime(), sb); |
| | | sb.append('_').append(alarmId.getSerialNo()).append('/'); |
| | | return sb.toString(); |
| | | } |
| | | |
| | | /** å建æ¥è¦ç®å½å éä»¶å表æ¥å¿ */ |
| | | public void createDir(T1210 alarmId) { |
| | | String dirPath = getDir(alarmId); |
| | | new File(dirPath).mkdirs(); |
| | | |
| | | List<T1210.Item> items = alarmId.getItems(); |
| | | StringBuilder fileList = new StringBuilder(items.size() * 50); |
| | | fileList.append(dirPath).append(IOUtils.Separator); |
| | | |
| | | for (T1210.Item item : items) |
| | | fileList.append(item.getName()).append('\t').append(item.getSize()).append(IOUtils.Separator); |
| | | |
| | | IOUtils.write(fileList.toString(), new File(dirPath, "fs.txt")); |
| | | } |
| | | |
| | | /** å°æ°æ®ååå
¥å°æ¥è¦æä»¶ï¼å¹¶è®°å½æ¥å¿ */ |
| | | public void writeFile(T1210 alarmId, DataPacket fileData) { |
| | | String dir = getDir(alarmId); |
| | | String name = dir + fileData.getName().trim(); |
| | | |
| | | int offset = fileData.getOffset(); |
| | | int length = fileData.getLength(); |
| | | |
| | | byte[] buffer = ByteBuffer.allocate(8) |
| | | .putInt(offset).putInt(length).array(); |
| | | |
| | | RandomAccessFile file = null; |
| | | FileOutputStream filelog = null; |
| | | ByteBuf data = fileData.getData(); |
| | | try { |
| | | file = new RandomAccessFile(name + ".tmp", "rw"); |
| | | filelog = new FileOutputStream(name + ".log", true); |
| | | |
| | | data.readBytes(file.getChannel(), offset, data.readableBytes()); |
| | | filelog.write(buffer); |
| | | } catch (IOException e) { |
| | | log.error("åå
¥æ¥è¦æä»¶", e); |
| | | } finally { |
| | | IOUtils.close(file, filelog); |
| | | } |
| | | } |
| | | |
| | | public void writeFileSingle(T1210 alarmId, DataPacket fileData) { |
| | | String dir = getDir(alarmId); |
| | | String name = dir + fileData.getName().trim(); |
| | | |
| | | int offset = fileData.getOffset(); |
| | | |
| | | RandomAccessFile file = null; |
| | | ByteBuf data = fileData.getData(); |
| | | try { |
| | | file = new RandomAccessFile(name, "rw"); |
| | | data.readBytes(file.getChannel(), offset, data.readableBytes()); |
| | | } catch (IOException e) { |
| | | log.error("åå
¥æ¥è¦æä»¶", e); |
| | | } finally { |
| | | IOUtils.close(file); |
| | | } |
| | | } |
| | | |
| | | /** æ ¹æ®æ¥å¿æ£æ¥æä»¶å®æ´æ§ï¼å¹¶è¿å缺å°çæ°æ®åä¿¡æ¯ */ |
| | | public int[] checkFile(T1210 alarmId, T1211 fileInfo) { |
| | | String dir = getDir(alarmId); |
| | | File logFile = new File(dir + fileInfo.getName() + ".log"); |
| | | |
| | | byte[] bytes; |
| | | FileInputStream in = null; |
| | | try { |
| | | in = new FileInputStream(logFile); |
| | | bytes = new byte[in.available()]; |
| | | in.read(bytes); |
| | | } catch (FileNotFoundException e) { |
| | | return null; |
| | | } catch (IOException e) { |
| | | log.error("æ£æ¥æä»¶å®æ´æ§", e); |
| | | return null; |
| | | } finally { |
| | | IOUtils.close(in); |
| | | } |
| | | |
| | | int size = bytes.length / 8; |
| | | long[][] items = new long[size + 2][2]; |
| | | items[size + 1][0] = fileInfo.getSize(); |
| | | |
| | | ByteBuffer buffer = ByteBuffer.wrap(bytes); |
| | | for (int i = 1; i <= size; i++) { |
| | | items[i][0] = buffer.getInt(); |
| | | items[i][1] = buffer.getInt(); |
| | | } |
| | | |
| | | List<Integer> result = new ArrayList<>(items.length); |
| | | int len = items.length - 1; |
| | | Arrays.sort(items, 1, len, comparator); |
| | | |
| | | for (int i = 0; i < len; ) { |
| | | long a = items[i][0] + items[i][1]; |
| | | long b = items[++i][0] - a; |
| | | if (b > 0) { |
| | | result.add((int) a); |
| | | result.add((int) b); |
| | | } |
| | | } |
| | | |
| | | if (result.isEmpty()) { |
| | | File file = new File(dir + fileInfo.getName() + ".tmp"); |
| | | File dest = new File(dir + fileInfo.getName()); |
| | | if (file.renameTo(dest)) { |
| | | logFile.delete(); |
| | | } |
| | | return null; |
| | | } |
| | | return StrUtils.toArray(result); |
| | | } |
| | | |
| | | /** å¤åªä½æ°æ®ä¸ä¼ */ |
| | | public boolean saveMediaFile(T0801 message) { |
| | | DeviceDO device = SessionKey.getDevice(message.getSession()); |
| | | T0200 location = message.getLocation(); |
| | | |
| | | StringBuilder filename = new StringBuilder(32); |
| | | filename.append(type(message.getType())).append('_'); |
| | | DateUtils.yyMMddHHmmss.formatTo(location.getDeviceTime(), filename); |
| | | filename.append('_'); |
| | | filename.append(message.getChannelId()).append('_'); |
| | | filename.append(message.getEvent()).append('_'); |
| | | filename.append(message.getId()).append('.'); |
| | | filename.append(suffix(message.getFormat())); |
| | | |
| | | String deviceId; |
| | | if (device == null) |
| | | deviceId = message.getClientId(); |
| | | else |
| | | deviceId = device.getDeviceId(); |
| | | |
| | | File dir = new File(mediaFileRoot + '/' + deviceId); |
| | | dir.mkdirs(); |
| | | |
| | | ByteBuf packet = message.getPacket(); |
| | | FileOutputStream fos = null; |
| | | try { |
| | | fos = new FileOutputStream(new File(dir, filename.toString())); |
| | | packet.readBytes(fos.getChannel(), 0, packet.readableBytes()); |
| | | return true; |
| | | } catch (IOException e) { |
| | | log.error("å¤åªä½æ°æ®ä¿å失败", e); |
| | | return false; |
| | | } finally { |
| | | IOUtils.close(fos); |
| | | packet.release(); |
| | | } |
| | | } |
| | | |
| | | private static String type(int type) { |
| | | switch (type) { |
| | | case 0: |
| | | return "image"; |
| | | case 1: |
| | | return "audio"; |
| | | case 2: |
| | | return "video"; |
| | | default: |
| | | return "unknown"; |
| | | } |
| | | } |
| | | |
| | | private static String suffix(int format) { |
| | | switch (format) { |
| | | case 0: |
| | | return "jpg"; |
| | | case 1: |
| | | return "tif"; |
| | | case 2: |
| | | return "mp3"; |
| | | case 3: |
| | | return "wav"; |
| | | case 4: |
| | | return "wmv"; |
| | | default: |
| | | return "bin"; |
| | | } |
| | | } |
| | | } |
| | |
| | | # application: |
| | | # name: parkbike |
| | | profiles: |
| | | active: proDev |
| | | active: dev |
| | | # JSONè¿åé
ç½® |
| | | jackson: |
| | | # é»è®¤æ¶åº |
| | |
| | | mqtt: |
| | | clientid: doumeeweb |
| | | subclientid: doumeewebSub |
| | | |
| | | jt-server: |
| | | jt808: |
| | | enable: true |
| | | port: |
| | | udp: 7611 |
| | | tcp: 7611 |
| | | media-file: |
| | | path: D:/jt_data/media_file |
| | | alarm-file: |
| | | host: 127.0.0.1 |
| | | port: 7612 |
| | | |
| | | alarm-file: |
| | | enable: true |
| | | port: 7612 |
| | | path: D:/jt_data/alarm_file |