public new Task InitializeAsync() { base.InitializeAsync().Wait(); // call base method initialization // set initial direction string initialDirection = deviceConfig.initialDirection; // use configuration value as default var myTwin = _DeviceClient.GetDynamicDigitalTwinAsync().Result; // get twin if (myTwin.Properties.Reported.Contains("GateDirection")) { // if there is a diretion property // set the value direction, don't use the Set method so we don't trigger a device twin property udpate CurrentDirection = (GateDirection)Enum.Parse(typeof(GateDirection), initialDirection = myTwin.Properties.Reported["GateDirection"]); } else // direction wasn't already set { // set direction of device via the setter so we update the device twin this.SetDirectionAsync((GateDirection)Enum.Parse(typeof(GateDirection), initialDirection)).Wait(); } TimedSimulatedEvent simulatedEvent = new TimedSimulatedEvent(2500, 1000, this.SimulatedTicketSwipeOccured); // set up any simulated events for this device this._EventScheduler.Add(simulatedEvent); // register any direct methods we're to recieve // receive ticket validation results this._DeviceClient.RegisterDirectMethodAsync(ReceiveTicketValidationResponse).Wait(); // receive gate direction change commands this._DeviceClient.RegisterDirectMethodAsync(ReceiveCommandGateChange).Wait(); _DeviceClient.RegisterDesiredPropertyUpdateCallbackAsync(OnGateDeviceDesiredPropertyChanged); return(Task.CompletedTask); }
// Update is called once per frame void Update() { if (gateDirection == GateDirection.LEFT && previousDirection == GateDirection.RIGHT) { // Debug.Log("Switch Left"); } if (gateDirection == GateDirection.RIGHT && previousDirection == GateDirection.LEFT) { //Debug.Log("Switch Right"); } previousDirection = gateDirection; }
/// <summary> /// This method updates the direction of the Gate Reader to either In or Out /// This updates not only the internal state of the device, but also its IOT Hub Device Twin /// </summary> /// <param name="value"></param> /// <returns></returns> public async Task SetDirectionAsync(GateDirection value) { // if the direction is different then what we've had before... if (this.Direction != value) { // set device twin property await this._DeviceClient.SetReportedDigitalTwinPropertyAsync(new KeyValuePair <string, object>("GateDirection", value.ToString())); // set local cached value. Done after the device twin update so if it failed, we didn't update our local value this.CurrentDirection = value; } return; }
/// <summary> /// This event is called by a timer to simulate a card/ticket being scanned. It checks the direction of the gate (in/out) /// And if the swipe is in the right direction will ask the "cloud" to validate the card and wait for that result. /// </summary> private bool SimulatedTicketSwipeOccured() { GateDirection randomDirection = this.Direction; // default to the 'right' direction // randomize if swipe was from 'right' direction, if so we need to validate the ticket Random gen = new Random(); if (gen.Next(100) > (100 - this.deviceConfig.PercentOfWrongWay)) // if from 'wrong' direction { // get other direction randomDirection = (this.Direction == GateDirection.In ? GateDirection.Out : GateDirection.In); } bool needtovalidate = randomDirection == this.Direction; // don't restart timer // if the swipe was from the right direction, as for the ticket to be validated if (needtovalidate) { ValidateTicketRequest cloudRequest = new ValidateTicketRequest() { DeviceId = this.deviceId, DeviceType = this.deviceType, TransactionId = Guid.NewGuid().ToString(), CreateTime = System.DateTime.UtcNow, MethodName = "ReceiveTicketValidationResponse" // must match callback method }; var messageString = JsonConvert.SerializeObject(cloudRequest); SendMessageToCloud(messageString); Console.WriteLine("{0} > Sending message: {1}", DateTime.Now, messageString); Console.WriteLine(); } // if the swipe was from the wrong direction, we ignore it else { Console.WriteLine(); Console.WriteLine("Swipe from Wrong Direction, ignoring"); } // if we asked for the ticket to be validated, return false so we don't trigger another swipe return(needtovalidate == false); }
public void TestGateReaderGateDirection() { FakeDeviceClient fakeDeviceClient = new FakeDeviceClient(fakeTwin); FakeEventScheduler fakeScheduler = new FakeEventScheduler(); TestContext.WriteLine(">> Testing the Device's Gate Direction initialization .."); // create our test device GateReaderDevice device = new GateReaderDevice(deviceconfig, fakeDeviceClient, fakeScheduler); device.InitializeAsync().Wait(); // gate direction should be "Out" as fakeTwin properties should override device config Assert.AreEqual(GateDirection.Out, device.Direction, $"Device gate direction is not correct, expected 'In', found {device.Direction}"); TestContext.WriteLine(">> Testing the Device's Gate Direction change commands.."); cmdGateDirectionUpdate commandGateDirectionUpdate = new cmdGateDirectionUpdate() { Direction = GateDirection.Out }; // call the gate change direction TestContext.WriteLine(string.Empty); TestContext.WriteLine(">> Sending command to change gate direction when its already pointed that way, shouldn't log event"); string requestString = JsonConvert.SerializeObject(commandGateDirectionUpdate); MethodRequest methodRequest = new MethodRequest("ReceiveCommandGateChange", Encoding.UTF8.GetBytes(requestString)); MethodResponse myresult = fakeDeviceClient.directMethods[1](methodRequest, null).Result; // gate direction should be "In" now Assert.AreEqual(GateDirection.Out, device.Direction, $"Device gate direction is not correct, expected 'Out', found {device.Direction}"); // check the device twin properties // ensures that the device is using the device client SetDigitalTwinPropertyAsync method for twin property updates GateDirection twinDirection = (GateDirection)Enum.Parse(typeof(GateDirection), fakeTwin.Properties.Reported["GateDirection"].ToString()); Assert.AreEqual(GateDirection.Out, twinDirection, $"Device gate direction in the device twin is not correct, expected 'Out', found {twinDirection}"); }