Fix for circular depedency [hold merge till other repos are ready] (#190)
* deviceProperties
* Json format
* comments
* Fix for Review comments
* GetPropertyNames
* GetPropertyNames
* nits
* Merge with master
** Resolve conflict
** Add tests
* Sort using
* Fix typo in file name
* Update DevicePropertyNames API
Change response from hashset to list
* Add API specs doc
* Fix indentation
* Fix typo
* Add test
* Add Comments
* deviceModelProperties
* api specs for device model Properties
* api spec update in sln
* Removing Comments
* DeviceModelPropertiesController Json change
* caps
* update API Spec
* reverting env var
* deviceModelProperties
* PREFIX moved to service model
* review comments some exception
* Revert "review comments some exception"
This reverts commit 6220a93d44
.
* adding comments
* Update SomeException.cs
* Update SomeException.cs
* fix typo
* nit
This commit is contained in:
Родитель
7f4befe616
Коммит
341f3020e9
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -9,6 +9,7 @@ using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Exceptions;
|
|||
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Models;
|
||||
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.StorageAdapter;
|
||||
using Moq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Services.Test.helpers;
|
||||
using Xunit;
|
||||
|
||||
|
@ -100,6 +101,31 @@ namespace Services.Test
|
|||
Assert.Equal(DEVICE_MODEL_ID, result.Id);
|
||||
}
|
||||
|
||||
[Fact, Trait(Constants.TYPE, Constants.UNIT_TEST)]
|
||||
public void ItReturnsPropertyNamesOfDeviceModels()
|
||||
{
|
||||
// Arrange
|
||||
var properties = new Dictionary<string, object>();
|
||||
properties.Add("Type", "chiller");
|
||||
properties.Add("Firmware", "1.0");
|
||||
properties.Add("Location", "Building 2");
|
||||
properties.Add("Model", "CH101");
|
||||
var deviceModels = this.GetDeviceModelsWithProperties(properties);
|
||||
this.customDeviceModels
|
||||
.Setup(x => x.GetListAsync())
|
||||
.ReturnsAsync(deviceModels);
|
||||
|
||||
// Act
|
||||
var result = this.target.GetPropertyNamesAsync().Result;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(properties.Count, result.Count);
|
||||
foreach (var prop in result)
|
||||
{
|
||||
Assert.True(properties.ContainsKey(prop.Split('.')[2]));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact, Trait(Constants.TYPE, Constants.UNIT_TEST)]
|
||||
public void ItThrowsResourceNotFoundExceptionWhenDeviceModelNotFound()
|
||||
{
|
||||
|
@ -128,6 +154,13 @@ namespace Services.Test
|
|||
[Fact, Trait(Constants.TYPE, Constants.UNIT_TEST)]
|
||||
public void ItThrowsExceptionWhenDeleteDeviceModelFailed()
|
||||
{
|
||||
/* SomeException is required to verify that the exception thrown is the one
|
||||
* configured in Arrange expression, and the test doesn't pass for the wrong
|
||||
* reason. That's why we use a helper class SomeException which
|
||||
* doesn't exist in the application. Configuring GetPropertyNameAsync to
|
||||
* throw SomeException allows us to verify that the exception thrown is
|
||||
* exactly SomeException and not something else. */
|
||||
|
||||
// Arrange
|
||||
this.customDeviceModels
|
||||
.Setup(x => x.DeleteAsync(It.IsAny<string>()))
|
||||
|
@ -255,5 +288,22 @@ namespace Services.Test
|
|||
.Setup(x => x.GetListAsync())
|
||||
.ReturnsAsync(deviceModelsList);
|
||||
}
|
||||
|
||||
private List<DeviceModel> GetDeviceModelsWithProperties(Dictionary<string, object> properties)
|
||||
{
|
||||
var deviceModels = new List<DeviceModel>
|
||||
{
|
||||
new DeviceModel {
|
||||
Id = "Id_1",
|
||||
Properties = properties
|
||||
},
|
||||
new DeviceModel {
|
||||
Id = "Id_2",
|
||||
Properties = properties
|
||||
}
|
||||
};
|
||||
|
||||
return deviceModels;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
|||
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Diagnostics;
|
||||
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Exceptions;
|
||||
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Models;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.Services
|
||||
{
|
||||
|
@ -36,6 +37,11 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.Services
|
|||
/// Delete a custom device model.
|
||||
/// </summary>
|
||||
Task DeleteAsync(string id);
|
||||
|
||||
/// <summary>
|
||||
/// Get property names from all device models.
|
||||
/// </summary>
|
||||
Task<List<string>> GetPropertyNamesAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -51,6 +57,7 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.Services
|
|||
private readonly ILogger log;
|
||||
private readonly ICustomDeviceModels customDeviceModels;
|
||||
private readonly IStockDeviceModels stockDeviceModels;
|
||||
private const string REPORTED_PREFIX = "Properties.Reported.";
|
||||
|
||||
public DeviceModels(
|
||||
ICustomDeviceModels customDeviceModels,
|
||||
|
@ -143,6 +150,33 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.Services
|
|||
await this.customDeviceModels.DeleteAsync(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get property names from all device models.
|
||||
/// </summary>
|
||||
public async Task<List<string>> GetPropertyNamesAsync()
|
||||
{
|
||||
var list = await this.GetListAsync();
|
||||
var properties = new HashSet<string>();
|
||||
|
||||
foreach (var model in list)
|
||||
{
|
||||
if (model.Properties != null)
|
||||
{
|
||||
foreach (var property in model.Properties)
|
||||
{
|
||||
this.PreparePropertyNames(properties, property.Value, property.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
List<string> result = new List<string>();
|
||||
|
||||
foreach (string property in properties)
|
||||
{
|
||||
result.Add(REPORTED_PREFIX + property);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns True if there is a stock model with the given Id
|
||||
/// </summary>
|
||||
|
@ -153,5 +187,36 @@ namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.Services
|
|||
return this.stockDeviceModels.GetList()
|
||||
.Any(model => id.Equals(model.Id, StringComparison.InvariantCultureIgnoreCase));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms property names from Json Object to "xxx.yyy.zzz" format
|
||||
/// </summary>
|
||||
private void PreparePropertyNames(HashSet<string> set, object obj, string prefix)
|
||||
{
|
||||
/* Sample conversion:
|
||||
* from -> Foo : {
|
||||
* Bar : Properties
|
||||
* }
|
||||
*
|
||||
* to -> Foo.Bar.Properties
|
||||
*/
|
||||
if (obj is JValue)
|
||||
{
|
||||
set.Add(prefix);
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj is bool || obj is string || double.TryParse(obj.ToString(), out _))
|
||||
{
|
||||
set.Add(prefix);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var item in (obj as JToken).Values())
|
||||
{
|
||||
var path = item.Path;
|
||||
this.PreparePropertyNames(set, item, $"{prefix}.{(path.Contains(".") ? path.Substring(path.LastIndexOf('.') + 1) : path)}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Services.Test.helpers
|
||||
{
|
||||
///<summary>
|
||||
/// This class is used to inject exceptions in the code under test
|
||||
/// and to verify that the system fails with the injected exception,
|
||||
/// i.e. not any exception, to be sure unit tests wouldn't pass in case
|
||||
/// a different exception is occurring, i.e. to avoid false positives.
|
||||
///</summary>
|
||||
public class SomeException : Exception
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services;
|
||||
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Models;
|
||||
using Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.v1.Controllers;
|
||||
using Moq;
|
||||
using Services.Test.helpers;
|
||||
using WebService.Test.helpers;
|
||||
using Xunit;
|
||||
|
||||
namespace WebService.Test.v1.Controllers
|
||||
{
|
||||
public class DeviceModelPropertiesControllerTest
|
||||
{
|
||||
private readonly Mock<IDeviceModels> deviceModelsService;
|
||||
private readonly DeviceModelPropertiesController target;
|
||||
|
||||
public DeviceModelPropertiesControllerTest()
|
||||
{
|
||||
this.deviceModelsService = new Mock<IDeviceModels>();
|
||||
this.target = new DeviceModelPropertiesController(this.deviceModelsService.Object);
|
||||
}
|
||||
|
||||
[Fact, Trait(Constants.TYPE, Constants.UNIT_TEST)]
|
||||
public void ItReturnsTheListOfPropertyNames()
|
||||
{
|
||||
// Arrange
|
||||
var properties = new List<string>
|
||||
{
|
||||
"Type", "Firmware" , "Location" ,"Model", "Latitude" ,"Longitude"
|
||||
};
|
||||
|
||||
this.deviceModelsService
|
||||
.Setup(x => x.GetPropertyNamesAsync())
|
||||
.ReturnsAsync(properties);
|
||||
|
||||
// Act
|
||||
var result = this.target.GetAsync().Result;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(properties.Count, result.Items.Count);
|
||||
foreach (var resultItem in result.Items)
|
||||
{
|
||||
Assert.Contains(resultItem, properties);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact, Trait(Constants.TYPE, Constants.UNIT_TEST)]
|
||||
public void ItThrowsExceptionWhenGetPropertyNamesFailed()
|
||||
{
|
||||
// Arrange
|
||||
this.deviceModelsService
|
||||
.Setup(x => x.GetPropertyNamesAsync())
|
||||
.ThrowsAsync(new SomeException());
|
||||
|
||||
// Act & Assert
|
||||
Assert.ThrowsAsync<SomeException>(
|
||||
async () => await this.target.GetAsync())
|
||||
.Wait(Constants.TEST_TIMEOUT);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services;
|
||||
using Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.v1.Filters;
|
||||
using Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.v1.Models;
|
||||
|
||||
namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.v1.Controllers
|
||||
{
|
||||
[Route(Version.PATH + "/[controller]"), TypeFilter(typeof(ExceptionsFilterAttribute))]
|
||||
public class DeviceModelPropertiesController : Controller
|
||||
{
|
||||
private readonly IDeviceModels deviceModelsService;
|
||||
|
||||
public DeviceModelPropertiesController(IDeviceModels deviceModelsService)
|
||||
{
|
||||
this.deviceModelsService = deviceModelsService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<DeviceModelPropertyListApiModel> GetAsync()
|
||||
{
|
||||
return new DeviceModelPropertyListApiModel(await this.deviceModelsService.GetPropertyNamesAsync());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services;
|
||||
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Diagnostics;
|
||||
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Models;
|
||||
using Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.v1.Exceptions;
|
||||
using Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.v1.Filters;
|
||||
using Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.v1.Models;
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Azure.IoTSolutions.DeviceSimulation.Services.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.Azure.IoTSolutions.DeviceSimulation.WebService.v1.Models
|
||||
{
|
||||
public class DeviceModelPropertyListApiModel
|
||||
{
|
||||
[JsonProperty(PropertyName = "Items")]
|
||||
public List<string> Items { get; set; }
|
||||
|
||||
[JsonProperty(PropertyName = "$metadata")]
|
||||
public Dictionary<string, string> Metadata => new Dictionary<string, string>
|
||||
{
|
||||
{ "$type", "DeviceModelPropertyList;" + Version.NUMBER },
|
||||
{ "$uri", "/" + Version.PATH + "/deviceModelProperties" }
|
||||
};
|
||||
|
||||
public DeviceModelPropertyListApiModel()
|
||||
{
|
||||
this.Items = new List<string>();
|
||||
}
|
||||
|
||||
/// <summary>Map a service model to the corresponding API model</summary>
|
||||
public DeviceModelPropertyListApiModel(List<string> values)
|
||||
{
|
||||
this.Items = values;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +1,19 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2012
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebService.Test", "WebService.Test\WebService.Test.csproj", "{9DFE22E7-03DD-4F30-BCC1-33F69BA15192}"
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27428.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebService.Test", "WebService.Test\WebService.Test.csproj", "{9DFE22E7-03DD-4F30-BCC1-33F69BA15192}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Services", "Services\Services.csproj", "{FBAB42CE-0D43-476A-B231-4C0105A7C67C}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Services", "Services\Services.csproj", "{FBAB42CE-0D43-476A-B231-4C0105A7C67C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Services.Test", "Services.Test\Services.Test.csproj", "{A135F921-CC62-40CD-A3C6-72DD95BB7E72}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Services.Test", "Services.Test\Services.Test.csproj", "{A135F921-CC62-40CD-A3C6-72DD95BB7E72}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimulationAgent", "SimulationAgent\SimulationAgent.csproj", "{93EBB353-A0B6-440F-BD34-17240C4F421B}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimulationAgent", "SimulationAgent\SimulationAgent.csproj", "{93EBB353-A0B6-440F-BD34-17240C4F421B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebService", "WebService\WebService.csproj", "{21FEAC28-BB2D-4827-B62A-0476BF44D602}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebService", "WebService\WebService.csproj", "{21FEAC28-BB2D-4827-B62A-0476BF44D602}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimulationAgent.Test", "SimulationAgent.Test\SimulationAgent.Test.csproj", "{DFE737E7-9FAA-4B08-A2B5-37F2E858FFAF}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimulationAgent.Test", "SimulationAgent.Test\SimulationAgent.Test.csproj", "{DFE737E7-9FAA-4B08-A2B5-37F2E858FFAF}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "solution", "solution", "{71787873-D1A0-4D9E-BC84-942E0FB3841E}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
|
@ -44,15 +46,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{2B58
|
|||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{DEF8CFF7-B332-4BA3-AB0B-8F7AC3275054}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
scripts\docker\.dockerignore = scripts\docker\.dockerignore
|
||||
scripts\docker\build = scripts\docker\build
|
||||
scripts\docker\build.cmd = scripts\docker\build.cmd
|
||||
scripts\docker\Dockerfile = scripts\docker\Dockerfile
|
||||
scripts\docker\run.cmd = scripts\docker\run.cmd
|
||||
scripts\docker\.dockerignore = scripts\docker\.dockerignore
|
||||
scripts\docker\run = scripts\docker\run
|
||||
scripts\docker\docker-compose.yml = scripts\docker\docker-compose.yml
|
||||
scripts\docker\Dockerfile = scripts\docker\Dockerfile
|
||||
scripts\docker\publish = scripts\docker\publish
|
||||
scripts\docker\publish.cmd = scripts\docker\publish.cmd
|
||||
scripts\docker\run = scripts\docker\run
|
||||
scripts\docker\run.cmd = scripts\docker\run.cmd
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "git", "git", "{4C88469C-C551-435D-AE2C-36C58EE686A5}"
|
||||
|
@ -72,20 +74,21 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "content", "content", "{39EA
|
|||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{0680130C-7156-4118-BE65-4734BA92638B}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
docs\CODEOWNERS = docs\CODEOWNERS
|
||||
docs\ISSUE_TEMPLATE.md = docs\ISSUE_TEMPLATE.md
|
||||
docs\PULL_REQUEST_TEMPLATE.md = docs\PULL_REQUEST_TEMPLATE.md
|
||||
docs\CODE_OF_CONDUCT.md = docs\CODE_OF_CONDUCT.md
|
||||
docs\CONTRIBUTING.md = docs\CONTRIBUTING.md
|
||||
docs\API_SPECS_DEVICE_MODELS.md = docs\API_SPECS_DEVICE_MODELS.md
|
||||
docs\API_SPECS_SERVICE.md = docs\API_SPECS_SERVICE.md
|
||||
docs\API_SPECS_SIMULATIONS.md = docs\API_SPECS_SIMULATIONS.md
|
||||
docs\DEVICE_MODELS.md = docs\DEVICE_MODELS.md
|
||||
docs\INDEX.md = docs\INDEX.md
|
||||
docs\BREAKING_CHANGES.md = docs\BREAKING_CHANGES.md
|
||||
docs\ENVIRONMENT_VARIABLES.md = docs\ENVIRONMENT_VARIABLES.md
|
||||
EndProjectSection
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
docs\API_SPECS_DEVICE_MODELS.md = docs\API_SPECS_DEVICE_MODELS.md
|
||||
docs\API_SPECS_DEVICE_MODEL_PROPERTIES.md = docs\API_SPECS_DEVICE_MODEL_PROPERTIES.md
|
||||
docs\API_SPECS_SERVICE.md = docs\API_SPECS_SERVICE.md
|
||||
docs\API_SPECS_SIMULATIONS.md = docs\API_SPECS_SIMULATIONS.md
|
||||
docs\BREAKING_CHANGES.md = docs\BREAKING_CHANGES.md
|
||||
docs\CODE_OF_CONDUCT.md = docs\CODE_OF_CONDUCT.md
|
||||
docs\CODEOWNERS = docs\CODEOWNERS
|
||||
docs\CONTRIBUTING.md = docs\CONTRIBUTING.md
|
||||
docs\DEVICE_MODELS.md = docs\DEVICE_MODELS.md
|
||||
docs\ENVIRONMENT_VARIABLES.md = docs\ENVIRONMENT_VARIABLES.md
|
||||
docs\INDEX.md = docs\INDEX.md
|
||||
docs\ISSUE_TEMPLATE.md = docs\ISSUE_TEMPLATE.md
|
||||
docs\PULL_REQUEST_TEMPLATE.md = docs\PULL_REQUEST_TEMPLATE.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -107,14 +110,14 @@ Global
|
|||
{A135F921-CC62-40CD-A3C6-72DD95BB7E72}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{93EBB353-A0B6-440F-BD34-17240C4F421B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{93EBB353-A0B6-440F-BD34-17240C4F421B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{93EBB353-A0B6-440F-BD34-17240C4F421B}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{93EBB353-A0B6-440F-BD34-17240C4F421B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{93EBB353-A0B6-440F-BD34-17240C4F421B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{93EBB353-A0B6-440F-BD34-17240C4F421B}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{21FEAC28-BB2D-4827-B62A-0476BF44D602}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{21FEAC28-BB2D-4827-B62A-0476BF44D602}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{21FEAC28-BB2D-4827-B62A-0476BF44D602}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{21FEAC28-BB2D-4827-B62A-0476BF44D602}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{21FEAC28-BB2D-4827-B62A-0476BF44D602}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{21FEAC28-BB2D-4827-B62A-0476BF44D602}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{DFE737E7-9FAA-4B08-A2B5-37F2E858FFAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DFE737E7-9FAA-4B08-A2B5-37F2E858FFAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DFE737E7-9FAA-4B08-A2B5-37F2E858FFAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
@ -123,6 +126,16 @@ Global
|
|||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{2B58D756-04D5-427F-9161-E1B45D35682A} = {71787873-D1A0-4D9E-BC84-942E0FB3841E}
|
||||
{DEF8CFF7-B332-4BA3-AB0B-8F7AC3275054} = {2B58D756-04D5-427F-9161-E1B45D35682A}
|
||||
{4C88469C-C551-435D-AE2C-36C58EE686A5} = {2B58D756-04D5-427F-9161-E1B45D35682A}
|
||||
{39EA50D7-B4CD-41C4-85EA-E53E89E9BC98} = {DEF8CFF7-B332-4BA3-AB0B-8F7AC3275054}
|
||||
{0680130C-7156-4118-BE65-4734BA92638B} = {71787873-D1A0-4D9E-BC84-942E0FB3841E}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {25EBA0C1-8A8C-4116-948B-626F1638B7DA}
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
Policies = $0
|
||||
$0.DotNetNamingPolicy = $1
|
||||
|
@ -133,11 +146,4 @@ Global
|
|||
$3.scope = text/x-csharp
|
||||
$0.VersionControlPolicy = $4
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{2B58D756-04D5-427F-9161-E1B45D35682A} = {71787873-D1A0-4D9E-BC84-942E0FB3841E}
|
||||
{DEF8CFF7-B332-4BA3-AB0B-8F7AC3275054} = {2B58D756-04D5-427F-9161-E1B45D35682A}
|
||||
{4C88469C-C551-435D-AE2C-36C58EE686A5} = {2B58D756-04D5-427F-9161-E1B45D35682A}
|
||||
{39EA50D7-B4CD-41C4-85EA-E53E89E9BC98} = {DEF8CFF7-B332-4BA3-AB0B-8F7AC3275054}
|
||||
{0680130C-7156-4118-BE65-4734BA92638B} = {71787873-D1A0-4D9E-BC84-942E0FB3841E}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
API specifications - Device Model Properties
|
||||
======================================
|
||||
|
||||
## Get a list of device model properties
|
||||
|
||||
The list of device model properties contains properties from all device models.
|
||||
|
||||
Request:
|
||||
```
|
||||
GET /v1/deviceModelProperties
|
||||
```
|
||||
|
||||
Response:
|
||||
```
|
||||
200 OK
|
||||
Content-Type: application/json
|
||||
```
|
||||
```json
|
||||
{
|
||||
"Items": [
|
||||
"Properties.Reported.Type",
|
||||
"Properties.Reported.Firmware",
|
||||
"Properties.Reported.Model",
|
||||
"Properties.Reported.Location",
|
||||
"Properties.Reported.Latitude",
|
||||
"Properties.Reported.Longitude",
|
||||
"Properties.Reported.FirmwareUpdateStatus"
|
||||
],
|
||||
"$metadata": {
|
||||
"$type": "DeviceModelPropertyList;1",
|
||||
"$uri": "/v1/deviceModelProperties"
|
||||
}
|
||||
}
|
||||
```
|
Загрузка…
Ссылка в новой задаче