private static async Task RunAsync()
        {
            DateTime start = DateTime.Now;

            Console.WriteLine(start.ToString());

            int newRecordId    = 0;
            int newRecordModId = 0;
            int emptyRecordId  = 0;

            // start the connection to FMS, specifying the FMS17 version
            var fmserver = new FMS17(server, testAccount, testPassword);

            // specify what file to work with
            // data from related files will also be available provided
            // that there are table occurrences to it in this target file
            // and that the account has access to it
            fmserver.SetFile(testFile);

            // ---------------------------------------------------------------------------------------------------
            // authenticate and get the token
            token = await fmserver.Authenticate();

            if (token.Contains("error"))
            {
                Console.WriteLine("could not obtain token, quiting");
                Console.WriteLine("");
                Console.Beep();
                Console.WriteLine("Press any key to close this window...");
                Console.ReadKey();
                Environment.Exit(0);
            }
            else
            {
                Console.WriteLine("token recevied = " + token);
            }


            // ---------------------------------------------------------------------------------------------------
            // create an empty record
            Console.WriteLine("==> Creating a new empty record...");

            // set the layout you want to interact with
            // all interactions are done through a layout, layout determines what table and what fields
            // basically your context
            fmserver.SetLayout(testLayoutData);
            var empty = fmserver.NewRecordRequest();

            empty.AddScript(ScriptTypes.before, "log", "creating empty record");
            var response = await empty.Execute();

            if (fmserver.lastErrorCode == 0)
            {
                emptyRecordId = response;
                Console.WriteLine("new empty record = " + emptyRecordId.ToString() + " in " + fmserver.CurrentLayout);
                Console.WriteLine("script error = " + fmserver.lastErrorCodeScriptPreRequest);
            }
            else
            {
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }


            // ---------------------------------------------------------------------------------------------------
            // create a new record and set some data
            Console.WriteLine("==> Creating a new record with data...");
            newRecordId = 0;
            fmserver.SetLayout(testLayoutData);

            // create a new request and specify what data to set in what field
            var request = fmserver.NewRecordRequest();

            request.AddField("country", GetRandomString());

            // and run a script
            request.AddScript(ScriptTypes.after, "log", "after creating record");

            // execute the request
            response = await request.Execute();

            if (fmserver.lastErrorCode == 0)
            {
                newRecordId = response;
                Console.WriteLine("new record = " + newRecordId.ToString() + " in " + fmserver.CurrentLayout);
                Console.WriteLine("script reports error # " + fmserver.lastErrorCodeScript);
            }
            else
            {
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }

            // ---------------------------------------------------------------------------------------------------
            // delete a record, we will use the newRecordId that we just created
            Console.WriteLine("==> deleting that last record...");
            fmserver.SetLayout(testLayoutData);
            response = await fmserver.DeleteRecord(newRecordId);

            if (fmserver.lastErrorCode == 0)
            {
                Console.WriteLine(newRecordId.ToString() + " deleted from " + fmserver.CurrentLayout);
            }
            else
            {
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }

            // ---------------------------------------------------------------------------------------------------
            // create a record + a related record
            Console.WriteLine("==> Creating a new record with related data...");
            newRecordId = 0;
            fmserver.SetLayout(testLayoutDataPortal);

            // create the request
            request = fmserver.NewRecordRequest();

            // add data to two fields, these fields belong to the table as set by the layout's context
            // not related fields
            request.AddField("cake", "Yummy Cake");
            request.AddField("country", GetRandomString());


            // using a relationship that does not allow the creation or records will generate
            // error 101 "Record is missing"
            //request.AddRelatedField("fruit", "cake_FRUIT", GetRandomString(), 0);

            // the portal itself does not need to be on the layout
            //fmserver.SetLayout("CAKE_utility__No_Portals");

            // add the related field - use 0 for the related record id to indicate that it is a new record
            // FMS accepts an empty recordId to denote a new related record
            // here were are creating one new record and setting two related fields
            request.AddRelatedField("fruit", "cake_FRUIT__ac", GetRandomString(), 0);
            request.AddRelatedField("number_field", "cake_FRUIT__ac", "7", 0);
            response = await request.Execute();

            if (fmserver.lastErrorCode == 0)
            {
                newRecordId = response;
                Console.WriteLine("new record = " + newRecordId.ToString() + " in " + fmserver.CurrentLayout);
            }
            else
            {
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }

            // ---------------------------------------------------------------------------------------------------
            // add one more related record to this parent
            // ==> would be nice if this was a simpler call than having to remember to use 'add related' and 0
            Console.WriteLine("==> Adding a related record to that new record...");

            // create the edit request
            var editRequest = fmserver.EditRequest(newRecordId);

            // add the new related record
            editRequest.AddRelatedField("fruit", "cake_FRUIT__ac", GetRandomString(), 0);
            response = await editRequest.Execute();

            if (fmserver.lastErrorCode == 0)
            {
                Console.WriteLine("related record added to " + newRecordId.ToString() + " in " + fmserver.CurrentLayout);
            }
            else
            {
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }


            // ---------------------------------------------------------------------------------------------------
            // do some edits on the empty record we created earlier
            Console.WriteLine("==> Adding data to the empty record...");
            fmserver.SetLayout(testLayoutData);

            // create the edit request
            editRequest = fmserver.EditRequest(emptyRecordId);

            // modify a field, in this case a repeating field
            editRequest.AddField("field_number_repeat", "100", 1);

            // execute the request
            response = await editRequest.Execute();

            if (fmserver.lastErrorCode == 0)
            {
                Console.WriteLine("data added to record = " + emptyRecordId.ToString() + " in " + fmserver.CurrentLayout);
            }
            else
            {
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }


            // ---------------------------------------------------------------------------------------------------
            // get a record and then the container
            Console.WriteLine("==> Get all the record data for recordId " + newRecordId.ToString() + " and then the container data");

            int    targetRecordId = 10000;
            string containerField = "container_field";

            // what layout has a container field on it?
            fmserver.SetLayout(testLayoutData);


            // create a find request, using the record that we create a while ago
            var findMyRecord = fmserver.FindRequest(targetRecordId);
            // execute the find
            var myData = await findMyRecord.Execute();

            // work with the result returned to get the URL of the container data
            FMData      FMresult  = myData.data;
            FMRecordSet FMrecords = FMresult.foundSet;
            // there is only one record
            FMRecord row = FMrecords.records.First();

            // get the URL from the container field
            string url = row.fieldsAndData[containerField];

            fmserver.SetDownloadFolder(@"C:\Users\Public");

            // get the container data
            FileInfo containerData = await fmserver.DownloadFileFromContainerField(url);

            if (containerField != null)
            {
                Console.WriteLine("File downloaded as: " + containerData.FullName);
            }
            else
            {
                Console.WriteLine("could not download the container data file");
            }



            // ---------------------------------------------------------------------------------------------------
            // get a record and its portal data
            Console.WriteLine("==> Get all the record data for recordId " + newRecordId.ToString());
            fmserver.SetLayout(testLayoutDataPortal);

            // create a find request, using the record that we create a while ago
            var findRequest = fmserver.FindRequest(newRecordId);

            // execute the record
            var getResponse = await findRequest.Execute();

            // save this reponse, we'll re-use it
            var savedResponseWithPortals = getResponse;

            if (getResponse.errorCode == 0)
            {
                Console.WriteLine("record count for " + newRecordId.ToString() + " in " + fmserver.CurrentLayout + " is " + getResponse.recordCount + ", with " + getResponse.data.relatedTableNames.Count + " portals");
                newRecordModId = Convert.ToInt32(getResponse.data.foundSet.records[0].modId);
            }
            else
            {
                Console.WriteLine(getResponse.errorCode.ToString());
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }


            // ---------------------------------------------------------------------------------------------------
            // get a record but use a different response layout
            Console.WriteLine("==> Get all the record data for recordId " + newRecordId.ToString() + " - but different response layout");
            fmserver.SetLayout(testLayoutDataPortal);

            // create a find request, using the record that we create a while ago
            findRequest = fmserver.FindRequest(newRecordId, testLayoutResponse);

            // execute the record
            getResponse = await findRequest.Execute();

            if (getResponse.errorCode == 0)
            {
                Console.WriteLine("record count for " + newRecordId.ToString() + " in " + fmserver.CurrentLayout + " is " + getResponse.recordCount + ", with " + getResponse.data.relatedTableNames.Count + " portals");
                newRecordModId = Convert.ToInt32(getResponse.data.foundSet.records[0].modId);
            }
            else
            {
                Console.WriteLine(getResponse.errorCode.ToString());
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }

            // ---------------------------------------------------------------------------------------------------
            // get a record but use a different response layout and run scripts
            Console.WriteLine("==> Get all the record data for recordId " + newRecordId.ToString() + " - but different response layout, and run scripts");
            fmserver.SetLayout(testLayoutDataPortal);

            // create a find request, using the record that we create a while ago
            findRequest = fmserver.FindRequest(newRecordId, testLayoutResponse);
            findRequest.AddScript(ScriptTypes.before, "log", "before - Etiam porta sem malesuada magna mollis euismod.");
            findRequest.AddScript(ScriptTypes.beforeSort, "log", "before sort - Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.");
            findRequest.AddScript(ScriptTypes.after, "log", "after - Donec sed odio dui. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.");

            // execute the record
            getResponse = await findRequest.Execute();

            if (getResponse.errorCode == 0)
            {
                Console.WriteLine("record count for " + newRecordId.ToString() + " in " + fmserver.CurrentLayout + " is " + getResponse.recordCount + ", with " + getResponse.data.relatedTableNames.Count + " portals");
                newRecordModId = Convert.ToInt32(getResponse.data.foundSet.records[0].modId);
            }
            else
            {
                Console.WriteLine(getResponse.errorCode.ToString());
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }

            // ---------------------------------------------------------------------------------------------------
            // update a specific related record

            // restore the response we had before
            getResponse = savedResponseWithPortals;

            // the the Table Occurrence name of the first related set of the first found record, from one of our previous requests

            string TOname = getResponse.data.foundSet.records[0].relatedRecordSets[0].tableName;

            FMRecord firstRelatedRecord = getResponse.data.foundSet.records[0].relatedRecordSets[0].records[0];
            // field name from that related table, and its original value, last field in the list
            KeyValuePair <string, string> kv = firstRelatedRecord.fieldsAndData.ElementAt(1); // second field to avoid recordId and modId
            string oldValue         = kv.Value;
            string relatedFieldName = kv.Key;

            // record id for the first related record
            int relatedRecordId = Convert.ToInt32(getResponse.data.foundSet.records[0].relatedRecordSets[0].records[0].recordId);

            // create the edit request
            editRequest = fmserver.EditRequest(newRecordId);

            // modify a field, in this case a repeating field
            string newValue = "99";

            editRequest.AddRelatedField(relatedFieldName, TOname, newValue, relatedRecordId);

            // execute the request
            response = await editRequest.Execute();

            if (fmserver.lastErrorCode == 0)
            {
                Console.WriteLine("data updated on related record = " + relatedRecordId.ToString() + " in " + fmserver.CurrentLayout + ", field = " + relatedFieldName + ", old value = " + oldValue + ", new value = " + newValue);
            }
            else
            {
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }


            // ---------------------------------------------------------------------------------------------------
            // get data that same record but with just one portal instead of everything
            Console.WriteLine("==> Get record data plus a selected portal...");

            // get the first portal name from the previous test
            string portalName = getResponse.data.foundSet.records[0].relatedRecordSets[0].tableLayoutObjectName;

            if (portalName == null)
            {
                // portal not named on the layout, use the relationship name
                portalName = getResponse.data.foundSet.records[0].relatedRecordSets[0].tableName;
            }

            // create the find request
            findRequest = fmserver.FindRequest(newRecordId);

            // specify the portal name to include
            findRequest.AddPortal(portalName);

            // execute the request
            var getResponsePartial = await findRequest.Execute();

            if (getResponsePartial.errorCode == 0)
            {
                Console.WriteLine("record count for " + newRecordId.ToString() + " in " + fmserver.CurrentLayout + " is " + getResponsePartial.recordCount + ", with " + getResponsePartial.data.relatedTableNames.Count + " portals");
            }
            else
            {
                Console.WriteLine(getResponsePartial.errorCode.ToString());
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }


            // ---------------------------------------------------------------------------------------------------
            // try with a portal that does not have a layout object name, does it then use the relationship/TO name?
            // seems not to, always fails.  Not sure if that is a bug - waiting on feedback from FMI.

            Console.WriteLine("==> Get record data plus a selected portal that has no object name...");
            Console.WriteLine("==> EXPECTED TO FAIL WITH AN ERROR, FM requires a named portal.");

            // get the first portal name from the previous test
            portalName  = getResponse.data.foundSet.records[0].relatedRecordSets.Last().tableName;
            findRequest = fmserver.FindRequest(newRecordId);
            findRequest.AddPortal(portalName);
            getResponsePartial = await findRequest.Execute();

            if (getResponsePartial.errorCode == 0)
            {
                Console.WriteLine("record count for " + newRecordId.ToString() + " in " + fmserver.CurrentLayout + " is " + getResponsePartial.recordCount + ", with " + getResponsePartial.data.relatedTableNames.Count + " portals");
            }
            else
            {
                Console.WriteLine(getResponsePartial.errorCode.ToString());
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }


            // ---------------------------------------------------------------------------------------------------
            // delete related record
            Console.WriteLine("==> delete a related record");

            // ==> can only do one at a time otherwise json complains of duplicate 'relatedRecord" key
            // ==> needs to be fixed to not allow multiple

            // set the context
            fmserver.SetLayout(testLayoutDataPortal);

            // grab the first record
            FMRecord firstRecord = getResponse.data.foundSet.records[0];

            // and the first related record for that record, from the first portal
            firstRelatedRecord = firstRecord.relatedRecordSets[0].records[0];

            // get that record's id
            int firstReleatedRecordId = Convert.ToInt32(firstRelatedRecord.recordId);

            // and the table occurrence for that first related set of records
            string relationship = firstRecord.relatedRecordSets[0].tableName;

            // execute the delete command
            response = await fmserver.DeleteRelatedRecord(newRecordId, relationship, firstReleatedRecordId);

            if (fmserver.lastErrorCode == 0)
            {
                Console.WriteLine("related record " + firstReleatedRecordId.ToString() + " deleted in " + fmserver.CurrentLayout + " from " + relationship + " for parent record " + newRecordId);
            }
            else
            {
                Console.WriteLine(getResponse.errorCode.ToString());
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }



            // ---------------------------------------------------------------------------------------------------
            // create a record and set repeating field
            Console.WriteLine("==> new record and set repeating field...");

            // some housekeeping since we keep reusing this variable
            newRecordId = 0;

            // set the context
            fmserver.SetLayout(testLayoutData);

            // create the request
            request = fmserver.CreateRequest();

            // add a field + value to the request
            request.AddField("country", GetRandomString());

            // add another field, this one is a repeating field
            // set 2nd repetition
            request.AddField("field_number_repeat", "17", 2);

            // execute the request
            response = await request.Execute();

            if (fmserver.lastErrorCode == 0)
            {
                newRecordId = response;
                Console.WriteLine("new record created and repeating field set = " + newRecordId + " in " + fmserver.CurrentLayout);
            }
            else
            {
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }



            // ---------------------------------------------------------------------------------------------------
            // edit a record and specify a particular mod id
            // hat is the mod id of a newly created record, 0 or 1? --> 0
            // ==> can fail because we didn't correctly capture the newRecordModId from the record we just created
            // we would have to do a Get on it first to know it.
            Console.WriteLine("==> edit a record by specifying both recordId and modId");

            // set the context
            fmserver.SetLayout(testLayoutData);

            // create the request, specifying the target record by id and also specifying the mod id
            var requestEditWithMod = fmserver.EditRequest(newRecordId, newRecordModId);

            // set the value for the target field
            requestEditWithMod.AddField("fruit", "Lorem Ipsum");

            // execute the request
            response = await requestEditWithMod.Execute();

            if (fmserver.lastErrorCode == 0)
            {
                Console.WriteLine("record edited = " + newRecordId + " in " + fmserver.CurrentLayout + " - mod id was " + newRecordModId);
            }
            else
            {
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }

            // ---------------------------------------------------------------------------------------------------
            // edit a record with non-matching mod id
            // -> same as above but change the mod id to lower than what is expected


            // ---------------------------------------------------------------------------------------------------
            // do a search
            Console.WriteLine("==> doing a find with criteria for range and start record");

            // set the context
            fmserver.SetLayout(testLayoutDataPortal);

            // create the request
            var getSelectedRecords = fmserver.FindRequest();

            // specify how many records to return
            getSelectedRecords.SetHowManyRecords(3);

            // specify the start record (offset)
            getSelectedRecords.SetStartRecord(2);

            // execute the request
            var getFindResponse = await getSelectedRecords.Execute();

            if (getFindResponse.errorCode > 0)
            {
                Console.WriteLine(getFindResponse.errorCode.ToString() + " - " + getFindResponse.result);
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }
            else
            {
                // at this point you could serialize these classes in anything you like
                // whatever is supported by the version of .NET for your platform
                // XML, JSON, DataSet, DataTable,...

                // get some output to the console
                PrintOut(getFindResponse);
            }

            // ---------------------------------------------------------------------------------------------------
            // same search and include only two records from the first portal
            Console.WriteLine("==> doing a find with criteria for range and start record, and a sort, and a selected portal with limited records");

            // set context
            fmserver.SetLayout(testLayoutDataPortal2);

            // create the request
            getSelectedRecords = fmserver.FindRequest();

            // add a portal, remember that you can use named parameters for any combination of startAt and howMany
            // those are optional parameters
            getSelectedRecords.AddPortal("first_portal", howManyRecords: 1, StartAtRecordNumber: 5);

            // specify the regular found set criteria (range and offset)
            getSelectedRecords.SetHowManyRecords(5);
            getSelectedRecords.SetStartRecord(10);

            // and also sort that found set
            getSelectedRecords.AddSortField("modification_count", FMS.SortDirection.descend);
            getSelectedRecords.AddSortField("country", FMS.SortDirection.ascend);

            // execute the request
            getFindResponse = await getSelectedRecords.Execute();

            if (getFindResponse.errorCode > 0)
            {
                Console.WriteLine(getFindResponse.errorCode.ToString() + " - " + getFindResponse.result);
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }
            else
            {
                // at this point you could serialize these classes in anything you like
                // whatever is supported by the version of .NET for your platform
                // XML, JSON, DataSet, DataTable,...

                // get some output to the console
                PrintOut(getFindResponse);
            }

            // ---------------------------------------------------------------------------------------------------
            // do an actual search, for values in a field
            Console.WriteLine("==> doing a find with criteria for multiple fields");

            // set the context
            // fmserver.SetLayout(testLayoutDataPortal);

            // create the request
            getSelectedRecords = fmserver.FindRequest();

            // add two sets of search criteria (group of fields), these will be executed as an AND search
            var request1 = getSelectedRecords.SearchCriterium();

            request1.AddFieldSearch("country", "belgium");
            request1.AddFieldSearch("cake", "spice");

            var request2 = getSelectedRecords.SearchCriterium();

            request2.AddFieldSearch("country", "belgium");
            request2.AddFieldSearch("cake", "rum");

            // only return related data from the first portal
            getSelectedRecords.AddPortal("first_portal");

            // execute the request
            getFindResponse = await getSelectedRecords.Execute();

            if (getFindResponse.errorCode > 0)
            {
                Console.WriteLine(getFindResponse.errorCode.ToString() + " - " + getFindResponse.result);
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }
            else
            {
                // at this point you could serialize these classes in anything you like
                // whatever is supported by the version of .NET for your platform
                // XML, JSON, DataSet, DataTable,...

                // get some output to the console
                PrintOut(getFindResponse);
            }


            // ---------------------------------------------------------------------------------------------------
            // set a global field
            Console.WriteLine("==> setting a single global field");

            // set the context
            fmserver.SetLayout(testLayoutData);

            // set the global (executes it automatically)
            var globalResponse = await fmserver.SetSingleGlobalField("global_field_text", "FRUIT", "Hello World!");

            // get a random record back to confirm the values
            findRequest     = fmserver.FindRequest(1);
            getFindResponse = await findRequest.Execute();

            if (getFindResponse.errorCode > 0)
            {
                Console.WriteLine(getFindResponse.errorCode.ToString() + " - " + getFindResponse.result);
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }
            else
            {
                // at this point you could serialize these classes in anything you like
                // whatever is supported by the version of .NET for your platform
                // XML, JSON, DataSet, DataTable,...

                // get some output to the console
                PrintOut(getFindResponse);
            }


            // ---------------------------------------------------------------------------------------------------
            // add multiple globals and get the response back
            Console.WriteLine("==> setting multiple global fields, including repeats");

            // set the context
            fmserver.SetLayout(testLayoutData);

            // create a list of global fields and their values you want to set
            List <Field> fields = new List <Field>();

            fields.Add(new Field("global_field_number", "FRUIT", 1, "7", 17));
            fields.Add(new Field("global_field_text", "FRUIT", 1, "Lorem Ipsum", 17));
            // and setting the 3rd repeat of a global:
            fields.Add(new Field("global_field_number_repeat", "FRUIT", 3, "77", 17));

            // execute it
            globalResponse = await fmserver.SetMultipleGlobalField(fields);

            // get a random record back to confirm the values
            findRequest     = fmserver.FindRequest(1);
            getFindResponse = await findRequest.Execute();

            if (getFindResponse.errorCode > 0)
            {
                Console.WriteLine(getFindResponse.errorCode.ToString() + " - " + getFindResponse.result);
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }
            else
            {
                // at this point you could serialize these classes in anything you like
                // whatever is supported by the version of .NET for your platform
                // XML, JSON, DataSet, DataTable,...

                // get some output to the console
                PrintOut(getFindResponse);
            }

            // upload a file to a container
            string   file = @"C:\Users\Wim Decorte\Downloads\faulty_20180205.zip";
            FileInfo f    = new FileInfo(file);

            //byte[] filedata = System.IO.File.ReadAllBytes(file);  // ---> no need, doing that in the library so clean up
            fmserver.SetLayout(testLayoutData);
            // int x = await fmserver.UploadFileIntoContainerField(10000, "container_field", filedata, "faulty_20180205.zip");
            int x = await fmserver.UploadFileIntoContainerField(10000, "container_field", f);

            if (fmserver.lastErrorCode == 0)
            {
                Console.WriteLine("file uploaded to container");
            }
            else
            {
                Console.WriteLine(fmserver.lastErrorCode.ToString() + " - " + fmserver.lastErrorMessage);
            }


            // ---------------------------------------------------------------------------------------------------
            // do something with getting containers too?
            // stream to base64 text?
            // probably not, FMS give you back a URL to use, you can grab the byte[] and work from that if you need to

            // ---------------------------------------------------------------------------------------------------
            // add a sort by value list name


            // ---------------------------------------------------------------------------------------------------
            // log out
            Console.WriteLine("Logging out...");

            try
            {
                int responseCode = await fmserver.Logout();

                Console.WriteLine("logout response = " + responseCode.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine("Logout failed = " + ex.Message);
            }


            // ---------------------------------------------------------------------------------------------------
            // wrapping up
            DateTime end     = DateTime.Now;
            double   elapsed = (end - start).TotalMilliseconds;

            Console.WriteLine(end.ToString());
            Console.WriteLine("total milliseconds = " + elapsed.ToString());
            Console.WriteLine("");
            Console.Beep();
            Console.WriteLine("Press any key to close this window...");
            Console.ReadKey();
        }
Ejemplo n.º 2
0
        private async void Timer_Tick(ThreadPoolTimer timer)
        {
            // record the start time
            DateTime start = DateTime.Now;

            // update the display
            leds.Initialize(GrovePi.Sensors.Orientation.GreenToRed);
            leds.SetLevel((byte)0);


            int    lightValue = 0;
            string lightError = string.Empty;

            // read the light
            try
            {
                lightValue = lightSensor.SensorValue();
                // int between 0 (dark) and 1023 (bright)
            }
            catch (Exception ex)
            {
                lightError = ex.Message;
            }

            int    soundValue = 0;
            string soundError = String.Empty;

            try
            {
                soundValue = soundSensor.SensorValue();
            }
            catch (Exception ex)
            {
                soundError = ex.Message;
            }

            // check if token is still valid
            // get a new token every 12 minutes - no real need to since we'll usually keep the connection alive
            if (token == null || token == string.Empty)
            {
                token = await fmserver.Authenticate();

                tokenRecieved = DateTime.Now;
            }
            else if (DateTime.Now > tokenRecieved.AddMinutes(12))
            {
                int logoutResponse = await fmserver.Logout();

                token    = string.Empty;
                fmserver = GetFMSInstance();
                token    = await fmserver.Authenticate();

                tokenRecieved = DateTime.Now;
            }
            if (token != string.Empty)
            {
                // get some data from the RPI itself
                var processorName = Raspberry.Board.Current.ProcessorName;
                var rpiModel      = Raspberry.Board.Current.Model.ToString();

                // write it to FMS
                var request = fmserver.NewRecordRequest();

                if (processorName != null)
                {
                    request.AddField("rpiProcessor", processorName);
                }

                if (rpiModel != null)
                {
                    request.AddField("rpiModel", rpiModel);
                }

                request.AddField("when_start", start.ToString());
                request.AddField("sound", soundValue.ToString());
                request.AddField("sound_error", soundError);
                request.AddField("light", lightValue.ToString());
                request.AddField("light_error", lightError);
                request.AddField("when", DateTime.Now.ToString());

                // add a script call to calculate the time diff to the previous record
                request.AddScript(ScriptTypes.after, "calculate_gap_grove");

                var response = await request.Execute();

                if (fmserver.lastErrorCode != 0)
                {
                    leds.SetLevel((byte)2);
                }
                else
                {
                    leds.SetLevel((byte)10);
                }
                Thread.Sleep(TimeSpan.FromMilliseconds(250));
                // no longer logging out after each call
                // await fmserver.Logout();
                // token = string.empty;
            }
            // clear the display again
            leds.SetLevel((byte)1);
            Thread.Sleep(TimeSpan.FromMilliseconds(250));
        }