Beispiel #1
0
 /// <summary>
 /// Создать данные события на основе строки таблицы
 /// </summary>
 protected EventTableLight.Event CreateEvent(DataRowView rowView)
 {
     EventTableLight.Event ev = new EventTableLight.Event();
     ev.Number     = ConvertToInt(rowView["Number"]);
     ev.DateTime   = ConvertToDateTime(rowView["DateTime"]);
     ev.ObjNum     = ConvertToInt(rowView["ObjNum"]);
     ev.KPNum      = ConvertToInt(rowView["KPNum"]);
     ev.ParamID    = ConvertToInt(rowView["ParamID"]);
     ev.CnlNum     = ConvertToInt(rowView["CnlNum"]);
     ev.OldCnlVal  = ConvertToDouble(rowView["OldCnlVal"]);
     ev.OldCnlStat = ConvertToInt(rowView["OldCnlStat"]);
     ev.NewCnlVal  = ConvertToDouble(rowView["NewCnlVal"]);
     ev.NewCnlStat = ConvertToInt(rowView["NewCnlStat"]);
     ev.Checked    = ConvertToBoolean(rowView["Checked"]);
     ev.UserID     = ConvertToInt(rowView["UserID"]);
     ev.Descr      = Convert.ToString(rowView["Descr"]);
     ev.Data       = Convert.ToString(rowView["Data"]);
     return(ev);
 }
Beispiel #2
0
        /// <summary>
        /// Добавить событие в файл или поток
        /// </summary>
        public void AppendEvent(EventTableLight.Event ev)
        {
            if (ev == null)
            {
                throw new ArgumentNullException("ev");
            }

            Stream       stream = null;
            BinaryWriter writer = null;

            try
            {
                stream = ioStream == null ?
                         new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite) :
                         ioStream;
                writer = new BinaryWriter(stream);

                // установка позиции записи кратной размеру данных события
                stream.Seek(0, SeekOrigin.End);
                long offset = stream.Position / EventDataSize * EventDataSize;
                stream.Seek(offset, SeekOrigin.Begin);

                // запись события
                writer.Write(CreateEventBuffer(ev));
            }
            finally
            {
                if (fileMode)
                {
                    if (writer != null)
                    {
                        writer.Close();
                    }
                    if (stream != null)
                    {
                        stream.Close();
                    }
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Создать буфер для записи события
        /// </summary>
        protected byte[] CreateEventBuffer(EventTableLight.Event ev)
        {
            byte[] evBuf = new byte[EventDataSize];
            Array.Copy(BitConverter.GetBytes(Arithmetic.EncodeDateTime(ev.DateTime)), 0, evBuf, 0, 8);
            evBuf[8]  = (byte)(ev.ObjNum % 256);
            evBuf[9]  = (byte)(ev.ObjNum / 256);
            evBuf[10] = (byte)(ev.KPNum % 256);
            evBuf[11] = (byte)(ev.KPNum / 256);
            evBuf[12] = (byte)(ev.ParamID % 256);
            evBuf[13] = (byte)(ev.ParamID / 256);
            evBuf[14] = (byte)(ev.CnlNum % 256);
            evBuf[15] = (byte)(ev.CnlNum / 256);
            Array.Copy(BitConverter.GetBytes(ev.OldCnlVal), 0, evBuf, 16, 8);
            evBuf[24] = (byte)ev.OldCnlStat;
            Array.Copy(BitConverter.GetBytes(ev.NewCnlVal), 0, evBuf, 25, 8);
            evBuf[33] = (byte)ev.NewCnlStat;
            evBuf[34] = ev.Checked ? (byte)1 : (byte)0;
            evBuf[35] = (byte)(ev.UserID % 256);
            evBuf[36] = (byte)(ev.UserID / 256);
            string descr = ev.Descr ?? "";

            if (descr.Length > MaxDescrLen)
            {
                descr = descr.Substring(0, MaxDescrLen);
            }
            evBuf[37] = (byte)descr.Length;
            Array.Copy(Encoding.Default.GetBytes(descr), 0, evBuf, 38, descr.Length);
            string data = ev.Data ?? "";

            if (data.Length > MaxDataLen)
            {
                data = data.Substring(0, MaxDataLen);
            }
            evBuf[138] = (byte)data.Length;
            Array.Copy(Encoding.Default.GetBytes(data), 0, evBuf, 139, data.Length);
            return(evBuf);
        }
Beispiel #4
0
        /// <summary>
        /// Заполнить объект dest из файла событий FileName
        /// </summary>
        protected void FillObj(object dest)
        {
            Stream stream = null;
            BinaryReader reader = null;
            DateTime fillTime = DateTime.Now;

            EventTableLight eventTableLight = null;
            DataTable dataTable = null;

            try
            {
                if (dest is EventTableLight)
                    eventTableLight = dest as EventTableLight;
                else if (dest is DataTable)
                    dataTable = dest as DataTable;
                else
                    throw new Exception("Destination object is invalid.");

                // определение даты событий в таблице
                DateTime date = Arithmetic.ExtractDate(tableName);

                // подготовка объекта для хранения данных
                if (eventTableLight != null)
                {
                    eventTableLight.Clear();
                    eventTableLight.TableName = tableName;
                }
                else // dataTable != null
                {
                    // формирование структуры таблицы
                    dataTable.BeginLoadData();
                    dataTable.DefaultView.Sort = "";

                    if (dataTable.Columns.Count == 0)
                    {
                        dataTable.Columns.Add("Number", typeof(int));
                        dataTable.Columns.Add("DateTime", typeof(DateTime)).DefaultValue = date;
                        dataTable.Columns.Add("ObjNum", typeof(int)).DefaultValue = 0;
                        dataTable.Columns.Add("KPNum", typeof(int)).DefaultValue = 0;
                        dataTable.Columns.Add("ParamID", typeof(int)).DefaultValue = 0;
                        dataTable.Columns.Add("CnlNum", typeof(int)).DefaultValue = 0;
                        dataTable.Columns.Add("OldCnlVal", typeof(double)).DefaultValue = 0.0;
                        dataTable.Columns.Add("OldCnlStat", typeof(int)).DefaultValue = 0;
                        dataTable.Columns.Add("NewCnlVal", typeof(double)).DefaultValue = 0.0;
                        dataTable.Columns.Add("NewCnlStat", typeof(int)).DefaultValue = 0;
                        dataTable.Columns.Add("Checked", typeof(bool)).DefaultValue = false;
                        dataTable.Columns.Add("UserID", typeof(int)).DefaultValue = 0;
                        dataTable.Columns.Add("Descr", typeof(string));
                        dataTable.Columns.Add("Data", typeof(string));
                        dataTable.DefaultView.AllowNew = false;
                        dataTable.DefaultView.AllowEdit = false;
                        dataTable.DefaultView.AllowDelete = false;
                    }
                    else
                    {
                        DataColumn colDateTime = dataTable.Columns["DateTime"];
                        if (colDateTime != null)
                            colDateTime.DefaultValue = date;
                        dataTable.Rows.Clear();
                    }
                }

                // заполнение таблицы из файла
                stream = ioStream == null ?
                    new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) :
                    ioStream;
                reader = new BinaryReader(stream);

                Byte[] eventBuf = new byte[EventDataSize]; // буфер данных события
                int evNum = 1; // порядковый номер события

                while (stream.Position < stream.Length)
                {
                    int readSize = reader.Read(eventBuf, 0, EventDataSize);
                    if (readSize == EventDataSize)
                    {
                        // создание события на основе считанных данных
                        EventTableLight.Event ev = new EventTableLight.Event();
                        ev.Number = evNum;
                        evNum++;

                        double time = BitConverter.ToDouble(eventBuf, 0);
                        int hour, min, sec;
                        Arithmetic.DecodeTime(time, out hour, out min, out sec);
                        ev.DateTime = new DateTime(date.Year, date.Month, date.Day, hour, min, sec);

                        ev.ObjNum = BitConverter.ToUInt16(eventBuf, 8);
                        ev.KPNum = BitConverter.ToUInt16(eventBuf, 10);
                        ev.ParamID = BitConverter.ToUInt16(eventBuf, 12);
                        ev.CnlNum = BitConverter.ToUInt16(eventBuf, 14);
                        ev.OldCnlVal = BitConverter.ToDouble(eventBuf, 16);
                        ev.OldCnlStat = eventBuf[24];
                        ev.NewCnlVal = BitConverter.ToDouble(eventBuf, 25);
                        ev.NewCnlStat = eventBuf[33];
                        ev.Checked = eventBuf[34] > 0;
                        ev.UserID = BitConverter.ToUInt16(eventBuf, 35);
                        ev.Descr = BytesToStr(eventBuf, 37);
                        ev.Data = BytesToStr(eventBuf, 138);

                        // создание строки заполняемой таблицы
                        if (eventTableLight != null)
                        {
                            eventTableLight.AllEvents.Add(ev); // быстрее, чем eventTableLight.AddEvent(ev)
                        }
                        else // dataTable != null
                        {
                            DataRow row = dataTable.NewRow();
                            row["Number"] = ev.Number;
                            row["DateTime"] = ev.DateTime;
                            row["ObjNum"] = ev.ObjNum;
                            row["KPNum"] = ev.KPNum;
                            row["ParamID"] = ev.ParamID;
                            row["CnlNum"] = ev.CnlNum;
                            row["OldCnlVal"] = ev.OldCnlVal;
                            row["OldCnlStat"] = ev.OldCnlStat;
                            row["NewCnlVal"] = ev.NewCnlVal;
                            row["NewCnlStat"] = ev.NewCnlStat;
                            row["Checked"] = ev.Checked;
                            row["UserID"] = ev.UserID;
                            row["Descr"] = ev.Descr;
                            row["Data"] = ev.Data;
                            dataTable.Rows.Add(row);
                        }
                    }
                }
            }
            catch (EndOfStreamException)
            {
                // нормальная ситуация окончания файла
            }
            catch
            {
                fillTime = DateTime.MinValue;
                throw;
            }
            finally
            {
                if (fileMode)
                {
                    if (reader != null)
                        reader.Close();
                    if (stream != null)
                        stream.Close();
                }

                if (eventTableLight != null)
                {
                    eventTableLight.LastFillTime = fillTime;
                }
                else if (dataTable != null)
                {
                    dataTable.EndLoadData();
                    dataTable.AcceptChanges();
                    dataTable.DefaultView.Sort = "Number";
                }
            }
        }
Beispiel #5
0
 /// <summary>
 /// Создать данные события на основе строки таблицы
 /// </summary>
 protected EventTableLight.Event CreateEvent(DataRowView rowView)
 {
     EventTableLight.Event ev = new EventTableLight.Event();
     ev.Number = ConvertToInt(rowView["Number"]);
     ev.DateTime = ConvertToDateTime(rowView["DateTime"]);
     ev.ObjNum = ConvertToInt(rowView["ObjNum"]);
     ev.KPNum = ConvertToInt(rowView["KPNum"]);
     ev.ParamID = ConvertToInt(rowView["ParamID"]);
     ev.CnlNum = ConvertToInt(rowView["CnlNum"]);
     ev.OldCnlVal = ConvertToDouble(rowView["OldCnlVal"]);
     ev.OldCnlStat = ConvertToInt(rowView["OldCnlStat"]);
     ev.NewCnlVal = ConvertToDouble(rowView["NewCnlVal"]);
     ev.NewCnlStat = ConvertToInt(rowView["NewCnlStat"]);
     ev.Checked = ConvertToBoolean(rowView["Checked"]);
     ev.UserID = ConvertToInt(rowView["UserID"]);
     ev.Descr = Convert.ToString(rowView["Descr"]);
     ev.Data = Convert.ToString(rowView["Data"]);
     return ev;
 }
Beispiel #6
0
        /// <summary>
        /// Обработать команду ТУ
        /// </summary>
        public void ProcCommand(CtrlCnl ctrlCnl, Command cmd, int userID, out bool passToClients)
        {
            passToClients = false;

            if (serverIsReady && ctrlCnl != null)
            {
                int ctrlCnlNum = ctrlCnl.CtrlCnlNum;

                // вычисление значения или данных команды по формуле канала управления
                if (ctrlCnl.CalcCmdVal != null)
                {
                    // вычисление значения стандартной команды
                    lock (curSrez) lock (calculator)
                    {
                        try
                        {
                            procSrez = curSrez; // необходимо для работы формул Val(n) и Stat(n)
                            double cmdVal = cmd.CmdVal;
                            ctrlCnl.CalcCmdVal(ref cmdVal);
                            cmd.CmdVal = cmdVal;
                            passToClients = !double.IsNaN(cmdVal);
                        }
                        catch (Exception ex)
                        {
                            AppLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Ошибка при вычислении значения стандартной команды для канала управления {0}: {1}" :
                                "Error calculating standard command value for the output channel {0}: {1}",
                                ctrlCnlNum, ex.Message), Log.ActTypes.Error);
                            cmd.CmdVal = double.NaN;
                        }
                        finally
                        {
                            procSrez = null;
                        }
                    }
                }
                else if (ctrlCnl.CalcCmdData != null)
                {
                    // вычисление данных бинарной команды
                    lock (curSrez) lock (calculator)
                    {
                        try
                        {
                            procSrez = curSrez;
                            byte[] cmdData = cmd.CmdData;
                            ctrlCnl.CalcCmdData(ref cmdData);
                            cmd.CmdData = cmdData;
                            passToClients = cmdData != null;
                        }
                        catch (Exception ex)
                        {
                            AppLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Ошибка при вычислении данных бинарной команды для канала управления {0}: {1}" :
                                "Error calculating binary command data for the output channel {0}: {1}",
                                ctrlCnlNum, ex.Message), Log.ActTypes.Error);
                            cmd.CmdVal = double.NaN;
                        }
                        finally
                        {
                            procSrez = null;
                        }
                    }
                }
                else
                {
                    passToClients = true;
                }

                // выполнение действий модулей после приёма команды
                RaiseOnCommandReceived(ctrlCnlNum, cmd, userID, ref passToClients);

                // создание события
                if (passToClients && ctrlCnl.EvEnabled)
                {
                    EventTableLight.Event ev = new EventTableLight.Event();
                    ev.DateTime = DateTime.Now;
                    ev.ObjNum = ctrlCnl.ObjNum;
                    ev.KPNum = ctrlCnl.KPNum;
                    ev.Descr = cmd.GetCmdDescr(ctrlCnlNum, userID);

                    // запись события и выполнение действий модулей
                    WriteEvent(ev);
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// Генерировать событие в соответствии со свойствами и данными входного канала
        /// </summary>
        private void GenEvent(InCnl inCnl, SrezTableLight.CnlData oldCnlData, SrezTableLight.CnlData newCnlData)
        {
            if (inCnl.EvEnabled)
            {
                double oldVal = oldCnlData.Val;
                double newVal = newCnlData.Val;
                int oldStat = oldCnlData.Stat;
                int newStat = newCnlData.Stat;

                bool dataHasChanged =
                    oldStat > BaseValues.CnlStatuses.Undefined && newStat > BaseValues.CnlStatuses.Undefined &&
                    (oldVal != newVal || oldStat != newStat);

                if (// события по изменению
                    inCnl.EvOnChange && dataHasChanged ||
                    // события по неопределённому состоянию и выходу из него
                    inCnl.EvOnUndef &&
                    (oldStat > BaseValues.CnlStatuses.Undefined && newStat == BaseValues.CnlStatuses.Undefined ||
                    oldStat == BaseValues.CnlStatuses.Undefined && newStat > BaseValues.CnlStatuses.Undefined) ||
                    // события нормализации, занижения и завышения
                    (newStat == BaseValues.CnlStatuses.Normal || newStat == BaseValues.CnlStatuses.LowCrash ||
                    newStat == BaseValues.CnlStatuses.Low || newStat == BaseValues.CnlStatuses.High ||
                    newStat == BaseValues.CnlStatuses.HighCrash) && oldStat != newStat)
                {
                    // создание события
                    EventTableLight.Event ev = new EventTableLight.Event();
                    ev.DateTime = DateTime.Now;
                    ev.ObjNum = inCnl.ObjNum;
                    ev.KPNum = inCnl.KPNum;
                    ev.ParamID = inCnl.ParamID;
                    ev.CnlNum = inCnl.CnlNum;
                    ev.OldCnlVal = oldCnlData.Val;
                    ev.OldCnlStat = oldStat;
                    ev.NewCnlVal = newCnlData.Val;
                    ev.NewCnlStat = dataHasChanged && oldStat == BaseValues.CnlStatuses.Defined &&
                        newStat == BaseValues.CnlStatuses.Defined ? BaseValues.CnlStatuses.Changed : newStat;

                    // запись события и выполнение действий модулей
                    WriteEvent(ev);
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// Обработать полученную команду
        /// </summary>
        private void ProcCommand(ClientInfo client, byte cmd, int cmdLen)
        {
            bool sendResp = true;    // отправить ответ на команду
            int respDataLen = 0;     // длина данных ответа на команду
            byte[] extraData = null; // дополнительные данные ответа

            switch (cmd)
            {
                case 0x01: // проверка имени и пароля
                    int userNameLen = inBuf[3];
                    string userName = Encoding.Default.GetString(inBuf, 4, userNameLen);
                    string password = Encoding.Default.GetString(inBuf, 5 + userNameLen, inBuf[4 + userNameLen]);
                    bool pwdIsEmpty = string.IsNullOrEmpty(password);
                    int roleID;
                    bool checkOk = CheckUser(userName, password, out roleID);

                    if (client.Authenticated)
                    {
                        if (pwdIsEmpty)
                        {
                            string checkOkStr = checkOk ?
                                (Localization.UseRussian ? "успешно" : "success") :
                                (Localization.UseRussian ? "ошибка" : "error");
                            appLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Получение роли пользователя {0}. Результат: {1}" : "Get user {0} role. Result: {1}",
                                userName, checkOkStr), Log.ActTypes.Action);
                        }
                        else
                        {
                            string checkOkStr = checkOk ?
                                (Localization.UseRussian ? "верно" : "passed") :
                                (Localization.UseRussian ? "неверно" : "failed");
                            appLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Проверка имени и пароля пользователя {0}. Результат: {1}" :
                                "Check user {0} name and password. Result: {1}",
                                userName, checkOkStr), Log.ActTypes.Action);
                        }
                    }
                    else
                    {
                        if (checkOk && roleID != BaseValues.Roles.Disabled && !pwdIsEmpty)
                        {
                            client.Authenticated = true;
                            client.UserName = userName;
                            client.UserRoleID = roleID;
                            appLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Пользователь {0} успешно аутентифицирован" :
                                "The user {0} is successfully authenticated",
                                userName), Log.ActTypes.Action);
                        }
                        else
                        {
                            client.ActivityDT = DateTime.MinValue; // для отключения клиента после отправки ответа
                            appLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Неудачная попытка аутентификации пользователя {0}" :
                                "Unsuccessful attempt to authenticate the user {0}",
                                userName), Log.ActTypes.Action);
                        }
                    }

                    respDataLen = 1;
                    outBuf[3] = (byte)roleID;
                    break;
                case 0x02: // запрос состояния сервера (ping)
                    respDataLen = 1;
                    outBuf[3] = mainLogic.ServerIsReady ? (byte)1 : (byte)0;
                    break;
                case 0x03: // запись текущего среза
                    if (client.UserRoleID == BaseValues.Roles.App)
                    {
                        int cnlCnt = BitConverter.ToUInt16(inBuf, 3);
                        SrezTableLight.Srez srez = new SrezTableLight.Srez(DateTime.MinValue, cnlCnt);

                        for (int i = 0, j = 5; i < cnlCnt; i++, j += 14)
                        {
                            srez.CnlNums[i] = (int)BitConverter.ToUInt32(inBuf, j);
                            srez.CnlData[i] = new SrezTableLight.CnlData(
                                BitConverter.ToDouble(inBuf, j + 4),
                                BitConverter.ToUInt16(inBuf, j + 12));
                        }

                        outBuf[3] = mainLogic.ProcCurData(srez) ? (byte)1 : (byte)0;
                    }
                    else
                    {
                        outBuf[3] = 0;
                    }

                    respDataLen = 1;
                    break;
                case 0x04: // запись архивного среза
                    if (client.UserRoleID == BaseValues.Roles.App)
                    {
                        DateTime dateTime = Arithmetic.DecodeDateTime(BitConverter.ToDouble(inBuf, 3));
                        int cnlCnt = BitConverter.ToUInt16(inBuf, 11);
                        SrezTableLight.Srez srez = new SrezTableLight.Srez(dateTime, cnlCnt);

                        for (int i = 0, j = 13; i < cnlCnt; i++, j += 14)
                        {
                            srez.CnlNums[i] = (int)BitConverter.ToUInt32(inBuf, j);
                            srez.CnlData[i] = new SrezTableLight.CnlData(
                                BitConverter.ToDouble(inBuf, j + 4),
                                BitConverter.ToUInt16(inBuf, j + 12));
                        }

                        outBuf[3] = mainLogic.ProcArcData(srez) ? (byte)1 : (byte)0;
                    }
                    else
                    {
                        outBuf[3] = 0;
                    }

                    respDataLen = 1;
                    break;
                case 0x05: // запись события
                    if (client.UserRoleID == BaseValues.Roles.App)
                    {
                        EventTableLight.Event ev = new EventTableLight.Event();
                        ev.DateTime = Arithmetic.DecodeDateTime(BitConverter.ToDouble(inBuf, 3));
                        ev.ObjNum = BitConverter.ToUInt16(inBuf, 11);
                        ev.KPNum = BitConverter.ToUInt16(inBuf, 13);
                        ev.ParamID = BitConverter.ToUInt16(inBuf, 15);
                        ev.CnlNum = (int)BitConverter.ToUInt32(inBuf, 17);
                        ev.OldCnlVal = BitConverter.ToDouble(inBuf, 21);
                        ev.OldCnlStat = BitConverter.ToUInt16(inBuf, 29);
                        ev.NewCnlVal = BitConverter.ToDouble(inBuf, 31);
                        ev.NewCnlStat = BitConverter.ToUInt16(inBuf, 39);
                        ev.Checked = BitConverter.ToBoolean(inBuf, 41);
                        ev.UserID = BitConverter.ToUInt16(inBuf, 42);
                        int evDescrLen = inBuf[44];
                        int evDataLen = inBuf[45 + evDescrLen];
                        ev.Descr = Encoding.Default.GetString(inBuf, 45, evDescrLen);
                        ev.Data = Encoding.Default.GetString(inBuf, 46 + evDescrLen, evDataLen);

                        outBuf[3] = mainLogic.ProcEvent(ev) ? (byte)1 : (byte)0;
                    }
                    else
                    {
                        outBuf[3] = 0;
                    }

                    respDataLen = 1;
                    break;
                case 0x06: // команда ТУ
                    bool cmdProcOk = false; // команда обработана успешно

                    if (client.UserRoleID == BaseValues.Roles.Admin ||
                        client.UserRoleID == BaseValues.Roles.Dispatcher || client.UserRoleID == BaseValues.Roles.App)
                    {
                        int cmdUserID = BitConverter.ToUInt16(inBuf, 3);
                        byte cmdTypeID = inBuf[5];
                        int ctrlCnlNum = BitConverter.ToUInt16(inBuf, 6);
                        MainLogic.CtrlCnl ctrlCnl = mainLogic.GetCtrlCnl(ctrlCnlNum);

                        string notFoundStr = ctrlCnl == null ? Localization.UseRussian ?
                            " (не найден)" : " (not found)" : "";
                        appLog.WriteAction(string.Format(Localization.UseRussian ?
                            "Команда ТУ: канал упр. = {0}{1}, ид. польз. = {2}" :
                            "Command: out channel = {0}{1}, user ID = {2}",
                            ctrlCnlNum, notFoundStr, cmdUserID), Log.ActTypes.Action);

                        if (ctrlCnl != null)
                        {
                            // создание команды ТУ
                            ModLogic.Command ctrlCmd = new ModLogic.Command(cmdTypeID);
                            ctrlCmd.CmdData = new byte[BitConverter.ToUInt16(inBuf, 8)];
                            Array.Copy(inBuf, 10, ctrlCmd.CmdData, 0, ctrlCmd.CmdData.Length);

                            if (cmdTypeID == BaseValues.CmdTypes.Standard || cmdTypeID == BaseValues.CmdTypes.Binary)
                            {
                                ctrlCmd.KPNum = (ushort)ctrlCnl.KPNum;
                                ctrlCmd.CmdNum = (ushort)ctrlCnl.CmdNum;
                                if (cmdTypeID == BaseValues.CmdTypes.Standard && ctrlCmd.CmdData.Length == 8)
                                    ctrlCmd.CmdVal = BitConverter.ToDouble(ctrlCmd.CmdData, 0);
                            }
                            else if (cmdTypeID == BaseValues.CmdTypes.Request)
                            {
                                ctrlCmd.KPNum = BitConverter.ToUInt16(inBuf, 10);
                            }

                            // обработка команды ТУ
                            bool passToClients;
                            mainLogic.ProcCommand(ctrlCnl, ctrlCmd, cmdUserID, out passToClients);

                            // передача команды ТУ подключенным клиентам
                            if (passToClients)
                            {
                                foreach (ClientInfo cl in clients)
                                    if (cl.UserRoleID == BaseValues.Roles.App)
                                        cl.CmdList.Add(ctrlCmd);
                            }
                            else
                            {
                                appLog.WriteAction(Localization.UseRussian ?
                                    "Команда ТУ отменена" : "Command is canceled", Log.ActTypes.Action);
                            }

                            cmdProcOk = true;
                        }
                    }

                    respDataLen = 1;
                    outBuf[3] = cmdProcOk ? (byte)1 : (byte)0;
                    break;
                case 0x07: // запрос команды ТУ
                    if (client.UserRoleID == BaseValues.Roles.App && client.CmdList.Count > 0)
                    {
                        ModLogic.Command ctrlCmd = client.CmdList[0];
                        int cmdDataLen = ctrlCmd.CmdData == null ? 0 : ctrlCmd.CmdData.Length;
                        respDataLen = 7 + cmdDataLen;
                        outBuf[3] = (byte)(cmdDataLen % 256);
                        outBuf[4] = (byte)(cmdDataLen / 256);
                        outBuf[5] = (byte)ctrlCmd.CmdTypeID;
                        outBuf[6] = (byte)(ctrlCmd.KPNum % 256);
                        outBuf[7] = (byte)(ctrlCmd.KPNum / 256);
                        outBuf[8] = (byte)(ctrlCmd.CmdNum % 256);
                        outBuf[9] = (byte)(ctrlCmd.CmdNum / 256);
                        if (cmdDataLen > 0)
                            Array.Copy(ctrlCmd.CmdData, 0, outBuf, 10, cmdDataLen);

                        // удаление команды ТУ из списка команд клиента
                        client.CmdList.RemoveAt(0);
                    }
                    else
                    {
                        respDataLen = 2;
                        outBuf[3] = 0;
                        outBuf[4] = 0;
                    }
                    break;
                case 0x08: // открытие и чтение из файла
                    int readCnt = 0;
                    bool readOk = false;

                    if (client.Authenticated)
                    {
                        client.CloseFile();

                        try { client.Dir = (Dirs)inBuf[3]; }
                        catch { client.Dir = Dirs.Cur; }

                        int fileNameLen = inBuf[4];
                        client.FileName = Encoding.Default.GetString(inBuf, 5, fileNameLen);
                        string fullFileName = GetFullFileName(client.Dir, client.FileName);
                        int count = BitConverter.ToUInt16(inBuf, 5 + fileNameLen);

                        if (settings.DetailedLog)
                            appLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Открытие файла {0}" : "Opening file {0}", fullFileName), Log.ActTypes.Action);

                        try
                        {
                            if (File.Exists(fullFileName))
                            {
                                client.FileStream = new FileStream(fullFileName,
                                    FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                                readCnt = client.FileStream.Read(outBuf, 6, count);
                                readOk = true;
                            }
                            else
                            {
                                appLog.WriteAction(string.Format(Localization.UseRussian ?
                                    "Файл {0} не найден." : "File {0} not found.",
                                    client.FullFileNameInfo), Log.ActTypes.Error);
                            }
                        }
                        catch (Exception ex)
                        {
                            appLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Ошибка при работе с файлом {0}: {1}" : "Error working with the file {0}: {1}",
                                client.FullFileNameInfo, ex.Message), Log.ActTypes.Exception);
                        }
                        finally
                        {
                            if (readCnt < count)
                                client.CloseFile();
                        }
                    }

                    respDataLen = 3 + readCnt;
                    outBuf[3] = readOk ? (byte)1 : (byte)0;
                    outBuf[4] = (byte)(readCnt % 256);
                    outBuf[5] = (byte)(readCnt / 256);
                    break;
                case 0x09: // перемещение позиции чтения из файла
                    long pos = 0;
                    bool seekOk = false;

                    if (client.Authenticated && client.FileStream != null)
                    {
                        SeekOrigin origin;
                        try { origin = (SeekOrigin)inBuf[3]; }
                        catch { origin = SeekOrigin.Begin; }
                        long offset = BitConverter.ToUInt32(inBuf, 4);

                        try
                        {
                            pos = client.FileStream.Seek(offset, origin);
                            seekOk = true;
                        }
                        catch (Exception ex)
                        {
                            appLog.WriteAction("Ошибка при работе с файлом " + client.FullFileNameInfo +
                                ": " + ex.Message, Log.ActTypes.Exception);
                        }
                    }

                    respDataLen = 5;
                    outBuf[3] = seekOk ? (byte)1 : (byte)0;
                    Array.Copy(BitConverter.GetBytes((uint)pos), 0, outBuf, 4, 4);
                    break;
                case 0x0A: // чтение из файла
                    readCnt = 0;

                    if (client.Authenticated && client.FileStream != null)
                    {
                        int count = BitConverter.ToUInt16(inBuf, 3);

                        try
                        {
                            readCnt = client.FileStream.Read(outBuf, 5, count);
                        }
                        catch (Exception ex)
                        {
                            appLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Ошибка при работе с файлом {0}: {1}" : "Error working with the file {0}: {1}",
                                client.FullFileNameInfo, ex.Message), Log.ActTypes.Exception);
                        }
                        finally
                        {
                            if (readCnt < count)
                                client.CloseFile();
                        }
                    }

                    respDataLen = 2 + readCnt;
                    outBuf[3] = (byte)(readCnt % 256);
                    outBuf[4] = (byte)(readCnt / 256);
                    break;
                case 0x0B: // закрытие файла
                    if (client.Authenticated && client.FileStream != null)
                    {
                        client.CloseFile();
                        outBuf[3] = 1;
                    }
                    else
                    {
                        outBuf[3] = 0;
                    }

                    respDataLen = 1;
                    break;
                case 0x0C: // запрос времени изменения файлов
                    int fileCnt = inBuf[3];
                    outBuf[3] = inBuf[3];

                    for (int i = 0, j = 4, k = 4; i < fileCnt; i++, k += 8)
                    {
                        Dirs dir;
                        try { dir = (Dirs)inBuf[j++]; }
                        catch { dir = Dirs.Cur; }

                        int fileNameLen = inBuf[j++];
                        string fileName = Encoding.Default.GetString(inBuf, j, fileNameLen);
                        string fullFileName = GetFullFileName(dir, fileName);
                        j += fileNameLen;

                        if (settings.DetailedLog)
                            appLog.WriteAction(string.Format(Localization.UseRussian ?
                                "Получение времени изменения файла {0}" :
                                "Obtaining the modification time of the file {0}", fullFileName), Log.ActTypes.Action);

                        double fileModTime;
                        try
                        {
                            fileModTime = File.Exists(fullFileName) ?
                                Arithmetic.EncodeDateTime(File.GetLastWriteTime(fullFileName)) : 0;
                        }
                        catch { fileModTime = 0; }

                        Array.Copy(BitConverter.GetBytes(fileModTime), 0, outBuf, k, 8);
                    }

                    respDataLen = 1 + 8 * fileCnt;
                    break;
                case 0x0D: // запрос данных из таблицы среза
                    byte srezTypeNum = inBuf[3];
                    MainLogic.SrezTypes srezType;
                    DateTime srezDate;

                    if (srezTypeNum == 0x01)
                    {
                        srezType = MainLogic.SrezTypes.Cur;
                        srezDate = DateTime.MinValue;
                    }
                    else
                    {
                        srezType = srezTypeNum == 0x02 ? MainLogic.SrezTypes.Hour : MainLogic.SrezTypes.Min;
                        srezDate = new DateTime(inBuf[4] + 2000, inBuf[5], inBuf[6]);
                    }

                    int cnlNumCnt = BitConverter.ToUInt16(inBuf, 7);
                    int[] cnlNums = new int[cnlNumCnt];

                    for (int i = 0, j = 9; i < cnlNumCnt; i++, j += 4)
                        cnlNums[i] = (int)BitConverter.ToUInt32(inBuf, j);

                    if (settings.DetailedLog)
                    {
                        string srezTypeStr;
                        if (srezType == MainLogic.SrezTypes.Cur)
                            srezTypeStr = Localization.UseRussian ? "текущие" : "current";
                        else if (srezType == MainLogic.SrezTypes.Min)
                            srezTypeStr = Localization.UseRussian ? "минутные" : "minute";
                        else
                            srezTypeStr = Localization.UseRussian ? "часовые" : "hourly";

                        appLog.WriteAction(string.Format(Localization.UseRussian ?
                            "Запрос данных. Тип: {0}. Дата: {1}. Каналы: {2}" :
                            "Data request. Type: {0}. Date: {1}. Channels: {2}",
                            srezTypeStr, srezDate.ToString("d", Localization.Culture), string.Join(", ", cnlNums)),
                            Log.ActTypes.Action);
                    }

                    SrezTableLight srezTable = mainLogic.GetSrezTable(srezDate, srezType, cnlNums);
                    int srezCnt = srezTable == null ? 0 : srezTable.SrezList.Count;
                    outBuf[5] = (byte)(srezCnt % 256);
                    outBuf[6] = (byte)(srezCnt / 256);
                    extraData = new byte[srezCnt * (10 * cnlNumCnt + 8)];

                    for (int i = 0, j = 0; i < srezCnt; i++)
                    {
                        SrezTableLight.Srez srez = srezTable.SrezList.Values[i];
                        Array.Copy(BitConverter.GetBytes(Arithmetic.EncodeDateTime(srez.DateTime)), 0, extraData, j, 8);
                        j += 8;

                        for (int k = 0; k < cnlNumCnt; k++)
                        {
                            SrezTable.CnlData cnlData = srez.CnlData[k];
                            Array.Copy(BitConverter.GetBytes(cnlData.Val), 0, extraData, j, 8);
                            j += 8;
                            extraData[j++] = (byte)(cnlData.Stat % 256);
                            extraData[j++] = (byte)(cnlData.Stat / 256);
                        }
                    }

                    respDataLen = 2 + extraData.Length;
                    break;
                case 0x0E: // квитирование события
                    if (client.Authenticated)
                    {
                        int evUserID = BitConverter.ToUInt16(inBuf, 3);
                        DateTime evDate = new DateTime(inBuf[5] + 2000, inBuf[6], inBuf[7]);
                        int evNum = BitConverter.ToUInt16(inBuf, 8);
                        outBuf[3] = mainLogic.CheckEvent(evDate, evNum, evUserID) ? (byte)1 : (byte)0;
                    }
                    else
                    {
                        outBuf[3] = 0;
                    }

                    respDataLen = 1;
                    break;
            }

            // передача ответа на команду
            if (sendResp)
            {
                if (cmd == 0x0D)
                {
                    int respLen = 5 + respDataLen;
                    Array.Copy(BitConverter.GetBytes((uint)respLen), 0, outBuf, 0, 4);
                    outBuf[4] = cmd;
                    client.NetStream.Write(outBuf, 0, 7);
                }
                else
                {
                    int respLen = 3 + respDataLen;
                    Array.Copy(BitConverter.GetBytes((ushort)respLen), 0, outBuf, 0, 2);
                    outBuf[2] = cmd;
                    client.NetStream.Write(outBuf, 0, respLen);
                }

                if (extraData != null && extraData.Length > 0)
                    client.NetStream.Write(extraData, 0, extraData.Length);
            }
        }
Beispiel #9
0
        private void btnSendEvent_Click(object sender, EventArgs e)
        {
            // отправка события SCADA-Серверу
            double oldCnlVal = ScadaUtils.StrToDouble(txtEvOldCnlVal.Text);
            if (double.IsNaN(oldCnlVal))
            {
                ScadaUtils.ShowError(AppPhrases.IncorrectOldCnlVal);
                return;
            }

            double newCnlVal = ScadaUtils.StrToDouble(txtEvNewCnlVal.Text);
            if (double.IsNaN(newCnlVal))
            {
                ScadaUtils.ShowError(AppPhrases.IncorrectNewCnlVal);
                return;
            }

            EventTableLight.Event ev = new EventTableLight.Event();
            ev.DateTime = dtpEvDate1.Value.Date.Add(dtpEvTime.Value.TimeOfDay);
            ev.ObjNum = decimal.ToInt32(numEvObjNum.Value);
            ev.KPNum = decimal.ToInt32(numEvKPNum.Value);
            ev.ParamID = decimal.ToInt32(numEvParamID.Value);
            ev.CnlNum = decimal.ToInt32(numEvCnlNum.Value);
            ev.OldCnlVal = oldCnlVal;
            ev.OldCnlStat = decimal.ToInt32(numEvOldCnlStat.Value);
            ev.NewCnlVal = newCnlVal;
            ev.NewCnlStat = decimal.ToInt32(numEvNewCnlStat.Value);
            ev.UserID = decimal.ToInt32(numEvUserID1.Value);
            ev.Checked = ev.UserID > 0;
            ev.Descr = txtEvDescr.Text;
            ev.Data = txtEvData.Text;

            bool result;
            if (ServerComm.SendEvent(ev, out result))
                ScadaUtils.ShowInfo(AppPhrases.SendEventCompleted);
            else
                ScadaUtils.ShowError(ServerComm.ErrMsg);
        }
Beispiel #10
0
        /// <summary>
        /// Записать изменения таблицы dataTable в файл или поток
        /// </summary>
        public void Update(DataTable dataTable)
        {
            if (dataTable == null)
            {
                throw new ArgumentNullException("dataTable");
            }

            Stream       stream = null;
            BinaryWriter writer = null;

            try
            {
                stream = ioStream == null ?
                         new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite) :
                         ioStream;
                writer = new BinaryWriter(stream);

                // запись изменённых событий
                DataView dataView = new DataView(dataTable, "", "", DataViewRowState.ModifiedCurrent);

                foreach (DataRowView rowView in dataView)
                {
                    EventTableLight.Event ev = CreateEvent(rowView);

                    if (ev.Number > 0)
                    {
                        stream.Seek((ev.Number - 1) * EventDataSize, SeekOrigin.Begin);
                        writer.Write(CreateEventBuffer(ev));
                    }
                }

                // запись добавленных событий
                dataView = new DataView(dataTable, "", "", DataViewRowState.Added);

                if (dataView.Count > 0)
                {
                    // установка позиции записи кратной размеру данных события
                    stream.Seek(0, SeekOrigin.End);
                    int evInd = (int)(stream.Position / EventDataSize);
                    int evNum = evInd + 1;
                    stream.Seek(evInd * EventDataSize, SeekOrigin.Begin);

                    // запись событий и установка номеров событий
                    foreach (DataRowView rowView in dataView)
                    {
                        EventTableLight.Event ev = CreateEvent(rowView);
                        writer.Write(CreateEventBuffer(ev));
                        rowView["Number"] = evNum++;
                    }
                }

                // подтверждение успешного сохранения изменений
                dataTable.AcceptChanges();
            }
            finally
            {
                if (fileMode)
                {
                    if (writer != null)
                    {
                        writer.Close();
                    }
                    if (stream != null)
                    {
                        stream.Close();
                    }
                }
            }
        }
Beispiel #11
0
        /// <summary>
        /// Заполнить объект dest из файла событий FileName
        /// </summary>
        protected void FillObj(object dest)
        {
            Stream       stream   = null;
            BinaryReader reader   = null;
            DateTime     fillTime = DateTime.Now;

            EventTableLight eventTableLight = null;
            DataTable       dataTable       = null;

            try
            {
                if (dest is EventTableLight)
                {
                    eventTableLight = dest as EventTableLight;
                }
                else if (dest is DataTable)
                {
                    dataTable = dest as DataTable;
                }
                else
                {
                    throw new ScadaException("Destination object is invalid.");
                }

                // определение даты событий в таблице
                DateTime date = Arithmetic.ExtractDate(tableName);

                // подготовка объекта для хранения данных
                if (eventTableLight != null)
                {
                    eventTableLight.Clear();
                    eventTableLight.TableName = tableName;
                }
                else // dataTable != null
                {
                    // формирование структуры таблицы
                    dataTable.BeginLoadData();
                    dataTable.DefaultView.Sort = "";

                    if (dataTable.Columns.Count == 0)
                    {
                        dataTable.Columns.Add("Number", typeof(int));
                        dataTable.Columns.Add("DateTime", typeof(DateTime)).DefaultValue = date;
                        dataTable.Columns.Add("ObjNum", typeof(int)).DefaultValue        = 0;
                        dataTable.Columns.Add("KPNum", typeof(int)).DefaultValue         = 0;
                        dataTable.Columns.Add("ParamID", typeof(int)).DefaultValue       = 0;
                        dataTable.Columns.Add("CnlNum", typeof(int)).DefaultValue        = 0;
                        dataTable.Columns.Add("OldCnlVal", typeof(double)).DefaultValue  = 0.0;
                        dataTable.Columns.Add("OldCnlStat", typeof(int)).DefaultValue    = 0;
                        dataTable.Columns.Add("NewCnlVal", typeof(double)).DefaultValue  = 0.0;
                        dataTable.Columns.Add("NewCnlStat", typeof(int)).DefaultValue    = 0;
                        dataTable.Columns.Add("Checked", typeof(bool)).DefaultValue      = false;
                        dataTable.Columns.Add("UserID", typeof(int)).DefaultValue        = 0;
                        dataTable.Columns.Add("Descr", typeof(string));
                        dataTable.Columns.Add("Data", typeof(string));
                        dataTable.DefaultView.AllowNew    = false;
                        dataTable.DefaultView.AllowEdit   = false;
                        dataTable.DefaultView.AllowDelete = false;
                    }
                    else
                    {
                        DataColumn colDateTime = dataTable.Columns["DateTime"];
                        if (colDateTime != null)
                        {
                            colDateTime.DefaultValue = date;
                        }
                        dataTable.Rows.Clear();
                    }
                }

                // заполнение таблицы из файла
                stream = ioStream == null ?
                         new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) :
                         ioStream;
                reader = new BinaryReader(stream);

                Byte[] eventBuf = new byte[EventDataSize]; // буфер данных события
                int    evNum    = 1;                       // порядковый номер события

                while (stream.Position < stream.Length)
                {
                    int readSize = reader.Read(eventBuf, 0, EventDataSize);
                    if (readSize == EventDataSize)
                    {
                        // создание события на основе считанных данных
                        EventTableLight.Event ev = new EventTableLight.Event();
                        ev.Number = evNum;
                        evNum++;

                        double time = BitConverter.ToDouble(eventBuf, 0);
                        int    hour, min, sec;
                        Arithmetic.DecodeTime(time, out hour, out min, out sec);
                        ev.DateTime = new DateTime(date.Year, date.Month, date.Day, hour, min, sec);

                        ev.ObjNum     = BitConverter.ToUInt16(eventBuf, 8);
                        ev.KPNum      = BitConverter.ToUInt16(eventBuf, 10);
                        ev.ParamID    = BitConverter.ToUInt16(eventBuf, 12);
                        ev.CnlNum     = BitConverter.ToUInt16(eventBuf, 14);
                        ev.OldCnlVal  = BitConverter.ToDouble(eventBuf, 16);
                        ev.OldCnlStat = eventBuf[24];
                        ev.NewCnlVal  = BitConverter.ToDouble(eventBuf, 25);
                        ev.NewCnlStat = eventBuf[33];
                        ev.Checked    = eventBuf[34] > 0;
                        ev.UserID     = BitConverter.ToUInt16(eventBuf, 35);
                        ev.Descr      = BytesToStr(eventBuf, 37);
                        ev.Data       = BytesToStr(eventBuf, 138);

                        // создание строки заполняемой таблицы
                        if (eventTableLight != null)
                        {
                            eventTableLight.AllEvents.Add(ev); // быстрее, чем eventTableLight.AddEvent(ev)
                        }
                        else // dataTable != null
                        {
                            DataRow row = dataTable.NewRow();
                            row["Number"]     = ev.Number;
                            row["DateTime"]   = ev.DateTime;
                            row["ObjNum"]     = ev.ObjNum;
                            row["KPNum"]      = ev.KPNum;
                            row["ParamID"]    = ev.ParamID;
                            row["CnlNum"]     = ev.CnlNum;
                            row["OldCnlVal"]  = ev.OldCnlVal;
                            row["OldCnlStat"] = ev.OldCnlStat;
                            row["NewCnlVal"]  = ev.NewCnlVal;
                            row["NewCnlStat"] = ev.NewCnlStat;
                            row["Checked"]    = ev.Checked;
                            row["UserID"]     = ev.UserID;
                            row["Descr"]      = ev.Descr;
                            row["Data"]       = ev.Data;
                            dataTable.Rows.Add(row);
                        }
                    }
                }
            }
            catch (EndOfStreamException)
            {
                // нормальная ситуация окончания файла
            }
            catch
            {
                fillTime = DateTime.MinValue;
                throw;
            }
            finally
            {
                if (fileMode)
                {
                    if (reader != null)
                    {
                        reader.Close();
                    }
                    if (stream != null)
                    {
                        stream.Close();
                    }
                }

                if (eventTableLight != null)
                {
                    eventTableLight.LastFillTime = fillTime;
                }
                else if (dataTable != null)
                {
                    dataTable.EndLoadData();
                    dataTable.AcceptChanges();
                    dataTable.DefaultView.Sort = "Number";
                }
            }
        }
Beispiel #12
0
        /// <summary>
        /// Отправить событие SCADA-Серверу
        /// </summary>
        public bool SendEvent(KPLogic.KPEvent kpEvent)
        {
            if (kpEvent == null || kpEvent.KPTag == null || kpEvent.KPTag.CnlNum <= 0)
            {
                return true;
            }
            else
            {
                EventTableLight.Event ev = new EventTableLight.Event();
                ev.Number = kpEvent.KPNum;
                ev.DateTime = kpEvent.DateTime;
                ev.ObjNum = kpEvent.KPTag.ObjNum;
                ev.KPNum = kpEvent.KPNum;
                ev.ParamID = kpEvent.KPTag.ParamID;
                ev.CnlNum = kpEvent.KPTag.CnlNum;
                ev.OldCnlVal = kpEvent.OldData.Val;
                ev.OldCnlStat = kpEvent.OldData.Stat;
                ev.NewCnlVal = kpEvent.NewData.Val;
                ev.NewCnlStat = kpEvent.NewData.Stat;
                ev.Checked = kpEvent.Checked;
                ev.UserID = kpEvent.UserID;
                ev.Descr = kpEvent.Descr;
                ev.Data = kpEvent.Data;

                bool result;
                return SendEvent(ev, out result) && result;
            }
        }