Newer
Older
SensorHub-NoiseCorr / SensorHub.Well / Well.cs
TAN YUE on 10 Jan 2024 12 KB 20240110 加速度值解析修改
using SensorHub.Servers;
using SensorHub.Servers.Commands.CASICCommands;
using SensorHub.Servers.JsonFormat;
using SuperSocket.SocketBase.Command;
using SuperSocket.SocketBase.Protocol;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using System.Configuration;

namespace SensorHub.Well
{
    public class Well : CommandBase<CasicSession, StringRequestInfo>
    {
        public override void ExecuteCommand(CasicSession session, StringRequestInfo requestInfo)
        {
            //TODO: construct the receving casic data
            String preamble = requestInfo.Parameters[0];
            String version = requestInfo.Parameters[1];
            String leng = requestInfo.Parameters[2];
            String devCode = requestInfo.Parameters[3];
            String routeFlag = requestInfo.Parameters[4];
            String dstNodeAddr = requestInfo.Parameters[5];
            String pduType = requestInfo.Parameters[6];
            String seq = requestInfo.Parameters[7];
            String settings = requestInfo.Parameters[8];
            String source = requestInfo.Parameters[9];

            String devName = "Well";

            if (source.Contains("-"))
            {
                session.Send("HTTP/1.1 200 OK\r\n\r\n\r\n");
                session.Close();
            }

            //print the receving data
            String devType = "井盖状态监测仪";
            String operType = Common.getOpeTypeByPdu(pduType);
            // session.Logger.Info("AD接收数据:" + requestInfo.Body);
            session.Logger.Info("设备编号:" + devCode);
            session.Logger.Info("设备类型:" + devType);
            session.Logger.Info("操作类型:" + operType);
            session.Logger.Info("包序列号:" + seq);
            session.Logger.Info("会话:" + session.HubAddr + "," + session.SessionID);

            List<Tag> tags = Common.getTags(settings, session);

            //具体业务处理
            String collectDate = "";
            List<String> eventList = new List<String>();
            List<DatasJson> datasList = new List<DatasJson>();
            List<String> startupList = new List<String>();
 
            foreach (Tag tag in tags)
            {
                if (!(tag is UploadTag))
                {
                    //非业务处理
                    if (tag != null && tag is SystemDateTag)
                    {
                        SystemDateTag systemDateTag = tag as SystemDateTag;
                        collectDate = systemDateTag.CollectDate;
                        continue;
                    }

                    if (tag != null && tag is SensorStartupTag)
                    {
                        SensorStartupTag sensorStartup = tag as SensorStartupTag;
                        String imei = sensorStartup.IMEI;
                        String iccid = sensorStartup.ICCID;

                        startupList.Add(imei);
                        startupList.Add(iccid);

                        session.Logger.Info("设备开机上报,设备编号DEVCODE:" + devCode + " IMEI:" + imei + " ICCID:" + iccid);
                        continue;
                    }
                }
                else
                {
                    //业务处理 
                    UploadTag uploadTag = tag as UploadTag;
                    switch (uploadTag.BizType)
                    {
                        case 7:
                            //开关状态
                            TagHandler wellHandler = new WellTagHandler();
                            wellHandler.resolve(tag, session);

                            if(wellHandler.DataList.Count > 0)
                            {
                                DateTime upTime = Convert.ToDateTime(collectDate + " " + wellHandler.CollecTime);
                                String uptime = upTime.ToString("yyyy") + upTime.ToString("MM") + upTime.ToString("dd")
                                    + upTime.ToString("HH") + upTime.ToString("mm") + upTime.ToString("ss");

                                switch ((byte)wellHandler.DataList[0])
                                {
                                    case 0:
                                        datasList.Add(new WellDatasJson(uptime, "00"));
                                        break;
                                    case 1:
                                        eventList.Add("WellOpenAlarm");//井盖开启
                                        break;
                                    case 2:
                                        eventList.Add("WellDeviceBadAlarm");//设备故障
                                        break; 
                                    case 3:
                                        //eventList.Add("WellLowBatteryAlarm");//低电量
                                        break;
                                    default:
                                        eventList.Add("WellUnknown");//未知异常
                                        break;
                                }
                            }
                            break;

                        case 21:
                            // 海量加速度值
                            TagHandler accelerationHandler = new AccelerationTagHandler();
                            accelerationHandler.resolve(tag, session);

                            string datas = (string)accelerationHandler.Data;

                            session.Logger.Info("接收总数据长度:" + datas.Length / 2 + "字节,采样点:" + datas.Length / (2 * 2));
                            // session.Logger.Info(datas);

                            double[] realValue = new double[datas.Length / (2 * 2)]; // 每个采样点2个字节
                            for (int i = 0; i < realValue.Length; i++)
                            {
                                string tempByteString = datas.Substring(i * 4, 4);
                                realValue[i] = HexToDouble(tempByteString);
                                // session.Logger.Info(i + ": " + tempByteString + "; " + HexToDouble(tempByteString));
                            }

                            AccelerationDatas.acclerationValueMap.Add(devCode, realValue);

                            // 创建存盘线程
                            Thread savethread = new Thread(SavetoFlie)
                            {
                                IsBackground = true//将线程设置为后台线程
                            };
                            savethread.Start(devCode);  //开启存盘线程
                            /*
                            byte[] responseFrame = BuildAccelerationDataReceived(devCode, new byte[2] { 0x05, 0x86 });
                            string responseBase64 = Convert.ToBase64String(responseFrame); // 转成base64下发
                            Common.SendAEPCommand(session, responseBase64, source);
                            return;
                            */
                            break;

                        default:
                            session.Logger.Info("未知业务类型!");
                            break;
                    }
                }
            }

            //Common.sendMessage(session, "Well", devCode, -1, eventList, datasList, startupList);
            Common.kafkaProduce(session, devName, devCode, -1, null, null, null, eventList, datasList, startupList);

            if (source != "433") //433井盖不要求回复
            {
                byte[] btPdu = new byte[2]; //2个字节
                if (operType == "TrapRequest")
                {
                    btPdu[0] = 0x05;
                }
                else if (operType == "StartupRequest")
                {
                    btPdu[0] = 0x09;
                }
              
                btPdu[1] = 0x86;

                // Common.sendConfig(session, devCode, routeFlag, source, btPdu);
                Common.sendGPRSConfig(session, devCode, btPdu, source, "TEA");
            }
        }

        private double HexToDouble(string hexString)
        {
            if (hexString.Length != 4)
                return 0;

            string convertStr = "0" + hexString.Substring(3, 1) + hexString.Substring(0, 2); // 将字节顺序反一下 最高4位置0

            Int16 originInt = Convert.ToInt16(convertStr, 16);
            if (originInt >= 2048)
            {
                originInt = (short)(originInt - 4095);
            }
            
            return (double)originInt / 1.024; // 换算成mg
        }

        private byte[] BuildAccelerationDataReceived(string devCode, byte[] btPdu)
        {
            byte[] frame = { 0xA3, 0x20,                          //帧头 - 固定
                             0x00, 0x26,                          //长度 - 固定
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //设备编号
                             0x03,                                //通信方式 - 固定
                             0x00, 0x00,                          //目标节点地址
                             0x00, 0x00,                          //PDUType
                             0x01,                                //Seq - 不分包 固定
                             0x10, 0x00, 0x00, 0x51, 0x00, 0x06,  //时间戳
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                             0x60, 0x00, 0x03, 0x00, 0x00, 0x08,  //数据接收状态
                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                           };
            // 设备编号字段
            byte[] btDevCode = StrToHexByte(devCode);
            btDevCode.CopyTo(frame, 4);
            Array.Copy(btDevCode, 4, frame, 11, 2); // 目标节点地址 = 设备编号最后2个字节

            // pduType字段
            btPdu.CopyTo(frame, 13);

            // 时间戳字段
            SystemTimeConfig sysTimeConfig = new SystemTimeConfig(null);
            byte[] btConfig = sysTimeConfig.getConfig(new byte[0]);
            btConfig.CopyTo(frame, 16);

            // TEA加密
            byte[] tag = new byte[frame.Length - 16];
            Array.Copy(frame, 16, tag, 0, tag.Length); // 需要加密的内容
            byte[] enTag;  // 加密后的内容

            int a = tag.Length % 8;
            if (a != 0)
            {
                enTag = new byte[tag.Length + 8 - a];
                tag.CopyTo(enTag, 0);
                for (int i = 0; i < 8 - a; i++)
                {
                    enTag[tag.Length + i] = 0;
                }
            }
            else
            {
                enTag = new byte[tag.Length];
                tag.CopyTo(enTag, 0);
            }

            TEA.encrypt(ref enTag, enTag.Length);

            byte[] result = new byte[1 + 1 + 2 + 6 + 1 + 2 + 2 + 1 + enTag.Length];
            Array.Copy(frame, result, 16);
            enTag.CopyTo(result, 16);

            byte[] afcrc = Common.CRC(result);
            return afcrc;
        }

        private void SavetoFlie(object obj)//存文件方法
        {
            // 如果有这个文件(参数是存储位置+文件名称,打开方式)打开文件末尾如果没有创建一个文件流的类并加入参数后实例化
            string path = Common.GetWindowsServiceInstallPath(ConfigurationManager.AppSettings["ServiceName"]) + "\\Datas\\";
            FileStream fileStream = new FileStream(path + DateTime.Now.ToString("yyyyMMddHHmmss-") + obj + ".wll", FileMode.Append);

            // 创建一个输入流的类并加入参数(文件路径和编码格式)实例化
            StreamWriter write = new StreamWriter(fileStream, Encoding.Default);
            StringBuilder exdata = new StringBuilder();//这里是创建写入数据的StringBuilder对象
            try
            {
                for (int i = 0; i < AccelerationDatas.acclerationValueMap[(string)obj].Length; i++)
                {
                    exdata.Append(AccelerationDatas.acclerationValueMap[(string)obj][i]).AppendLine(); //添加StringBuilder字符串内容
                }

                write.Write(exdata); //向目标文件中写入数据
            }
            catch (Exception ex)
            {
                Console.WriteLine("存储数据到文件时发生错误:" + ex.Message);
            }
            finally
            {
                // 关闭文件流
                write.Close();
                fileStream.Close();
                AccelerationDatas.acclerationValueMap.Remove((string)obj);
            }
        }

        private byte[] StrToHexByte(string hexString)
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
                hexString += "0";
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }
    }
}