scada server error

Forum Home Forums Rapid SCADA on Raspberry Pi scada server error

This topic contains 11 replies, has 2 voices, and was last updated by Mikhail Mikhail 1 year, 10 months ago.

Viewing 12 posts - 1 through 12 (of 12 total)
  • Author
    Posts
  • #686
    welschemeyer
    welschemeyer
    Participant

    Hello,

    I have installed the SCADA server according to the instructions on the Raspberry Pi get now but in the initial configuration changes without something to have this error:

    log from ScadaServerSvc.log

    --------------------------------------------------------------------------------
    2015-11-09 15:29:17 <raspberrypi><root><ACT> ScadaServerService 4.5.0.5 is started
    2015-11-09 15:29:18 <raspberrypi><root><ACT> Check the existence of the data directories is completed successfully
    2015-11-09 15:29:18 <raspberrypi><root><ACT> Check the existence of the configuration database files is completed successfully
    2015-11-09 15:29:19 <raspberrypi><root><ACT> Input channels are read from the configuration database. Active channel count: 14
    2015-11-09 15:29:19 <raspberrypi><root><ACT> Ouput channels are read from the configuration database
    2015-11-09 15:29:19 <raspberrypi><root><ACT> Users are read from the configuration database
    2015-11-09 15:29:19 <raspberrypi><root><ACT> Formulas are read from the configuration database
    2015-11-09 15:29:22 <raspberrypi><root><ERR> Error compiling the source code of the formulas: 
    Line 79, column 31: error CS0589: Internal compiler error during parsingSystem.FormatException: Input string was not in the correct format
    Line 0, column 0: error :   at System.Double.Parse (System.String s, NumberStyles style, IFormatProvider provider) [0x00000] in <filename unknown>:0 
    Line 0, column 0: error :   at Mono.CSharp.Tokenizer.adjust_real (TypeCode t, Location loc) [0x00000] in <filename unknown>:0 
    Line 0, column 0: error :   at Mono.CSharp.Tokenizer.is_number (Int32 c, Boolean dotLead) [0x00000] in <filename unknown>:0 
    Line 0, column 0: error :   at Mono.CSharp.Tokenizer.xtoken () [0x00000] in <filename unknown>:0 
    Line 0, column 0: error :   at Mono.CSharp.Tokenizer.token () [0x00000] in <filename unknown>:0 
    Line 0, column 0: error :   at Mono.CSharp.CSharpParser.yyparse (yyInput yyLex) [0x00000] in <filename unknown>:0 
    Line 0, column 0: error :   at Mono.CSharp.CSharpParser.parse () [0x00000] in <filename unknown>:0 
    See the file /etc/scada/ScadaServer/Log/CalcEngine.cs with the source code
    2015-11-09 15:29:23 <raspberrypi><root><ERR> Normal program execution is impossible.

    Here ist the CalcEngine.cs:

    /*
     * Copyright 2015 Mikhail Shiryaev
     * 
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     * 
     *     http://www.apache.org/licenses/LICENSE-2.0
     * 
    10 * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     * 
     * 
     * Product  : Rapid SCADA
     * Module   : SCADA-Server Service
     * Summary  : Mechanism providing calculation of formulas
    20 * 
     * Author   : Mikhail Shiryaev
     * Created  : 2013
     * Modified : 2015
     */
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    using Scada.Data;
    ///30
    namespace Scada.Server.Svc
    {
        /// <summary>
        /// Mechanism providing calculation of formulas
        /// <para>Механизм, обеспечивающий вычисления по формулам</para>
        /// </summary>
        public class CalcEngine
        {
            /// <summary>
    ///40        The channel number for which the formula is calculated
            /// <para>Номер канала, для которого вычисляется формула </para>
            /// </summary>
            private int curCnlNum;
            /// <summary>
            /// Input channel data transmitted to the server before the calculation
            /// <para>Передаваемые серверу данные входного канала до расчёта</para>
            /// </summary>
            private SrezTableLight.CnlData initialCnlData;
            /// <summary>
    ///50        Standard command value transmitted to the server before the calculation
            /// <para>Передаваемое серверу значение стандартной команды управления до расчёта</para>
            /// </summary>
            private double initialCmdVal;
            /// <summary>
            /// Binary command data transmitted to the server before the calculation
            /// <para>Передаваемые серверу данные бинарной команды управления до расчёта</para>
            /// </summary>
            private byte[] initialCmdData;
            /// <summary>
    ///60        Calculate the input channel formula flag
            /// <para>Признак вычисления формулы входного канала</para>
            /// </summary>
            private bool calcInCnl;
            /// <summary>
            /// Getting input channel data method
            /// <para>Метод получения данных входного канала</para>
            /// </summary>
            private Func<int, SrezTableLight.CnlData> getCnlData;
    
    ///70        
            /// <summary>
            /// Initializes a new instance of the class
            /// <para>Конструктор</para>
            /// </summary>
            public CalcEngine()
            {
                curCnlNum = -1;
                initialCnlData = SrezTableLight.CnlData.Empty;
    ///79:
                initialCmdVal = 0.0;
                initialCmdData = null;
                calcInCnl = false;
                getCnlData = null;
            }
    
            /// <summary>
            /// Initializes a new instance of the class
            /// <para>Конструктор</para>
            /// </summary>
            public CalcEngine(Func<int, SrezTableLight.CnlData> getCnlData)
                : this()
            {
                this.getCnlData = getCnlData;
            }
    
            /// <summary>
            /// Gets input channel value transmitted to the server before the calculation
            /// <para>Получить передаваемое серверу значение входного канала до расчёта</para>
            /// </summary>
            public double Cnl
            {
                get
                {
                    return initialCnlData.Val;
                }
            }
    
            /// <summary>
            /// Gets input channel value transmitted to the server before the calculation
            /// <para>Получить передаваемое серверу значение входного канала до расчёта</para>
            /// </summary>
            public double CnlVal
            {
                get
                {
                    return initialCnlData.Val;
                }
            }
            
            /// <summary>
            /// Gets input channel status transmitted to the server before the calculation
            /// <para>Получить передаваемый серверу статус входного канала до расчёта</para>
            /// </summary>
            public int CnlStat
            {
                get
                {
                    return initialCnlData.Stat;
                }
            }
    
            /// <summary>
            /// Gets command value transmitted to the server before the calculation
            /// <para>Получить передаваемое серверу значение команды управления до расчёта</para>
            /// </summary>
            public double Cmd
            {
                get
                {
                    return initialCmdVal;
                }
            }
    
            /// <summary>
            /// Gets standard command value transmitted to the server before the calculation
            /// <para>Получить передаваемое серверу значение стандартной команды управления до расчёта</para>
            /// </summary>
            public double CmdVal
            {
                get
                {
                    return initialCmdVal;
                }
            }
    
            /// <summary>
            /// Gets binary command data transmitted to the server before the calculation
            /// <para>Получить передаваемые серверу данные бинарной команды управления до расчёта</para>
            /// </summary>
            public byte[] CmdData
            {
                get
                {
                    return initialCmdData;
                }
            }
    
            /// <summary>
            /// Gets the channel number for which the formula is calculated
            /// <para>Получить номер канала, для которого вычисляется формула</para>
            /// </summary>
            public int CnlNum
            {
                get
                {
                    return curCnlNum;
                }
            }
    
            /// <summary>
            /// Gets the natural logarithmic base, specified by the constant, e
            /// <para>Получить число e</para>
            /// </summary>
            public double E
            {
                get
                {
                    return Math.E;
                }
            }
    
            /// <summary>
            /// Gets the ratio of the circumference of a circle to its diameter, specified by the constant, π
            /// <para>Получить число π</para>
            /// </summary>
            public double PI
            {
                get
                {
                    return Math.PI;
                }
            }
    
            /// <summary>
            /// Starts the input channel data calculation
            /// <para>Начать вычисление данных входного канала</para>
            /// </summary>
            private void BeginCalcCnlData(int cnlNum, SrezTableLight.CnlData initialCnlData)
            {
                curCnlNum = cnlNum;
                this.initialCnlData = initialCnlData;
                initialCmdVal = 0.0;
                initialCmdData = null;
                calcInCnl = true;
            }
    
            /// <summary>
            /// Ends the input channel data calculation
            /// <para>Завершить вычисление данных входного канала</para>
            /// </summary>
            private void EndCalcCnlData()
            {
                curCnlNum = -1;
                initialCnlData = SrezTableLight.CnlData.Empty;
                calcInCnl = false;
            }
    
            /// <summary>
            /// Starts the command value or data calculation
            /// <para>Начать вычисление значения или данных команды</para>
            /// </summary>
            private void BeginCalcCmdData(int ctrlCnlNum, double initialCmdVal, byte[] initialCmdData)
            {
                curCnlNum = ctrlCnlNum;
                this.initialCnlData = SrezTableLight.CnlData.Empty;
                this.initialCmdVal = initialCmdVal;
                this.initialCmdData = initialCmdData;
            }
    
            /// <summary>
            /// Ends the command value or data calculation
            /// <para>Завершить вычисление значения или данных команды</para>
            /// </summary>
            private void EndCalcCmdData()
            {
                curCnlNum = -1;
                initialCmdVal = 0.0;
                initialCmdData = null;
            }
    
            /// <summary>
            /// Gets the current value of the formula channel
            /// <para>Получить текущее значение канала формулы</para>
            /// </summary>
            public double Val()
            {
                return calcInCnl ? Val(curCnlNum) : SrezTableLight.CnlData.Empty.Val;
            }
    
            /// <summary>
            /// Gets the current value of the channel n
            /// <para>Получить текущее значение канала n</para>
            /// </summary>
            public double Val(int n)
            {
                return (getCnlData == null ? SrezTableLight.CnlData.Empty : getCnlData(n)).Val;
            }
    
            /// <summary>
            /// Gets the current status of the formula channel
            /// <para>Получить текущий статус канала формулы</para>
            /// </summary>
            public int Stat()
            {
                return Stat(curCnlNum);
            }
    
            /// <summary>
            /// Gets the current status of the channel n
            /// <para>Получить текущий статус канала n</para>
            /// </summary>
            public int Stat(int n)
            {
                return (getCnlData == null ? SrezTableLight.CnlData.Empty : getCnlData(n)).Stat;
            }
    
            /// <summary>
            /// Calculates the absolute value of a double-precision floating-point number
            /// <para>Вычислить модуль</para>
            /// </summary>
            public double Abs(double x)
            {
                return Math.Abs(x);
            }
    
            /// <summary>
            /// Calculates the sine of the specified angle
            /// <para>Вычислить синус</para>
            /// </summary>
            public double Sin(double x)
            {
                return Math.Sin(x);
            }
    
            /// <summary>
            /// Calculates the cosine of the specified angle
            /// <para>Вычислить косинус</para>
            /// </summary>
            public double Cos(double x)
            {
                return Math.Cos(x);
            }
    
            /// <summary>
            /// Calculates the tangent of the specified angle
            /// <para>Вычислить тангенс</para>
            /// </summary>
            public double Tan(double x)
            {
                return Math.Tan(x);
            }
    
            /// <summary>
            /// Calculates e raised to the specified power
            /// <para>Вычислить экспоненту</para>
            /// </summary>
            public double Exp(double x)
            {
                return Math.Exp(x);
            }
    
            /// <summary>
            /// Calculates the natural (base e) logarithm of a specified number
            /// <para>Вычислить натуральный логарифм</para>
            /// </summary>
            public double Ln(double x)
            {
                return Math.Log(x);
            }
    
            /// <summary>
            /// Calculates the natural (base e) logarithm of a specified number
            /// <para>Вычислить натуральный логарифм</para>
            /// </summary>
            public double Log(double x)
            {
                return Math.Log(x);
            }
            
            /// <summary>
            /// Calculates the square of a specified number
            /// <para>Возвести в квадрат</para>
            /// </summary>
            public double Sqr(double x)
            {
                return x * x;
            }
    
            /// <summary>
            /// Calculates the square root of a specified number
            /// <para>Вычислить квадратный корень</para>
            /// </summary>
            public double Sqrt(double x)
            {
                return Math.Sqrt(x);
            }
    
            #region Custom source code. Пользовательский исходный код
    public bool DayBeg()
    {
        DateTime nowDT = DateTime.Now;
        DateTime execDT;
        if ((nowDT.Hour == 0 && nowDT.Minute > 0 || nowDT.Hour == 1) &&
            (!DayBegDict.TryGetValue(CnlNum, out execDT) || execDT.Date < nowDT.Date))
        {
            DayBegDict[CnlNum] = nowDT;
            return true;
        }
        else
        {
            return false;
        }
    }
    public Dictionary<int, DateTime> DayBegDict = new Dictionary<int, DateTime>();
    public double GetBit(double val, int n)
    {
        UInt64 uintVal = (UInt64)val;
        return (uintVal >> n) & 1;
    }
    public bool HourBeg()
    {
        DateTime nowDT = DateTime.Now;
        DateTime execDT;
        if (nowDT.Minute == 1 && (!HourBegDict.TryGetValue(CnlNum, out execDT) || 
            execDT < new DateTime(nowDT.Year, nowDT.Month, nowDT.Day, nowDT.Hour, 0, 0)))
        {
            HourBegDict[CnlNum] = nowDT;
            return true;
        }
        else
        {
            return false;
        }
    }
    public Dictionary<int, DateTime> HourBegDict = new Dictionary<int, DateTime>();
    public bool MonthBeg()
    {
        DateTime nowDT = DateTime.Now;
        DateTime execDT;
        if (nowDT.Day == 1 && (nowDT.Hour == 0 && nowDT.Minute > 0 || nowDT.Hour == 1) &&
            (!MonthBegDict.TryGetValue(CnlNum, out execDT) || execDT.Date < nowDT.Date))
        {
            MonthBegDict[CnlNum] = nowDT;
            return true;
        }
        else
        {
            return false;
        }
    }
    public Dictionary<int, DateTime> MonthBegDict = new Dictionary<int, DateTime>();
    public double CalcCnl101Val() { return Convert.ToDouble(Cnl*200/65536 - 40); }
    public int CalcCnl101Stat() { return CnlStat; }
    public void CalcCnl101Data(ref SrezTableLight.CnlData cnlData) { try { BeginCalcCnlData(101, cnlData); cnlData = new SrezTableLight.CnlData(CalcCnl101Val(), CalcCnl101Stat()); } finally { EndCalcCnlData(); }}
    public double CalcCnl102Val() { return Convert.ToDouble(Cnl*200/65536 - 40); }
    public int CalcCnl102Stat() { return CnlStat; }
    public void CalcCnl102Data(ref SrezTableLight.CnlData cnlData) { try { BeginCalcCnlData(102, cnlData); cnlData = new SrezTableLight.CnlData(CalcCnl102Val(), CalcCnl102Stat()); } finally { EndCalcCnlData(); }}
    public double CalcCnl103Val() { return Convert.ToDouble(Cnl*200/65536 - 40); }
    public int CalcCnl103Stat() { return CnlStat; }
    public void CalcCnl103Data(ref SrezTableLight.CnlData cnlData) { try { BeginCalcCnlData(103, cnlData); cnlData = new SrezTableLight.CnlData(CalcCnl103Val(), CalcCnl103Stat()); } finally { EndCalcCnlData(); }}
    public double CalcCnl104Val() { return Convert.ToDouble(Cnl*200/65536 - 40); }
    public int CalcCnl104Stat() { return CnlStat; }
    public void CalcCnl104Data(ref SrezTableLight.CnlData cnlData) { try { BeginCalcCnlData(104, cnlData); cnlData = new SrezTableLight.CnlData(CalcCnl104Val(), CalcCnl104Stat()); } finally { EndCalcCnlData(); }}
    public double CalcCnl105Val() { return Convert.ToDouble(Cnl*200/65536 - 40); }
    public int CalcCnl105Stat() { return CnlStat; }
    public void CalcCnl105Data(ref SrezTableLight.CnlData cnlData) { try { BeginCalcCnlData(105, cnlData); cnlData = new SrezTableLight.CnlData(CalcCnl105Val(), CalcCnl105Stat()); } finally { EndCalcCnlData(); }}
    public double CalcCnl106Val() { return Convert.ToDouble(Cnl*200/65536 - 40); }
    public int CalcCnl106Stat() { return CnlStat; }
    public void CalcCnl106Data(ref SrezTableLight.CnlData cnlData) { try { BeginCalcCnlData(106, cnlData); cnlData = new SrezTableLight.CnlData(CalcCnl106Val(), CalcCnl106Stat()); } finally { EndCalcCnlData(); }}
    public double CalcCnl107Val() { return Convert.ToDouble(Cnl*200/65536 - 40); }
    public int CalcCnl107Stat() { return CnlStat; }
    public void CalcCnl107Data(ref SrezTableLight.CnlData cnlData) { try { BeginCalcCnlData(107, cnlData); cnlData = new SrezTableLight.CnlData(CalcCnl107Val(), CalcCnl107Stat()); } finally { EndCalcCnlData(); }}
            #endregion
        }
    }
    #688
    Mikhail
    Mikhail
    Moderator

    Hi,
    Thanks for the information. I’ll check the issue within a few days. Do you use Raspbian?

    #690
    welschemeyer
    welschemeyer
    Participant

    Yes i use a new Installation of raspian jessie.

    #699
    Mikhail
    Mikhail
    Moderator

    Hi,

    I have tested again Rapid SCADA 4.5 Mono on my Raspberry Pi 2 with Raspbian. It works. Probably, a cause is in the configuration of the specified RPi. Let’s find the cause.

    Line 79 is

    initialCmdVal = 0.0;
    

    Message “Input string was not in the correct format Line 0, column 0: error : at System.Double.Parse” means that 0.0 is not correct double value.

    What culture settings do you use? Is decimal separator a dot in your culture?
    I think that Mono C# compiler contains a bug because line 79 is correct. Compiler must not depend on culture. So we should find workaround.

    #700
    Mikhail
    Mikhail
    Moderator

    Please check your Mono version using the following command

    mono --version
    

    I have tested on:
    Mono JIT compiler version 3.2.8 (Debian 3.2.8+dfsg-4+rpi1)

    #702
    welschemeyer
    welschemeyer
    Participant

    That was the error …..

    I’m From germany an we use a decimal separator ( , )

    Then I will continue to test and hope that everything works out soon

    #703
    Mikhail
    Mikhail
    Moderator

    Write about results, please.

    #718
    welschemeyer
    welschemeyer
    Participant

    So..

    Da bin Ich mal wieder hier ein paar Ideen um die Installation auf dem Raspberry zu vereinfachen.

    Ich weiß mein Englisch ist nicht sehr gut aber, Ich gebe mein bestes.

    Aktuell bin Ich dabei irgendwie eine Kommunikation auf Basis von libnodave.dll nachzubauen, damit man auch mit Siemens SPS kommunizieren kann.

    Installation of Rapid SCADA on Raspberry Pi
    ——————————————-

    1. Copy all the files of Rapid SCADA Mono from scada folder to /etc/scada
    over the UI with Root rights over Console:„sudo pcmanfm“
    after copy set the Folderpermissions to PI / Pi ( right
    click Preferences on folder scada)

    2. Copy the scripts from daemons folder to /etc/init.d

    3. Grant full access to SCADA-Web log folder:

    1. Install Rapid SCADA

    2. Create and test the configuration using Windows

    3. Copy to Raspberry Pi content of the following directories:

    C:\SCADA\BaseDAT
    C:\SCADA\Interface
    C:\SCADA\ScadaComm\Config
    C:\SCADA\ScadaServer\Config (Don’t overwrite ScadaServerSVCConf.xml !!!)
    C:\SCADA\ScadaWeb\config

    #719
    Mikhail
    Mikhail
    Moderator

    Thanks for the improvements of the instruction )

    I use WinSCP for copying files from my Windows workstation. And Putty with MidnightCommander (mc) to run scripts.

    Have you solved the issue caused by decimal separator?

    #720
    Mikhail
    Mikhail
    Moderator

    Google Translate translates German completely unclear )

    #721
    welschemeyer
    welschemeyer
    Participant

    Yes I was able to fix the error.
    I have located the Raspberry again in English.

    What could possibly even in the manual inside, is an example of the calculation function, since I had hastily cleared your example and then had to look no further to find an example.

    Oh sorry that was my mistake.

    I always write only what I want to write in German and then again in English (which I have just forgotten about that)

    ———–

    Ja die Fehler habe ich beheben können

    Was auch noch evtl. in die Anleitung hinein könnte ist ein Beispiel der Berechnungsfunktion, da ich voreilig dein Beispiel gelöscht hatte und dann erstmal länger suchen musste um ein Beispiel zu finden.

    #722
    Mikhail
    Mikhail
    Moderator

    I agree that the manual is not rich of examples. In case of restricted resources the best way is to simplify the UI to allow a user easily understand how to configure a system.
    This forum is a knowledge base. Be free to ask for examples (in a new topic).

Viewing 12 posts - 1 through 12 (of 12 total)

You must be logged in to reply to this topic.