mirror of https://github.com/dapr/quickstarts.git
				
				
				
			Implemented reminders to clear alarm state after 15 seconds
Signed-off-by: Paul Yuknewicz <paulyuk@Pauls-MBP-2.lan>
This commit is contained in:
		
							parent
							
								
									a3b93d848e
								
							
						
					
					
						commit
						702bbcdc81
					
				| 
						 | 
				
			
			@ -90,16 +90,12 @@ Expected output:
 | 
			
		|||
 | 
			
		||||
When you ran the client app:
 | 
			
		||||
 | 
			
		||||
1. A `SmartDetectorActor` is created with these properties: Id = 1, Location = "First Floor", Status = "Ready".
 | 
			
		||||
2. Another `SmartDetectorActor` is created with these properties: Id = 2, Location = "Second Floor", Status = "Ready".
 | 
			
		||||
3. The status of `SmartDetectorActor` 1 is read and printed to the console.
 | 
			
		||||
4. The status of `SmartDetectorActor` 2 is read and printed to the console.
 | 
			
		||||
5. The `DetectSmokeAsync` method of `SmartDetectorActor` 1 is called.
 | 
			
		||||
6. The `TriggerAlarmForAllDetectors` method of `ControllerActor` is called.
 | 
			
		||||
7. The `SoundAlarm` method of `SmartDetectorActor` 1 is called.
 | 
			
		||||
8. The `SoundAlarm` method of `SmartDetectorActor` 2 is called.
 | 
			
		||||
9. The status of `SmartDetectorActor` 1 is read and printed to the console.
 | 
			
		||||
10. The status of `SmartDetectorActor` 2 is read and printed to the console.
 | 
			
		||||
1. Two `SmartDetectorActor` actors are created and initialized with Id, Location, and Status="Ready"
 | 
			
		||||
2. The `DetectSmokeAsync` method of `SmartDetectorActor` 1 is called.
 | 
			
		||||
3. The `TriggerAlarmForAllDetectors` method of `ControllerActor` is called.
 | 
			
		||||
4. The `SoundAlarm` methods of `SmartDetectorActor` 1 and 2 are called.
 | 
			
		||||
5. The `ControllerActor` also creates a reminder to `ClearAlarm` after 15 seconds using `RegisterReminderAsync`
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Looking at the code, `SmartDetectorActor` objects are created in the client application and initialized with object state with `ActorProxy.Create<ISmartDevice>(actorId, actorType)` and then `proxySmartDevice.SetDataAsync(data)`.  These objects are re-entrant and will hold on to the state as shown by `proxySmartDevice.GetDataAsync()`.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -144,6 +140,25 @@ The `ControllerActor` object is used to keep track of the devices and trigger th
 | 
			
		|||
        Console.WriteLine($"Registered devices: {string.Join(", " , deviceIds)}");
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `ControllerActor` internally triggers all alarms when smoke is detected, and then sets a reminder to clear all alarm states after 15 seconds.
 | 
			
		||||
 | 
			
		||||
```csharp
 | 
			
		||||
    public async Task TriggerAlarmForAllDetectors()
 | 
			
		||||
    {
 | 
			
		||||
        var deviceIds =  await ListRegisteredDeviceIdsAsync();
 | 
			
		||||
        foreach (var deviceId in deviceIds)
 | 
			
		||||
        {
 | 
			
		||||
            // Sound the alarm on all devices
 | 
			
		||||
            var actorId = new ActorId(deviceId);
 | 
			
		||||
            var proxySmartDevice = ProxyFactory.CreateActorProxy<ISmartDevice>(actorId, "SmokeDetectorActor");
 | 
			
		||||
            await proxySmartDevice.SoundAlarm();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Register a reminder to refresh and clear alarm state every 15 seconds
 | 
			
		||||
        await this.RegisterReminderAsync("AlarmRefreshReminder", null, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
 | 
			
		||||
    }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Additionally look at:
 | 
			
		||||
 | 
			
		||||
- `SmartDevice.Service/SmartDetectorActor.cs` which contains the implementation of the the smart device actor actions
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,9 +57,6 @@ class Program
 | 
			
		|||
        var controllerActorId = new ActorId("controller");
 | 
			
		||||
        var proxyController = ActorProxy.Create<IController>(controllerActorId, controllerActorType);
 | 
			
		||||
 | 
			
		||||
        //Register reminders every 30 to clear out invalid state or alarms
 | 
			
		||||
        await proxyController.RegisterReminder();
 | 
			
		||||
 | 
			
		||||
        Console.WriteLine($"Registering the IDs of both Devices...");
 | 
			
		||||
        await proxyController.RegisterDeviceIdsAsync(new string[]{deviceId1, deviceId2});
 | 
			
		||||
        var deviceIds = await proxyController.ListRegisteredDeviceIdsAsync();
 | 
			
		||||
| 
						 | 
				
			
			@ -77,8 +74,8 @@ class Program
 | 
			
		|||
        Console.WriteLine($"Device 2 state: {storedDeviceData2}");
 | 
			
		||||
 | 
			
		||||
        // Sleep for 35 seconds and observe reminders have cleared alarm state
 | 
			
		||||
        Console.WriteLine("Sleeping for 35 seconds before observing alarm state after reminders fire");
 | 
			
		||||
        await Task.Delay(35000);
 | 
			
		||||
        Console.WriteLine("Sleeping for 16 seconds before checking status again to see reminders fire and clear alarms");
 | 
			
		||||
        await Task.Delay(16000);
 | 
			
		||||
 | 
			
		||||
        storedDeviceData1 = await proxySmartDevice1.GetDataAsync();
 | 
			
		||||
        Console.WriteLine($"Device 1 state: {storedDeviceData1}");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,12 +6,6 @@ public interface IController : IActor
 | 
			
		|||
    Task RegisterDeviceIdsAsync(string[] deviceIds);
 | 
			
		||||
    Task<string[]> ListRegisteredDeviceIdsAsync();
 | 
			
		||||
    Task TriggerAlarmForAllDetectors();
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Registers a timer.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>A task that represents the asynchronous save operation.</returns>
 | 
			
		||||
    Task RegisterReminder();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public class ControllerData
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ public interface ISmartDevice : IActor
 | 
			
		|||
    Task<SmartDeviceData> GetDataAsync();
 | 
			
		||||
    Task DetectSmokeAsync();
 | 
			
		||||
    Task SoundAlarm();
 | 
			
		||||
    Task ClearAlarm();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public class SmartDeviceData
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ using SmartDevice.Interfaces;
 | 
			
		|||
 | 
			
		||||
namespace SmartDevice;
 | 
			
		||||
 | 
			
		||||
internal class ControllerActor : Actor, IController
 | 
			
		||||
internal class ControllerActor : Actor, IController, IRemindable
 | 
			
		||||
{
 | 
			
		||||
    private readonly string deviceIdsKey = "device-ids";
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -60,12 +60,21 @@ internal class ControllerActor : Actor, IController
 | 
			
		|||
            var proxySmartDevice = ProxyFactory.CreateActorProxy<ISmartDevice>(actorId, "SmokeDetectorActor");
 | 
			
		||||
            await proxySmartDevice.SoundAlarm();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Register a reminder to refresh and clear alarm state every 15 seconds
 | 
			
		||||
        await this.RegisterReminderAsync("AlarmRefreshReminder", null, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public async Task RegisterReminder()
 | 
			
		||||
    public async Task ReceiveReminderAsync(string reminderName, byte[] state, TimeSpan dueTime, TimeSpan period)
 | 
			
		||||
    {
 | 
			
		||||
        // Register a reminder to refresh alarm state every 30 seconds
 | 
			
		||||
        await this.RegisterReminderAsync("AlarmRefreshReminder", null, TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(30));
 | 
			
		||||
        if (reminderName == "AlarmRefreshReminder") {
 | 
			
		||||
        var deviceIds =  await ListRegisteredDeviceIdsAsync();
 | 
			
		||||
            foreach (var deviceId in deviceIds)
 | 
			
		||||
            {
 | 
			
		||||
                var actorId = new ActorId(deviceId);
 | 
			
		||||
                var proxySmartDevice = ProxyFactory.CreateActorProxy<ISmartDevice>(actorId, "SmokeDetectorActor");
 | 
			
		||||
                await proxySmartDevice.ClearAlarm();            
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,4 +81,11 @@ internal class SmokeDetectorActor : Actor, ISmartDevice
 | 
			
		|||
        smartDeviceData.Status = "Alarm";
 | 
			
		||||
        await SetDataAsync(smartDeviceData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public async Task ClearAlarm()
 | 
			
		||||
    {
 | 
			
		||||
        var smartDeviceData = await GetDataAsync();
 | 
			
		||||
        smartDeviceData.Status = "Ready";
 | 
			
		||||
        await SetDataAsync(smartDeviceData);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue