123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419 |
- package com.js.kbt.socket;
-
- import java.math.BigDecimal;
- import java.text.ParseException;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.List;
- import javax.annotation.Resource;
- import org.apache.log4j.Logger;
- import org.springframework.stereotype.Service;
- import com.alibaba.fastjson.JSONObject;
- import com.aliyuncs.http.HttpRequest;
- import com.js.kbt.mapper.MouldHistoryMapper;
- import com.js.kbt.mapper.MouldHistoryTimeMapper;
- import com.js.kbt.mapper.TbFactoryMapper;
- import com.js.kbt.mapper.TbMouldEquipmentMapper;
- import com.js.kbt.mapper.TbMouldMapper;
- import com.js.kbt.model.MouldHistory;
- import com.js.kbt.model.MouldHistoryTime;
- import com.js.kbt.model.MouldHistoryTimeExample;
- import com.js.kbt.model.TbMould;
- import com.js.kbt.model.TbMouldEquipment;
- import com.js.kbt.model.TbMouldEquipmentExample;
- import com.js.kbt.model.TbMouldExample;
- import com.js.kbt.util.MathUtil;
- import io.netty.buffer.ByteBuf;
- import io.netty.buffer.Unpooled;
- import io.netty.channel.ChannelHandlerContext;
- import io.netty.channel.SimpleChannelInboundHandler;
- import io.netty.handler.timeout.IdleState;
- import io.netty.handler.timeout.IdleStateEvent;
- @Service("userHandler")
- public class UserHandler extends SimpleChannelInboundHandler<String> {
- private static final Logger logger = Logger.getLogger(UserHandler.class);
-
- private ChannelHandlerContext ctx;
-
- @Resource
- private MouldHistoryMapper mouldHistoryMapper;
- @Resource
- private MouldHistoryTimeMapper mouldHistoryTimeMapper;
- @Resource
- private TbMouldMapper tbMouldMapper;
- @Resource
- private TbMouldEquipmentMapper tbMouldEquipmentMapper;
- @Resource
- private TbFactoryMapper tbFactoryMapper;
-
- @Override
- protected void channelRead0(ChannelHandlerContext arg0, String arg1)
- {
- System.out.println("收到==="+arg1+"\n");
- String ret = processMsg(arg1);
- // sendMsg(ret);
- }
-
- private String processMsg(String input) {
- String ret = "FA AF 00 07 02 1e 78 1e 50 00 3C";
- logger.info("=====接收到======"+input);
- if (!input.startsWith("FAAF")) {
- logger.info("非云模盒消息,不处理");
- return ret;
- }
- MouldHistory item = new MouldHistory();
-
- //抽取手机号码
- String mobilePart = input.substring(4*2, 15*2);
- System.out.println("原始mobile="+mobilePart);
- String mobile = getStringFromHexStr(mobilePart);
- System.out.println("手机号码为"+mobile);
- item.setSim(mobile);
- //获取设备编码15-24
- String deviceNumPart = input.substring(15*2, 25*2);
- String deviceNum = getStringFromHexStr(deviceNumPart);
- System.out.println("设备No="+deviceNum);
- item.setEquipmentNo(deviceNum);
- //软件版本号25
- String version = input.substring(25*2, 26*2);
- System.out.println("软件版本号="+version);
- item.setVersion(version);
- String status = input.substring(26*2, 27*2);
- System.out.println("工作状态="+status);
- item.setStatus(Integer.decode("0x"+status).toString());
- //经度27-37
- String longitude = getStringFromHexStr(input.substring(27*2, 38*2));
- System.out.println("经度="+longitude);
- item.setLng(longitude);
- //38-47纬度以 N 开头
- String latitude = getStringFromHexStr(input.substring(38*2, 48*2));
- System.out.println("纬度="+latitude);
- item.setLat(latitude);
- System.out.println("==lac"+reverseParseHex(input.substring(48*2, 50*2)));
- System.out.println("==ci"+reverseParseHex(input.substring(50*2, 52*2)));
- item.setGprsLac(""+reverseParseHex(input.substring(48*2, 50*2)));
- item.setGprsCi(""+reverseParseHex(input.substring(50*2, 52*2)));
- item.setWifiBbsid(input.substring(52*2, 58*2));
- String temp = "0x"+input.substring(58*2, 59*2);
- System.out.println(temp);
- int i = Integer.decode(temp);
- System.out.println(i);
- item.setTemperature(i);
- item.setBattery(Integer.decode("0x"+input.substring(59*2, 60*2)));
- item.setSig2g(Integer.decode("0x"+input.substring(60*2, 61*2)));
- item.setSigNb(Integer.decode("0x"+input.substring(61*2, 62*2)));
- item.setSigWifi(Integer.decode("0x"+input.substring(62*2, 63*2)));
- item.setExt0(""+Integer.decode("0x"+input.substring(63*2, 64*2)));
- item.setAlarm(Integer.decode("0x"+input.substring(64*2, 65*2)));
- String str = input.substring(65*2, 69*2);
- item.setRunCnt(reverseParseHex(str));
-
- //根据基站lac和ci获取经纬度
- String api = "http://api.cellocation.com:81/cell/?mcc=460&mnc=0&lac="+item.getGprsLac()+"&ci="+item.getGprsCi()+"&output=json";
- String resp = com.js.kbt.util.HttpRequest.sendGet(api, null);
- JSONObject json = JSONObject.parseObject(resp);
- if (json.getInteger("errcode") == 0) {
- item.setLng(json.getDouble("lon") + "");
- item.setLat(json.getDouble("lat") + "");
- } else {
- logger.error("调用基站解析平台出错: " + resp);
- }
- String crcStr = input.substring(input.length() - 4);
- item.setCrcCode(""+reverseParseHex(crcStr));
- //存入数据库
- mouldHistoryMapper.insertSelective(item);
- //模具开合记录
- int cnt = item.getRunCnt();
- int start = 69;
- logger.info("累计开合模次数="+cnt);
- int end = input.length() - 4; //最后2位 0xXX,0xXX ,是CRC校验位
- logger.info("时间信息=="+input.substring(start*2, end));
- if (end - start*2 >= 24) {//时间最少6位,1位显示0x00,开合算两个时间,所以是6*2*2=24
- //本次运行周期内的开合模次数
- int periodCnt = (end-start*2)/24;
- logger.info("本次开合模次数=="+periodCnt);
- for (int pos=0; pos<periodCnt; pos++ ) {
- //合模时间
- MouldHistoryTime time = new MouldHistoryTime();
- time.setHistoryId(item.getId());
- time.setEquipmentNo(item.getEquipmentNo());
- time.setSeq(pos + 1);
- Date closeTime = parseDate(input, start, pos, 0);
- time.setCloseTime(closeTime);
- //开模时间
- Date openTime = parseDate(input, start, pos, 6);
- time.setOpenTime(openTime);
- int timeCost = (int) (openTime.getTime() - closeTime.getTime());
- time.setTimeCost(timeCost);
- mouldHistoryTimeMapper.insertSelective(time);
- }
- } else {
- logger.info("本次开合模次数==0");
- }
- //统计该模盒的平均开合周期
- MouldHistoryTimeExample exp = new MouldHistoryTimeExample();
- exp.createCriteria().andEquipmentNoEqualTo(item.getEquipmentNo());
- List<MouldHistoryTime> list = mouldHistoryTimeMapper.selectByExample(exp);
- int avgTime = 0;
- int totalTime = 0;
- for (MouldHistoryTime t : list) {
- totalTime += t.getTimeCost();
- }
- if (list.size() == 0) {
- avgTime = 0;
- } else {
- avgTime = totalTime / list.size();
- }
-
- handleModLogic(item, avgTime);
- return ret;
- }
-
- private void handleModLogic(MouldHistory item, int avgTime) {
- TbMouldEquipmentExample meqExp = new TbMouldEquipmentExample();
- meqExp.createCriteria().andEquipmentNoEqualTo(item.getEquipmentNo());
- if (tbMouldEquipmentMapper.countByExample(meqExp) > 0) {
- TbMouldEquipment me = tbMouldEquipmentMapper.selectByExample(meqExp).get(0);
- me.setHillNumber(item.getBattery()+"%");
- if (item.getLng() != null) {
- me.setLng(Double.parseDouble(item.getLng()));
- me.setLat(Double.parseDouble(item.getLat()));
- }
-
- me.setTemperature(item.getTemperature());
- tbMouldEquipmentMapper.updateByPrimaryKeySelective(me);
-
- TbMouldExample tExp = new TbMouldExample();
- tExp.setOrderByClause("id desc limit 1");
- tExp.createCriteria().andEquipmentIdEqualTo(me.getId());
- if (tbMouldMapper.countByExample(tExp) > 0) {
- TbMould tm = tbMouldMapper.selectByExample(tExp).get(0);
- tm.setState(item.getStatus());
- tm.setRunTimes(tm.getRunTimes() + item.getRunCnt());
-
- //处理每模平均周期(单位秒)
- BigDecimal bd = new BigDecimal(avgTime*1.00/1000);
- tm.setOcCycle(bd);
- tbMouldMapper.updateByPrimaryKeySelective(tm);
-
- //处理报警
- if (item.getAlarm() > 0) {
- /**
- * 无报警 0;
- 低电量报警 1;
- 温度过热 2;
- 安装被拆 8。
- */
- logger.info("设备报警啦:"+item.getAlarm());
- }
- }
- }
- }
-
- /**
- * 低位在前的16进制解析
- * @param rHex
- * @return
- */
- public static int reverseParseHex(String rHex) {
- int size = rHex.length()/2;
- StringBuilder sb = new StringBuilder();
- for (int i=0;i<size; i++) {
- sb.append(rHex.substring((size - i -1)*2, (size - i)*2));
- }
- String str = sb.toString();
- return Integer.parseInt(str, 16);
- }
-
- private static Date parseDate(String input, int start, int pos, int dateStartPos) {
- String year = input.substring((start+pos*6 + dateStartPos)*2, (start+pos*6 + 1 + dateStartPos)*2);
- String month = input.substring((start+pos*6+1 + dateStartPos)*2, (start+pos*6 + 2 + dateStartPos)*2);
- String day = input.substring((start+pos*6+2 + dateStartPos)*2, (start+pos*6 + 3 + dateStartPos)*2);
- String hh = input.substring((start+pos*6+3 + dateStartPos)*2, (start+pos*6 + 4 + dateStartPos)*2);
- String mm = input.substring((start+pos*6+4 + dateStartPos)*2, (start+pos*6 + 5 + dateStartPos)*2);
- String ss = input.substring((start+pos*6+5 + dateStartPos)*2, (start+pos*6 + 6 + dateStartPos)*2);
- StringBuilder sb = new StringBuilder();
- int yearInt = Integer.parseInt(year, 16);
- if (yearInt == 0) {
- sb.append("2019-01-01");
- } else {
- sb.append(yearInt < 100?"20":"2");
- sb.append(yearInt).append("-");
- int monthInt = Integer.parseInt(month, 16);
- sb.append(monthInt<10?"0":"").append(monthInt).append("-");
- int dayInt = Integer.parseInt(day, 16);
- sb.append(dayInt<10?"0":"").append(dayInt);
- }
-
- Date parseDate = null;
- try {
- parseDate = new SimpleDateFormat("yyyy-MM-dd").parse(sb.toString());
- parseDate.setHours(Integer.parseInt(hh, 16));
- parseDate.setMinutes(Integer.parseInt(mm, 16));
- parseDate.setSeconds(Integer.parseInt(ss, 16));
- } catch (ParseException e) {
- e.printStackTrace();
- }
- return parseDate;
- }
-
-
- private String getStringFromHexStr(String hexStr) {
- StringBuilder sb = new StringBuilder();
- for (int i=0;i<hexStr.length()/2; i++) {
- String str = "0x"+hexStr.substring(i*2, i*2 + 2);
- int intVal = Integer.decode(str).intValue();
- char c = (char)intVal;
- sb.append(c);
- }
- return sb.toString();
- }
-
-
- public void close() {
- ctx.close();
- }
-
- public void sendMsg(String hexString) {
- System.out.println("发送消息=="+hexString);
- byte[] buffer = hexStrToBinaryStr(hexString);
- ByteBuf bf = Unpooled.buffer(hexString.length()/2);
- bf.writeBytes(buffer);
-
- ctx.writeAndFlush(bf);
- // ctx.close();
- }
-
- /**
- * channel被激活时调用
- */
- @Override
- public void channelActive(ChannelHandlerContext ctx){
- // TODO Auto-generated method stub
- this.ctx = ctx;
- System.out.println("==========Active========="+ctx.channel().localAddress().toString()+", connection num="+HelloServer.deviceMap.size());
- }
- @Override
- public void channelInactive(ChannelHandlerContext ctx) throws Exception {
- super.channelInactive(ctx);
- System.out.println("==========Inactive=========");
- }
-
- @Override
- public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
- // TODO Auto-generated method stub
- super.handlerRemoved(ctx);
- System.out.println("[YunSu]handlerRemoved=掉线了===");
- }
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
- throws Exception {
- // TODO Auto-generated method stub
- super.exceptionCaught(ctx, cause);
- System.out.println("我捕捉到异常信息了");
- }
-
-
- @Override
- public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
- throws Exception {
- if (evt instanceof IdleStateEvent) {
- IdleStateEvent event = (IdleStateEvent) evt;
- if (event.state().equals(IdleState.READER_IDLE)) {
- } else if (event.state().equals(IdleState.WRITER_IDLE)) {
- // System.out.println("WRITER_IDLE=="+userInfo.getWxName());
- // logger.debug(ctx.channel().remoteAddress().toString()+ "WRITER_IDLE");
- // 超时关闭channel
- // ctx.close();
- } else if (event.state().equals(IdleState.ALL_IDLE)) {
- // 发送心跳
- ctx.channel().writeAndFlush("$&_".toString());
- }
- }
- // super.userEventTriggered(ctx, evt);
- }
-
- /**
- * 将十六进制的字符串转换成字节数组
- *
- * @param hexString
- * @return
- */
- public static byte[] hexStrToBinaryStr(String hexString) {
- if (hexString == null || "".contentEquals(hexString)) {
- return null;
- }
- hexString = hexString.replaceAll(" ", "");
- int len = hexString.length();
- int index = 0;
- byte[] bytes = new byte[len / 2];
- while (index < len) {
- String sub = hexString.substring(index, index + 2);
- bytes[index/2] = (byte)Integer.parseInt(sub,16);
- index += 2;
- }
- return bytes;
- }
-
- /**
- * 将字节数组转换成十六进制的字符串
- *
- * @return
- */
- public static String BinaryToHexString(byte[] bytes) {
- String hexStr = "0123456789ABCDEF";
- String result = "";
- String hex = "";
- for (byte b : bytes) {
- hex = String.valueOf(hexStr.charAt((b & 0xF0) >> 4));
- hex += String.valueOf(hexStr.charAt(b & 0x0F));
- result += hex + " ";
- }
- return result;
- }
-
- public static void main(String[] args) {
- // String str = "1F51";
- String input = "FAAF530000000000000000000000003137333030303239343310010000000000000000000000000000000000000000001F51E85F00000000000045004A54000100110000001308160F171F1308160F2D188FCA";
- // String temp = "0x"+str;
- // int i = Integer.decode(temp);
- // System.out.println(i);
- // int p = reverseParseHex(str);
- // System.out.println(p);
- // int start = 69;
- // System.out.println(str.substring(69*2));
- // Date d = parseDate(str, start, 0, 0);
- // System.out.println(d.toGMTString());
-
- int start = 69;
- int end = input.length() - 4; //最后2位 0xXX,0xXX ,是CRC校验位
- logger.info("时间信息=="+input.substring(start*2, end));
- if (end - start*2 >= 24) {//时间最少6位,1位显示0x00,开合算两个时间,所以是6*2*2=24
- //本次运行周期内的开合模次数
- int periodCnt = (end-start*2)/24;
- logger.info("本次开合模次数=="+periodCnt);
- for (int pos=0; pos<periodCnt; pos++ ) {
- //合模时间
- MouldHistoryTime time = new MouldHistoryTime();
- time.setSeq(pos + 1);
- Date closeTime = parseDate(input, start, pos, 0);
- time.setCloseTime(closeTime);
- //开模时间
- Date openTime = parseDate(input, start, pos, 6);
- time.setOpenTime(openTime);
- int timeCost = (int) (openTime.getTime() - closeTime.getTime());
- time.setTimeCost(timeCost);
- }
- } else {
- logger.info("本次开合模次数==0");
- }
- }
-
- }
|