/// <summary> /// Initialize the system properties for a new device. /// </summary> /// <param name="device"></param> /// <param name="iccid"></param> /// <returns></returns> private static void InitializeSystemProperties(DeviceModel device, string iccid) { SystemProperties systemProps = new SystemProperties(); systemProps.ICCID = iccid; device.SystemProperties = systemProps; }
/// <summary> /// Adds a device to the Device Identity Store and Device Registry /// </summary> /// <param name="device">Device to add to the underlying repositories</param> /// <returns>Device created along with the device identity store keys</returns> public async Task<DeviceWithKeys> AddDeviceAsync(DeviceModel device) { // Validation logic throws an exception if it finds a validation error await this.ValidateDevice(device); SecurityKeys generatedSecurityKeys = this._securityKeyGenerator.CreateRandomKeys(); DeviceModel savedDevice = await this.AddDeviceToRepositoriesAsync(device, generatedSecurityKeys); return new DeviceWithKeys(savedDevice, generatedSecurityKeys); }
/// <summary> /// Initialize the device properties for a new device. /// </summary> /// <param name="device"></param> /// <param name="deviceId"></param> /// <param name="isSimulated"></param> /// <returns></returns> private static void InitializeDeviceProperties(DeviceModel device, string deviceId, bool isSimulated) { DeviceProperties deviceProps = new DeviceProperties(); deviceProps.DeviceID = deviceId; deviceProps.HubEnabledState = null; deviceProps.CreatedTime = DateTime.UtcNow; deviceProps.DeviceState = "normal"; deviceProps.UpdatedTime = null; device.DeviceProperties = deviceProps; }
/// <summary> /// Build a valid device representation used throughout the app. /// </summary> /// <param name="deviceId"></param> /// <param name="isSimulated"></param> /// <param name="iccid"></param> /// <returns></returns> public static DeviceModel BuildDeviceStructure(string deviceId, bool isSimulated, string iccid) { DeviceModel device = new DeviceModel(); InitializeDeviceProperties(device, deviceId, isSimulated); InitializeSystemProperties(device, iccid); device.Commands = new List<Command>(); device.CommandHistory = new List<CommandHistory>(); device.IsSimulatedDevice = isSimulated; return device; }
public void GetListOfAvailableIccidsTest() { var iccids = fixture.Create<List<Iccid>>(); iccids.Add(new Iccid("id1")); IList<DeviceModel> devices = fixture.Create<List<DeviceModel>>(); var device = new DeviceModel(); device.DeviceProperties = new DeviceProperties(); device.DeviceProperties.DeviceID = "id1"; device.SystemProperties = new SystemProperties(); device.SystemProperties.ICCID = "id1"; devices.Add(device); cellularService.Setup(mock => mock.GetTerminals()).Returns(iccids); var result = cellularExtensions.GetListOfAvailableIccids(devices); Assert.Equal(result.Count(), devices.Count - 1); Assert.False(result.Contains("id1")); }
/// <summary> /// Adds the provided device to the IoT hub with the provided security keys /// </summary> /// <param name="device"></param> /// <param name="securityKeys"></param> /// <returns></returns> public async Task<DeviceModel> AddDeviceAsync(DeviceModel device, SecurityKeys securityKeys) { var iotHubDevice = new Device(device.DeviceProperties.DeviceID); var authentication = new AuthenticationMechanism { SymmetricKey = new SymmetricKey { PrimaryKey = securityKeys.PrimaryKey, SecondaryKey = securityKeys.SecondaryKey } }; iotHubDevice.Authentication = authentication; await AzureRetryHelper.OperationWithBasicRetryAsync(async () => await this._deviceManager.AddDeviceAsync(iotHubDevice)); return device; }
/// <summary> /// Adds a device to the DocumentDB. /// Throws a DeviceAlreadyRegisteredException if a device already exists in the database with the provided deviceId /// </summary> /// <param name="device"></param> /// <returns></returns> public async Task<DeviceModel> AddDeviceAsync(DeviceModel device) { if (device == null) { throw new ArgumentNullException("device"); } if (string.IsNullOrEmpty(device.id)) { device.id = Guid.NewGuid().ToString(); } DeviceModel existingDevice = await GetDeviceAsync(device.DeviceProperties.DeviceID); if (existingDevice != null) { throw new DeviceAlreadyRegisteredException(device.DeviceProperties.DeviceID); } var savedDevice = await _documentClient.SaveAsync(device); return savedDevice; }
private async Task ProcessEventItem(DeviceModel eventData) { if (eventData == null || eventData.ObjectType == null) { Trace.TraceWarning("Event has no ObjectType defined. No action was taken on Event packet."); return; } string objectType = eventData.ObjectType; var objectTypePrefix = _configurationProvider.GetConfigurationSettingValue("ObjectTypePrefix"); if (string.IsNullOrWhiteSpace(objectTypePrefix)) { objectTypePrefix = ""; } if (objectType == objectTypePrefix + SampleDeviceFactory.OBJECT_TYPE_DEVICE_INFO) { await ProcessDeviceInfo(eventData); } else { Trace.TraceWarning("Unknown ObjectType in event."); } }
public IEnumerable<DevicePropertyValueModel> ExtractDevicePropertyValuesModels( DeviceModel device) { DeviceProperties deviceProperties; string hostNameValue; IEnumerable<DevicePropertyValueModel> propValModels; if (device == null) { throw new ArgumentNullException("device"); } deviceProperties = device.DeviceProperties; if (deviceProperties == null) { throw new DeviceRequiredPropertyNotFoundException("Required DeviceProperties not found"); } propValModels = ExtractPropertyValueModels(deviceProperties); hostNameValue = _configProvider.GetConfigurationSettingValue("iotHub.HostName"); if (!string.IsNullOrEmpty(hostNameValue)) { propValModels = propValModels.Concat( new DevicePropertyValueModel[] { new DevicePropertyValueModel() { DisplayOrder = 0, IsEditable = false, IsIncludedWithUnregisteredDevices = true, Name = "HostName", PropertyType = Models.PropertyType.String, Value = hostNameValue } }); } return propValModels; }
private IList<SelectListItem> GetCommandListItems(DeviceModel device) { IList<SelectListItem> result = new List<SelectListItem>(); IList<Command> commands = device.Commands; if (commands != null) { foreach (Command command in commands) { if (IsCommandPublic(command)) { SelectListItem item = new SelectListItem(); item.Value = command.Name; item.Text = command.Name; result.Add(item); } } } return result; }
private bool ValidateDeviceId(DeviceModel device, List<string> validationErrors) { if (device.DeviceProperties == null || string.IsNullOrWhiteSpace(device.DeviceProperties.DeviceID)) { validationErrors.Add(Strings.ValidationDeviceIdMissing); return false; } return true; }
public IList<DeviceTelemetryFieldModel> ExtractTelemetry(DeviceModel device) { // Get Telemetry Fields if (device != null && device.Telemetry != null) { var deviceTelemetryFields = new List<DeviceTelemetryFieldModel>(); foreach (var field in device.Telemetry) { // Default displayName to null if not present string displayName = field.DisplayName != null ? field.DisplayName : null; deviceTelemetryFields.Add(new DeviceTelemetryFieldModel { DisplayName = displayName, Name = field.Name, Type = field.Type }); } return deviceTelemetryFields; } else { return null; } }
private async Task ValidateDevice(DeviceModel device) { List<string> validationErrors = new List<string>(); if (ValidateDeviceId(device, validationErrors)) { await CheckIfDeviceExists(device, validationErrors); } if (validationErrors.Count > 0) { var validationException = new ValidationException(device.DeviceProperties != null ? device.DeviceProperties.DeviceID : null); foreach (string error in validationErrors) { validationException.Errors.Add(error); } throw validationException; } }
private static bool GetValueMatchesStatus(DeviceModel item, string statusName) { if (item == null) { throw new ArgumentNullException("item"); } if (string.IsNullOrEmpty(statusName)) { return false; } var normalizedStatus = statusName.ToUpperInvariant(); var enabledState = item.DeviceProperties?.HubEnabledState == null ? (bool?) null : item.DeviceProperties.GetHubEnabledState(); switch (normalizedStatus) { case "RUNNING": return enabledState == true; case "DISABLED": return enabledState == false; case "PENDING": return !enabledState.HasValue; default: throw new ArgumentOutOfRangeException("statusName", statusName, "statusName has an unhandled status value."); } }
private static void AssignDeviceProperties(DeviceModel device) { int randomId = Rand.Next(0, _possibleDeviceLocations.Count - 1); if (device?.DeviceProperties == null) { throw new DeviceRequiredPropertyNotFoundException("Required DeviceProperties not found"); } device.DeviceProperties.HubEnabledState = true; device.DeviceProperties.Manufacturer = "Contoso Inc."; device.DeviceProperties.ModelNumber = "MD-" + randomId; device.DeviceProperties.SerialNumber = "SER" + randomId; device.DeviceProperties.FirmwareVersion = "1." + randomId; device.DeviceProperties.Platform = "Plat-" + randomId; device.DeviceProperties.Processor = "i3-" + randomId; device.DeviceProperties.InstalledRAM = randomId + " MB"; // Choose a location among the 16 above and set Lat and Long for device properties device.DeviceProperties.Latitude = _possibleDeviceLocations[randomId].Latitude; device.DeviceProperties.Longitude = _possibleDeviceLocations[randomId].Longitude; }
private static void AssignCommands(DeviceModel device) { device.Commands.Add(new Command("PingDevice")); device.Commands.Add(new Command("StartTelemetry")); device.Commands.Add(new Command("StopTelemetry")); device.Commands.Add(new Command("ChangeSetPointTemp", new [] { new Parameter("SetPointTemp", "double") })); device.Commands.Add(new Command("DiagnosticTelemetry", new[] { new Parameter("Active", "boolean") })); device.Commands.Add(new Command("ChangeDeviceState", new[] { new Parameter("DeviceState", "string") })); }
private static void AssignTelemetry(DeviceModel device) { device.Telemetry.Add(new Telemetry("Temperature", "Temperature", "double")); device.Telemetry.Add(new Telemetry("Humidity", "Humidity", "double")); }
private async Task CheckIfDeviceExists(DeviceModel device, List<string> validationErrors) { // check if device exists if (await this.GetDeviceAsync(device.DeviceProperties.DeviceID) != null) { validationErrors.Add(Strings.ValidationDeviceExists); } }
private async Task ProcessDeviceInfo(DeviceModel deviceInfo) { string versionAsString = ""; if (deviceInfo.Version != null) { versionAsString = deviceInfo.Version; } switch (versionAsString) { case SampleDeviceFactory.VERSION_1_0: //Data coming in from the simulator can sometimes turn a boolean into 0 or 1. //Check the HubEnabledState since this is actually displayed and make sure it's in a good format //Should not be required for strongly typed object //DeviceSchemaHelperND.FixDeviceSchema(deviceInfo); if (deviceInfo.IoTHub == null) { throw new DeviceRequiredPropertyNotFoundException("'IoTHubProperties' property is missing"); } string name = deviceInfo.IoTHub.ConnectionDeviceId; Trace.TraceInformation("ProcessEventAsync -- DeviceInfo: {0}", name); await _deviceLogic.UpdateDeviceFromDeviceInfoPacketAsync(deviceInfo); break; default: Trace.TraceInformation("Unknown version {0} provided in Device Info packet", versionAsString); break; } }
/// <summary> /// Adds the given device and assigned keys to the underlying repositories /// </summary> /// <param name="device">Device to add to repositories</param> /// <param name="securityKeys">Keys to assign to the device</param> /// <returns>Device that was added to the device registry</returns> private async Task<DeviceModel> AddDeviceToRepositoriesAsync(DeviceModel device, SecurityKeys securityKeys) { DeviceModel registryRepositoryDevice = null; ExceptionDispatchInfo capturedException = null; // if an exception happens at this point pass it up the stack to handle it // (Making this call first then the call against the Registry removes potential issues // with conflicting rollbacks if the operation happens to still be in progress.) await _iotHubRepository.AddDeviceAsync(device, securityKeys); try { registryRepositoryDevice = await _deviceRegistryCrudRepository.AddDeviceAsync(device); } catch (Exception ex) { // grab the exception so we can attempt an async removal of the device from the IotHub capturedException = ExceptionDispatchInfo.Capture(ex); } //Create a device in table storage if it is a simulated type of device //and the document was stored correctly without an exception bool isSimulatedAsBool = false; try { isSimulatedAsBool = (bool)device.IsSimulatedDevice; } catch (InvalidCastException ex) { Trace.TraceError("The IsSimulatedDevice property was in an invalid format. Exception Error Message: {0}", ex.Message); } if (capturedException == null && isSimulatedAsBool) { try { await _virtualDeviceStorage.AddOrUpdateDeviceAsync(new InitialDeviceConfig() { DeviceId = device.DeviceProperties.DeviceID, HostName = _configProvider.GetConfigurationSettingValue("iotHub.HostName"), Key = securityKeys.PrimaryKey }); } catch (Exception ex) { //if we fail adding to table storage for the device simulator just continue Trace.TraceError("Failed to add simulated device : {0}", ex.Message); } } // Since the rollback code runs async and async code cannot run within the catch block it is run here if (capturedException != null) { // This is a lazy attempt to remove the device from the Iot Hub. If it fails // the device will still remain in the Iot Hub. A more robust rollback may be needed // in some scenarios. await _iotHubRepository.TryRemoveDeviceAsync(device.DeviceProperties.DeviceID); capturedException.Throw(); } return registryRepositoryDevice; }
/// <summary> /// Updates the device in the device registry with the exact device provided in this call. /// NOTE: The device provided here should represent the entire device that will be /// serialized into the device registry. /// </summary> /// <param name="device">Device to update in the device registry</param> /// <returns>Device that was saved into the device registry</returns> public async Task<DeviceModel> UpdateDeviceAsync(DeviceModel device) { return await _deviceRegistryCrudRepository.UpdateDeviceAsync(device); }
private IList<SelectListItem> CommandListItems(DeviceModel device) { if (device.Commands != null) { return GetCommandListItems(device); } return new List<SelectListItem>(); }
public async Task<DeviceModel> UpdateDeviceFromDeviceInfoPacketAsync(DeviceModel device) { if (device == null) { throw new ArgumentNullException("device"); } // Get original device document DeviceModel existingDevice = await this.GetDeviceAsync(device.IoTHub.ConnectionDeviceId); // Save the command history, original created date, and system properties (if any) of the existing device if (existingDevice.DeviceProperties != null) { DeviceProperties deviceProperties = device.DeviceProperties; deviceProperties.CreatedTime = existingDevice.DeviceProperties.CreatedTime; existingDevice.DeviceProperties = deviceProperties; } device.CommandHistory = existingDevice.CommandHistory; // Copy the existing system properties, or initialize them if they do not exist if (existingDevice.SystemProperties != null) { device.SystemProperties = existingDevice.SystemProperties; } else { device.SystemProperties = null; } // If there is Telemetry or Command objects from device, replace instead of merge if (device.Telemetry != null) { existingDevice.Telemetry = device.Telemetry; } if (device.Commands != null) { existingDevice.Commands = device.Commands; } return await _deviceRegistryCrudRepository.UpdateDeviceAsync(existingDevice); }
private bool SearchTypePropertiesForValue(DeviceModel device, string search) { // if the device or its system properties are null then // there's nothing that can be searched on if (device?.DeviceProperties == null) { return false; } // iterate through the DeviceProperties Properties and look for the search value // case insensitive search var upperCaseSearch = search.ToUpperInvariant(); return device.DeviceProperties.ToKeyValuePairs().Any(t => (t.Value != null) && t.Value.ToString().ToUpperInvariant().Contains(upperCaseSearch)); }
/// <summary> /// Sends a command to the provided device and updates the command history of the device /// </summary> /// <param name="device">Device to send the command to</param> /// <param name="commandName">Name of the command to send</param> /// <param name="parameters">Parameters to send with the command</param> /// <returns></returns> private async Task<CommandHistory> SendCommandAsyncWithDevice(DeviceModel device, string commandName, dynamic parameters) { if (device == null) { throw new ArgumentNullException("device"); } var deviceId = device.DeviceProperties.DeviceID; if (device.Commands.FirstOrDefault(x => x.Name == commandName) == null) { throw new UnsupportedCommandException(deviceId, commandName); } var commandHistory = new CommandHistory(commandName, parameters); if (device.CommandHistory == null) { device.CommandHistory = new List<CommandHistory>(); } device.CommandHistory.Add(commandHistory); await _iotHubRepository.SendCommand(deviceId, commandHistory); await _deviceRegistryCrudRepository.UpdateDeviceAsync(device); return commandHistory; }
/// <summary> /// Updates an existing device in the DocumentDB /// Throws a DeviceNotRegisteredException is the device does not already exist in the DocumentDB /// </summary> /// <param name="device"></param> /// <returns></returns> public async Task<DeviceModel> UpdateDeviceAsync(DeviceModel device) { if (device == null) { throw new ArgumentNullException("device"); } if (device.DeviceProperties == null) { throw new DeviceRequiredPropertyNotFoundException("'DeviceProperties' property is missing"); } if (string.IsNullOrEmpty(device.DeviceProperties.DeviceID)) { throw new DeviceRequiredPropertyNotFoundException("'DeviceID' property is missing"); } DeviceModel existingDevice = await GetDeviceAsync(device.DeviceProperties.DeviceID); if (existingDevice == null) { throw new DeviceNotRegisteredException(device.DeviceProperties.DeviceID); } string incomingRid = device._rid ?? ""; if (string.IsNullOrWhiteSpace(incomingRid)) { // copy the existing _rid onto the incoming data if needed var existingRid = existingDevice._rid ?? ""; if (string.IsNullOrWhiteSpace(existingRid)) { throw new InvalidOperationException("Could not find _rid property on existing device"); } device._rid = existingRid; } string incomingId = device.id ?? ""; if (string.IsNullOrWhiteSpace(incomingId)) { // copy the existing id onto the incoming data if needed if (existingDevice.DeviceProperties == null) { throw new DeviceRequiredPropertyNotFoundException("'DeviceProperties' property is missing"); } var existingId = existingDevice.id ?? ""; if (string.IsNullOrWhiteSpace(existingId)) { throw new InvalidOperationException("Could not find id property on existing device"); } device.id = existingId; } device.DeviceProperties.UpdatedTime = DateTime.UtcNow; var savedDevice = await this._documentClient.SaveAsync(device); return savedDevice; }
private async Task<DeviceModel> AddOrRemoveSimulatedDevice(DeviceModel repositoryDevice, bool isEnabled) { var deviceId = repositoryDevice.DeviceProperties.DeviceID; if (isEnabled) { try { var securityKeys = await this.GetIoTHubKeysAsync(deviceId); await _virtualDeviceStorage.AddOrUpdateDeviceAsync(new InitialDeviceConfig() { DeviceId = deviceId, HostName = _configProvider.GetConfigurationSettingValue("iotHub.HostName"), Key = securityKeys.PrimaryKey }); } catch (Exception ex) { //if we fail adding to table storage for the device simulator just continue Trace.TraceError("Failed to add enabled device to simulated device storage. Device telemetry is expected not to be sent. : {0}", ex.Message); } } else { try { await _virtualDeviceStorage.RemoveDeviceAsync(deviceId); } catch (Exception ex) { //if an exception occurs while attempting to remove the //simulated device from table storage do not roll back the changes. Trace.TraceError("Failed to remove disabled device from simulated device store. Device will keep sending telemetry data. : {0}", ex.Message); } } return repositoryDevice; }
public DeviceWithKeys(DeviceModel device, SecurityKeys securityKeys) { Device = device; SecurityKeys = securityKeys; }
/// <summary> /// Modified a Device using a list of /// <see cref="DevicePropertyValueModel" />. /// </summary> /// <param name="device"> /// The Device to modify. /// </param> /// <param name="devicePropertyValueModels"> /// The list of <see cref="DevicePropertyValueModel" />s for modifying /// <paramref name="device" />. /// </param> public void ApplyDevicePropertyValueModels( DeviceModel device, IEnumerable<DevicePropertyValueModel> devicePropertyValueModels) { if (device == null) { throw new ArgumentNullException("device"); } if (devicePropertyValueModels == null) { throw new ArgumentNullException("devicePropertyValueModels"); } if (device.DeviceProperties == null) { throw new DeviceRequiredPropertyNotFoundException("Required DeviceProperties not found"); } ApplyPropertyValueModels(device.DeviceProperties, devicePropertyValueModels); }