Exemple #1
0
        private async static void ReceiveFeedbackAsync()
        {
            var db = new IsmIoTPortalContext();

            while (true)
            {
                var feedbackBatch = await feedbackReceiver.ReceiveAsync();

                if (feedbackBatch == null)
                {
                    continue;
                }

                //
                foreach (FeedbackRecord record in feedbackBatch.Records)
                {
                    // https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messaging#cloud-to-device-messages
                    // Message is always success, because MQTT clients can't reject C2D Messages
                    switch (record.OriginalMessageId.Substring(0, 3)) // Substring(0, 3) is the MessageIdPrefix
                    {
                    // CMD
                    case MessageIdPrefix.CMD:
                        await Task.Factory.StartNew(() => ProcessCmdMessage(record));

                        break;

                    default:
                        break;
                    }
                }

                await feedbackReceiver.CompleteAsync(feedbackBatch);
            }
        }
Exemple #2
0
        private void UpdateFirmwareUpdateStatus(UpdateState updateState)
        {
            using (IsmIoTPortalContext db = new IsmIoTPortalContext())
            {
                // Get reference to device
                string deviceId = updateState.DeviceId;
                var    device   = db.IsmDevices.FirstOrDefault(d => d.DeviceId.Equals(deviceId));
                if (device == null)
                {
                    this.OnLogMessage(new LogMessageEventArgs(String.Format("{0} > UpdateFirmwareUpdateStatus Error: DeviceId unknown.<br>", DateTime.Now.ToString())));
                    return;
                }
                // Check update status for error
                if (updateState.FwUpdateStatus.Contains("Error"))
                {
                    device.UpdateStatus = updateState.FwUpdateStatus;
                }
                else
                {
                    device.UpdateStatus = IsmIoTSettings.UpdateStatus.READY;
                }

                // Get reference to release
                var release = db.Releases.FirstOrDefault(r => r.Name.Equals(updateState.Version));
                if (release == null)
                {
                    this.OnLogMessage(new LogMessageEventArgs(String.Format("{0} > UpdateFirmwareUpdateStatus Error: Release unknown.<br>", DateTime.Now.ToString())));
                    db.SaveChanges();
                    return;
                }
                device.UpdateMessage = updateState.Message;
                var updateLog = new UpdateLog
                {
                    IsmDeviceId = device.IsmDeviceId,
                    ReleaseId   = release.SoftwareId,
                    LogData     = updateState.Log,
                    Date        = DateTime.Now
                };
                db.UpdateLogs.Add(updateLog);
                device.SoftwareId = release.SoftwareId;
                db.SaveChanges();
                this.OnLogMessage(new LogMessageEventArgs(String.Format("{0} > UpdateFirmwareUpdateStatus Info: Update Log: {1} <br>", DateTime.Now.ToString(), updateState.Log)));
            }
        }
Exemple #3
0
        /*
         *  In the Changed event, RoleEnvironment.CurrentRoleInstance.Role.Instances returns the target role instances,
         *  not the original role instances. If you need to know about the original instances,
         *  you can save this information when the Changing event fires and access it from the Changed event
         *  (since these events are always fired in sequence).
         */
        private void RoleEnvironmentChanged(object sender, RoleEnvironmentChangedEventArgs e)
        {
            targetNumOfInstances = RoleEnvironment.CurrentRoleInstance.Role.Instances.Count;
            Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > RoleEnvironmentChanged Eventhandler logging target instance count of {1} <br>", DateTime.Now.ToString(), targetNumOfInstances);
            Logfile.Get(logfile).Update();

            // The change is a downscale! Delete Mcr flag entry from db
            if (originalNumOfInstances > targetNumOfInstances)
            {
                using (IsmIoTPortalContext db = new IsmIoTPortalContext())
                {
                    try
                    {
                        // The highest role instance id was determined in the changing event
                        ImagingProcessorWorkerInstance entry = null;
                        var queryResults = db.ImagingProcessorWorkerInstances.Where(en => en.RoleInstanceId == highestRoleInstanceId);
                        if (queryResults.Count() > 0)
                        {
                            entry = queryResults.First();
                        }

                        if (lowestRoleInstanceId) // The role instance with the lowest id deletes the db entry in case of downscale.
                        {
                            Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > Delete database entry with key {1} <br>", DateTime.Now.ToString(), highestRoleInstanceId);
                            Logfile.Get(logfile).Update();

                            // Delete entry from DB
                            db.ImagingProcessorWorkerInstances.Remove(entry);
                            db.SaveChanges();
                        }
                    }
                    catch (Exception ex)
                    {
                        Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > Failed to delete McrInstalled flag DB entry. <br>", DateTime.Now.ToString());
                        Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > Exception: {1} <br>", DateTime.Now.ToString(), ex.Message);
                        Logfile.Get(logfile).Update();
                        throw;
                    }
                }
            }
        }
Exemple #4
0
        private static async Task ProcessCmdMessage(FeedbackRecord record)
        {
            using (var db = new IsmIoTPortalContext())
            {
                // Achtung .Substring(4), weil die ersten 3 Zeichen das Präfix "CMD" sind
                int CommandId = Convert.ToInt32(record.OriginalMessageId.Substring(4));   // Beim Senden des Commands wurde der Schlüssel des DB Eintrages als MessageId angegeben
                var entry     = db.Commands.Where(c => c.CommandId == CommandId).First(); // Es gibt natürlich nur ein DB Eintrag mit dem Schlüssel CommandId

                if (record.StatusCode == FeedbackStatusCode.Success)
                {
                    db.Entry(entry).Entity.CommandStatus = CommandStatus.SUCCESS;
                }
                else // Rejected,...
                {
                    db.Entry(entry).Entity.CommandStatus = CommandStatus.FAILURE;
                }

                db.Entry(entry).State = EntityState.Modified;
                db.SaveChanges();

                await signalRHelper.IsmDevicesIndexChangedTask();
            }
        }
Exemple #5
0
        private void ProcessImage(DeviceSettings DeviceSettings)
        {
            try
            {
                //
                MWArray[] argsIn   = new MWArray[6];
                string    blobname = DeviceSettings.CurrentCaptureName;
                argsIn[0] = GetBlobSasUri(blobname);                   // Path / Uri of the image (with Shared Access Signature for MATLAB)
                argsIn[1] = DeviceSettings.VarianceThreshold;          //var_thresh = 0.0025; % variance threshold
                argsIn[2] = DeviceSettings.DistanceMapThreshold;       //dist_thresh = 8.5; % distance - map threshold
                argsIn[3] = DeviceSettings.RGThreshold;                //RG_thresh = 3.75; % R.R.G.threshold
                argsIn[4] = DeviceSettings.RestrictedFillingThreshold; //fill_area = 4; % Restricted filling threshold
                argsIn[5] = DeviceSettings.DilateValue;                // dilate_value = 16; % Size of square SE used for dilation of dist.- map mask

                MWArray[]         argsOut           = new MWArray[3];  // [TEFL, real_length, img_colored]
                FilamentDetection filamentDetection = new FilamentDetection();

                filamentDetection.new_detectFilaments(3, ref argsOut, argsIn); // MATLAB call

                //
                double fl = (double)((MWNumericArray)argsOut[0]); // FL (TEFL)

                double[] single_lengths;
                if (((MWNumericArray)argsOut[1]).IsEmpty)
                {
                    single_lengths = new double[] { }
                }
                ;
                else
                {
                    single_lengths = (double[])((MWNumericArray)argsOut[1]).ToVector(MWArrayComponent.Real); // TODO: NullReference checks
                }
                int h1 = 0, h2 = 0, h3 = 0, h4 = 0, h5 = 0, h6 = 0, h7 = 0, h8 = 0, h9 = 0, h10 = 0;
                for (int i = 0; i < single_lengths.Length; i++)
                {
                    switch (GetInterval(single_lengths[i]))
                    {
                    case 0: h1++; break;

                    case 1: h2++; break;

                    case 2: h3++; break;

                    case 3: h4++; break;

                    case 4: h5++; break;

                    case 5: h6++; break;

                    case 6: h7++; break;

                    case 7: h8++; break;

                    case 8: h9++; break;

                    case 9: h10++; break;

                    default:
                        break;
                    }
                }

                double fc = single_lengths.Length; // FC

                // colored image
                CloudBlockBlob blob;
                string         coloredImage = argsOut[2].ToString();
                using (System.IO.FileStream fs = new System.IO.FileStream(coloredImage, System.IO.FileMode.Open))
                {
                    blob        = GenerateBlobAsync().Result;
                    fs.Position = 0;
                    blob.UploadFromStream(fs);
                }
                File.Delete(coloredImage);

                //
                using (IsmIoTPortalContext db = new IsmIoTPortalContext())
                {
                    /*
                     *  IsmDeviceId ist Foreign-Key von FilamentData zu IsmDevice
                     */
                    int id = db.IsmDevices.Where(d => d.DeviceId == DeviceSettings.DeviceId).First().IsmDeviceId;

                    IsmIoTPortal.Models.FilamentData fildata = new IsmIoTPortal.Models.FilamentData(fc, fl, id, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10,
                                                                                                    DeviceSettings.DeviceId, DeviceSettings.CurrentCaptureName, blob.Name);

                    // 1.) Sende in Queue für DashboardBroker
                    // FilamentData ist [DataContract], somit sind die Objekte mit DataContractSerializer serialisierbar
                    var queueMessage = new BrokeredMessage(fildata);
                    queueMessage.Label = IsmIoTPortal.CommandType.PRV; // BrokeredMessage.Label reicht aus um Nachrichtentyp festzulegen

                    // CapturePeriod als Information für DashboardBroker mitsenden.
                    queueMessage.Properties.Add(new KeyValuePair <string, object>("capturePeriod", DeviceSettings.CapturePeriod));

                    queueClient.SendAsync(queueMessage).Wait();

                    /*
                     * // 1.) Sende Daten an Dashboards
                     * signalRHubProxy.Invoke<string>("DataForDashboard", fildata.DeviceId, fildata.BlobUriImg, fildata.FC.ToString(), fildata.FL.ToString(), fildata.BlobUriColoredImg).ContinueWith(t =>
                     * {
                     *  //Console.WriteLine(t.Result);
                     *  this.OnLogMessage(new LogMessageEventArgs(String.Format("{0} > Send Filament Data to Dashboard <br>BlobUriimg: {1}", DateTime.Now.ToString(), fildata.BlobUriImg)));
                     * });
                     */

                    // 2.) Bei DAT sende die Daten in EventHub, bei PRV nicht
                    if (DeviceSettings.StateName == IsmIoTPortal.DeviceStates.RUN_STATE)
                    {
                        ForwaredFilamentDataToEventHub(fildata);
                    }
                }
            }
            catch (Exception ex)
            {
                this.OnLogMessage(new LogMessageEventArgs(String.Format("{0} > ProcessImage Exception: {1} <br>", DateTime.Now.ToString(), ex.Message)));
            }
        }
Exemple #6
0
        private async Task RunAsync(CancellationToken cancellationToken)
        {
            // 1. Check if this is after restart and "MCR is installed" already
            //
            bool   mcrAlreadyInstalled = false;
            string line = "";

            try
            {
                using (IsmIoTPortalContext db = new IsmIoTPortalContext())
                {
                    ImagingProcessorWorkerInstance entry = null;
                    var queryResults = db.ImagingProcessorWorkerInstances.Where(e => e.RoleInstanceId == RoleEnvironment.CurrentRoleInstance.Id);
                    if (queryResults.Count() > 0)
                    {
                        entry = queryResults.First(); // Es gibt natürlich nur ein DB Eintrag mit dem Schlüssel RoleInstanceId
                    }
                    if (entry == null)                // First start of this Instance -> Create and add new DB entry
                    {
                        //
                        entry = new ImagingProcessorWorkerInstance();
                        entry.RoleInstanceId = RoleEnvironment.CurrentRoleInstance.Id;
                        entry.McrInstalled   = false;
                        entry.Timestamp      = DateTime.UtcNow;
                        db.ImagingProcessorWorkerInstances.Add(entry);
                        db.SaveChanges();
                        // mcrAlreadyInstalled is still false
                    }
                    else
                    {
                        if (entry.McrInstalled == true)
                        {
                            mcrAlreadyInstalled = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > Failed to use McrInstalled flag. <br>", DateTime.Now.ToString());
                Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > Exception: {1} <br>", DateTime.Now.ToString(), ex.Message);
                Logfile.Get(logfile).Update();
                mcrAlreadyInstalled = false;
            }

            // *************DEBUG*****************
            mcrAlreadyInstalled = true; // DEBUG


            // 2. Poll the MCR Installation Log if mcrAlreadyInstalled == false
            //
            Stopwatch stopWatch = new Stopwatch();
            bool      timeout   = false;

            stopWatch.Start();
            while (!mcrAlreadyInstalled && true)
            {
                try
                {
                    // Timeout
                    if (stopWatch.Elapsed > TimeSpan.FromMinutes(30))
                    {
                        timeout = true;
                        break;
                    }

                    // Sleep
                    await Task.Delay(TimeSpan.FromMinutes(5));

                    if (!File.Exists(mcrlog))
                    {
                        continue;
                    }

                    line = File.ReadLines(mcrlog).Last();
                    if (!line.Contains("End - Successful"))
                    {
                        continue;
                    }
                    else
                    {
                        break;
                    }
                }
                catch (Exception ex)
                {
                    // Probably file reading errors because the MCR installer uses the file
                    continue;
                }
            }


            //
            // MCR is installed now -->Set the flag in DB and Reboot
            if (!mcrAlreadyInstalled && timeout == false)
            {
                try
                {
                    using (IsmIoTPortalContext db = new IsmIoTPortalContext())
                    {
                        // Update DB entry and set the McrInstalled Flag to true
                        var entry = db.ImagingProcessorWorkerInstances.Where(e => e.RoleInstanceId == RoleEnvironment.CurrentRoleInstance.Id).First(); // // Es gibt natürlich nur ein DB Eintrag mit dem Schlüssel RoleInstanceId
                        db.Entry(entry).Entity.McrInstalled = true;
                        db.Entry(entry).Entity.Timestamp    = DateTime.UtcNow;
                        db.Entry(entry).State = EntityState.Modified;
                        db.SaveChanges();

                        // Restart Worker Role
                        // Update: Der User nach dem Startup Task darf wohl kein shuttdown ausführen --> benutze schtasks
                        //string stat = ExecuteCommandSync("shutdown /R /F");

                        // Mit schtasks
                        DateTime executionTime = DateTime.Now.Add(new TimeSpan(0, 1, 0));
                        string   date          = string.Format("{0}/{1}/{2}", executionTime.Month.ToString("d2"), executionTime.Day.ToString("d2"), executionTime.Year);
                        string   time          = string.Format("{0}:{1}", executionTime.Hour.ToString("d2"), executionTime.Minute.ToString("d2"));
                        string   cmd           = string.Format("schtasks /CREATE /TN RebootRoleInstance /SC ONCE /SD {0} /ST {1} /RL HIGHEST /RU scheduser /RP Qwer123 /TR \"shutdown /R /F\" /F", date, time);
                        string   stat          = ExecuteCommandSync(cmd);
                        Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > {1} <br>", DateTime.Now.ToString(), stat);
                        Logfile.Get(logfile).Update();
                    }
                }
                catch (Exception ex)
                {
                    Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > Failed writing to update McrInstalled flag and reboot. <br>", DateTime.Now.ToString());
                    Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > Exception: {1} <br>", DateTime.Now.ToString(), ex.Message);
                    Logfile.Get(logfile).Update();
                }
            }
            // Timeout --> Write to log and do Not start Event Processor
            if (!mcrAlreadyInstalled && timeout == true)
            {
                Logfile.Get(logfile).fTextout(Logging.Fontcolors.RED, "{0} > Timeout occured during MCR Installation Polling. <br>", DateTime.Now.ToString());
                Logfile.Get(logfile).Update();
            }
            // Reboot and MCR is already installed --> Start Event Processor
            if (mcrAlreadyInstalled)
            {
                //
                // Create EventProcessorHost

                /*the iotHubD2cEndpoint in the example is the name of the device-to - cloud endpoint on your IoT hub.
                 * Technically, and IoT hub could have multiple endpoints that are compatible with Event Hubs.
                 * At this time the only Event Hubs - compatible endpoint is called "messages/events", so it is a fixed string. */
                string iotHubD2cEndpoint = "messages/events";
                string eventHubName      = CloudConfigurationManager.GetSetting("iotHubName"); //"IsmIoTHub";
                string consumerGroupName = EventHubConsumerGroup.DefaultGroupName;
                // Alternativ geht auch CurrentRoleInstance.Id (ist auch unique)
                //string eventProcessorHostName = Guid.NewGuid().ToString();

                string eventProcessorHostName = RoleEnvironment.CurrentRoleInstance.Id;
                // leaseContainerName-Parameter wie im scaled out event processing beispiel:
                // here it's using eventhub as lease name. but it can be specified as any you want.
                // if the host is having same lease name, it will be shared between hosts.
                // by default it is using eventhub name as lease name.
                eventProcessorHost = new EventProcessorHost(eventProcessorHostName,
                                                            iotHubD2cEndpoint,                                     // eigentlich steht hier der EventHub Name aber siehe Kommentar, bei IoTHubs ist hier der fixe string "messages/events" notwendig
                                                            consumerGroupName,
                                                                                                                   //iotHubConnectionString,
                                                            CloudConfigurationManager.GetSetting("ismiothub"),     //System.Configuration.ConfigurationSettings.AppSettings.Get("ismiothub"),
                                                                                                                   //EventProcessor.StorageConnectionString,
                                                            CloudConfigurationManager.GetSetting("ismiotstorage"), //System.Configuration.ConfigurationSettings.AppSettings.Get("ismiotstorage"),
                                                            eventHubName.ToLowerInvariant());

                factory = new EventProcessorFactory(logfile);
                await eventProcessorHost.RegisterEventProcessorFactoryAsync(factory);

                // Register EventProcessorHost
                Logfile.Get(logfile).fTextout("{0} > Registering EventProcessor... <br>", DateTime.Now.ToString());
                Logfile.Get(logfile).Update();

                // Ansatz ohne Factory. Hatte jedoch den Nachteil, dass man keine Referenz auf das EventProcessor Objekt
                // hat und somit z.B. keine Eventhandler registrieren konnte. Parameter an Konstruktor gigen ja auch nicht,
                // weil dieser niemals sichtbar aufgerufen wird bei dem Ansatz
                //eventProcessorHost.RegisterEventProcessorAsync<EventProcessor>().Wait();
            }

            while (!cancellationToken.IsCancellationRequested)
            {
                await Task.Delay(TimeSpan.FromHours(1), cancellationToken);
            }
        }
Exemple #7
0
        /// <summary>
        /// Creates a new firmware update ready to be rolled out. Call asynchronously because it can take some time. Don't use await.
        /// </summary>
        /// <param name="file">File of firmware update. Must be a tar.</param>
        /// <param name="location">Directory of where file will be stored on server.</param>
        /// <param name="id">Key of software version in databse.</param>
        /// <returns></returns>
        public static async Task CreateNewFirmwareUpdateTask(string fileUrl, string location, int id)
        {
            IsmIoTPortalContext db = new IsmIoTPortalContext();
            // Get reference to software
            var software = db.Releases.Find(id);

            try
            {
                // Filename is always the same
                var fileName = "update.tar";
                // Creates all directories in path that do not exist
                Directory.CreateDirectory(location);
                // Full path of file
                string filePath = Path.Combine(location, fileName);
                // Save file to disk
                var retval = await DownloadFromBlobStorage(fileUrl, filePath).ConfigureAwait(false);

                if (retval.Equals("Error"))
                {
                    // Update software status
                    software.Status = "Error during download of file.";
                    db.SaveChanges();
                    return;
                }
                // Update software status
                software.Status = "Saved";
                db.SaveChanges();

                // Calculate SHA 256 hash
                var checksum = await Sha256Sum(filePath).ConfigureAwait(false);

                // Get checksum string
                var checksum_string = BitConverter.ToString(checksum).Replace("-", String.Empty).ToLower();
                // Add checksum string to database
                software.Checksum = checksum_string;
                db.SaveChanges();

                // Get access to key vault
                var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetToken));
                // Sign Checksum
                var sig = await kv.SignAsync(
                    // Key ID is in appsettings
                    keyIdentifier : ConfigurationManager.AppSettings["kv:fw-signing-key"],
                    // Sign with RS256
                    algorithm : Microsoft.Azure.KeyVault.WebKey.JsonWebKeySignatureAlgorithm.RS256,
                    // We want to sign the checksum
                    digest : checksum).ConfigureAwait(false);

                // Save byte data as sig
                string checksumPath = Path.Combine(location, "sig");
                File.WriteAllBytes(checksumPath, sig.Result);
                software.Status = "Signed";
                db.SaveChanges();

                // Create tarball (.tar.gz file containing signed checksum and tarfile with update)
                var tarball = CreateTarBall(location);
                software.Status = "Compressed";
                db.SaveChanges();

                // Upload
                var uri = await UploadToBlobStorage(Path.GetFileName(tarball), tarball).ConfigureAwait(false);

                if (uri.Equals("Error"))
                {
                    software.Status = "Error during upload.";
                    db.SaveChanges();
                    return;
                }
                // Remove old file from BLOB storage
                var retVal = RemoveFromBlobStorage(fileUrl);
                if (retval.Equals("Error"))
                {
                    software.Status = "Error during removal of old file from BLOB storage.";
                    db.SaveChanges();
                    return;
                }
                // Everything is ok
                software.Status = "Ready";
                software.Url    = uri;
                db.SaveChanges();
            }
            catch (Exception e)
            {
                software.Status = "Error";
                db.SaveChanges();
            }
        }