Newer
Older
SensorHub / SensorHub.Concentrator / Concentrator.cs
root on 17 Sep 2021 10 KB first commit
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SuperSocket.SocketBase.Command;
using SuperSocket.SocketBase.Protocol;
using SensorHub.Servers;
using SensorHub.Servers.JsonFormat;
using Newtonsoft.Json;
using System.Threading;
using SensorHub.Servers.Commands.CASICCommands;
using System.IO;
using System.Configuration;

namespace SensorHub.Concentrator
{
    public class Concentrator : 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];

            //print the receving data
            String operType = Common.getOpeTypeByPdu(pduType);
            session.Logger.Info("接收集中器心跳数据:" + requestInfo.Body);
            session.Logger.Info("会话:" + session.SessionID);

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

            String softwareVersion = "";
            uint offset = 0;
            uint size = 0;

            foreach (Tag tag in tags)
            {
                if (!(tag is UploadTag))
                {
                    //非业务处理
                    if (tag != null && tag is SoftwareVersionTag)
                    {
                        SoftwareVersionTag versionTag = (SoftwareVersionTag)tag;
                        softwareVersion = versionTag.Version;
                        continue;
                    }

                    if (tag != null && tag is OffsetTag)
                    {
                        OffsetTag offsetTag = (OffsetTag)tag;
                        offset = offsetTag.Offset;
                        continue;
                    }

                    if (tag != null && tag is SizeTag)
                    {
                        SizeTag tagTag = (SizeTag)tag;
                        size = tagTag.Size;
                        continue;
                    }

                }
            }



            byte[] btPdu = new byte[2];
            btPdu[0] = Common.getRespOperType(operType, true);//0x07;
            btPdu[1] = 0x85;

            if (session.HubAddr == null)//集中器新连接到来
            {
                session.Logger.Info("集中器新建立连接");
                session.HubAddr = devCode;

                if (Common.concentratorWithSessionIdMap.ContainsKey(devCode))
                {
                    String sessionID = Common.concentratorWithSessionIdMap[devCode];
                    CasicSession s = session.AppServer.GetSessionByID(sessionID);

                    session.Logger.Info("存在旧连接" + devCode + "," + sessionID);

                    if (s != null && s.Connected)
                    {
                        s.HubAddr = null;
                        s.Close();
                        session.Logger.Info("断开旧连接");
                    }

                    Common.concentratorWithSessionIdMap[devCode] = session.SessionID;

                    //该集中器之前已连接,更新会话,断开旧连接
                    Common.sender433Config(session, devCode, btPdu, 0x00);
                    return;
                }
                else
                {
                    session.Logger.Info("添加新连接");
                    Common.concentratorWithSessionIdMap.Add(devCode, session.SessionID);
                }

                DateTime now = DateTime.Now;
                DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); //当地时区
                long timeStamp = (long)(now - startTime).TotalMilliseconds; //相差毫秒数

                String logtime = now.ToString("yyyy") + now.ToString("MM") + now.ToString("dd")
                    + now.ToString("HH") + now.ToString("mm") + now.ToString("ss");

                String message = JsonConvert.SerializeObject(new Json("Event", "Concentrator", devCode,
                    new DataJson("ConcentratorOnline", -1, null, logtime), timeStamp));

                if (Common.SendMessage(message))
                {
                    session.Logger.Info("往第三方发送数据:" + message);
                }
                else
                {
                    session.Logger.Info("未连接上第三方服务器");
                }

                //集中器上线,完成之前未完成的缓存的下发配置操作
                RedisHelper redis = new RedisHelper(0);
                redis.Publish("Config", devCode);//主动发布消息

            }
            else//心跳数据到来,10次心跳发送一次在线消息
            {
                if (Common.concentratorWithHeartbeatMap.ContainsKey(devCode))
                {
                    if (++Common.concentratorWithHeartbeatMap[devCode] >= 10)
                    {
                        DateTime now = DateTime.Now;
                        DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); //当地时区
                        long timeStamp = (long)(now - startTime).TotalMilliseconds; //相差毫秒数

                        String logtime = now.ToString("yyyy") + now.ToString("MM") + now.ToString("dd")
                            + now.ToString("HH") + now.ToString("mm") + now.ToString("ss");

                        String message = JsonConvert.SerializeObject(new Json("Event", "Concentrator", devCode,
                            new DataJson("ConcentratorOnline", -1, null, logtime), timeStamp));

                        if (Common.SendMessage(message))
                        {
                            session.Logger.Info("往第三方发送数据:" + message);
                            Common.concentratorWithHeartbeatMap[devCode] = 0;
                        }
                        else
                        {
                            session.Logger.Info("未连接上第三方服务器");
                        }
                    }
                }
                else
                {
                    Common.concentratorWithHeartbeatMap.Add(devCode, 0);
                }
            }

            if (!String.IsNullOrEmpty(softwareVersion))//有上传版本号,进行升级回复
            {
                //读取文件
                //String path = Directory.GetCurrentDirectory();
                String path = Common.GetWindowsServiceInstallPath(ConfigurationManager.AppSettings["ServiceName"]);
                path += "\\Update\\Concentrator";
                String lastestFilePath = String.Empty;

                var files = Directory.GetFiles(path);
                foreach (var file in files)
                {
                    if (String.IsNullOrEmpty(lastestFilePath))
                    {
                        lastestFilePath = file;
                        continue;
                    }

                    if (lastestFilePath.CompareTo(file) < 0)
                    {
                        lastestFilePath = file;
                    }
                }

                int index = lastestFilePath.LastIndexOf('_');
                String lastestVersion = lastestFilePath.Substring(index + 2);
                if (softwareVersion.CompareTo(lastestVersion) < 0)//判断是否需要升级
                {
                    //读取二进制文件
                    BinaryReader br = null;
                    try
                    {
                        br = new BinaryReader(new FileStream(lastestFilePath, FileMode.Open, FileAccess.Read, FileShare.Read));
                        long length = br.BaseStream.Length;
                        byte[] data = br.ReadBytes((int)length);
                        byte[] crc = Common.getCRC(data);

                        Common.sender433UpdateConfig(session, devCode, btPdu, 0x00, (uint)br.BaseStream.Length, crc);

                    }
                    catch (IOException e)
                    {
                        session.Logger.Error(e.Message + "\n Cannot read from file.");
                        Common.sender433Config(session, devCode, btPdu, 0x00);//回复不升级
                    }
                    br.Close();
                    return;
                }
                else
                {
                    Common.sender433Config(session, devCode, btPdu, 0x00);
                    return;
                }
            }
            else if (operType == "GetRequest" && size > 0)//下发升级数据包
            {
                //String path = Directory.GetCurrentDirectory();
                String path = Common.GetWindowsServiceInstallPath(ConfigurationManager.AppSettings["ServiceName"]);
                path += "\\Update\\Concentrator";
                String lastestFilePath = String.Empty;

                var files = Directory.GetFiles(path);
                foreach (var file in files)
                {
                    if (String.IsNullOrEmpty(lastestFilePath))
                    {
                        lastestFilePath = file;
                        continue;
                    }

                    if (lastestFilePath.CompareTo(file) < 0)
                    {
                        lastestFilePath = file;
                    }
                }

                //读取二进制文件
                BinaryReader br = null;
                try
                {
                    br = new BinaryReader(new FileStream(lastestFilePath, FileMode.Open, FileAccess.Read, FileShare.Read));

                    byte[] data;
                    int left = (int)br.BaseStream.Length - (int)offset;
                    if (left >= size)
                    {
                        data = new byte[size];
                        br.BaseStream.Position = offset;
                        br.Read(data, 0, (int)size);
                    }
                    else
                    {
                        data = new byte[left];
                        br.BaseStream.Position = offset;
                        br.Read(data, 0, left);
                    }

                    //byte[] crc = Common.getCRC(data);

                    Common.sender433UpdateDataConfig(session, devCode, btPdu, 0x00, data);

                }
                catch (IOException e)
                {
                    session.Logger.Error(e.Message + "\n Cannot read from file.");
                }
                br.Close();
                return;
                
            }

            Common.sender433Config(session, devCode, btPdu, 0x00);
        }
    }
}