Example #1
0
        public void runSendThread()
        {
            OnOffSample    nextSampleValue;
            HttpStatusCode createTableReturnCode;
            HttpStatusCode insertEntityReturnCode = HttpStatusCode.Ambiguous;
            int            actYear   = DateTime.Now.Year;
            string         tableName = _tablePrefix + actYear.ToString();

            bool nextSampleValueIsNull      = false;
            bool nextSampleValueShallBeSent = false;

            int loopCtr = 0;

            while (loopCtr < 3)       // We try 3 times to deliver to Azure, if not accepted, we neglect
            {
                nextSampleValue            = PreViewNextSampleValue();
                nextSampleValueIsNull      = (nextSampleValue == null) ? true : false;
                nextSampleValueShallBeSent = false;
                if (!nextSampleValueIsNull)
                {
                    nextSampleValueShallBeSent = (nextSampleValue.ForceSend || ((nextSampleValue.TimeOfSample - sampleTimeOfLastSent) > _sendInterval)) ? true : false;
                }
                if (nextSampleValueIsNull)
                {
                    this.OnAzureCommandSend(this, new AzureSendEventArgs(false, true, HttpStatusCode.Ambiguous, 1, tableName + _Buffer_empty));
                    //Debug.Print("Leaving because buffer is empty. Count in buffer when leaving AzureSendManager = " + Count);
                    break;
                }
                if (!nextSampleValueShallBeSent)
                {
                    nextSampleValue = DequeueNextSampleValue();        // Discard this to early object
                    this.OnAzureCommandSend(this, new AzureSendEventArgs(false, false, HttpStatusCode.Ambiguous, 2, tableName + _Early_object_discarded));
                }

                #region Create a Azure Table, Name = _tablePrefix plus the actual year (only when needed)
                if ((DateTime.Now.Year != yearOfLastSend) || (_tablePrefix != prefixOfLastTable))
                {
                    actYear   = DateTime.Now.Year;
                    tableName = _tablePrefix + actYear.ToString();

                    lock (theLock)
                    {
                        createTableReturnCode = createTable(_CloudStorageAccount, tableName);
                    }

                    //createTableReturnCode = HttpStatusCode.NotAcceptable;
                    //createTableReturnCode = HttpStatusCode.Ambiguous;
                    if (createTableReturnCode == HttpStatusCode.Created)
                    {
                        //Debug.Print("Table was created: " + tableName + ". HttpStatusCode: " + createTableReturnCode.ToString());
                        this.OnAzureCommandSend(this, new AzureSendEventArgs(false, true, HttpStatusCode.Ambiguous, 3, tableName + _Table_created));
                        yearOfLastSend    = actYear;
                        prefixOfLastTable = _tablePrefix;
                    }
                    else
                    {
                        if (createTableReturnCode == HttpStatusCode.Conflict)
                        {
                            //Debug.Print("Table " + tableName + " already exists");
                            yearOfLastSend    = actYear;
                            prefixOfLastTable = _tablePrefix;
                            this.OnAzureCommandSend(this, new AzureSendEventArgs(false, true, HttpStatusCode.Ambiguous, 4, tableName + _Table_already_exists));
                        }
                        else
                        {
                            if (createTableReturnCode == HttpStatusCode.NoContent)
                            {
                                //Debug.Print("Create Table operation. HttpStatusCode: " + createTableReturnCode.ToString());
                                yearOfLastSend    = actYear;
                                prefixOfLastTable = _tablePrefix;
                            }
                            else
                            {
                                //Debug.Print("Failed to create Table " + tableName + ". HttpStatusCode: " + createTableReturnCode.ToString());
                                this.OnAzureCommandSend(this, new AzureSendEventArgs(false, true, HttpStatusCode.Ambiguous, 5, tableName + _Failed_to_create_Table));
                                Thread.Sleep(10000);
                                Microsoft.SPOT.Hardware.PowerState.RebootDevice(true, 3000);
                                while (true)
                                {
                                    Thread.Sleep(100);
                                }
                                //break;
                            }
                        }
                    }
                    Thread.Sleep(3000);
                }
                #endregion

                #region Create an ArrayList  to hold the properties of the entity
                this.OnAzureCommandSend(this, new AzureSendEventArgs(false, true, HttpStatusCode.Ambiguous, 6, tableName + _Going_to_insert_Entity));
                //Debug.Print("\r\nGoing to insert an entity");
                // Now we create an Arraylist to hold the properties of a table Row,
                // write these items to an entity
                // and send this entity to the Cloud

                ArrayList propertiesAL = new System.Collections.ArrayList();
                lock (theLock)
                {
                    propertiesAL = createOnOffPropertyArrayList(nextSampleValue, _azureSends);
                }

                #endregion

                //Thread.Sleep(1100);
                //DateTime actDate = DateTime.Now;
                DateTime actDate = nextSampleValue.TimeOfSample;


                //calculate reverse Date, so the last entity can be retrieved with the Azure $top1 query
                string reverseDate = (10000 - actDate.Year).ToString("D4") + (12 - actDate.Month).ToString("D2") + (31 - actDate.Day).ToString("D2")
                                     + (23 - actDate.Hour).ToString("D2") + (59 - actDate.Minute).ToString("D2") + (59 - actDate.Second).ToString("D2");

                TempEntity myTempEntity;
                lock (theLock)
                {
                    myTempEntity = new TempEntity(nextSampleValue.PartitionKey, reverseDate, propertiesAL);
                }
                string insertEtag = null;

                insertEntityReturnCode = insertTableEntity(_CloudStorageAccount, tableName, myTempEntity, out insertEtag);

                #region Outcommented (for tests)
                // only for testing to produce entity that is rejected by Azure
                //insertEntityReturnCode = insertTableEntity(_CloudStorageAccount, tableName.Substring(0, 6), myTempEntity, out insertEtag);

                //****************  to delete ****************************

                /*
                 *   if (DateTime.Now < new DateTime(2016, 8, 2, 0, 31, 1))
                 *   {
                 *       Debug.Print("Löschen geblockt");
                 *       insertEntityReturnCode = HttpStatusCode.Ambiguous;
                 *   }
                 *   else
                 *   {
                 *       Debug.Print("Löschen erlaubt");
                 *   }
                 */
                //*********************************************************
                #endregion

                if ((insertEntityReturnCode == HttpStatusCode.Created) || (insertEntityReturnCode == HttpStatusCode.NoContent))
                {
                    //Debug.Print("Entity was inserted. Try: " + loopCtr.ToString() + " HttpStatusCode: " + insertEntityReturnCode.ToString());

                    nextSampleValue = DequeueNextSampleValue();
                    if (nextSampleValue != null)
                    {
                        if (!nextSampleValue.ForceSend)
                        {
                            sampleTimeOfLastSent = nextSampleValue.TimeOfSample;
                        }
                    }


                    this.OnAzureCommandSend(this, new AzureSendEventArgs(true, false, insertEntityReturnCode, 0, tableName + _Entity_was_inserted));

                    // don't break, the loop is left when we try to get the next row until it is null
                }
                else
                {
                    if (insertEntityReturnCode == HttpStatusCode.Ambiguous)     // this is returned when no contact to internet
                    {
                        yearOfLastSend = 2000;
                        this.OnAzureCommandSend(this, new AzureSendEventArgs(false, true, HttpStatusCode.Ambiguous, 7, "No Internet access"));
                        //Debug.Print("Leaving because of no internet access. Count in buffer when leaving AzureSendManager = " + Count);
                        break;
                    }
                    else
                    {
                        yearOfLastSend = 2000;
                        this.OnAzureCommandSend(this, new AzureSendEventArgs(false, false, HttpStatusCode.Ambiguous, 8, "Failed to insert Entity, one try"));
                        //Debug.Print("Failed to insert Entity, Try: " + loopCtr.ToString() + " HttpStatusCode: " + insertEntityReturnCode.ToString());
                        Thread.Sleep(3000);
                        loopCtr++;
                    }
                }

                if (loopCtr >= 3)               // if Azure does not accept the entity, we give up after the third try and discard this entity
                {
                    nextSampleValue = DequeueNextSampleValue();
                    this.OnAzureCommandSend(this, new AzureSendEventArgs(false, true, HttpStatusCode.Ambiguous, 9, "Failed to insert Entity after 3 tries"));
                    //Debug.Print("Leaving because Entity was discarded after 3rd try. Count in buffer when leaving AzureSendManager = " + Count);
                    if (DateTime.Now < new DateTime(2016, 7, 1))           // Reboot if Entity can not be inserted, probably because of wrong time
                    {
                        Thread.Sleep(20000);
                        Microsoft.SPOT.Hardware.PowerState.RebootDevice(true, 3000);
                        while (true)
                        {
                            Thread.Sleep(100);
                        }
                    }
                    break;
                }
                Thread.Sleep(1);
            }
            //Debug.Print("Jumped out of while loop");

            //Debug.Print("Count in buffer when entering AzureSendManager = " + Count);
        }
        public void runSendThread()
        {
            SampleValue    nextSampleValue;
            HttpStatusCode createTableReturnCode;
            HttpStatusCode insertEntityReturnCode = HttpStatusCode.Ambiguous;
            int            actYear     = DateTime.Now.Year;
            string         tableName   = null;
            string         tablePreFix = null;

            //string tableName = _tablePrefix + actYear.ToString();
            //string tablePreFix = _tablePrefix;

            bool nextSampleValueIsNull      = false;
            bool nextSampleValueShallBeSent = false;

            int loopCtr = 0;

            while (loopCtr < 3)   // We try 3 times to deliver to Azure, if not accepted, we neglect
            {
                Debug.Print("Number of entities in Queue is: " + Count.ToString());

                nextSampleValue            = PreViewNextSampleValue();
                nextSampleValueIsNull      = (nextSampleValue == null) ? true : false;
                nextSampleValueShallBeSent = false;
                if (!nextSampleValueIsNull)
                {
                    nextSampleValueShallBeSent = (nextSampleValue.ForceSend || ((nextSampleValue.TimeOfSample - sampleTimeOfLastSent) > _sendInterval)) ? true : false;
                    tableName   = nextSampleValue.TableName;
                    tablePreFix = tableName.Substring(0, tableName.Length - 4);
                }
                if (nextSampleValueIsNull)
                {
                    this.OnAzureCommandSend(this, new AzureSendEventArgs(false, true, HttpStatusCode.Ambiguous, 1, "Buffer empty"));
                    //Debug.Print("Leaving because buffer is empty. Count in buffer when leaving AzureSendManager = " + Count);
                    break;
                }
                if (!nextSampleValueShallBeSent)
                {
                    //nextSampleValue = DequeueNextSampleValue();    // Discard this to early object
                    DiscardNextSampleValue();
                    this.OnAzureCommandSend(this, new AzureSendEventArgs(false, false, HttpStatusCode.Ambiguous, 2, "Early object discarded"));
                }


                #region Create a Azure Table, Name = tablePrefix plus the actual year (only when needed)

                if ((DateTime.Now.Year != yearOfLastSend) || (!LastTableNames.Contains(tableName)))
                {
                    createTableReturnCode = createTable(_CloudStorageAccount, tableName);

                    if ((createTableReturnCode == HttpStatusCode.Created) || (createTableReturnCode == HttpStatusCode.Conflict))
                    {
                        if (createTableReturnCode == HttpStatusCode.Created)
                        {
                            this.OnAzureCommandSend(this, new AzureSendEventArgs(false, false, createTableReturnCode, 3, tableName + _Table_created));
                        }
                        else
                        {
                            this.OnAzureCommandSend(this, new AzureSendEventArgs(false, false, HttpStatusCode.Ambiguous, 4, tableName + _Table_already_exists));
                        }

                        yearOfLastSend = DateTime.Now.Year;

                        if (!LastTableNames.Contains(tableName))
                        {
                            LastTableNames.Add(tableName);
                        }
                    }
                    else
                    {
                        if (createTableReturnCode == HttpStatusCode.NoContent)
                        {
                            //Debug.Print("Create Table operation. HttpStatusCode: " + createTableReturnCode.ToString());
                            yearOfLastSend = DateTime.Now.Year;
                        }
                        else
                        {
                            this.OnAzureCommandSend(this, new AzureSendEventArgs(false, false, HttpStatusCode.Ambiguous, 5, tableName + _Failed_to_create_Table));
                            Thread.Sleep(10000);
                            Microsoft.SPOT.Hardware.PowerState.RebootDevice(true, 3000);
                            while (true)
                            {
                                Thread.Sleep(100);
                            }
                        }
                    }
                    Thread.Sleep(3000);
                }
                #endregion


                #region Create an ArrayList  to hold the properties of the entity
                this.OnAzureCommandSend(this, new AzureSendEventArgs(false, true, HttpStatusCode.Ambiguous, 6, tableName + _Going_to_insert_Entity));

                // Now we create an Arraylist to hold the properties of a table Row,
                // write these items to an entity
                // and send this entity to the Cloud

                string TimeOffsetUTCString = nextSampleValue.TimeOffSetUTC < 0 ? nextSampleValue.TimeOffSetUTC.ToString("D3") : "+" + nextSampleValue.TimeOffSetUTC.ToString("D3");

                ArrayList           propertiesAL = new System.Collections.ArrayList();
                TableEntityProperty property;
                lock (theLock)
                {
                    //Add properties to ArrayList (Name, Value, Type)
                    property = new TableEntityProperty(_sensorValueHeader, nextSampleValue.TheSampleValue.ToString("f2"), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));
                    property = new TableEntityProperty("min", nextSampleValue.DayMin.ToString("f2"), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));
                    property = new TableEntityProperty("max", nextSampleValue.DayMax.ToString("f2"), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));

                    property = new TableEntityProperty("T_1", nextSampleValue.T_0.ToString("f2"), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));


                    property = new TableEntityProperty("T_2", nextSampleValue.T_1.ToString("f2"), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));


                    property = new TableEntityProperty("T_3", nextSampleValue.T_2.ToString("f2"), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));


                    property = new TableEntityProperty("T_4", nextSampleValue.T_3.ToString("f2"), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));

                    property = new TableEntityProperty("T_5", nextSampleValue.T_4.ToString("f2"), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));

                    property = new TableEntityProperty("T_6", nextSampleValue.T_5.ToString("f2"), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));

                    property = new TableEntityProperty(_socketSensorHeader, nextSampleValue.SecondReport, "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));
                    property = new TableEntityProperty("Status", nextSampleValue.Status, "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));

                    property = new TableEntityProperty("Location", nextSampleValue.Location, "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));
                    property = new TableEntityProperty("SampleTime", nextSampleValue.TimeOfSample.ToString() + " " + TimeOffsetUTCString, "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));
                    property = new TableEntityProperty("TimeFromLast", nextSampleValue.TimeFromLast.Days.ToString("D3") + "-" + nextSampleValue.TimeFromLast.Hours.ToString("D2") + ":" + nextSampleValue.TimeFromLast.Minutes.ToString("D2") + ":" + nextSampleValue.TimeFromLast.Seconds.ToString("D2"), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));

                    property = new TableEntityProperty("Info", nextSampleValue.SendInfo.ToString("D4"), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));

                    property = new TableEntityProperty("RSSI", nextSampleValue.RSSI.ToString("D3"), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));

                    property = new TableEntityProperty("Iterations", nextSampleValue.Iterations.ToString("D6"), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));
                    property = new TableEntityProperty("Sends", _azureSends.ToString("D6"), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));
                    property = new TableEntityProperty("RemainRam", nextSampleValue.RemainingRam.ToString("D7"), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));
                    property = new TableEntityProperty("forcedReboots", nextSampleValue.ForcedReboots.ToString("D6"), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));
                    property = new TableEntityProperty("badReboots", nextSampleValue.BadReboots.ToString("D6"), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));
                    property = new TableEntityProperty("sendErrors", nextSampleValue.SendErrors.ToString("D4"), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));
                    property = new TableEntityProperty("bR", nextSampleValue.BootReason.ToString(), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));
                    property = new TableEntityProperty("fS", nextSampleValue.ForceSend ? "X" : ".", "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));
                    property = new TableEntityProperty("Message", nextSampleValue.Message.ToString(), "Edm.String");
                    propertiesAL.Add(makePropertyArray.result(property));
                }
                #endregion


                DateTime actDate = nextSampleValue.TimeOfSample;


                //calculate reverse Date, so the last entity can be retrieved with the Azure $top1 query
                string reverseDate = (10000 - actDate.Year).ToString("D4") + (12 - actDate.Month).ToString("D2") + (31 - actDate.Day).ToString("D2")
                                     + (23 - actDate.Hour).ToString("D2") + (59 - actDate.Minute).ToString("D2") + (59 - actDate.Second).ToString("D2");

                TempEntity myTempEntity = new TempEntity(nextSampleValue.PartitionKey, reverseDate, propertiesAL);
                string     insertEtag   = null;

                //RoSchmi
                Debug.Print("\r\nTry to insert in Table: " + tableName + " RowKey " + reverseDate + "\r\n");

                insertEntityReturnCode = insertTableEntity(_CloudStorageAccount, tableName, myTempEntity, out insertEtag);

                #region Outcommented (for tests)
                // only for testing to produce entity that is rejected by Azure
                // insertEntityReturnCode = insertTableEntity(_CloudStorageAccount, tableName.Substring(0, 6), myTempEntity, out insertEtag);

                //****************  to delete ****************************

                /*
                 *   if (DateTime.Now < new DateTime(2016, 8, 2, 0, 31, 1))
                 *   {
                 *       Debug.Print("Löschen geblockt");
                 *       insertEntityReturnCode = HttpStatusCode.Ambiguous;
                 *   }
                 *   else
                 *   {
                 *       Debug.Print("Löschen erlaubt");
                 *   }
                 */
                //*********************************************************
                #endregion


                if ((insertEntityReturnCode == HttpStatusCode.Created) || (insertEntityReturnCode == HttpStatusCode.NoContent) || (insertEntityReturnCode == HttpStatusCode.Conflict))
                {
                    //Debug.Print("Entity was inserted. Try: " + loopCtr.ToString() + " HttpStatusCode: " + insertEntityReturnCode.ToString());

                    nextSampleValue = DequeueNextSampleValue();
                    Thread.Sleep(0);
                    if (nextSampleValue != null)
                    {
                        if (!nextSampleValue.ForceSend)
                        {
                            sampleTimeOfLastSent = nextSampleValue.TimeOfSample;
                        }
                    }

                    if (insertEntityReturnCode == HttpStatusCode.Conflict)
                    {
                        this.OnAzureCommandSend(this, new AzureSendEventArgs(false, false, HttpStatusCode.Ambiguous, 7, tableName + _Entity_already_created_deleted_from_buffer + reverseDate));
                    }
                    else
                    {
                        this.OnAzureCommandSend(this, new AzureSendEventArgs(true, false, insertEntityReturnCode, 0, tableName + _Entity_was_inserted + reverseDate));
                    }

                    // don't break, the loop is left when we try to get the next row until it is null
                }
                else
                {
                    if (insertEntityReturnCode == HttpStatusCode.Ambiguous) // this is returned when no contact to internet
                    {
                        yearOfLastSend = 2000;
                        this.OnAzureCommandSend(this, new AzureSendEventArgs(false, true, HttpStatusCode.Ambiguous, 7, "No Internet access"));
                        //Debug.Print("Leaving because of no internet access. Count in buffer when leaving AzureSendManager = " + Count);
                        break;
                    }
                    else
                    {
                        yearOfLastSend = 2000;
                        this.OnAzureCommandSend(this, new AzureSendEventArgs(false, false, HttpStatusCode.Ambiguous, 8, tableName + ": Failed to insert Entity, one try" + reverseDate));
                        //Debug.Print("Failed to insert Entity, Try: " + loopCtr.ToString() + " HttpStatusCode: " + insertEntityReturnCode.ToString());
                        Thread.Sleep(3000);
                        loopCtr++;
                    }
                }



                if (loopCtr >= 3)           // if Azure does not accept the entity, we give up after the third try and discard this entity
                {
                    nextSampleValue = DequeueNextSampleValue();
                    this.OnAzureCommandSend(this, new AzureSendEventArgs(false, true, HttpStatusCode.Ambiguous, 9, tableName + "Failed to insert Entity after 3 tries"));
                    //Debug.Print("Leaving because Entity was discarded after 3rd try. Count in buffer when leaving AzureSendManager = " + Count);
                    if (DateTime.Now < new DateTime(2016, 7, 1))       // Reboot if Entity can not be inserted, probably because of wrong time
                    {
                        Thread.Sleep(20000);
                        Microsoft.SPOT.Hardware.PowerState.RebootDevice(true, 3000);
                        while (true)
                        {
                            Thread.Sleep(100);
                        }
                    }
                    break;
                }
                Thread.Sleep(1);
            }
            Debug.Print("Jumped out of while loop");

            //Debug.Print("Count in buffer when entering AzureSendManager = " + Count);
        }