Example #1
0
        internal SensorCommunity(Support s)
        {
            string line;

            Sup = s;
            Sup.LogDebugMessage($"SensorCommunity ctor: Start");

            SensorCommunityHttpClient             = new HttpClient();
            SensorCommunityHttpClient.Timeout     = TimeSpan.FromSeconds(30);
            SensorCommunityHttpClient.BaseAddress = new Uri(URL);

            using (StreamReader cpuFile = new StreamReader("/proc/cpuinfo"))
            {
                line = cpuFile.ReadLine();
                Sup.LogDebugMessage($"SensorCommunity ctor reading cpuinfo: {line}");

                do
                {
                    if (line.Contains("Serial", StringComparison.InvariantCultureIgnoreCase))
                    {
                        Sup.LogDebugMessage($"SensorCommunity ctor: Serial line found => {line}");
                        string[] splitstring = line.Split(':');
                        SensorID = "raspi-" + splitstring[1].Trim();

                        Sup.LogDebugMessage($"SensorCommunity ctor: SensorID = {SensorID}");
                        break;
                    }

                    line = cpuFile.ReadLine();
                } while (true);   // end while
            } // end using => disposes the cpuFile

            Sup.LogDebugMessage($"SensorCommunity ctor end");
        } // end constructor
Example #2
0
        static public void DetectSensors(Support Sup)
        {
            Sup.LogDebugMessage("I2C Detect");
            Sup.LogDebugMessage("===============");

            _I2CDetect = new I2cDetect();
            var list = _I2CDetect.Detect();

            foreach (var i2c in list)
            {
                int r = i2c / 16;
                int c = i2c % 16;
                _nDevices[r, c] = 1;

                // Check if the devices we want are present
                for (int i = 0; i < i2cAddress.Length; i++)
                {
                    if (i2c == i2cAddress[i])
                    {
                        i2cAddressDetected[i] = true;
                        Sup.LogDebugMessage($"DetectSensors: found {Enum.GetName( typeof( I2cSensorsSupported ), i )} at {i2c:x2}  ");
                    }
                }
            }

            Sup.LogDebugMessage("     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f");


            for (int i = 0; i < _rows; i++)
            {
                PrintRow(i, Sup);
            }
        }
Example #3
0
 public I2cSimulatorDevice(Support s, string Name)
 {
     Sup = s;
     Sup.LogDebugMessage($"I2cSimulatorDevice Constructor...{Name}");
     SensorUsed = I2cSensorsSupported.Simulator;
     Valid      = true;
 }
Example #4
0
 public I2cDummyDevice(Support s, string Name)
 {
     Sup = s;
     Sup.LogDebugMessage($"Dummy Constructor...{Name}");
     SensorUsed = I2cSensorsSupported.Dummy;
     Valid      = false;
 }
Example #5
0
        public double NowCast25, NowCast10;                               // Just need one parameter, after calculation
                                                                          // it is send by the webserver and can be forgotten.

        public EmulateAirLink(Support s)
        {
            Sup = s;
            Sup.LogDebugMessage($"AirLink Emulator: Constructor and started");

            DoCalibrated = Sup.GetSensorsIniValue("General", "UseCalibration", "True").Equals("true", StringComparison.OrdinalIgnoreCase);
        }
Example #6
0
        public List <I2cSensordata> ObservationList  = new List <I2cSensordata>(); // The list to create the minutevalues. Filled in DoWork(), Cleared in SetMinuteValuesFromObservations()


        public I2C(Support s, string Name)
        {
            Sup = s;

            Sup.LogDebugMessage($"I2C Constructor {Name}");

            // Make all addresses
            i2cAddress[(int)I2cSensorsSupported.SHT31] = 0x44;

            // Now create the actual device
            try
            {
                SensorUsed = (I2cSensorsSupported)Enum.Parse(typeof(I2cSensorsSupported), Name, true);
                switch (SensorUsed)
                {
                case I2cSensorsSupported.SHT31:
                    Sup.LogDebugMessage("I2C Constructor: Creating SHT31 sensor");
                    Sensor = new SHT31Device(Sup, Name);
                    break;

                case I2cSensorsSupported.Simulator:
                    Sup.LogDebugMessage("I2C Constructor: Creating SHT31 sensor");
                    Sensor = new I2cSimulatorDevice(Sup, Name);
                    break;

                default:
                    Sup.LogDebugMessage($"I2C Constructor: I2c sensor not implemented {SensorUsed}");
                    Sensor = new I2cDummyDevice(Sup, Name);
                    break;
                }
                Sensor.Start();
            }
            catch (Exception e) when(e is ArgumentException || e is ArgumentNullException)
            {
                // We arrive here if the sensor does not exist in the Enum definition
                Sup.LogTraceErrorMessage($"I2C Constructor: Exception on parsing I2cDevice Name : {e.Message}");
                Sup.LogTraceErrorMessage("Either an error in naming or driver not implemented.");
                Sup.LogTraceErrorMessage("Replacing this device by a Dummy Driver. Continuing...");
                Sensor = new I2cDummyDevice(Sup, Name);
            }
        }// Constructor
Example #7
0
        public List <PMSensordata> ObservationList  = new List <PMSensordata>();      // The list to create the minutevalues

        public Serial(Support s, string Name)
        {
            Sup = s;

            Sup.LogDebugMessage($"Serial: Constructor...{Name}");
            try
            {
                SensorUsed = (SerialSensorsSupported)Enum.Parse(typeof(SerialSensorsSupported), Name, true);

                switch (SensorUsed)
                {
                case SerialSensorsSupported.PMS1003:
                    Sup.LogDebugMessage("Serial Constructor: Creating PMS1003 sensor");
                    Sensor = new PMS1003Device(Sup, Name);
                    break;

                case SerialSensorsSupported.Simulator:
                    Sup.LogDebugMessage("Serial Constructor: Creating PMS1003 sensor");
                    Sensor = new SerialSimulatorDevice(Sup, Name);
                    break;

                default:
                    Sup.LogDebugMessage($"Serial Constructor: Serial sensor not implemented {SensorUsed}");
                    Sensor = new SerialDummyDevice(Sup, Name);
                    break;
                }

                Sensor.Open(); // Also called Open in some circles
            }
            catch (Exception e) when(e is ArgumentException || e is ArgumentNullException)
            {
                // We arrive here if the sensor does not exist in the Enum definition
                Sup.LogTraceErrorMessage($"Serial Constructor: Exception on parsing Serial Device Name : {e.Message}");
                Sup.LogTraceErrorMessage("Either an error in naming or driver not implemented.");
                Sup.LogTraceErrorMessage("Replacing this device by a Dummy Driver. Continuing...");
                Sensor = new SerialDummyDevice(Sup, Name);
            }
        }// Serial Constructor
Example #8
0
            internal DefinitionSerialPort(Support s, string Name)
            {
                Sup = s;

                Sup.LogDebugMessage($"DefinitionSerialPort Constructor...");

                try
                {
                    SerialPortUsed     = Sup.GetSensorsIniValue("PortDefinitions", $"{Name}_SerialPort", "/dev/ttyS0");
                    SerialBaudRate     = Convert.ToInt32(Sup.GetSensorsIniValue("PortDefinitions", $"{Name}_SerialBaudrate", "9600"));
                    SerialParity       = (Parity)Enum.Parse(typeof(Parity), Sup.GetSensorsIniValue("PortDefinitions", $"{Name}_SerialParity", "None"), true);
                    SerialDataBits     = Convert.ToInt32(Sup.GetSensorsIniValue("PortDefinitions", $"{Name}_SerialDataBits", "8"));
                    SerialNrOfStopBits = (StopBits)Enum.Parse(typeof(StopBits), Sup.GetSensorsIniValue("PortDefinitions", $"{Name}_SerialStopBits", "One"), true);
                }
                catch (Exception e) when(e is ArgumentException || e is ArgumentNullException || e is OverflowException || e is FormatException)
                {
                    Sup.LogTraceErrorMessage($"Serial: Exception on Serial Port definitions in Inifile : {e.Message}");
                }
            }
Example #9
0
        static private void PrintRow(int rowId, Support Sup)
        {
            string row = string.Format("{0:00}: ", rowId);

            for (int i = 0; i < _cols; i++)
            {
                if ((rowId == 0 && i < 3) || (rowId == 7 && i > 7))
                {
                    row += "   ";
                }
                else
                if (_nDevices[rowId, i] == 0)
                {
                    row += string.Format("-- ");
                }
                else
                {
                    row += string.Format("{0}{1:X} ", rowId, i);
                }
            }

            Sup.LogDebugMessage(row);
        }
Example #10
0
 public override void Start()
 {
     Sup.LogDebugMessage($"I2cSensorDevice {SensorUsed} Start on address {I2C.i2cAddress[ (int) SensorUsed ]:x2}");
     thisConnect = Program.ThisDriver.Connect(I2C.i2cAddress[(int)SensorUsed]);
 }
Example #11
0
        void Init()
        {
            bool NoSerialDevice = false;
            bool NoI2cDevice    = false;

            // Setup logging and Ini
            Sup = new Support();

            Sup.LogDebugMessage(message: "Init() : Start");

            string AirLinkPMDevice = "";
            string AirLinkTHDevice = "";

            Console.CancelKeyPress += new ConsoleCancelEventHandler(CtrlCHandler);
            CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;

            // Setup tracing
            Trace.Listeners.Add(new TextWriterTraceListener($"log/{DateTime.Now.ToString( "yyMMddHHmm", CultureInfo.InvariantCulture )}sensors.log"));
            Trace.AutoFlush = true;
            CUSensorsSwitch = new TraceSwitch("CUSensorsSwitch", "Tracing switch for CUSensors")
            {
                Level = TraceLevel.Verbose
            };

            Sup.LogDebugMessage($"Initial {CUSensorsSwitch} => Error: {CUSensorsSwitch.TraceError}, Warning: {CUSensorsSwitch.TraceWarning}, Info: {CUSensorsSwitch.TraceInfo}, Verbose: {CUSensorsSwitch.TraceVerbose}, ");

            string thisTrace = Sup.GetSensorsIniValue("General", "TraceInfo", "Warning");     // Verbose, Information, Warning, Error, Off

            // Now set the Trace level to the wanted value
            switch (thisTrace.ToLower())
            {
            case "error": CUSensorsSwitch.Level = TraceLevel.Error; break;

            case "warning": CUSensorsSwitch.Level = TraceLevel.Warning; break;

            case "info": CUSensorsSwitch.Level = TraceLevel.Info; break;

            case "verbose": CUSensorsSwitch.Level = TraceLevel.Verbose; break;

            default: CUSensorsSwitch.Level = TraceLevel.Off; break;
            }

            Sup.LogDebugMessage($"According to Inifile {CUSensorsSwitch} => Error: {CUSensorsSwitch.TraceError}, Warning: {CUSensorsSwitch.TraceWarning}, Info: {CUSensorsSwitch.TraceInfo}, Verbose: {CUSensorsSwitch.TraceVerbose}, ");

            // Determine which sensor has to be for the AirLink:
            AirLinkEmulation = Sup.GetSensorsIniValue("General", "AirLinkEmulation", "false").Equals("true", StringComparison.OrdinalIgnoreCase);
            AirLinkPMDevice  = Sup.GetSensorsIniValue("AirLinkDevices", $"PMdevice", "");
            AirLinkTHDevice  = Sup.GetSensorsIniValue("AirLinkDevices", $"THdevice", "");

            // Check if we want AirLinkEmulation and do accordingly
            //
            if (AirLinkEmulation)
            {
                Sup.LogDebugMessage(message: "Init : Creating the AirLink Emulator and the Webserver");
                thisEmulator  = new EmulateAirLink(Sup);
                thisWebserver = new WebServer(Sup, thisEmulator);
            }

            // Do the Serial devices
            Sup.LogDebugMessage(message: "Init : Creating the Serial devices");
            for (int i = 0; i < MaxNrSerialSensors; i++)
            {
                string DeviceName = Sup.GetSensorsIniValue("SerialDevices", $"Serial{i}", "");
                thisSerial[i] = new Serial(Sup, DeviceName);
                if (AirLinkEmulation && $"Serial{i}" == AirLinkPMDevice)
                {
                    Sup.LogDebugMessage(message: $"Init : Serial{i} is AirLink device");
                    thisSerial[i].IsAirLinkSensor = true;
                    thisEmulator.SetSerialDevice(thisSerial[i]);
                }

                if (i == 0 && string.IsNullOrEmpty(DeviceName))
                {
                    NoSerialDevice = true;
                    break;
                }
            }// Serial devices

            // Do the i2c devices
            // Define the driver on this level so we only have one driver in the system on which we open all connections
            Sup.LogTraceInfoMessage(message: "Init : Creating the I2C driver");
            ThisDriver = new I2cDriver(ProcessorPin.Gpio02, ProcessorPin.Gpio03, false);
            Sup.LogTraceInfoMessage(message: $"Init : created the I2cDriver {ThisDriver}");
            I2C.DetectSensors(Sup);

            for (int i = 0; i < MaxNrI2cSensors; i++)
            {
                string DeviceName = Sup.GetSensorsIniValue("I2CDevices", $"I2C{i}", "");
                thisI2C[i] = new I2C(Sup, DeviceName);
                if (AirLinkEmulation && $"I2C{i}" == AirLinkTHDevice)
                {
                    Sup.LogDebugMessage(message: $"Init : I2C{i} is AirLink device");
                    thisI2C[i].IsAirLinkSensor = true;
                    thisEmulator.SetI2cDevice(thisI2C[i]);
                }

                if (i == 0 && string.IsNullOrEmpty(DeviceName))
                {
                    NoI2cDevice = true;
                    break;
                }
            }// i2c devices

            if (AirLinkEmulation && (NoI2cDevice || NoSerialDevice))
            {
                Sup.LogDebugMessage("Init: At leat one serial and one I2c device is required for PM and T/H in AirLink emulation");
                Environment.Exit(0);
            }

            if (AirLinkEmulation)
            {
                Sup.LogDebugMessage(message: $"Init : Starting the webserver");
                thisWebserver.Start();

                // Do the SensorCommunity Init
                DoSensorCommunity = Sup.GetSensorsIniValue("General", "SensorCommunity", "false").Equals("true", StringComparison.OrdinalIgnoreCase);
                Sup.LogDebugMessage(message: $"Init : Starting SensorCommunity: SensorCommunity is {DoSensorCommunity}");

                if (DoSensorCommunity)
                {
                    thisSensorCommunity = new SensorCommunity(Sup);
                }
            }
        } // Init
Example #12
0
        async Task RealMain()
        {
            Init();

            Sup.LogDebugMessage(message: "ZeroWsensors : ----------------------------");
            Sup.LogDebugMessage(message: "ZeroWsensors : Entering Main");

            Console.WriteLine($"{Sup.Version()} {Sup.Copyright}");
            Sup.LogDebugMessage($"{Sup.Version()} {Sup.Copyright}");

            Console.WriteLine("This program comes with ABSOLUTELY NO WARRANTY;\n" +
                              "This is free software, and you are welcome to redistribute it under certain conditions.");
            Sup.LogDebugMessage("This program comes with ABSOLUTELY NO WARRANTY;\n" +
                                "This is free software, and you are welcome to redistribute it under certain conditions.");


            #region MainLoop

            // Start the loop
            using (StreamWriter of = new StreamWriter("CUSensorArray.txt", true))
            {
                int Clock = 0;

                do
                {
                    string thisLine = "";

                    // Do this condional because the ctrl-c interrupt can be given aanywhere.
                    Sup.LogTraceInfoMessage(message: "ZeroWsensors : Getting sensor values from the Main 10 second loop");

                    if (Continue)
                    {
                        Clock++;

                        for (int i = 0; i < MaxNrSerialSensors; i++)
                        {
                            thisSerial[i].DoWork();                                                 // Takes care of the reading of the serial devices
                        }
                        for (int i = 0; i < MaxNrI2cSensors; i++)
                        {
                            thisI2C[i].DoWork();                                                    // Takes care of the  reading of the I2C devices
                        }
                        // So we came here 6 times every 10 seconds. Create the minute values and remove the existing list, create a new one
                        // The average values are always real averages even if some fetches failed in which case the list is shorter
                        // This is the basic work of the sensor handler: fetch data and write to local logfile

                        if (Clock == 6)
                        {
                            Clock = 0;

                            for (int i = 0; i < MaxNrSerialSensors; i++)
                            {
                                thisSerial[i].SetMinuteValuesFromObservations();
                            }
                            for (int i = 0; i < MaxNrI2cSensors; i++)
                            {
                                thisI2C[i].SetMinuteValuesFromObservations();
                            }

                            // Now we do the AirLink handling which is assumed to be called once per minute with the observation list to create
                            // all other necessary lists and calculated values from there
                            if (AirLinkEmulation)
                            {
                                thisEmulator.DoAirLink();

                                // When all done Write out the values to SensorCommunity
                                if (DoSensorCommunity)
                                {
                                    await thisSensorCommunity.Send(thisEmulator);
                                }
                            }

                            // Write out to the logfile
                            for (int i = 0; i < MaxNrSerialSensors; i++)
                            {
                                thisLine += $";{thisSerial[ i ].MinuteValues.Pm1_atm:F1};{thisSerial[ i ].MinuteValues.Pm25_atm:F1};{thisSerial[ i ].MinuteValues.Pm10_atm:F1}";
                            }
                            for (int i = 0; i < MaxNrI2cSensors; i++)
                            {
                                thisLine += $";{thisI2C[ i ].MinuteValues.TemperatureC:F1};{thisI2C[ i ].MinuteValues.Humidity:F0}";
                            }

                            Sup.LogTraceInfoMessage(message: "ZeroWsensors : Writing out the data to the logfile");
                            Sup.LogTraceInfoMessage(message: $"{DateTime.Now:dd-MM-yyyy HH:mm}{thisLine}");
                            of.WriteLine($"{DateTime.Now:dd-MM-yyyy HH:mm}{thisLine}");
                            of.Flush();
                        }
                    }

                    // This is really hardcoded and should NOT change. The whole thing is based on 6 measurements per minute, so loop every 10 seconds
                    Thread.Sleep(10000);
                } while (Continue);   // Do-While
            } // Using the datafile

            #endregion

            Sup.LogDebugMessage("SensorArray Gracefull exit... End");

            Trace.Flush();
            Trace.Close();

            return;
        } // Real main()