puzhibing
2025-06-05 41c64a5680521bf1d41fa6b9caadc55feac68ca3
ruoyi-service/ruoyi-dataInterchange/src/main/java/com/ruoyi/dataInterchange/server/WarnMsgService.java
@@ -1,14 +1,17 @@
package com.ruoyi.dataInterchange.server;
import com.alibaba.fastjson.JSON;
import com.ruoyi.dataInterchange.dao.UPWarnMsgAdptInfoDao;
import com.ruoyi.dataInterchange.dao.UPWarnMsgUrgeTodoAckDao;
import com.ruoyi.dataInterchange.model.DOWNWarnMsgUrgeTodoReq;
import com.ruoyi.dataInterchange.model.UPWarnMsgAdptInfo;
import com.ruoyi.dataInterchange.model.UPWarnMsgUrgeTodoAck;
import com.ruoyi.dataInterchange.model.WarnMsg;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.dataInterchange.dao.*;
import com.ruoyi.dataInterchange.model.*;
import com.ruoyi.dataInterchange.model.enu.DataType;
import com.ruoyi.dataInterchange.netty.client.ChannelMap;
import com.ruoyi.dataInterchange.util.haikang.Artemis;
import com.ruoyi.dataInterchange.util.haikang.model.Alarm;
import com.ruoyi.dataInterchange.util.haikang.model.Event;
import com.ruoyi.dataInterchange.util.haikang.model.FindPicturesByAlarmIdRequest;
import com.ruoyi.dataInterchange.util.haikang.model.SubscriptionEvent;
import com.ruoyi.dataInterchange.util.jtt809.common.Jtt809Util;
import com.ruoyi.dataInterchange.util.jtt809.packet.common.OuterPacket;
import io.netty.buffer.ByteBuf;
@@ -18,11 +21,15 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.StringJoiner;
/**
 * @author zhibing.pu
@@ -42,12 +49,25 @@
   private UPWarnMsgAdptInfoDao upWarnMsgAdptInfoDao;
   
   @Resource
   private UPWarnMsgOperationInfoDao upWarnMsgOperationInfoDao;
   @Resource
   private UpWarnMsgFileListAckDao upWarnMsgFileListAckDao;
   @Resource
   private RedisTemplate redisTemplate;
   @Resource
   private UPExgMsgRealLocationDao upExgMsgRealLocationDao;
   //走川标的公司
   private List<Integer> enterprise = Arrays.asList(17458936, 43984060, 13914394);
   //固定报警类型
   private List<Integer> warnType = Arrays.asList(0x0201, 0x0202, 0x0301, 0x000B, 0x0012, 0x0203, 0x0208, 0x0002, 0x0211, 0x0212, 0x0214, 0x0213, 0x0215, 0x0217, 0x0307);
   
   
   public void up_warn_msg(ChannelHandlerContext ctx, OuterPacket out) {
      if (!redisTemplate.hasKey("login:" + out.getGnsscenterId())) {
         log.error("链路还未登录校验,拒绝连接");
         log.error("链路还未登录校验,拒绝连接:{}", out.getGnsscenterId());
         ctx.close();
         return;
      }
@@ -62,11 +82,18 @@
            log.info("上报报警信息({}):{}", DataType.UP_WARN_MSG_ADPT_INFO.getCode(), out);
            up_warn_msg_adpt_info(ctx, out.getGnsscenterId(), warnMsg);
            break;
         case UP_WARN_MSG_OPERATION_INFO:
            log.info("上报报警处理信息({}):{}", DataType.UP_WARN_MSG_OPERATION_INFO.getCode(), out);
            up_warn_msg_operation_info(ctx, out.getGnsscenterId(), warnMsg);
            break;
         case UP_WARN_MSG_FILELIST_ACK:
            log.info("报警附件目录请求应答({}):{}", DataType.UP_WARN_MSG_FILELIST_ACK.getCode(), out);
            up_warn_msg_filelist_ack(ctx, out.getGnsscenterId(), warnMsg);
            break;
         default:
            break;
      }
   }
   
   /**
    * 解析子业务数据
@@ -96,8 +123,7 @@
      warnMsg.setData(data);
      return warnMsg;
   }
   /**
    * 报警督办应答消息
    *
@@ -111,7 +137,7 @@
      upWarnMsgUrgeTodoAck.setCreateTime(LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)));
      upWarnMsgUrgeTodoAckDao.save(upWarnMsgUrgeTodoAck);
   }
   /**
    * 上报报警信息
    *
@@ -120,20 +146,147 @@
    * @param warnMsg
    */
   public void up_warn_msg_adpt_info(ChannelHandlerContext ctx, int inferiorPlatformId, WarnMsg warnMsg) {
      UPWarnMsgAdptInfo upWarnMsgAdptInfo = new UPWarnMsgAdptInfo().decode(warnMsg);
      UPWarnMsgAdptInfo upWarnMsgAdptInfo = enterprise.contains(inferiorPlatformId) ? new UPWarnMsgAdptInfo().decode2(warnMsg) : new UPWarnMsgAdptInfo().decode1(warnMsg);
      if(!warnType.contains(upWarnMsgAdptInfo.getWarnType())){
         return;
      }
      upWarnMsgAdptInfo.setResult(0x00);
      upWarnMsgAdptInfo.setInferiorPlatformId(inferiorPlatformId);
      upWarnMsgAdptInfo.setCreateTime(LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)));
      if(0 == upWarnMsgAdptInfo.getLongitude()){
         UPExgMsgRealLocation upExgMsgRealLocation = upExgMsgRealLocationDao.findByVehicleNoOrderByCreateTimeDesc(upWarnMsgAdptInfo.getVehicleNo());
         if (null != upExgMsgRealLocation) {
            GnssData gnssData = upExgMsgRealLocation.getGnssData();
            upWarnMsgAdptInfo.setSpeed(gnssData.getVec1());
            upWarnMsgAdptInfo.setLongitude(gnssData.getLon());
            upWarnMsgAdptInfo.setLatitude(gnssData.getLat());
         }
      }
      upWarnMsgAdptInfoDao.save(upWarnMsgAdptInfo);
      //请求报警附件(川标协议)
      if(enterprise.contains(inferiorPlatformId)){
         DOWNWarnMsgFileListReq downWarnMsgFileListReq = new DOWNWarnMsgFileListReq();
         downWarnMsgFileListReq.setVehicleNo(upWarnMsgAdptInfo.getVehicleNo());
         downWarnMsgFileListReq.setVehicleColor(upWarnMsgAdptInfo.getVehicleColor());
         downWarnMsgFileListReq.setDataType(DataType.DOWN_WARN_MSG_FILELIST_REQ.getCode());
         downWarnMsgFileListReq.setDataLength(32);
         downWarnMsgFileListReq.setInfoId(upWarnMsgAdptInfo.getInfoId());
         byte[] body = downWarnMsgFileListReq.encode();
         OuterPacket out = new OuterPacket(DataType.DOWN_WARN_MSG.getCode(), inferiorPlatformId, body);
         //获取从链路通道
         Channel channel = ChannelMap.getClientChannel(inferiorPlatformId);
         if (null != channel && channel.isActive()) {
            channel.writeAndFlush(out);
            log.info("报警附件目录请求({}):{}", DataType.DOWN_WARN_MSG_FILELIST_REQ.getCode(), JSON.toJSONString(downWarnMsgFileListReq));
         }
      }
   }
   
   
   /**
    * 定时任务督办报警请求
    * 上报报警处理信息
    * @param ctx
    * @param inferiorPlatformId
    * @param warnMsg
    */
   public void up_warn_msg_operation_info(ChannelHandlerContext ctx, int inferiorPlatformId, WarnMsg warnMsg) {
      UPWarnMsgOperationInfo upWarnMsgOperationInfo = new UPWarnMsgOperationInfo().decode(warnMsg);
      upWarnMsgOperationInfo.setInferiorPlatformId(inferiorPlatformId);
      upWarnMsgOperationInfo.setCreateTime(LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)));
      upWarnMsgOperationInfoDao.save(upWarnMsgOperationInfo);
      //修改报警处理结果
      UPWarnMsgAdptInfo upWarnMsgAdptInfo = upWarnMsgAdptInfoDao.findByInfoIdIs(upWarnMsgOperationInfo.getInfoId());
      if(null != upWarnMsgAdptInfo){
         upWarnMsgAdptInfo.setResult(upWarnMsgOperationInfo.getResult());
         upWarnMsgAdptInfoDao.save(upWarnMsgAdptInfo);
      }
   }
   /**
    * 报警附件目录请求应答
    * @param ctx
    * @param inferiorPlatformId
    * @param warnMsg
    */
   public void up_warn_msg_filelist_ack(ChannelHandlerContext ctx, int inferiorPlatformId, WarnMsg warnMsg){
      UpWarnMsgFileListAck upWarnMsgFileListAck = new UpWarnMsgFileListAck().decode(warnMsg).decode(warnMsg);
      upWarnMsgFileListAck.setInferiorPlatformId(inferiorPlatformId);
      upWarnMsgFileListAck.setCreateTime(LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)));
      upWarnMsgFileListAckDao.save(upWarnMsgFileListAck);
      //修改报警附件数据
      UPWarnMsgAdptInfo upWarnMsgAdptInfo = upWarnMsgAdptInfoDao.findByInfoIdIs(upWarnMsgFileListAck.getInfoId());
      if(upWarnMsgFileListAck.getFileList().size() > 0){
         StringJoiner joiner = new StringJoiner(",");
         upWarnMsgFileListAck.getFileList().forEach(file->{
            if(file.getFileType() == 0x00){
               joiner.add(file.getFileUrl());
            }
         });
         upWarnMsgAdptInfo.setPicUrl(joiner.toString());
      }else{
         upWarnMsgAdptInfo.setPicUrl("*");
      }
      upWarnMsgAdptInfoDao.save(upWarnMsgAdptInfo);
   }
   /**
    * 定时任务督办报警请求和附件请求
    */
   public void taskUrgeTodo() {
      List<UPWarnMsgAdptInfo> list = upWarnMsgAdptInfoDao.findByResultIsAndPushTimeBefore(0x00, LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)));
      List<UPWarnMsgAdptInfo> list = upWarnMsgAdptInfoDao.findByResultIsAndLevelNotNullAndPushTimeBefore(0x00, LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)));
      for (UPWarnMsgAdptInfo upWarnMsgAdptInfo : list) {
         Integer inferiorPlatformId = upWarnMsgAdptInfo.getInferiorPlatformId();
         //海康威视直接走接口
         if(25439966 == inferiorPlatformId){
            try {
               if(!StringUtils.hasLength(upWarnMsgAdptInfo.getPicUrl())){
                  FindPicturesByAlarmIdRequest findPicturesByAlarmIdRequest = new FindPicturesByAlarmIdRequest();
                  findPicturesByAlarmIdRequest.setAlarmId(upWarnMsgAdptInfo.getInfoId());
                  long warnTime = upWarnMsgAdptInfo.getWarnTime();
                  String format = LocalDateTime.ofEpochSecond(warnTime, 0, ZoneOffset.ofHours(8)).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
                  format = format.replace(" ", "T") + "+08:00";
                  findPicturesByAlarmIdRequest.setAlarmTime(format);
                  String pictures = Artemis.findPicturesByAlarmId(findPicturesByAlarmIdRequest);
                  JSONObject jsonObject = JSONObject.parseObject(pictures);
                  Integer code = jsonObject.getInteger("code");
                  if(0 == code){
                     JSONArray data = jsonObject.getJSONArray("data");
                     StringJoiner joiner = new StringJoiner(",");
                     for (int i = 0; i < data.size(); i++) {
                        JSONObject jsonObject1 = data.getJSONObject(0);
                        String url = jsonObject1.getString("url");
                        joiner.add(url);
                     }
                     upWarnMsgAdptInfo.setPicUrl(joiner.length() > 0 ? joiner.toString() : "*");
                     upWarnMsgAdptInfoDao.save(upWarnMsgAdptInfo);
                  }
               }
            }catch (Exception e){
               e.printStackTrace();
            }
         }
         //请求报警附件(川标协议)
         if(enterprise.contains(inferiorPlatformId) && !StringUtils.hasLength(upWarnMsgAdptInfo.getPicUrl())){
            DOWNWarnMsgFileListReq downWarnMsgFileListReq = new DOWNWarnMsgFileListReq();
            downWarnMsgFileListReq.setVehicleNo(upWarnMsgAdptInfo.getVehicleNo());
            downWarnMsgFileListReq.setVehicleColor(upWarnMsgAdptInfo.getVehicleColor());
            downWarnMsgFileListReq.setDataType(DataType.DOWN_WARN_MSG_FILELIST_REQ.getCode());
            downWarnMsgFileListReq.setDataLength(32);
            downWarnMsgFileListReq.setInfoId(upWarnMsgAdptInfo.getInfoId());
            byte[] body = downWarnMsgFileListReq.encode();
            OuterPacket out = new OuterPacket(DataType.DOWN_WARN_MSG.getCode(), inferiorPlatformId, body);
            //获取从链路通道
            Channel channel = ChannelMap.getClientChannel(inferiorPlatformId);
            if (null != channel && channel.isActive()) {
               channel.writeAndFlush(out);
               log.info("报警附件目录请求({}):{}", DataType.DOWN_WARN_MSG_FILELIST_REQ.getCode(), JSON.toJSONString(downWarnMsgFileListReq));
            }
         }
         down_warn_msg_urge_todo_req(upWarnMsgAdptInfo);
      }
   }
@@ -144,7 +297,7 @@
    */
   public void down_warn_msg_urge_todo_req(UPWarnMsgAdptInfo upWarnMsgAdptInfo) {
      if (!redisTemplate.hasKey("login:" + upWarnMsgAdptInfo.getInferiorPlatformId())) {
         log.error("链路还未登录校验,拒绝连接");
         log.error("链路还未登录校验,拒绝连接:{}", upWarnMsgAdptInfo.getInferiorPlatformId());
         return;
      }
      int inferiorPlatformId = upWarnMsgAdptInfo.getInferiorPlatformId();
@@ -152,7 +305,7 @@
      downWarnMsgUrgeTodoReq.setDataType(DataType.DOWN_WARN_MSG_URGE_TODO_REQ.getCode());
      downWarnMsgUrgeTodoReq.setDataLength(92);
      byte[] body = downWarnMsgUrgeTodoReq.encode();
      OuterPacket out = new OuterPacket(DataType.DOWN_WARN_MSG_URGE_TODO_REQ.getCode(), body);
      OuterPacket out = new OuterPacket(DataType.DOWN_WARN_MSG.getCode(), inferiorPlatformId, body);
      //获取从链路通道
      Channel channel = ChannelMap.getClientChannel(inferiorPlatformId);
      if (null != channel && channel.isActive()) {
@@ -162,4 +315,271 @@
      upWarnMsgAdptInfo.setPushTime(LocalDateTime.now().plusDays(7).toEpochSecond(ZoneOffset.ofHours(8)));
      upWarnMsgAdptInfoDao.save(upWarnMsgAdptInfo);
   }
   /**
    * 存储mqtt协议报警信息
    */
   public void saveWarnMsgService(JSONObject jsonObject) {
      SubscriptionEvent subscriptionEvent = jsonObject.getObject("params", SubscriptionEvent.class);
      List<Event> events = subscriptionEvent.getEvents();
      if(null != events){
         events.forEach(event -> {
            try {
               //车牌号
               String srcName = event.getSrcName();
               Alarm data = JSONObject.parseObject(event.getData(), Alarm.class);
               if(!StringUtils.hasLength(data.getAlarmId())){
                  return;
               }
               UPWarnMsgAdptInfo upWarnMsgAdptInfo = upWarnMsgAdptInfoDao.findByInfoIdIs(data.getAlarmId());
               if(null == upWarnMsgAdptInfo){
                  upWarnMsgAdptInfo = new UPWarnMsgAdptInfo();
               }
               upWarnMsgAdptInfo.setVehicleNo(srcName);
               upWarnMsgAdptInfo.setVehicleColor(null == data.getVehicleLicenseColor() ? 0 : data.getVehicleLicenseColor());
               upWarnMsgAdptInfo.setWarnSrc(data.getSourceType() + 1);
               upWarnMsgAdptInfo.setWarnType(getAlarmType(data.getEventType()));
               if(null != data.getAlarmTime()){
                  upWarnMsgAdptInfo.setWarnTime(LocalDateTime.parse(data.getAlarmTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")).toEpochSecond(ZoneOffset.ofHours(8)));
               }
               upWarnMsgAdptInfo.setInfoId(data.getAlarmId());
               upWarnMsgAdptInfo.setLevel(getLevel(data.getLevel()));
//               if(null != data.getLatitude()){
//                  upWarnMsgAdptInfo.setLongitude(data.getLatitude().intValue() * 10);
//               }
//               if(null != data.getLongitude()){
//                  upWarnMsgAdptInfo.setLatitude(data.getLongitude().intValue());
//               }
               //调用获取实时定位数据
               UPExgMsgRealLocation upExgMsgRealLocation = upExgMsgRealLocationDao.findByVehicleNoOrderByCreateTimeDesc(upWarnMsgAdptInfo.getVehicleNo());
               if (null != upExgMsgRealLocation) {
                  GnssData gnssData = upExgMsgRealLocation.getGnssData();
                  upWarnMsgAdptInfo.setSpeed(gnssData.getVec1());
                  upWarnMsgAdptInfo.setLongitude(gnssData.getLon());
                  upWarnMsgAdptInfo.setLatitude(gnssData.getLat());
               }else{
                  return;
               }
               if(null != data.getHeight()){
                  upWarnMsgAdptInfo.setAltitude(data.getHeight().intValue() / 10);
               }
               if(null != data.getSpeed()){
                  upWarnMsgAdptInfo.setSpeed(data.getSpeed().intValue() / 100000);
               }
               if(null != data.getSpeed()){
                  upWarnMsgAdptInfo.setVec2(data.getSpeed().intValue() / 100000);
               }
               upWarnMsgAdptInfo.setStatus(data.getStatus());
               if(null != data.getDirection()){
                  upWarnMsgAdptInfo.setDirection(data.getDirection() / 100);
               }
               upWarnMsgAdptInfo.setInfoContent(data.getAlarmInfo());
               upWarnMsgAdptInfo.setInferiorPlatformId(25439966);
               upWarnMsgAdptInfo.setCreateTime(LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)));
               if(!warnType.contains(upWarnMsgAdptInfo.getWarnType())){
                  return;
               }
               upWarnMsgAdptInfo.setResult(0x00);
               //获取报警抓拍图片
               if(data.getPicNum() > 0){
                  FindPicturesByAlarmIdRequest findPicturesByAlarmIdRequest = new FindPicturesByAlarmIdRequest();
                  findPicturesByAlarmIdRequest.setAlarmId(data.getAlarmId());
                  long warnTime = upWarnMsgAdptInfo.getWarnTime();
                  String format = LocalDateTime.ofEpochSecond(warnTime, 0, ZoneOffset.ofHours(8)).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
                  format = format.replace(" ", "T") + "+08:00";
                  findPicturesByAlarmIdRequest.setAlarmTime(format);
                  String pictures = Artemis.findPicturesByAlarmId(findPicturesByAlarmIdRequest);
                  JSONObject jsonObject1 = JSONObject.parseObject(pictures);
                  Integer code = jsonObject1.getInteger("code");
                  if(0 == code){
                     JSONArray data1 = jsonObject1.getJSONArray("data");
                     StringJoiner joiner = new StringJoiner(",");
                     for (int i = 0; i < data1.size(); i++) {
                        JSONObject jsonObject2 = data1.getJSONObject(0);
                        String url = jsonObject2.getString("url");
                        joiner.add(url);
                     }
                     upWarnMsgAdptInfo.setPicUrl(joiner.toString());
                  }
               }else{
                  upWarnMsgAdptInfo.setPicUrl("*");
               }
               upWarnMsgAdptInfoDao.save(upWarnMsgAdptInfo);
            }catch (Exception e){
               e.printStackTrace();
            }
         });
      }
   }
   public int getAlarmType(long eventType){
      switch ((int) eventType){
         case 0x00020501:
            return 0x0301;
         case 0x00020502:
            return 0x0201;
         case 0x00020503:
            return 0x0202;
         case 0x00020504:
            return 0x0202;
         case 0x00020505:
            return 0x0202;
         case 0x00020506:
            return 0x0202;
         case 0x00020507:
            return 0x0203;
         case 0x00020508:
            return 0x0203;
         case 0x00020509:
            return 0x0204;
         case 0x00020510:
            return 0x0204;
         case 0x00037017:
            return 0x00FF;
         case 0x00020511:
            return 0x00FF;
         case 0x00037005:
            return 0x00FF;
         case 0x00020512:
            return 0x0002;
         case 0x00020513:
            return 0x0002;
         case 0x00020514:
            return 0x00FF;
         case 0x00020515:
            return 0x00FF;
         case 0x00020516:
            return 0x0214;
         case 0x00020517:
            return 0x0213;
         case 0x00020519:
            return 0x0215;
         case 0x00020520:
            return 0x0234;
         case 0x00020521:
            return 0x0234;
         case 0x00020522:
            return 0x0234;
         case 0x00020523:
            return 0x0241;
         case 0x00020524:
            return 0x0242;
         case 0x00020525:
            return 0x0243;
         case 0x00020526:
            return 0x0243;
         case 0x00020531:
            return 0x00FF;
         case 0x00020532:
            return 0x00FF;
         case 0x00020533:
            return 0x00FF;
         case 0x00020534:
            return 0x0218;
         case 0x00020518:
            return 0xA0FF;
         case 0x00037001:
            return 0xA0FF;
         case 0x00037002:
            return 0x0216;
         case 0x00037006:
            return 0x0216;
         case 0x00020535:
            return 0x0001;
         case 0x00020536:
            return 0x0001;
         case 0x00020537:
            return 0x000D;
         case 0x00020102:
            return 0x0102;
         case 0x00020538:
            return 0x0005;
         case 0x00020539:
            return 0x0004;
         case 0x00020540:
            return 0x0304;
         case 0x00020541:
            return 0x0304;
         case 0x00020542:
            return 0x000B;
         case 0x00020543:
            return 0x0001;
         case 0x00020544:
            return 0x0001;
         case 0x00020545:
            return 0xA001;
         case 0x00020546:
            return 0x0305;
         case 0x00020547:
            return 0x0305;
         case 0x00020548:
            return 0xA0FF;
         case 0x00010202:
            return 0x0103;
         case 0x00010206:
            return 0x0103;
         case 0x00020101:
            return 0x0101;
         case 0x00020103:
            return 0x000C;
         case 0x00020549:
            return 0xA00A;
         case 0x00020550:
            return 0xA00A;
         case 0x00020551:
            return 0xA00A;
         case 0x00020552:
            return 0x0308;
         case 0x00020553:
            return 0x0308;
         case 0x00020554:
            return 0x0308;
         case 0x00020555:
            return 0x0308;
         case 0x00020556:
            return 0x0308;
         case 0x00020557:
            return 0x0308;
         case 0x00020558:
            return 0x0308;
         case 0x00020559:
            return 0x0003;
         case 0x00020527:
            return 0x0301;
         case 0x00020528:
            return 0x0201;
         case 0x00020529:
            return 0x0302;
         case 0x00020530:
            return 0x0302;
         case 0x00020560:
            return 0x0009;
         case 0x00020561:
            return 0x0306;
         case 0x00020562:
            return 0x0307;
         case 0x00090001:
            return 0x00FF;
            default:
               return 0x00FF;
      }
   }
   public int getLevel(String level){
      switch (level){
         case "h":
         case "m":
            return 1;
         case "l":
         case "w":
            return 2;
         default:
            return 0;
      }
   }
}