Added MQTT tester, added input service
This commit is contained in:
parent
e1a596dae9
commit
f102b89a21
@ -10,7 +10,7 @@ using Microsoft.AspNetCore.Authorization;
|
|||||||
|
|
||||||
namespace Birdmap.API.Controllers
|
namespace Birdmap.API.Controllers
|
||||||
{
|
{
|
||||||
[Authorize]
|
[Authorize(Roles = "Admin")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
public class DevicesController : ControllerBase
|
public class DevicesController : ControllerBase
|
||||||
@ -26,6 +26,7 @@ namespace Birdmap.API.Controllers
|
|||||||
|
|
||||||
/// <summary>Get all device info</summary>
|
/// <summary>Get all device info</summary>
|
||||||
/// <returns>Array of devices</returns>
|
/// <returns>Array of devices</returns>
|
||||||
|
[Authorize(Roles = "User,Admin")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<ActionResult<List<Device>>> Getall()
|
public async Task<ActionResult<List<Device>>> Getall()
|
||||||
{
|
{
|
||||||
@ -61,6 +62,7 @@ namespace Birdmap.API.Controllers
|
|||||||
/// <summary>Get all device info</summary>
|
/// <summary>Get all device info</summary>
|
||||||
/// <param name="deviceID">ID of device to query</param>
|
/// <param name="deviceID">ID of device to query</param>
|
||||||
/// <returns>Information about a particular device</returns>
|
/// <returns>Information about a particular device</returns>
|
||||||
|
[Authorize(Roles = "User,Admin")]
|
||||||
[HttpGet, Route("{deviceID}")]
|
[HttpGet, Route("{deviceID}")]
|
||||||
public async Task<ActionResult<Device>> Getdevice([BindRequired] Guid deviceID)
|
public async Task<ActionResult<Device>> Getdevice([BindRequired] Guid deviceID)
|
||||||
{
|
{
|
||||||
@ -99,6 +101,7 @@ namespace Birdmap.API.Controllers
|
|||||||
/// <param name="deviceID">ID of device to query</param>
|
/// <param name="deviceID">ID of device to query</param>
|
||||||
/// <param name="sensorID">ID of sensor to query</param>
|
/// <param name="sensorID">ID of sensor to query</param>
|
||||||
/// <returns>Information about a sensor</returns>
|
/// <returns>Information about a sensor</returns>
|
||||||
|
[Authorize(Roles = "User,Admin")]
|
||||||
[HttpGet, Route("{deviceID}/{sensorID}")]
|
[HttpGet, Route("{deviceID}/{sensorID}")]
|
||||||
public async Task<ActionResult<Sensor>> Getsensor([BindRequired] Guid deviceID, [BindRequired] Guid sensorID)
|
public async Task<ActionResult<Sensor>> Getsensor([BindRequired] Guid deviceID, [BindRequired] Guid sensorID)
|
||||||
{
|
{
|
||||||
|
@ -14,7 +14,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Birdmap.API.Controllers
|
namespace Birdmap.API.Controllers
|
||||||
{
|
{
|
||||||
[Authorize]
|
[Authorize(Roles = "Admin")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
public class ServicesController : ControllerBase
|
public class ServicesController : ControllerBase
|
||||||
@ -30,6 +30,7 @@ namespace Birdmap.API.Controllers
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize(Roles = "User,Admin")]
|
||||||
[HttpGet, ProducesResponseType(StatusCodes.Status200OK)]
|
[HttpGet, ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public async Task<ActionResult<List<ServiceInfo>>> GetAsync()
|
public async Task<ActionResult<List<ServiceInfo>>> GetAsync()
|
||||||
{
|
{
|
||||||
|
16
Birdmap.BLL/Helpers/IEnumerableExtensions.cs
Normal file
16
Birdmap.BLL/Helpers/IEnumerableExtensions.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Birdmap.BLL.Helpers
|
||||||
|
{
|
||||||
|
public static class IEnumerableExtensions
|
||||||
|
{
|
||||||
|
public static TSource RandomElementAt<TSource>(this IEnumerable<TSource> source, Random random = null)
|
||||||
|
{
|
||||||
|
random ??= new Random();
|
||||||
|
|
||||||
|
return source.ElementAt(random.Next(source.Count()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
163
Birdmap.BLL/Interfaces/IInputService.cs
Normal file
163
Birdmap.BLL/Interfaces/IInputService.cs
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Birdmap.BLL.Interfaces
|
||||||
|
{
|
||||||
|
|
||||||
|
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0))")]
|
||||||
|
public partial interface IInputService
|
||||||
|
{
|
||||||
|
/// <summary>Get input object by ID</summary>
|
||||||
|
/// <param name="tagID">ID of input object file</param>
|
||||||
|
/// <returns>input object</returns>
|
||||||
|
/// <exception cref="ApiException">A server side error occurred.</exception>
|
||||||
|
System.Threading.Tasks.Task<InputSingeResponse> GetInputAsync(System.Guid tagID);
|
||||||
|
|
||||||
|
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
|
||||||
|
/// <summary>Get input object by ID</summary>
|
||||||
|
/// <param name="tagID">ID of input object file</param>
|
||||||
|
/// <returns>input object</returns>
|
||||||
|
/// <exception cref="ApiException">A server side error occurred.</exception>
|
||||||
|
System.Threading.Tasks.Task<InputSingeResponse> GetInputAsync(System.Guid tagID, System.Threading.CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
|
||||||
|
public partial class InputSingeResponse
|
||||||
|
{
|
||||||
|
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
|
||||||
|
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||||
|
public string Status { get; set; }
|
||||||
|
|
||||||
|
[Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.Always)]
|
||||||
|
[System.ComponentModel.DataAnnotations.Required]
|
||||||
|
public InputObject Message { get; set; } = new InputObject();
|
||||||
|
|
||||||
|
private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
|
||||||
|
|
||||||
|
[Newtonsoft.Json.JsonExtensionData]
|
||||||
|
public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
|
||||||
|
{
|
||||||
|
get { return _additionalProperties; }
|
||||||
|
set { _additionalProperties = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
|
||||||
|
public partial class InputResponse : System.Collections.ObjectModel.Collection<InputObject>
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
|
||||||
|
public partial class InputObject
|
||||||
|
{
|
||||||
|
[Newtonsoft.Json.JsonProperty("tag", Required = Newtonsoft.Json.Required.Always)]
|
||||||
|
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||||
|
public System.Guid Tag { get; set; }
|
||||||
|
|
||||||
|
[Newtonsoft.Json.JsonProperty("date", Required = Newtonsoft.Json.Required.Always)]
|
||||||
|
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||||
|
[Newtonsoft.Json.JsonConverter(typeof(DateFormatConverter))]
|
||||||
|
public System.DateTimeOffset Date { get; set; }
|
||||||
|
|
||||||
|
[Newtonsoft.Json.JsonProperty("device_id", Required = Newtonsoft.Json.Required.Always)]
|
||||||
|
public Guid Device_id { get; set; }
|
||||||
|
|
||||||
|
private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
|
||||||
|
|
||||||
|
[Newtonsoft.Json.JsonExtensionData]
|
||||||
|
public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
|
||||||
|
{
|
||||||
|
get { return _additionalProperties; }
|
||||||
|
set { _additionalProperties = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
|
||||||
|
public partial class ApiResponse
|
||||||
|
{
|
||||||
|
[Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)]
|
||||||
|
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||||
|
public string Status { get; set; }
|
||||||
|
|
||||||
|
[Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.Always)]
|
||||||
|
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||||
|
public string Message { get; set; }
|
||||||
|
|
||||||
|
private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
|
||||||
|
|
||||||
|
[Newtonsoft.Json.JsonExtensionData]
|
||||||
|
public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
|
||||||
|
{
|
||||||
|
get { return _additionalProperties; }
|
||||||
|
set { _additionalProperties = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
|
||||||
|
public partial class Description
|
||||||
|
{
|
||||||
|
[Newtonsoft.Json.JsonProperty("deviceid", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||||
|
public string Deviceid { get; set; }
|
||||||
|
|
||||||
|
[Newtonsoft.Json.JsonProperty("date", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||||
|
[Newtonsoft.Json.JsonConverter(typeof(DateFormatConverter))]
|
||||||
|
public System.DateTimeOffset Date { get; set; }
|
||||||
|
|
||||||
|
private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>();
|
||||||
|
|
||||||
|
[Newtonsoft.Json.JsonExtensionData]
|
||||||
|
public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
|
||||||
|
{
|
||||||
|
get { return _additionalProperties; }
|
||||||
|
set { _additionalProperties = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.2.1.0 (Newtonsoft.Json v12.0.0.0)")]
|
||||||
|
internal class DateFormatConverter : Newtonsoft.Json.Converters.IsoDateTimeConverter
|
||||||
|
{
|
||||||
|
public DateFormatConverter()
|
||||||
|
{
|
||||||
|
DateTimeFormat = "yyyy-MM-dd";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0))")]
|
||||||
|
public partial class FileParameter
|
||||||
|
{
|
||||||
|
public FileParameter(System.IO.Stream data)
|
||||||
|
: this(data, null, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileParameter(System.IO.Stream data, string fileName)
|
||||||
|
: this(data, fileName, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileParameter(System.IO.Stream data, string fileName, string contentType)
|
||||||
|
{
|
||||||
|
Data = data;
|
||||||
|
FileName = fileName;
|
||||||
|
ContentType = contentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public System.IO.Stream Data { get; private set; }
|
||||||
|
|
||||||
|
public string FileName { get; private set; }
|
||||||
|
|
||||||
|
public string ContentType { get; private set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -6,8 +6,12 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Birdmap.BLL.Services
|
namespace Birdmap.BLL.Services
|
||||||
{
|
{
|
||||||
public abstract class DeviceServiceBase : IDeviceService
|
public abstract class DeviceAndInputServiceBase : IDeviceService, IInputService
|
||||||
{
|
{
|
||||||
|
public virtual Task<InputSingeResponse> GetInputAsync(Guid tagID)
|
||||||
|
=> GetInputAsync(tagID, CancellationToken.None);
|
||||||
|
public abstract Task<InputSingeResponse> GetInputAsync(Guid tagID, CancellationToken cancellationToken);
|
||||||
|
|
||||||
public virtual Task<ICollection<Device>> GetallAsync()
|
public virtual Task<ICollection<Device>> GetallAsync()
|
||||||
=> GetallAsync(CancellationToken.None);
|
=> GetallAsync(CancellationToken.None);
|
||||||
public abstract Task<ICollection<Device>> GetallAsync(CancellationToken cancellationToken);
|
public abstract Task<ICollection<Device>> GetallAsync(CancellationToken cancellationToken);
|
@ -1,4 +1,5 @@
|
|||||||
using Birdmap.BLL.Interfaces;
|
using Birdmap.BLL.Helpers;
|
||||||
|
using Birdmap.BLL.Interfaces;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -7,33 +8,40 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Birdmap.BLL.Services
|
namespace Birdmap.BLL.Services
|
||||||
{
|
{
|
||||||
public class DummyDeviceService : DeviceServiceBase
|
public class DummyDeviceAndInputService : DeviceAndInputServiceBase
|
||||||
{
|
{
|
||||||
|
private const int numberOfDevices = 15;
|
||||||
|
|
||||||
private const double centerLong = 21.469640;
|
private const double centerLong = 21.469640;
|
||||||
private const double centerLat = 48.275939;
|
private const double centerLat = 48.275939;
|
||||||
private const double radius = 0.000200;
|
private const double radius = 0.000200;
|
||||||
|
|
||||||
private readonly Lazy<ICollection<Device>> _devices = new Lazy<ICollection<Device>>(GenerateDevices);
|
private static readonly Random Rand = new Random();
|
||||||
|
|
||||||
|
private static readonly Lazy<ICollection<Device>> Devices = new Lazy<ICollection<Device>>(GenerateDevices);
|
||||||
|
|
||||||
|
private static readonly Dictionary<Guid, InputSingeResponse> TagToInput = new Dictionary<Guid, InputSingeResponse>();
|
||||||
|
private static readonly object InputLock = new object();
|
||||||
|
|
||||||
private static ListOfDevices GenerateDevices()
|
private static ListOfDevices GenerateDevices()
|
||||||
{
|
{
|
||||||
var devices = new ListOfDevices();
|
var devices = new ListOfDevices();
|
||||||
var rand = new Random();
|
|
||||||
|
|
||||||
T GetRandomEnum<T>()
|
T GetRandomEnum<T>()
|
||||||
{
|
{
|
||||||
var values = Enum.GetValues(typeof(T));
|
var values = Enum.GetValues(typeof(T));
|
||||||
return (T)values.GetValue(rand.Next(values.Length));
|
return (T)values.GetValue(Rand.Next(values.Length));
|
||||||
}
|
}
|
||||||
|
|
||||||
double GetPlusMinus(double center, double radius)
|
double GetPlusMinus(double center, double radius)
|
||||||
{
|
{
|
||||||
return center - radius + rand.NextDouble() * radius * 2;
|
return center - radius + Rand.NextDouble() * radius * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int d = 0; d < 15; d++)
|
for (int d = 0; d < numberOfDevices; d++)
|
||||||
{
|
{
|
||||||
var sensors = new ArrayofSensors();
|
var sensors = new ArrayofSensors();
|
||||||
for (int s = 0; s < rand.Next(1, 5); s++)
|
for (int s = 0; s < Rand.Next(1, 6); s++)
|
||||||
{
|
{
|
||||||
sensors.Add(new Sensor
|
sensors.Add(new Sensor
|
||||||
{
|
{
|
||||||
@ -61,17 +69,17 @@ namespace Birdmap.BLL.Services
|
|||||||
|
|
||||||
public override Task<ICollection<Device>> GetallAsync(CancellationToken cancellationToken)
|
public override Task<ICollection<Device>> GetallAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return Task.FromResult(_devices.Value);
|
return Task.FromResult(Devices.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task<Device> GetdeviceAsync(Guid deviceID, CancellationToken cancellationToken)
|
public override Task<Device> GetdeviceAsync(Guid deviceID, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return Task.FromResult(_devices.Value.SingleOrDefault(d => d.Id == deviceID));
|
return Task.FromResult(Devices.Value.SingleOrDefault(d => d.Id == deviceID));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task<Sensor> GetsensorAsync(Guid deviceID, Guid sensorID, CancellationToken cancellationToken)
|
public override Task<Sensor> GetsensorAsync(Guid deviceID, Guid sensorID, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return Task.FromResult(_devices.Value.SingleOrDefault(d => d.Id == deviceID)?.Sensors.SingleOrDefault(s => s.Id == sensorID));
|
return Task.FromResult(Devices.Value.SingleOrDefault(d => d.Id == deviceID)?.Sensors.SingleOrDefault(s => s.Id == sensorID));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task OfflineallAsync(CancellationToken cancellationToken)
|
public override Task OfflineallAsync(CancellationToken cancellationToken)
|
||||||
@ -114,7 +122,7 @@ namespace Birdmap.BLL.Services
|
|||||||
|
|
||||||
private void SetStatus(DeviceStatus deviceStatus, SensorStatus sensorStatus)
|
private void SetStatus(DeviceStatus deviceStatus, SensorStatus sensorStatus)
|
||||||
{
|
{
|
||||||
foreach (var device in _devices.Value)
|
foreach (var device in Devices.Value)
|
||||||
{
|
{
|
||||||
device.Status = deviceStatus;
|
device.Status = deviceStatus;
|
||||||
foreach (var sensor in device.Sensors)
|
foreach (var sensor in device.Sensors)
|
||||||
@ -135,5 +143,29 @@ namespace Birdmap.BLL.Services
|
|||||||
var sensor = GetsensorAsync(deviceId, sensorID).Result;
|
var sensor = GetsensorAsync(deviceId, sensorID).Result;
|
||||||
sensor.Status = status;
|
sensor.Status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Task<InputSingeResponse> GetInputAsync(Guid tagID, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
lock (InputLock)
|
||||||
|
{
|
||||||
|
if (!TagToInput.TryGetValue(tagID, out var value))
|
||||||
|
{
|
||||||
|
value = new InputSingeResponse
|
||||||
|
{
|
||||||
|
Status = "Dummy_OK",
|
||||||
|
Message = new InputObject
|
||||||
|
{
|
||||||
|
Tag = tagID,
|
||||||
|
Date = DateTime.Now,
|
||||||
|
Device_id = Devices.Value.Where(d => d.Status == DeviceStatus.Online).RandomElementAt(Rand).Id,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TagToInput.TryAdd(tagID, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.FromResult(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
477
Birdmap.BLL/Services/LiveInputService.cs
Normal file
477
Birdmap.BLL/Services/LiveInputService.cs
Normal file
@ -0,0 +1,477 @@
|
|||||||
|
//----------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// Generated using the NSwag toolchain v13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0)) (http://NSwag.org)
|
||||||
|
// </auto-generated>
|
||||||
|
//----------------------
|
||||||
|
|
||||||
|
#pragma warning disable 108 // Disable "CS0108 '{derivedDto}.ToJson()' hides inherited member '{dtoBase}.ToJson()'. Use the new keyword if hiding was intended."
|
||||||
|
#pragma warning disable 114 // Disable "CS0114 '{derivedDto}.RaisePropertyChanged(String)' hides inherited member 'dtoBase.RaisePropertyChanged(String)'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword."
|
||||||
|
#pragma warning disable 472 // Disable "CS0472 The result of the expression is always 'false' since a value of type 'Int32' is never equal to 'null' of type 'Int32?'
|
||||||
|
#pragma warning disable 1573 // Disable "CS1573 Parameter '...' has no matching param tag in the XML comment for ...
|
||||||
|
#pragma warning disable 1591 // Disable "CS1591 Missing XML comment for publicly visible type or member ..."
|
||||||
|
|
||||||
|
namespace Birdmap.BLL.Services
|
||||||
|
{
|
||||||
|
using Birdmap.BLL.Interfaces;
|
||||||
|
using System = global::System;
|
||||||
|
|
||||||
|
[System.CodeDom.Compiler.GeneratedCode("NSwag", "13.8.2.0 (NJsonSchema v10.2.1.0 (Newtonsoft.Json v12.0.0.0))")]
|
||||||
|
public partial class LiveInputService : IInputService
|
||||||
|
{
|
||||||
|
private string _baseUrl = "https://birb.k8s.kmlabz.com";
|
||||||
|
private System.Net.Http.HttpClient _httpClient;
|
||||||
|
private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings;
|
||||||
|
|
||||||
|
public LiveInputService(System.Net.Http.HttpClient httpClient)
|
||||||
|
{
|
||||||
|
_httpClient = httpClient;
|
||||||
|
_settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(CreateSerializerSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings()
|
||||||
|
{
|
||||||
|
var settings = new Newtonsoft.Json.JsonSerializerSettings();
|
||||||
|
UpdateJsonSerializerSettings(settings);
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string BaseUrl
|
||||||
|
{
|
||||||
|
get { return _baseUrl; }
|
||||||
|
set { _baseUrl = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettings { get { return _settings.Value; } }
|
||||||
|
|
||||||
|
partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings);
|
||||||
|
partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url);
|
||||||
|
partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder);
|
||||||
|
partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response);
|
||||||
|
|
||||||
|
/// <summary>Get all stored input queries</summary>
|
||||||
|
/// <returns>Array of input objects</returns>
|
||||||
|
/// <exception cref="ApiException">A server side error occurred.</exception>
|
||||||
|
public System.Threading.Tasks.Task<System.Collections.Generic.ICollection<InputObject>> GetallAsync()
|
||||||
|
{
|
||||||
|
return GetallAsync(System.Threading.CancellationToken.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
|
||||||
|
/// <summary>Get all stored input queries</summary>
|
||||||
|
/// <returns>Array of input objects</returns>
|
||||||
|
/// <exception cref="ApiException">A server side error occurred.</exception>
|
||||||
|
public async System.Threading.Tasks.Task<System.Collections.Generic.ICollection<InputObject>> GetallAsync(System.Threading.CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var urlBuilder_ = new System.Text.StringBuilder();
|
||||||
|
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/sample");
|
||||||
|
|
||||||
|
var client_ = _httpClient;
|
||||||
|
var disposeClient_ = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var request_ = new System.Net.Http.HttpRequestMessage())
|
||||||
|
{
|
||||||
|
request_.Method = new System.Net.Http.HttpMethod("GET");
|
||||||
|
request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
|
||||||
|
|
||||||
|
PrepareRequest(client_, request_, urlBuilder_);
|
||||||
|
var url_ = urlBuilder_.ToString();
|
||||||
|
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
|
||||||
|
PrepareRequest(client_, request_, url_);
|
||||||
|
|
||||||
|
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
|
||||||
|
var disposeResponse_ = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
|
||||||
|
if (response_.Content != null && response_.Content.Headers != null)
|
||||||
|
{
|
||||||
|
foreach (var item_ in response_.Content.Headers)
|
||||||
|
headers_[item_.Key] = item_.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessResponse(client_, response_);
|
||||||
|
|
||||||
|
var status_ = (int)response_.StatusCode;
|
||||||
|
if (status_ == 200)
|
||||||
|
{
|
||||||
|
var objectResponse_ = await ReadObjectResponseAsync<System.Collections.Generic.ICollection<InputObject>>(response_, headers_).ConfigureAwait(false);
|
||||||
|
if (objectResponse_.Object == null)
|
||||||
|
{
|
||||||
|
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
|
||||||
|
}
|
||||||
|
return objectResponse_.Object;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (status_ == 404)
|
||||||
|
{
|
||||||
|
var objectResponse_ = await ReadObjectResponseAsync<ApiResponse>(response_, headers_).ConfigureAwait(false);
|
||||||
|
if (objectResponse_.Object == null)
|
||||||
|
{
|
||||||
|
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
|
||||||
|
}
|
||||||
|
throw new ApiException<ApiResponse>("No object matching filter", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||||
|
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (disposeResponse_)
|
||||||
|
response_.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (disposeClient_)
|
||||||
|
client_.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>uploads a sample into the system</summary>
|
||||||
|
/// <returns>successful operation</returns>
|
||||||
|
/// <exception cref="ApiException">A server side error occurred.</exception>
|
||||||
|
public System.Threading.Tasks.Task<ApiResponse> UploadFileAsync(Description description, FileParameter file)
|
||||||
|
{
|
||||||
|
return UploadFileAsync(description, file, System.Threading.CancellationToken.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
|
||||||
|
/// <summary>uploads a sample into the system</summary>
|
||||||
|
/// <returns>successful operation</returns>
|
||||||
|
/// <exception cref="ApiException">A server side error occurred.</exception>
|
||||||
|
public async System.Threading.Tasks.Task<ApiResponse> UploadFileAsync(Description description, FileParameter file, System.Threading.CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var urlBuilder_ = new System.Text.StringBuilder();
|
||||||
|
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/sample");
|
||||||
|
|
||||||
|
var client_ = _httpClient;
|
||||||
|
var disposeClient_ = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var request_ = new System.Net.Http.HttpRequestMessage())
|
||||||
|
{
|
||||||
|
var boundary_ = System.Guid.NewGuid().ToString();
|
||||||
|
var content_ = new System.Net.Http.MultipartFormDataContent(boundary_);
|
||||||
|
content_.Headers.Remove("Content-Type");
|
||||||
|
content_.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundary=" + boundary_);
|
||||||
|
if (description == null)
|
||||||
|
throw new System.ArgumentNullException("description");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
content_.Add(new System.Net.Http.StringContent(ConvertToString(description, System.Globalization.CultureInfo.InvariantCulture)), "description");
|
||||||
|
}
|
||||||
|
if (file == null)
|
||||||
|
throw new System.ArgumentNullException("file");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var content_file_ = new System.Net.Http.StreamContent(file.Data);
|
||||||
|
if (!string.IsNullOrEmpty(file.ContentType))
|
||||||
|
content_file_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse(file.ContentType);
|
||||||
|
content_.Add(content_file_, "file", file.FileName ?? "file");
|
||||||
|
}
|
||||||
|
request_.Content = content_;
|
||||||
|
request_.Method = new System.Net.Http.HttpMethod("POST");
|
||||||
|
request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
|
||||||
|
|
||||||
|
PrepareRequest(client_, request_, urlBuilder_);
|
||||||
|
var url_ = urlBuilder_.ToString();
|
||||||
|
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
|
||||||
|
PrepareRequest(client_, request_, url_);
|
||||||
|
|
||||||
|
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
|
||||||
|
var disposeResponse_ = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
|
||||||
|
if (response_.Content != null && response_.Content.Headers != null)
|
||||||
|
{
|
||||||
|
foreach (var item_ in response_.Content.Headers)
|
||||||
|
headers_[item_.Key] = item_.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessResponse(client_, response_);
|
||||||
|
|
||||||
|
var status_ = (int)response_.StatusCode;
|
||||||
|
if (status_ == 200)
|
||||||
|
{
|
||||||
|
var objectResponse_ = await ReadObjectResponseAsync<ApiResponse>(response_, headers_).ConfigureAwait(false);
|
||||||
|
if (objectResponse_.Object == null)
|
||||||
|
{
|
||||||
|
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
|
||||||
|
}
|
||||||
|
return objectResponse_.Object;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (status_ == 400)
|
||||||
|
{
|
||||||
|
var objectResponse_ = await ReadObjectResponseAsync<ApiResponse>(response_, headers_).ConfigureAwait(false);
|
||||||
|
if (objectResponse_.Object == null)
|
||||||
|
{
|
||||||
|
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
|
||||||
|
}
|
||||||
|
throw new ApiException<ApiResponse>("JSON parse error", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (status_ == 415)
|
||||||
|
{
|
||||||
|
var objectResponse_ = await ReadObjectResponseAsync<ApiResponse>(response_, headers_).ConfigureAwait(false);
|
||||||
|
if (objectResponse_.Object == null)
|
||||||
|
{
|
||||||
|
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
|
||||||
|
}
|
||||||
|
throw new ApiException<ApiResponse>("Media type error", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (status_ == 417)
|
||||||
|
{
|
||||||
|
var objectResponse_ = await ReadObjectResponseAsync<ApiResponse>(response_, headers_).ConfigureAwait(false);
|
||||||
|
if (objectResponse_.Object == null)
|
||||||
|
{
|
||||||
|
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
|
||||||
|
}
|
||||||
|
throw new ApiException<ApiResponse>("JSON invalid schema", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (status_ == 469)
|
||||||
|
{
|
||||||
|
var objectResponse_ = await ReadObjectResponseAsync<ApiResponse>(response_, headers_).ConfigureAwait(false);
|
||||||
|
if (objectResponse_.Object == null)
|
||||||
|
{
|
||||||
|
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
|
||||||
|
}
|
||||||
|
throw new ApiException<ApiResponse>("No file found", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (status_ == 470)
|
||||||
|
{
|
||||||
|
var objectResponse_ = await ReadObjectResponseAsync<ApiResponse>(response_, headers_).ConfigureAwait(false);
|
||||||
|
if (objectResponse_.Object == null)
|
||||||
|
{
|
||||||
|
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
|
||||||
|
}
|
||||||
|
throw new ApiException<ApiResponse>("Description missing", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||||
|
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (disposeResponse_)
|
||||||
|
response_.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (disposeClient_)
|
||||||
|
client_.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Get input object by ID</summary>
|
||||||
|
/// <param name="tagID">ID of input object file</param>
|
||||||
|
/// <returns>input object</returns>
|
||||||
|
/// <exception cref="ApiException">A server side error occurred.</exception>
|
||||||
|
public System.Threading.Tasks.Task<InputSingeResponse> GetInputAsync(System.Guid tagID)
|
||||||
|
{
|
||||||
|
return GetInputAsync(tagID, System.Threading.CancellationToken.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
|
||||||
|
/// <summary>Get input object by ID</summary>
|
||||||
|
/// <param name="tagID">ID of input object file</param>
|
||||||
|
/// <returns>input object</returns>
|
||||||
|
/// <exception cref="ApiException">A server side error occurred.</exception>
|
||||||
|
public async System.Threading.Tasks.Task<InputSingeResponse> GetInputAsync(System.Guid tagID, System.Threading.CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (tagID == null)
|
||||||
|
throw new System.ArgumentNullException("tagID");
|
||||||
|
|
||||||
|
var urlBuilder_ = new System.Text.StringBuilder();
|
||||||
|
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/sample/{tagID}");
|
||||||
|
urlBuilder_.Replace("{tagID}", System.Uri.EscapeDataString(ConvertToString(tagID, System.Globalization.CultureInfo.InvariantCulture)));
|
||||||
|
|
||||||
|
var client_ = _httpClient;
|
||||||
|
var disposeClient_ = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var request_ = new System.Net.Http.HttpRequestMessage())
|
||||||
|
{
|
||||||
|
request_.Method = new System.Net.Http.HttpMethod("GET");
|
||||||
|
request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));
|
||||||
|
|
||||||
|
PrepareRequest(client_, request_, urlBuilder_);
|
||||||
|
var url_ = urlBuilder_.ToString();
|
||||||
|
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
|
||||||
|
PrepareRequest(client_, request_, url_);
|
||||||
|
|
||||||
|
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
|
||||||
|
var disposeResponse_ = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
|
||||||
|
if (response_.Content != null && response_.Content.Headers != null)
|
||||||
|
{
|
||||||
|
foreach (var item_ in response_.Content.Headers)
|
||||||
|
headers_[item_.Key] = item_.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessResponse(client_, response_);
|
||||||
|
|
||||||
|
var status_ = (int)response_.StatusCode;
|
||||||
|
if (status_ == 200)
|
||||||
|
{
|
||||||
|
var objectResponse_ = await ReadObjectResponseAsync<InputSingeResponse>(response_, headers_).ConfigureAwait(false);
|
||||||
|
if (objectResponse_.Object == null)
|
||||||
|
{
|
||||||
|
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
|
||||||
|
}
|
||||||
|
return objectResponse_.Object;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (status_ == 404)
|
||||||
|
{
|
||||||
|
var objectResponse_ = await ReadObjectResponseAsync<ApiResponse>(response_, headers_).ConfigureAwait(false);
|
||||||
|
if (objectResponse_.Object == null)
|
||||||
|
{
|
||||||
|
throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null);
|
||||||
|
}
|
||||||
|
throw new ApiException<ApiResponse>("Tag not found", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||||
|
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (disposeResponse_)
|
||||||
|
response_.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (disposeClient_)
|
||||||
|
client_.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected struct ObjectResponseResult<T>
|
||||||
|
{
|
||||||
|
public ObjectResponseResult(T responseObject, string responseText)
|
||||||
|
{
|
||||||
|
this.Object = responseObject;
|
||||||
|
this.Text = responseText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Object { get; }
|
||||||
|
|
||||||
|
public string Text { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ReadResponseAsString { get; set; }
|
||||||
|
|
||||||
|
protected virtual async System.Threading.Tasks.Task<ObjectResponseResult<T>> ReadObjectResponseAsync<T>(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary<string, System.Collections.Generic.IEnumerable<string>> headers)
|
||||||
|
{
|
||||||
|
if (response == null || response.Content == null)
|
||||||
|
{
|
||||||
|
return new ObjectResponseResult<T>(default(T), string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ReadResponseAsString)
|
||||||
|
{
|
||||||
|
var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var typedBody = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(responseText, JsonSerializerSettings);
|
||||||
|
return new ObjectResponseResult<T>(typedBody, responseText);
|
||||||
|
}
|
||||||
|
catch (Newtonsoft.Json.JsonException exception)
|
||||||
|
{
|
||||||
|
var message = "Could not deserialize the response body string as " + typeof(T).FullName + ".";
|
||||||
|
throw new ApiException(message, (int)response.StatusCode, responseText, headers, exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
|
||||||
|
using (var streamReader = new System.IO.StreamReader(responseStream))
|
||||||
|
using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader))
|
||||||
|
{
|
||||||
|
var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings);
|
||||||
|
var typedBody = serializer.Deserialize<T>(jsonTextReader);
|
||||||
|
return new ObjectResponseResult<T>(typedBody, string.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Newtonsoft.Json.JsonException exception)
|
||||||
|
{
|
||||||
|
var message = "Could not deserialize the response body stream as " + typeof(T).FullName + ".";
|
||||||
|
throw new ApiException(message, (int)response.StatusCode, string.Empty, headers, exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ConvertToString(object value, System.Globalization.CultureInfo cultureInfo)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value is System.Enum)
|
||||||
|
{
|
||||||
|
var name = System.Enum.GetName(value.GetType(), value);
|
||||||
|
if (name != null)
|
||||||
|
{
|
||||||
|
var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name);
|
||||||
|
if (field != null)
|
||||||
|
{
|
||||||
|
var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field, typeof(System.Runtime.Serialization.EnumMemberAttribute))
|
||||||
|
as System.Runtime.Serialization.EnumMemberAttribute;
|
||||||
|
if (attribute != null)
|
||||||
|
{
|
||||||
|
return attribute.Value != null ? attribute.Value : name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return System.Convert.ToString(System.Convert.ChangeType(value, System.Enum.GetUnderlyingType(value.GetType()), cultureInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (value is bool)
|
||||||
|
{
|
||||||
|
return System.Convert.ToString((bool)value, cultureInfo).ToLowerInvariant();
|
||||||
|
}
|
||||||
|
else if (value is byte[])
|
||||||
|
{
|
||||||
|
return System.Convert.ToBase64String((byte[])value);
|
||||||
|
}
|
||||||
|
else if (value.GetType().IsArray)
|
||||||
|
{
|
||||||
|
var array = System.Linq.Enumerable.OfType<object>((System.Array)value);
|
||||||
|
return string.Join(",", System.Linq.Enumerable.Select(array, o => ConvertToString(o, cultureInfo)));
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = System.Convert.ToString(value, cultureInfo);
|
||||||
|
return (result is null) ? string.Empty : result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning restore 1591
|
||||||
|
#pragma warning restore 1573
|
||||||
|
#pragma warning restore 472
|
||||||
|
#pragma warning restore 114
|
||||||
|
#pragma warning restore 108
|
@ -14,9 +14,15 @@ namespace Birdmap.BLL
|
|||||||
services.AddTransient<IServiceService, ServiceService>();
|
services.AddTransient<IServiceService, ServiceService>();
|
||||||
|
|
||||||
if (configuration.GetValue<bool>("UseDummyServices"))
|
if (configuration.GetValue<bool>("UseDummyServices"))
|
||||||
services.AddTransient<IDeviceService, DummyDeviceService>();
|
{
|
||||||
|
services.AddTransient<IInputService, DummyDeviceAndInputService>();
|
||||||
|
services.AddTransient<IDeviceService, DummyDeviceAndInputService>();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
services.AddTransient<IInputService, LiveInputService>();
|
||||||
services.AddTransient<IDeviceService, LiveDummyService>();
|
services.AddTransient<IDeviceService, LiveDummyService>();
|
||||||
|
}
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Birdmap.BLL", "Birdmap.BLL\
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Birdmap.DAL", "Birdmap.DAL\Birdmap.DAL.csproj", "{543FAB06-B960-41A9-8865-1624A2ED2170}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Birdmap.DAL", "Birdmap.DAL\Birdmap.DAL.csproj", "{543FAB06-B960-41A9-8865-1624A2ED2170}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Birdmap.Common", "Birdmap.Common\Birdmap.Common.csproj", "{CE96BAFA-A0FD-4010-8EF2-700451091F71}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Birdmap.Common", "Birdmap.Common\Birdmap.Common.csproj", "{CE96BAFA-A0FD-4010-8EF2-700451091F71}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.TestApp.WinForm", "MQTTnet.TestApp.WinForm\MQTTnet.TestApp.WinForm.csproj", "{E1707FE7-4A65-42AC-B71C-6CC1A55FC42A}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@ -33,6 +35,10 @@ Global
|
|||||||
{CE96BAFA-A0FD-4010-8EF2-700451091F71}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{CE96BAFA-A0FD-4010-8EF2-700451091F71}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{CE96BAFA-A0FD-4010-8EF2-700451091F71}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{CE96BAFA-A0FD-4010-8EF2-700451091F71}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{CE96BAFA-A0FD-4010-8EF2-700451091F71}.Release|Any CPU.Build.0 = Release|Any CPU
|
{CE96BAFA-A0FD-4010-8EF2-700451091F71}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{E1707FE7-4A65-42AC-B71C-6CC1A55FC42A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{E1707FE7-4A65-42AC-B71C-6CC1A55FC42A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{E1707FE7-4A65-42AC-B71C-6CC1A55FC42A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{E1707FE7-4A65-42AC-B71C-6CC1A55FC42A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
394
MQTTnet.TestApp.WinForm/Form1.Designer.cs
generated
Normal file
394
MQTTnet.TestApp.WinForm/Form1.Designer.cs
generated
Normal file
@ -0,0 +1,394 @@
|
|||||||
|
namespace MQTTnet.TestApp.WinForm
|
||||||
|
{
|
||||||
|
partial class Form1
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.label1 = new System.Windows.Forms.Label();
|
||||||
|
this.TextBoxPort = new System.Windows.Forms.TextBox();
|
||||||
|
this.ButtonServerStart = new System.Windows.Forms.Button();
|
||||||
|
this.ButtonServerStop = new System.Windows.Forms.Button();
|
||||||
|
this.label2 = new System.Windows.Forms.Label();
|
||||||
|
this.maskedTextBox1 = new System.Windows.Forms.MaskedTextBox();
|
||||||
|
this.label3 = new System.Windows.Forms.Label();
|
||||||
|
this.TextBoxTopicPublished = new System.Windows.Forms.TextBox();
|
||||||
|
this.label4 = new System.Windows.Forms.Label();
|
||||||
|
this.label5 = new System.Windows.Forms.Label();
|
||||||
|
this.ButtonPublisherStop = new System.Windows.Forms.Button();
|
||||||
|
this.ButtonPublisherStart = new System.Windows.Forms.Button();
|
||||||
|
this.TextBoxPublish = new System.Windows.Forms.TextBox();
|
||||||
|
this.ButtonPublish = new System.Windows.Forms.Button();
|
||||||
|
this.ButtonSubscriberStop = new System.Windows.Forms.Button();
|
||||||
|
this.ButtonSubscriberStart = new System.Windows.Forms.Button();
|
||||||
|
this.TextBoxSubscriber = new System.Windows.Forms.TextBox();
|
||||||
|
this.ButtonGeneratePublishedMessage = new System.Windows.Forms.Button();
|
||||||
|
this.label6 = new System.Windows.Forms.Label();
|
||||||
|
this.TextBoxTopicSubscribed = new System.Windows.Forms.TextBox();
|
||||||
|
this.ButtonSubscribe = new System.Windows.Forms.Button();
|
||||||
|
this.label7 = new System.Windows.Forms.Label();
|
||||||
|
this.trackBar1 = new System.Windows.Forms.TrackBar();
|
||||||
|
this.ButtonAutoPublisherStop = new System.Windows.Forms.Button();
|
||||||
|
this.ButtonAutoPublisherStart = new System.Windows.Forms.Button();
|
||||||
|
this.label8 = new System.Windows.Forms.Label();
|
||||||
|
this.checkBox1 = new System.Windows.Forms.CheckBox();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
this.label1.AutoSize = true;
|
||||||
|
this.label1.Location = new System.Drawing.Point(119, 24);
|
||||||
|
this.label1.Name = "label1";
|
||||||
|
this.label1.Size = new System.Drawing.Size(32, 15);
|
||||||
|
this.label1.TabIndex = 0;
|
||||||
|
this.label1.Text = "Port:";
|
||||||
|
//
|
||||||
|
// TextBoxPort
|
||||||
|
//
|
||||||
|
this.TextBoxPort.Location = new System.Drawing.Point(172, 21);
|
||||||
|
this.TextBoxPort.Name = "TextBoxPort";
|
||||||
|
this.TextBoxPort.Size = new System.Drawing.Size(100, 23);
|
||||||
|
this.TextBoxPort.TabIndex = 1;
|
||||||
|
this.TextBoxPort.Text = "1883";
|
||||||
|
this.TextBoxPort.TextChanged += new System.EventHandler(this.TextBoxPortTextChanged);
|
||||||
|
//
|
||||||
|
// ButtonServerStart
|
||||||
|
//
|
||||||
|
this.ButtonServerStart.Location = new System.Drawing.Point(433, 21);
|
||||||
|
this.ButtonServerStart.Name = "ButtonServerStart";
|
||||||
|
this.ButtonServerStart.Size = new System.Drawing.Size(75, 23);
|
||||||
|
this.ButtonServerStart.TabIndex = 2;
|
||||||
|
this.ButtonServerStart.Text = "Start";
|
||||||
|
this.ButtonServerStart.UseVisualStyleBackColor = true;
|
||||||
|
this.ButtonServerStart.Click += new System.EventHandler(this.ButtonServerStartClick);
|
||||||
|
//
|
||||||
|
// ButtonServerStop
|
||||||
|
//
|
||||||
|
this.ButtonServerStop.Location = new System.Drawing.Point(514, 21);
|
||||||
|
this.ButtonServerStop.Name = "ButtonServerStop";
|
||||||
|
this.ButtonServerStop.Size = new System.Drawing.Size(75, 23);
|
||||||
|
this.ButtonServerStop.TabIndex = 3;
|
||||||
|
this.ButtonServerStop.Text = "Stop";
|
||||||
|
this.ButtonServerStop.UseVisualStyleBackColor = true;
|
||||||
|
this.ButtonServerStop.Click += new System.EventHandler(this.ButtonServerStopClick);
|
||||||
|
//
|
||||||
|
// label2
|
||||||
|
//
|
||||||
|
this.label2.AutoSize = true;
|
||||||
|
this.label2.Location = new System.Drawing.Point(33, 25);
|
||||||
|
this.label2.Name = "label2";
|
||||||
|
this.label2.Size = new System.Drawing.Size(39, 15);
|
||||||
|
this.label2.TabIndex = 4;
|
||||||
|
this.label2.Text = "Server";
|
||||||
|
//
|
||||||
|
// maskedTextBox1
|
||||||
|
//
|
||||||
|
this.maskedTextBox1.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.maskedTextBox1.Name = "maskedTextBox1";
|
||||||
|
this.maskedTextBox1.Size = new System.Drawing.Size(100, 23);
|
||||||
|
this.maskedTextBox1.TabIndex = 5;
|
||||||
|
this.maskedTextBox1.Text = "maskedTextBox1";
|
||||||
|
//
|
||||||
|
// label3
|
||||||
|
//
|
||||||
|
this.label3.AutoSize = true;
|
||||||
|
this.label3.Location = new System.Drawing.Point(33, 79);
|
||||||
|
this.label3.Name = "label3";
|
||||||
|
this.label3.Size = new System.Drawing.Size(90, 15);
|
||||||
|
this.label3.TabIndex = 5;
|
||||||
|
this.label3.Text = "Topic Published";
|
||||||
|
//
|
||||||
|
// TextBoxTopicPublished
|
||||||
|
//
|
||||||
|
this.TextBoxTopicPublished.Location = new System.Drawing.Point(164, 76);
|
||||||
|
this.TextBoxTopicPublished.Name = "TextBoxTopicPublished";
|
||||||
|
this.TextBoxTopicPublished.Size = new System.Drawing.Size(425, 23);
|
||||||
|
this.TextBoxTopicPublished.TabIndex = 1;
|
||||||
|
this.TextBoxTopicPublished.Text = "devices/output";
|
||||||
|
this.TextBoxTopicPublished.TextChanged += new System.EventHandler(this.TextBoxPortTextChanged);
|
||||||
|
//
|
||||||
|
// label4
|
||||||
|
//
|
||||||
|
this.label4.AutoSize = true;
|
||||||
|
this.label4.Location = new System.Drawing.Point(33, 109);
|
||||||
|
this.label4.Name = "label4";
|
||||||
|
this.label4.Size = new System.Drawing.Size(90, 15);
|
||||||
|
this.label4.TabIndex = 5;
|
||||||
|
this.label4.Text = "Client Publisher";
|
||||||
|
//
|
||||||
|
// label5
|
||||||
|
//
|
||||||
|
this.label5.AutoSize = true;
|
||||||
|
this.label5.Location = new System.Drawing.Point(33, 224);
|
||||||
|
this.label5.Name = "label5";
|
||||||
|
this.label5.Size = new System.Drawing.Size(96, 15);
|
||||||
|
this.label5.TabIndex = 5;
|
||||||
|
this.label5.Text = "Client Subscriber";
|
||||||
|
//
|
||||||
|
// ButtonPublisherStop
|
||||||
|
//
|
||||||
|
this.ButtonPublisherStop.Location = new System.Drawing.Point(514, 105);
|
||||||
|
this.ButtonPublisherStop.Name = "ButtonPublisherStop";
|
||||||
|
this.ButtonPublisherStop.Size = new System.Drawing.Size(75, 23);
|
||||||
|
this.ButtonPublisherStop.TabIndex = 3;
|
||||||
|
this.ButtonPublisherStop.Text = "Stop";
|
||||||
|
this.ButtonPublisherStop.UseVisualStyleBackColor = true;
|
||||||
|
this.ButtonPublisherStop.Click += new System.EventHandler(this.ButtonPublisherStopClick);
|
||||||
|
//
|
||||||
|
// ButtonPublisherStart
|
||||||
|
//
|
||||||
|
this.ButtonPublisherStart.Location = new System.Drawing.Point(433, 105);
|
||||||
|
this.ButtonPublisherStart.Name = "ButtonPublisherStart";
|
||||||
|
this.ButtonPublisherStart.Size = new System.Drawing.Size(75, 23);
|
||||||
|
this.ButtonPublisherStart.TabIndex = 2;
|
||||||
|
this.ButtonPublisherStart.Text = "Start";
|
||||||
|
this.ButtonPublisherStart.UseVisualStyleBackColor = true;
|
||||||
|
this.ButtonPublisherStart.Click += new System.EventHandler(this.ButtonPublisherStartClick);
|
||||||
|
//
|
||||||
|
// TextBoxPublish
|
||||||
|
//
|
||||||
|
this.TextBoxPublish.Location = new System.Drawing.Point(33, 134);
|
||||||
|
this.TextBoxPublish.Name = "TextBoxPublish";
|
||||||
|
this.TextBoxPublish.Size = new System.Drawing.Size(394, 23);
|
||||||
|
this.TextBoxPublish.TabIndex = 1;
|
||||||
|
this.TextBoxPublish.TextChanged += new System.EventHandler(this.TextBoxPortTextChanged);
|
||||||
|
//
|
||||||
|
// ButtonPublish
|
||||||
|
//
|
||||||
|
this.ButtonPublish.Location = new System.Drawing.Point(514, 134);
|
||||||
|
this.ButtonPublish.Name = "ButtonPublish";
|
||||||
|
this.ButtonPublish.Size = new System.Drawing.Size(75, 23);
|
||||||
|
this.ButtonPublish.TabIndex = 3;
|
||||||
|
this.ButtonPublish.Text = "Publish";
|
||||||
|
this.ButtonPublish.UseVisualStyleBackColor = true;
|
||||||
|
this.ButtonPublish.Click += new System.EventHandler(this.ButtonPublishClick);
|
||||||
|
//
|
||||||
|
// ButtonSubscriberStop
|
||||||
|
//
|
||||||
|
this.ButtonSubscriberStop.Location = new System.Drawing.Point(514, 220);
|
||||||
|
this.ButtonSubscriberStop.Name = "ButtonSubscriberStop";
|
||||||
|
this.ButtonSubscriberStop.Size = new System.Drawing.Size(75, 23);
|
||||||
|
this.ButtonSubscriberStop.TabIndex = 3;
|
||||||
|
this.ButtonSubscriberStop.Text = "Stop";
|
||||||
|
this.ButtonSubscriberStop.UseVisualStyleBackColor = true;
|
||||||
|
this.ButtonSubscriberStop.Click += new System.EventHandler(this.ButtonSubscriberStopClick);
|
||||||
|
//
|
||||||
|
// ButtonSubscriberStart
|
||||||
|
//
|
||||||
|
this.ButtonSubscriberStart.Location = new System.Drawing.Point(433, 220);
|
||||||
|
this.ButtonSubscriberStart.Name = "ButtonSubscriberStart";
|
||||||
|
this.ButtonSubscriberStart.Size = new System.Drawing.Size(75, 23);
|
||||||
|
this.ButtonSubscriberStart.TabIndex = 2;
|
||||||
|
this.ButtonSubscriberStart.Text = "Start";
|
||||||
|
this.ButtonSubscriberStart.UseVisualStyleBackColor = true;
|
||||||
|
this.ButtonSubscriberStart.Click += new System.EventHandler(this.ButtonSubscriberStartClick);
|
||||||
|
//
|
||||||
|
// TextBoxSubscriber
|
||||||
|
//
|
||||||
|
this.TextBoxSubscriber.Location = new System.Drawing.Point(33, 309);
|
||||||
|
this.TextBoxSubscriber.Multiline = true;
|
||||||
|
this.TextBoxSubscriber.Name = "TextBoxSubscriber";
|
||||||
|
this.TextBoxSubscriber.Size = new System.Drawing.Size(556, 182);
|
||||||
|
this.TextBoxSubscriber.TabIndex = 6;
|
||||||
|
//
|
||||||
|
// ButtonGeneratePublishedMessage
|
||||||
|
//
|
||||||
|
this.ButtonGeneratePublishedMessage.Location = new System.Drawing.Point(433, 133);
|
||||||
|
this.ButtonGeneratePublishedMessage.Name = "ButtonGeneratePublishedMessage";
|
||||||
|
this.ButtonGeneratePublishedMessage.Size = new System.Drawing.Size(75, 23);
|
||||||
|
this.ButtonGeneratePublishedMessage.TabIndex = 2;
|
||||||
|
this.ButtonGeneratePublishedMessage.Text = "Random";
|
||||||
|
this.ButtonGeneratePublishedMessage.UseVisualStyleBackColor = true;
|
||||||
|
this.ButtonGeneratePublishedMessage.Click += new System.EventHandler(this.ButtonGeneratePublishedMessageClick);
|
||||||
|
//
|
||||||
|
// label6
|
||||||
|
//
|
||||||
|
this.label6.AutoSize = true;
|
||||||
|
this.label6.Location = new System.Drawing.Point(33, 252);
|
||||||
|
this.label6.Name = "label6";
|
||||||
|
this.label6.Size = new System.Drawing.Size(96, 15);
|
||||||
|
this.label6.TabIndex = 5;
|
||||||
|
this.label6.Text = "Topic Subscribed";
|
||||||
|
//
|
||||||
|
// TextBoxTopicSubscribed
|
||||||
|
//
|
||||||
|
this.TextBoxTopicSubscribed.Location = new System.Drawing.Point(164, 249);
|
||||||
|
this.TextBoxTopicSubscribed.Name = "TextBoxTopicSubscribed";
|
||||||
|
this.TextBoxTopicSubscribed.Size = new System.Drawing.Size(344, 23);
|
||||||
|
this.TextBoxTopicSubscribed.TabIndex = 1;
|
||||||
|
this.TextBoxTopicSubscribed.Text = "devices/output";
|
||||||
|
this.TextBoxTopicSubscribed.TextChanged += new System.EventHandler(this.TextBoxPortTextChanged);
|
||||||
|
//
|
||||||
|
// ButtonSubscribe
|
||||||
|
//
|
||||||
|
this.ButtonSubscribe.Location = new System.Drawing.Point(514, 248);
|
||||||
|
this.ButtonSubscribe.Name = "ButtonSubscribe";
|
||||||
|
this.ButtonSubscribe.Size = new System.Drawing.Size(75, 23);
|
||||||
|
this.ButtonSubscribe.TabIndex = 3;
|
||||||
|
this.ButtonSubscribe.Text = "Subscribe";
|
||||||
|
this.ButtonSubscribe.UseVisualStyleBackColor = true;
|
||||||
|
this.ButtonSubscribe.Click += new System.EventHandler(this.ButtonSubscribeClick);
|
||||||
|
//
|
||||||
|
// label7
|
||||||
|
//
|
||||||
|
this.label7.AutoSize = true;
|
||||||
|
this.label7.Location = new System.Drawing.Point(33, 167);
|
||||||
|
this.label7.Name = "label7";
|
||||||
|
this.label7.Size = new System.Drawing.Size(141, 15);
|
||||||
|
this.label7.TabIndex = 5;
|
||||||
|
this.label7.Text = "Auto (Random) Publisher";
|
||||||
|
//
|
||||||
|
// trackBar1
|
||||||
|
//
|
||||||
|
this.trackBar1.LargeChange = 500;
|
||||||
|
this.trackBar1.Location = new System.Drawing.Point(180, 162);
|
||||||
|
this.trackBar1.Maximum = 5050;
|
||||||
|
this.trackBar1.Minimum = 50;
|
||||||
|
this.trackBar1.Name = "trackBar1";
|
||||||
|
this.trackBar1.Size = new System.Drawing.Size(247, 45);
|
||||||
|
this.trackBar1.SmallChange = 100;
|
||||||
|
this.trackBar1.TabIndex = 7;
|
||||||
|
this.trackBar1.TickFrequency = 500;
|
||||||
|
this.trackBar1.Value = 550;
|
||||||
|
this.trackBar1.Scroll += new System.EventHandler(this.trackBar1_Scroll);
|
||||||
|
//
|
||||||
|
// ButtonAutoPublisherStop
|
||||||
|
//
|
||||||
|
this.ButtonAutoPublisherStop.Location = new System.Drawing.Point(513, 162);
|
||||||
|
this.ButtonAutoPublisherStop.Name = "ButtonAutoPublisherStop";
|
||||||
|
this.ButtonAutoPublisherStop.Size = new System.Drawing.Size(75, 23);
|
||||||
|
this.ButtonAutoPublisherStop.TabIndex = 8;
|
||||||
|
this.ButtonAutoPublisherStop.Text = "Stop";
|
||||||
|
this.ButtonAutoPublisherStop.UseVisualStyleBackColor = true;
|
||||||
|
this.ButtonAutoPublisherStop.Click += new System.EventHandler(this.ButtonAutoPublisherStopClick);
|
||||||
|
//
|
||||||
|
// ButtonAutoPublisherStart
|
||||||
|
//
|
||||||
|
this.ButtonAutoPublisherStart.Location = new System.Drawing.Point(433, 162);
|
||||||
|
this.ButtonAutoPublisherStart.Name = "ButtonAutoPublisherStart";
|
||||||
|
this.ButtonAutoPublisherStart.Size = new System.Drawing.Size(75, 23);
|
||||||
|
this.ButtonAutoPublisherStart.TabIndex = 8;
|
||||||
|
this.ButtonAutoPublisherStart.Text = "Start";
|
||||||
|
this.ButtonAutoPublisherStart.UseVisualStyleBackColor = true;
|
||||||
|
this.ButtonAutoPublisherStart.Click += new System.EventHandler(this.ButtonAutoPublisherStartClick);
|
||||||
|
//
|
||||||
|
// label8
|
||||||
|
//
|
||||||
|
this.label8.Anchor = System.Windows.Forms.AnchorStyles.Right;
|
||||||
|
this.label8.AutoSize = true;
|
||||||
|
this.label8.Location = new System.Drawing.Point(180, 191);
|
||||||
|
this.label8.Name = "label8";
|
||||||
|
this.label8.RightToLeft = System.Windows.Forms.RightToLeft.No;
|
||||||
|
this.label8.Size = new System.Drawing.Size(44, 15);
|
||||||
|
this.label8.TabIndex = 9;
|
||||||
|
this.label8.Text = "550 ms";
|
||||||
|
this.label8.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||||
|
//
|
||||||
|
// checkBox1
|
||||||
|
//
|
||||||
|
this.checkBox1.AutoSize = true;
|
||||||
|
this.checkBox1.Checked = true;
|
||||||
|
this.checkBox1.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||||
|
this.checkBox1.Location = new System.Drawing.Point(433, 191);
|
||||||
|
this.checkBox1.Name = "checkBox1";
|
||||||
|
this.checkBox1.Size = new System.Drawing.Size(82, 19);
|
||||||
|
this.checkBox1.TabIndex = 10;
|
||||||
|
this.checkBox1.Text = "randomize";
|
||||||
|
this.checkBox1.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// Form1
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.ClientSize = new System.Drawing.Size(627, 530);
|
||||||
|
this.Controls.Add(this.checkBox1);
|
||||||
|
this.Controls.Add(this.label8);
|
||||||
|
this.Controls.Add(this.ButtonAutoPublisherStart);
|
||||||
|
this.Controls.Add(this.ButtonAutoPublisherStop);
|
||||||
|
this.Controls.Add(this.trackBar1);
|
||||||
|
this.Controls.Add(this.label7);
|
||||||
|
this.Controls.Add(this.TextBoxSubscriber);
|
||||||
|
this.Controls.Add(this.label5);
|
||||||
|
this.Controls.Add(this.label4);
|
||||||
|
this.Controls.Add(this.label3);
|
||||||
|
this.Controls.Add(this.label2);
|
||||||
|
this.Controls.Add(this.ButtonServerStop);
|
||||||
|
this.Controls.Add(this.ButtonServerStart);
|
||||||
|
this.Controls.Add(this.TextBoxPort);
|
||||||
|
this.Controls.Add(this.label1);
|
||||||
|
this.Controls.Add(this.TextBoxTopicPublished);
|
||||||
|
this.Controls.Add(this.ButtonPublisherStop);
|
||||||
|
this.Controls.Add(this.ButtonPublisherStart);
|
||||||
|
this.Controls.Add(this.TextBoxPublish);
|
||||||
|
this.Controls.Add(this.ButtonPublish);
|
||||||
|
this.Controls.Add(this.ButtonSubscriberStop);
|
||||||
|
this.Controls.Add(this.ButtonSubscriberStart);
|
||||||
|
this.Controls.Add(this.ButtonGeneratePublishedMessage);
|
||||||
|
this.Controls.Add(this.label6);
|
||||||
|
this.Controls.Add(this.TextBoxTopicSubscribed);
|
||||||
|
this.Controls.Add(this.ButtonSubscribe);
|
||||||
|
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||||
|
this.Name = "Form1";
|
||||||
|
this.Text = "MQTT Testing";
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit();
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
this.PerformLayout();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private System.Windows.Forms.Label label1;
|
||||||
|
private System.Windows.Forms.TextBox TextBoxPort;
|
||||||
|
private System.Windows.Forms.Button ButtonServerStart;
|
||||||
|
private System.Windows.Forms.Button ButtonServerStop;
|
||||||
|
private System.Windows.Forms.Label label2;
|
||||||
|
private System.Windows.Forms.MaskedTextBox maskedTextBox1;
|
||||||
|
private System.Windows.Forms.Label label3;
|
||||||
|
private System.Windows.Forms.Label label4;
|
||||||
|
private System.Windows.Forms.Label label5;
|
||||||
|
private System.Windows.Forms.Button ButtonPublisherStop;
|
||||||
|
private System.Windows.Forms.Button ButtonPublisherStart;
|
||||||
|
private System.Windows.Forms.TextBox TextBoxPublish;
|
||||||
|
private System.Windows.Forms.Button ButtonPublish;
|
||||||
|
private System.Windows.Forms.Button ButtonSubscriberStop;
|
||||||
|
private System.Windows.Forms.Button ButtonSubscriberStart;
|
||||||
|
private System.Windows.Forms.TextBox TextBoxSubscriber;
|
||||||
|
private System.Windows.Forms.Button ButtonGeneratePublishedMessage;
|
||||||
|
private System.Windows.Forms.Label label6;
|
||||||
|
private System.Windows.Forms.TextBox TextBoxTopicPublished;
|
||||||
|
private System.Windows.Forms.Button ButtonSubscribe;
|
||||||
|
private System.Windows.Forms.TextBox TextBoxTopicSubscribed;
|
||||||
|
private System.Windows.Forms.Label label7;
|
||||||
|
private System.Windows.Forms.TrackBar trackBar1;
|
||||||
|
private System.Windows.Forms.Button ButtonAutoPublisherStop;
|
||||||
|
private System.Windows.Forms.Button ButtonAutoPublisherStart;
|
||||||
|
private System.Windows.Forms.Label label8;
|
||||||
|
private System.Windows.Forms.CheckBox checkBox1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
476
MQTTnet.TestApp.WinForm/Form1.cs
Normal file
476
MQTTnet.TestApp.WinForm/Form1.cs
Normal file
@ -0,0 +1,476 @@
|
|||||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||||
|
// <copyright file="Form1.cs" company="Haemmer Electronics">
|
||||||
|
// Copyright (c) 2020 All rights reserved.
|
||||||
|
// </copyright>
|
||||||
|
// <summary>
|
||||||
|
// The main form.
|
||||||
|
// </summary>
|
||||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace MQTTnet.TestApp.WinForm
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.Timers;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
using MQTTnet.Client.Connecting;
|
||||||
|
using MQTTnet.Client.Disconnecting;
|
||||||
|
using MQTTnet.Client.Options;
|
||||||
|
using MQTTnet.Client.Receiving;
|
||||||
|
using MQTTnet.Extensions.ManagedClient;
|
||||||
|
using MQTTnet.Formatter;
|
||||||
|
using MQTTnet.Protocol;
|
||||||
|
using MQTTnet.Server;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Timer = System.Timers.Timer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The main form.
|
||||||
|
/// </summary>
|
||||||
|
public partial class Form1 : Form
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The managed publisher client.
|
||||||
|
/// </summary>
|
||||||
|
private IManagedMqttClient managedMqttClientPublisher;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The managed subscriber client.
|
||||||
|
/// </summary>
|
||||||
|
private IManagedMqttClient managedMqttClientSubscriber;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The MQTT server.
|
||||||
|
/// </summary>
|
||||||
|
private IMqttServer mqttServer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The port.
|
||||||
|
/// </summary>
|
||||||
|
private string port = "1883";
|
||||||
|
|
||||||
|
private readonly Random random;
|
||||||
|
private readonly Timer randomPublisherTimer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="Form1"/> class.
|
||||||
|
/// </summary>
|
||||||
|
public Form1()
|
||||||
|
{
|
||||||
|
this.InitializeComponent();
|
||||||
|
|
||||||
|
var timer = new Timer
|
||||||
|
{
|
||||||
|
AutoReset = true, Enabled = true, Interval = 1000
|
||||||
|
};
|
||||||
|
|
||||||
|
timer.Elapsed += this.TimerElapsed;
|
||||||
|
|
||||||
|
random = new Random();
|
||||||
|
randomPublisherTimer = new Timer
|
||||||
|
{
|
||||||
|
AutoReset = true,
|
||||||
|
Enabled = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
randomPublisherTimer.Elapsed += (_, __) => this.BeginInvoke((MethodInvoker)delegate
|
||||||
|
{
|
||||||
|
if (checkBox1.Checked)
|
||||||
|
ButtonGeneratePublishedMessageClick(ButtonGeneratePublishedMessage, EventArgs.Empty);
|
||||||
|
|
||||||
|
ButtonPublishClick(ButtonPublish, EventArgs.Empty);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles the publisher connected event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The MQTT client connected event args.</param>
|
||||||
|
private void OnPublisherConnected(MqttClientConnectedEventArgs x)
|
||||||
|
{
|
||||||
|
var item = "Publisher Connected";
|
||||||
|
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles the publisher disconnected event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The MQTT client disconnected event args.</param>
|
||||||
|
private void OnPublisherDisconnected(MqttClientDisconnectedEventArgs x)
|
||||||
|
{
|
||||||
|
var item = "Publisher Disconnected";
|
||||||
|
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles the subscriber connected event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The MQTT client connected event args.</param>
|
||||||
|
private void OnSubscriberConnected(MqttClientConnectedEventArgs x)
|
||||||
|
{
|
||||||
|
var item = "Subscriber Connected";
|
||||||
|
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles the subscriber disconnected event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The MQTT client disconnected event args.</param>
|
||||||
|
private void OnSubscriberDisconnected(MqttClientDisconnectedEventArgs x)
|
||||||
|
{
|
||||||
|
var item = "Subscriber Disconnected";
|
||||||
|
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The method that handles the button click to generate a message.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender.</param>
|
||||||
|
/// <param name="e">The event args.</param>
|
||||||
|
private void ButtonGeneratePublishedMessageClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var message = new
|
||||||
|
{
|
||||||
|
tag = Guid.NewGuid(),
|
||||||
|
probability = random.NextDouble(),
|
||||||
|
};
|
||||||
|
|
||||||
|
var json = JsonConvert.SerializeObject(message);
|
||||||
|
this.TextBoxPublish.Text = json;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The method that handles the button click to publish a message.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender.</param>
|
||||||
|
/// <param name="e">The event args.</param>
|
||||||
|
private async void ButtonPublishClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
((Button)sender).Enabled = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var payload = Encoding.UTF8.GetBytes(this.TextBoxPublish.Text);
|
||||||
|
var message = new MqttApplicationMessageBuilder().WithTopic(this.TextBoxTopicPublished.Text.Trim()).WithPayload(payload).WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce).WithRetainFlag().Build();
|
||||||
|
|
||||||
|
if (this.managedMqttClientPublisher != null)
|
||||||
|
{
|
||||||
|
await this.managedMqttClientPublisher.PublishAsync(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var item = ex.Message;
|
||||||
|
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
|
||||||
|
}
|
||||||
|
|
||||||
|
((Button)sender).Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The method that handles the button click to start the publisher.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender.</param>
|
||||||
|
/// <param name="e">The event args.</param>
|
||||||
|
private async void ButtonPublisherStartClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var mqttFactory = new MqttFactory();
|
||||||
|
|
||||||
|
var tlsOptions = new MqttClientTlsOptions
|
||||||
|
{
|
||||||
|
UseTls = false, IgnoreCertificateChainErrors = true, IgnoreCertificateRevocationErrors = true, AllowUntrustedCertificates = true
|
||||||
|
};
|
||||||
|
|
||||||
|
var options = new MqttClientOptions
|
||||||
|
{
|
||||||
|
ClientId = "ClientPublisher",
|
||||||
|
ProtocolVersion = MqttProtocolVersion.V311,
|
||||||
|
ChannelOptions = new MqttClientTcpOptions
|
||||||
|
{
|
||||||
|
Server = "localhost", Port = int.Parse(this.TextBoxPort.Text.Trim()), TlsOptions = tlsOptions
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (options.ChannelOptions == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
options.Credentials = new MqttClientCredentials
|
||||||
|
{
|
||||||
|
Username = "username", Password = Encoding.UTF8.GetBytes("password")
|
||||||
|
};
|
||||||
|
|
||||||
|
options.CleanSession = true;
|
||||||
|
options.KeepAlivePeriod = TimeSpan.FromSeconds(5);
|
||||||
|
this.managedMqttClientPublisher = mqttFactory.CreateManagedMqttClient();
|
||||||
|
this.managedMqttClientPublisher.UseApplicationMessageReceivedHandler(this.HandleReceivedApplicationMessage);
|
||||||
|
this.managedMqttClientPublisher.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnPublisherConnected);
|
||||||
|
this.managedMqttClientPublisher.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(OnPublisherDisconnected);
|
||||||
|
|
||||||
|
await this.managedMqttClientPublisher.StartAsync(
|
||||||
|
new ManagedMqttClientOptions
|
||||||
|
{
|
||||||
|
ClientOptions = options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The method that handles the button click to stop the publisher.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender.</param>
|
||||||
|
/// <param name="e">The event args.</param>
|
||||||
|
private async void ButtonPublisherStopClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (this.managedMqttClientPublisher == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.managedMqttClientPublisher.StopAsync();
|
||||||
|
this.managedMqttClientPublisher = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The method that handles the button click to start the server.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender.</param>
|
||||||
|
/// <param name="e">The event args.</param>
|
||||||
|
private async void ButtonServerStartClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (this.mqttServer != null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var storage = new JsonServerStorage();
|
||||||
|
storage.Clear();
|
||||||
|
this.mqttServer = new MqttFactory().CreateMqttServer();
|
||||||
|
var options = new MqttServerOptions();
|
||||||
|
options.DefaultEndpointOptions.Port = int.Parse(this.TextBoxPort.Text);
|
||||||
|
options.Storage = storage;
|
||||||
|
options.EnablePersistentSessions = true;
|
||||||
|
options.ConnectionValidator = new MqttServerConnectionValidatorDelegate(
|
||||||
|
c =>
|
||||||
|
{
|
||||||
|
if (c.ClientId.Length < 10)
|
||||||
|
{
|
||||||
|
c.ReasonCode = MqttConnectReasonCode.ClientIdentifierNotValid;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c.Username != "username")
|
||||||
|
{
|
||||||
|
c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c.Password != "password")
|
||||||
|
{
|
||||||
|
c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
c.ReasonCode = MqttConnectReasonCode.Success;
|
||||||
|
});
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await this.mqttServer.StartAsync(options);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
var item = ex.Message;
|
||||||
|
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
|
||||||
|
|
||||||
|
await this.mqttServer.StopAsync();
|
||||||
|
this.mqttServer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The method that handles the button click to stop the server.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender.</param>
|
||||||
|
/// <param name="e">The event args.</param>
|
||||||
|
private async void ButtonServerStopClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (this.mqttServer == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.mqttServer.StopAsync();
|
||||||
|
this.mqttServer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The method that handles the button click to subscribe to a certain topic.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender.</param>
|
||||||
|
/// <param name="e">The event args.</param>
|
||||||
|
private async void ButtonSubscribeClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var topicFilter = new MqttTopicFilter { Topic = this.TextBoxTopicSubscribed.Text.Trim() };
|
||||||
|
await this.managedMqttClientSubscriber.SubscribeAsync(topicFilter);
|
||||||
|
var item = "Topic " + this.TextBoxTopicSubscribed.Text.Trim() + " is subscribed";
|
||||||
|
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The method that handles the button click to start the subscriber.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender.</param>
|
||||||
|
/// <param name="e">The event args.</param>
|
||||||
|
private async void ButtonSubscriberStartClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var mqttFactory = new MqttFactory();
|
||||||
|
|
||||||
|
var tlsOptions = new MqttClientTlsOptions
|
||||||
|
{
|
||||||
|
UseTls = false, IgnoreCertificateChainErrors = true, IgnoreCertificateRevocationErrors = true, AllowUntrustedCertificates = true
|
||||||
|
};
|
||||||
|
|
||||||
|
var options = new MqttClientOptions
|
||||||
|
{
|
||||||
|
ClientId = "ClientSubscriber",
|
||||||
|
ProtocolVersion = MqttProtocolVersion.V311,
|
||||||
|
ChannelOptions = new MqttClientTcpOptions
|
||||||
|
{
|
||||||
|
Server = "localhost", Port = int.Parse(this.TextBoxPort.Text.Trim()), TlsOptions = tlsOptions
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (options.ChannelOptions == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
options.Credentials = new MqttClientCredentials
|
||||||
|
{
|
||||||
|
Username = "username",
|
||||||
|
Password = Encoding.UTF8.GetBytes("password")
|
||||||
|
};
|
||||||
|
|
||||||
|
options.CleanSession = true;
|
||||||
|
options.KeepAlivePeriod = TimeSpan.FromSeconds(5);
|
||||||
|
|
||||||
|
this.managedMqttClientSubscriber = mqttFactory.CreateManagedMqttClient();
|
||||||
|
this.managedMqttClientSubscriber.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnSubscriberConnected);
|
||||||
|
this.managedMqttClientSubscriber.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(OnSubscriberDisconnected);
|
||||||
|
this.managedMqttClientSubscriber.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(this.OnSubscriberMessageReceived);
|
||||||
|
|
||||||
|
await this.managedMqttClientSubscriber.StartAsync(
|
||||||
|
new ManagedMqttClientOptions
|
||||||
|
{
|
||||||
|
ClientOptions = options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The method that handles the button click to stop the subscriber.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender.</param>
|
||||||
|
/// <param name="e">The event args.</param>
|
||||||
|
private async void ButtonSubscriberStopClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (this.managedMqttClientSubscriber == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.managedMqttClientSubscriber.StopAsync();
|
||||||
|
this.managedMqttClientSubscriber = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles the received application message event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The MQTT application message received event args.</param>
|
||||||
|
private void HandleReceivedApplicationMessage(MqttApplicationMessageReceivedEventArgs x)
|
||||||
|
{
|
||||||
|
var item = $"Timestamp: {DateTime.Now:O} | Topic: {x.ApplicationMessage.Topic} | Payload: {x.ApplicationMessage.ConvertPayloadToString()} | QoS: {x.ApplicationMessage.QualityOfServiceLevel}";
|
||||||
|
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles the received subscriber message event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The MQTT application message received event args.</param>
|
||||||
|
private void OnSubscriberMessageReceived(MqttApplicationMessageReceivedEventArgs x)
|
||||||
|
{
|
||||||
|
var item = $"Timestamp: {DateTime.Now:O} | Topic: {x.ApplicationMessage.Topic} | Payload: {x.ApplicationMessage.ConvertPayloadToString()} | QoS: {x.ApplicationMessage.QualityOfServiceLevel}";
|
||||||
|
this.BeginInvoke((MethodInvoker)delegate { this.TextBoxSubscriber.Text = item + Environment.NewLine + this.TextBoxSubscriber.Text; });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The method that handles the text changes in the text box.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender.</param>
|
||||||
|
/// <param name="e">The event args.</param>
|
||||||
|
private void TextBoxPortTextChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
// ReSharper disable once StyleCop.SA1126
|
||||||
|
if (int.TryParse(this.TextBoxPort.Text, out _))
|
||||||
|
{
|
||||||
|
this.port = this.TextBoxPort.Text.Trim();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.TextBoxPort.Text = this.port;
|
||||||
|
this.TextBoxPort.SelectionStart = this.TextBoxPort.Text.Length;
|
||||||
|
this.TextBoxPort.SelectionLength = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The method that handles the timer events.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender.</param>
|
||||||
|
/// <param name="e">The event args.</param>
|
||||||
|
private void TimerElapsed(object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
this.BeginInvoke(
|
||||||
|
(MethodInvoker)delegate
|
||||||
|
{
|
||||||
|
// Server
|
||||||
|
this.TextBoxPort.Enabled = this.mqttServer == null;
|
||||||
|
this.ButtonServerStart.Enabled = this.mqttServer == null;
|
||||||
|
this.ButtonServerStop.Enabled = this.mqttServer != null;
|
||||||
|
|
||||||
|
// Publisher
|
||||||
|
this.ButtonPublisherStart.Enabled = this.managedMqttClientPublisher == null;
|
||||||
|
this.ButtonPublisherStop.Enabled = this.managedMqttClientPublisher != null;
|
||||||
|
|
||||||
|
// Auto Publisher
|
||||||
|
this.ButtonAutoPublisherStart.Enabled = !this.randomPublisherTimer.Enabled;
|
||||||
|
this.ButtonAutoPublisherStop.Enabled = this.randomPublisherTimer.Enabled;
|
||||||
|
|
||||||
|
// Subscriber
|
||||||
|
this.ButtonSubscriberStart.Enabled = this.managedMqttClientSubscriber == null;
|
||||||
|
this.ButtonSubscriberStop.Enabled = this.managedMqttClientSubscriber != null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void trackBar1_Scroll(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
this.label8.Text = $"{this.trackBar1.Value:N0} ms";
|
||||||
|
this.randomPublisherTimer.Interval = this.trackBar1.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ButtonAutoPublisherStartClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
((Button)sender).Enabled = false;
|
||||||
|
this.randomPublisherTimer.Start();
|
||||||
|
((Button)sender).Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ButtonAutoPublisherStopClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
((Button)sender).Enabled = false;
|
||||||
|
this.randomPublisherTimer.Stop();
|
||||||
|
((Button)sender).Enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
60
MQTTnet.TestApp.WinForm/Form1.resx
Normal file
60
MQTTnet.TestApp.WinForm/Form1.resx
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<root>
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
83
MQTTnet.TestApp.WinForm/JsonServerStorage.cs
Normal file
83
MQTTnet.TestApp.WinForm/JsonServerStorage.cs
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||||
|
// <copyright file="JsonServerStorage.cs" company="Haemmer Electronics">
|
||||||
|
// Copyright (c) 2020 All rights reserved.
|
||||||
|
// </copyright>
|
||||||
|
// <summary>
|
||||||
|
// The JSON server storage.
|
||||||
|
// </summary>
|
||||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace MQTTnet.TestApp.WinForm
|
||||||
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using MQTTnet.Server;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IMqttServerStorage"/>
|
||||||
|
/// <summary>
|
||||||
|
/// The JSON server storage.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="IMqttServerStorage"/>
|
||||||
|
public class JsonServerStorage : IMqttServerStorage
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The file name.
|
||||||
|
/// </summary>
|
||||||
|
private readonly string filename = Path.Combine(Directory.GetCurrentDirectory(), "Retained.json");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the file.
|
||||||
|
/// </summary>
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
if (File.Exists(this.filename))
|
||||||
|
{
|
||||||
|
File.Delete(this.filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IMqttServerStorage"/>
|
||||||
|
/// <summary>
|
||||||
|
/// Loads the retained messages.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A <see cref="IList{T}"/> of <see cref="MqttApplicationMessage"/>.</returns>
|
||||||
|
/// <seealso cref="IMqttServerStorage"/>
|
||||||
|
public async Task<IList<MqttApplicationMessage>> LoadRetainedMessagesAsync()
|
||||||
|
{
|
||||||
|
await Task.CompletedTask;
|
||||||
|
|
||||||
|
if (!File.Exists(this.filename))
|
||||||
|
{
|
||||||
|
return new List<MqttApplicationMessage>();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var json = await File.ReadAllTextAsync(this.filename);
|
||||||
|
return JsonConvert.DeserializeObject<List<MqttApplicationMessage>>(json);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return new List<MqttApplicationMessage>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IMqttServerStorage"/>
|
||||||
|
/// <summary>
|
||||||
|
/// Saves the retained messages to a file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="messages">The messages.</param>
|
||||||
|
/// <returns>A <see cref="Task"/> representing any asynchronous operation.</returns>
|
||||||
|
/// <seealso cref="IMqttServerStorage"/>
|
||||||
|
public async Task SaveRetainedMessagesAsync(IList<MqttApplicationMessage> messages)
|
||||||
|
{
|
||||||
|
await Task.CompletedTask;
|
||||||
|
var json = JsonConvert.SerializeObject(messages);
|
||||||
|
await File.WriteAllTextAsync(this.filename, json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
MQTTnet.TestApp.WinForm/MQTTnet.TestApp.WinForm.csproj
Normal file
19
MQTTnet.TestApp.WinForm/MQTTnet.TestApp.WinForm.csproj
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="GitVersionTask" Version="5.3.3">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="MQTTnet" Version="3.0.11" />
|
||||||
|
<PackageReference Include="MQTTnet.Extensions.ManagedClient" Version="3.0.11" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
32
MQTTnet.TestApp.WinForm/Program.cs
Normal file
32
MQTTnet.TestApp.WinForm/Program.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||||
|
// <copyright file="Program.cs" company="Haemmer Electronics">
|
||||||
|
// Copyright (c) 2020 All rights reserved.
|
||||||
|
// </copyright>
|
||||||
|
// <summary>
|
||||||
|
// The main program.
|
||||||
|
// </summary>
|
||||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace MQTTnet.TestApp.WinForm
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The main program.
|
||||||
|
/// </summary>
|
||||||
|
internal static class Program
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The main entry point for the application.
|
||||||
|
/// </summary>
|
||||||
|
[STAThread]
|
||||||
|
private static void Main()
|
||||||
|
{
|
||||||
|
Application.SetHighDpiMode(HighDpiMode.SystemAware);
|
||||||
|
Application.EnableVisualStyles();
|
||||||
|
Application.SetCompatibleTextRenderingDefault(false);
|
||||||
|
Application.Run(new Form1());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
167
input.yml
Normal file
167
input.yml
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
openapi: 3.0.3
|
||||||
|
info:
|
||||||
|
title: Input Service
|
||||||
|
description: This is the input interface of the Birbnetes system.
|
||||||
|
contact:
|
||||||
|
email: tormakristof@tormakristof.eu
|
||||||
|
license:
|
||||||
|
name: Apache 2.0
|
||||||
|
url: http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
version: 1.1.3
|
||||||
|
servers:
|
||||||
|
- url: https://birb.k8s.kmlabz.com
|
||||||
|
tags:
|
||||||
|
- name: input
|
||||||
|
description: Input Service interaction
|
||||||
|
paths:
|
||||||
|
/sample:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- input
|
||||||
|
summary: Get all stored input queries
|
||||||
|
operationId: getall
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Array of input objects
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/InputResponse'
|
||||||
|
404:
|
||||||
|
description: No object matching filter
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- input
|
||||||
|
summary: uploads a sample into the system
|
||||||
|
operationId: uploadFile
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
multipart/form-data:
|
||||||
|
schema:
|
||||||
|
required:
|
||||||
|
- description
|
||||||
|
- file
|
||||||
|
properties:
|
||||||
|
description:
|
||||||
|
type: object
|
||||||
|
description: Metadata json
|
||||||
|
properties:
|
||||||
|
deviceid:
|
||||||
|
type: string
|
||||||
|
date:
|
||||||
|
type: string
|
||||||
|
format: date
|
||||||
|
file:
|
||||||
|
type: string
|
||||||
|
description: Wave file to upload
|
||||||
|
format: binary
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
400:
|
||||||
|
description: JSON parse error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
415:
|
||||||
|
description: Media type error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
417:
|
||||||
|
description: JSON invalid schema
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
469:
|
||||||
|
description: No file found
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
470:
|
||||||
|
description: Description missing
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
/sample/{tagID}:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- input
|
||||||
|
summary: Get input object by ID
|
||||||
|
operationId: getInput
|
||||||
|
parameters:
|
||||||
|
- name: tagID
|
||||||
|
in: path
|
||||||
|
description: ID of input object file
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: input object
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/InputSingeResponse'
|
||||||
|
404:
|
||||||
|
description: Tag not found
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
InputSingeResponse:
|
||||||
|
required:
|
||||||
|
- message
|
||||||
|
- status
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
$ref: '#/components/schemas/InputObject'
|
||||||
|
InputResponse:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/InputObject'
|
||||||
|
InputObject:
|
||||||
|
required:
|
||||||
|
- date
|
||||||
|
- device_id
|
||||||
|
- tag
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
tag:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
date:
|
||||||
|
type: string
|
||||||
|
format: date
|
||||||
|
device_id:
|
||||||
|
type: integer
|
||||||
|
ApiResponse:
|
||||||
|
required:
|
||||||
|
- message
|
||||||
|
- status
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
Loading…
Reference in New Issue
Block a user