diff --git a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/ConfigManager.cs b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/ConfigManager.cs index edd39f9..f63076e 100644 --- a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/ConfigManager.cs +++ b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/ConfigManager.cs @@ -14,82 +14,64 @@ internal ConfigManager(Driver Driver) { _driver = Driver; - Guid ID = Guid.Empty; - string RequestPL = string.Empty; - Dictionary Request; - - Request = new Dictionary(); - ID = Guid.NewGuid(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.LoadManufacturers); - RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - Request = new Dictionary(); - ID = Guid.NewGuid(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.LoadDeviceIndex); - RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - + // Fire-and-forget the load commands but observe failures to avoid unobserved exceptions. + var req1 = new Dictionary + { + { "command", Enums.Commands.LoadManufacturers } + }; + _ = _driver.SendRequestAsync(req1).ContinueWith(t => + { + System.Diagnostics.Debug.WriteLine($"LoadManufacturers request failed: {t.Exception?.GetBaseException()}"); + }, TaskContinuationOptions.OnlyOnFaulted); + + var req2 = new Dictionary + { + { "command", Enums.Commands.LoadDeviceIndex } + }; + _ = _driver.SendRequestAsync(req2).ContinueWith(t => + { + System.Diagnostics.Debug.WriteLine($"LoadDeviceIndex request failed: {t.Exception?.GetBaseException()}"); + }, TaskContinuationOptions.OnlyOnFaulted); } // Checked as of : 3.5.0 public Task LookupDevice(int ManufacturerID, int ProductTypeID, int ProductId) { - - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary + { + { "command", Enums.Commands.LookupDevice }, + { "manufacturerId", ManufacturerID }, + { "productType", ProductTypeID }, + { "productId", ProductId } + }; + + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { DeviceConfig Config = JO.SelectToken("result.config").ToObject(); Res.SetPayload(Config); } - Result.SetResult(Res); }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.LookupDevice); - Request.Add("manufacturerId", ManufacturerID); - Request.Add("productType", ProductTypeID); - Request.Add("productId", ProductId); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task LookupManufacturer(int ManufacturerID) { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary + { + { "command", Enums.Commands.LookupManufacturer }, + { "manufacturerId", ManufacturerID } + }; + + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { string Name = JO.SelectToken("result.name").ToObject(); Res.SetPayload(Name); } - Result.SetResult(Res); }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.LookupManufacturer); - Request.Add("manufacturerId", ManufacturerID); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } } } \ No newline at end of file diff --git a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Controller.cs b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Controller.cs index 3ae7094..62f5ed5 100644 --- a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Controller.cs +++ b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Controller.cs @@ -144,439 +144,268 @@ internal void Trigger_FirmwareUpdateProgress(ControllerFirmwareUpdateProgressArg // Checked as of : 3.5.0 public Task GetAvailableFirmwareUpdates(int NodeID, bool IncludePrereleases, UsageEnvironment Environment, string APIKey = null) { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - if (Environment == UsageEnvironment.Commercial && string.IsNullOrEmpty(APIKey)) { CMDResult Res = new CMDResult(Enums.ErrorCodes.CommercialAPIKey, "A valid API license key is required for commercial use", false); - Result.SetResult(Res); - return Result.Task; + return Task.FromResult(Res); } - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - + { "command", Enums.Commands.GetAvailableFirmwareUpdates }, + { "nodeId", NodeID }, + { "apiKey", APIKey ?? Driver.FWUSAPIKey }, + { "includePrereleases", IncludePrereleases } + }; + return _driver.SendRequestAsync(request, (JO, Res) => + { if (Res.Success) { FirmwareUpdateInfo[] FUI = JO.SelectToken("result.updates").ToObject(); Res.SetPayload(FUI); } - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.GetAvailableFirmwareUpdates); - Request.Add("nodeId", NodeID); - Request.Add("apiKey", APIKey ?? Driver.FWUSAPIKey); - Request.Add("includePrereleases", IncludePrereleases); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task FirmwareUpdateOTA(int NodeID, FirmwareUpdateInfo Update) { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); + var request = new Dictionary + { + { "command", Enums.Commands.FirmwareUpdateOTA }, + { "nodeId", NodeID }, + { "updateInfo", Update } + }; - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { NodeFirmwareUpdateResultArgs FUR = JO.SelectToken("result.result").ToObject(); Res.SetPayload(FUR); } - Result.SetResult(Res); }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.FirmwareUpdateOTA); - Request.Add("nodeId", NodeID); - Request.Add("updateInfo", Update); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task GetRFRegion() { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); + var request = new Dictionary + { + { "command", Enums.Commands.GetRFRegion } + }; - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Enums.RFRegion Region = JO.SelectToken("result.region").ToObject(); Res.SetPayload(Region); } - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.GetRFRegion); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task SetRFRegion(Enums.RFRegion Region) { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.SetRFRegion); - Request.Add("region", Region); + { "command", Enums.Commands.SetRFRegion }, + { "region", Region } + }; - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 public Task SetMaxLongRangePowerlevel(decimal Limit) { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("limit", Limit); - Request.Add("command", Enums.Commands.SetLRMaxPower); - + { "limit", Limit }, + { "command", Enums.Commands.SetLRMaxPower } + }; - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 public Task GetMaxLongRangePowerlevel() { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); + { "command", Enums.Commands.GetLRMaxPower } + }; + return _driver.SendRequestAsync(request, (JO, Res) => + { if (Res.Success) { decimal Level = JO.SelectToken("result.limit").ToObject(); Res.SetPayload(Level); } - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.GetLRMaxPower); - - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task GetPowerLevel() { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); + { "command", Enums.Commands.GetPowerlevel } + }; + return _driver.SendRequestAsync(request, (JO, Res) => + { if (Res.Success) { PowerLevel Level = JO.SelectToken("result").ToObject(); Res.SetPayload(Level); } - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.GetPowerlevel); - - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task SetPowerLevel(decimal PowerLevel, decimal Measured0dBm) { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); + { "command", Enums.Commands.SetPowerlevel }, + { "powerlevel", PowerLevel }, + { "measured0dBm", Measured0dBm } + }; - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.SetPowerlevel); - Request.Add("powerlevel", PowerLevel); - Request.Add("measured0dBm", Measured0dBm); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; + return _driver.SendRequestAsync(request); } + // Checked as of : 3.5.0 public Task FirmwareUpdateOTW(FirmwareUpdate Update) { if (Update.firmwareTarget != null) { - TaskCompletionSource Fail = new TaskCompletionSource(); CMDResult Res = new CMDResult(Enums.ErrorCodes.WrongOverride, "Please use the override that DOES NOT include 'firmwareTarget'", false); - Fail.SetResult(Res); - - return Fail.Task; + return Task.FromResult(Res); } - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); + { "command", Enums.Commands.FirmwareUpdateOTW }, + { "file", Update.data }, + { "filename", Update.filename } + }; + return _driver.SendRequestAsync(request, (JO, Res) => + { if (Res.Success) { ControllerFirmwareUpdateResultArgs UpdateResult = JO.SelectToken("result.result").ToObject(); Res.SetPayload(UpdateResult); } - Result.SetResult(Res); - }); - - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.FirmwareUpdateOTW); - Request.Add("file", Update.data); - Request.Add("filename", Update.filename); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task GetProvisioningEntries() { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => - { - CMDResult Res = new CMDResult(JO); - - if (Res.Success) - { - SmartStartProvisioningEntry[] Entries = JO.SelectToken("result.entries").ToObject(); - Res.SetPayload(Entries); - } - Result.SetResult(Res); - - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.GetProvisioningEntries); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + var request = new Dictionary + { + { "command", Enums.Commands.GetProvisioningEntries } + }; - return Result.Task; + return _driver.SendRequestAsync(request, (JO, Res) => + { + if (Res.Success) + { + SmartStartProvisioningEntry[] Entries = JO.SelectToken("result.entries").ToObject(); + Res.SetPayload(Entries); + } + }); } // Checked as of : 3.5.0 public Task ToggleRF(bool Enabled) { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); + { "command", Enums.Commands.ToggleRF }, + { "enabled", Enabled } + }; - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.ToggleRF); - Request.Add("enabled", Enabled); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 public Task RemoveAssociations(AssociationAddress Source, int Group, AssociationAddress[] Targets) { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => - { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.RemoveAssociations); - Request.Add("nodeId", Source.nodeId); - Request.Add("endpoint", Source.endpoint); - Request.Add("group", Group); - Request.Add("associations", Targets); - - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + var request = new Dictionary + { + { "command", Enums.Commands.RemoveAssociations }, + { "nodeId", Source.nodeId }, + { "endpoint", Source.endpoint }, + { "group", Group }, + { "associations", Targets } + }; - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 public Task AddAssociations(AssociationAddress Source, int Group, AssociationAddress[] Targets) { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.AddAssociations); - Request.Add("nodeId", Source.nodeId); - Request.Add("endpoint", Source.endpoint); - Request.Add("group", Group); - Request.Add("associations", Targets); + { "command", Enums.Commands.AddAssociations }, + { "nodeId", Source.nodeId }, + { "endpoint", Source.endpoint }, + { "group", Group }, + { "associations", Targets } + }; - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 public Task GetAssociations(int Node, int Endpoint) { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => - { - CMDResult Res = new CMDResult(JO); - if (Res.Success) - { - Dictionary Associations = JO.SelectToken("result.associations").ToObject>(); - Res.SetPayload(Associations); - } - - Result.SetResult(Res); - - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.GetAssociations); - Request.Add("nodeId", Node); - Request.Add("endpoint", Endpoint); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; + var request = new Dictionary + { + { "command", Enums.Commands.GetAssociations }, + { "nodeId", Node }, + { "endpoint", Endpoint } + }; + + return _driver.SendRequestAsync(request, (JO, Res) => + { + if (Res.Success) + { + Dictionary Associations = JO.SelectToken("result.associations").ToObject>(); + Res.SetPayload(Associations); + } + }); } // Checked as of : 3.5.0 public Task GetAssociationGroups(int Node, int Endpoint) { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => - { - CMDResult Res = new CMDResult(JO); - if (Res.Success) - { - Dictionary Groups = JO.SelectToken("result.groups").ToObject>(); - - Res.SetPayload(Groups); - } - - Result.SetResult(Res); - - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.GetAssociationGroups); - Request.Add("nodeId", Node); - Request.Add("endpoint", Endpoint); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + var request = new Dictionary + { + { "command", Enums.Commands.GetAssociationGroups }, + { "nodeId", Node }, + { "endpoint", Endpoint } + }; - return Result.Task; + return _driver.SendRequestAsync(request, (JO, Res) => + { + if (Res.Success) + { + Dictionary Groups = JO.SelectToken("result.groups").ToObject>(); + Res.SetPayload(Groups); + } + }); } // Checked as of : 3.5.0 @@ -585,28 +414,19 @@ public Task RestoreNVM(byte[] NVMData, ConvertRestoreNVMProgress Conv ConvertRestoreNVMProgressSub = ConvertProgress; RestoreNVMProgressSub = RestoreProgress; - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => - { - CMDResult Res = new CMDResult(JO); - if (Res.Success) - { - _driver.Restart(); - } - Result.SetResult(Res); - - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.RestoreNVM); - Request.Add("nvmData", Convert.ToBase64String(NVMData)); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + var request = new Dictionary + { + { "command", Enums.Commands.RestoreNVM }, + { "nvmData", Convert.ToBase64String(NVMData) } + }; - return Result.Task; + return _driver.SendRequestAsync(request, (JO, Res) => + { + if (Res.Success) + { + _driver.Restart(); + } + }); } // Checked as of : 3.5.0 @@ -614,29 +434,19 @@ public Task BackupNVMRaw(BackupNVMProgress OnProgress = null) { BackupNVMProgressSub = OnProgress; - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => - { - CMDResult Res = new CMDResult(JO); - if (Res.Success) - { - string B64 = JO.SelectToken("result.nvmData").ToObject(); - Res.SetPayload(Convert.FromBase64String(B64)); - } - - Result.SetResult(Res); - - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.BackUpNVM); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + var request = new Dictionary + { + { "command", Enums.Commands.BackUpNVM } + }; - return Result.Task; + return _driver.SendRequestAsync(request, (JO, Res) => + { + if (Res.Success) + { + string B64 = JO.SelectToken("result.nvmData").ToObject(); + Res.SetPayload(Convert.FromBase64String(B64)); + } + }); } // Checked as of : 3.5.0 @@ -646,22 +456,17 @@ public Task ReplaceFailedNode(int NodeID, InclusionOptions Options) GrantSecurityClassesSub = null; AbortSub = null; - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - switch (Options.strategy) { case Enums.InclusionStrategy.Default: - CMDResult Res = new CMDResult(Enums.ErrorCodes.InvalidStrategy, "Invalid Strategy for 'ReplaceFailedNode' Valid Strategies are : [Insecure, Security_S0, Security_S2]", false); - Result.SetResult(Res); - return Result.Task; + CMDResult invalid = new CMDResult(Enums.ErrorCodes.InvalidStrategy, "Invalid Strategy for 'ReplaceFailedNode' Valid Strategies are : [Insecure, Security_S0, Security_S2]", false); + return Task.FromResult(invalid); case Enums.InclusionStrategy.Security_S2: ValidateDSKAndEnterPINSub = Options.userCallbacks?.validateDSKAndEnterPIN ?? null; GrantSecurityClassesSub = Options.userCallbacks?.grantSecurityClasses ?? null; AbortSub = Options.userCallbacks?.abort ?? null; break; - } if (Options.strategy == Enums.InclusionStrategy.Security_S2) @@ -669,15 +474,13 @@ public Task ReplaceFailedNode(int NodeID, InclusionOptions Options) if (ValidateDSKAndEnterPINSub == null || GrantSecurityClassesSub == null || AbortSub == null) { CMDResult Res = new CMDResult(Enums.ErrorCodes.MissingS2Callbacks, "S2 Security require userCallbacks to be provided [validateDSKAndEnterPIN, grantSecurityClasses, abort]", false); - Result.SetResult(Res); - return Result.Task; + return Task.FromResult(Res); } if (_driver.Options != null && _driver.Options.MissingKeys(true, false)) { CMDResult Res = new CMDResult(Enums.ErrorCodes.MissingKeys, "Missing Security Keys in Options", false); - Result.SetResult(Res); - return Result.Task; + return Task.FromResult(Res); } } @@ -686,142 +489,88 @@ public Task ReplaceFailedNode(int NodeID, InclusionOptions Options) if (_driver.Options != null && _driver.Options.MissingKeys(false, true)) { CMDResult Res = new CMDResult(Enums.ErrorCodes.MissingKeys, "Missing Security Keys in Options", false); - Result.SetResult(Res); - return Result.Task; + return Task.FromResult(Res); } } if (_driver.Options != null && !_driver.Options.CheckKeyLength()) { CMDResult Res = new CMDResult(Enums.ErrorCodes.InvalidkeyLength, "Invalid Key length. All Security Keys must be a 32 character hexadecimal string (representing 16 bytes)", false); - Result.SetResult(Res); - return Result.Task; + return Task.FromResult(Res); } + var optionsDict = new Dictionary + { + { "strategy", (int)Options.strategy } + }; - _driver.Callbacks.Add(ID, (JO) => - { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary _Options = new Dictionary(); - _Options.Add("strategy", (int)Options.strategy); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.ReplaceFailedNode); - Request.Add("nodeId", NodeID); - Request.Add("options", _Options); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + var request = new Dictionary + { + { "command", Enums.Commands.ReplaceFailedNode }, + { "nodeId", NodeID }, + { "options", optionsDict } + }; - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 public Task RemoveFailedNode(int NodeID) { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - - _driver.Callbacks.Add(ID, (JO) => - { - CMDResult RES = new CMDResult(JO); - Result.SetResult(RES); - }); - - Dictionary Request = new Dictionary(); - - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.RemoveFailedNode); - Request.Add("nodeId", NodeID); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + var request = new Dictionary + { + { "command", Enums.Commands.RemoveFailedNode }, + { "nodeId", NodeID } + }; - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 public Task RebuildNodeRoutes(int NodeID) { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - - _driver.Callbacks.Add(ID, (JO) => - { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.RebuildNodeRoutes); - Request.Add("nodeId", NodeID); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + var request = new Dictionary + { + { "command", Enums.Commands.RebuildNodeRoutes }, + { "nodeId", NodeID } + }; - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 public Task BeginRebuildingRoutes(RebuildRoutesOptions Options) { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - - _driver.Callbacks.Add(ID, (JO) => - { - CMDResult Res = new CMDResult(JO); - if (Res.Success && Res.ResultPayloadAs()) - { - this.isRebuildingRoutes = true; - } - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.BeginRebuildingRoutes); - Request.Add("options", Options); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + var request = new Dictionary + { + { "command", Enums.Commands.BeginRebuildingRoutes }, + { "options", Options } + }; - return Result.Task; + return _driver.SendRequestAsync(request, (JO, Res) => + { + if (Res.Success && Res.ResultPayloadAs()) + { + this.isRebuildingRoutes = true; + } + }); } // Checked as of : 3.5.0 public Task StopRebuildingRoutes() { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - - _driver.Callbacks.Add(ID, (JO) => - { - CMDResult Res = new CMDResult(JO); - if (Res.Success && Res.ResultPayloadAs()) - { - this.isRebuildingRoutes = false; - } - - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.StopRebuildingRoutes); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + var request = new Dictionary + { + { "command", Enums.Commands.StopRebuildingRoutes } + }; - return Result.Task; + return _driver.SendRequestAsync(request, (JO, Res) => + { + if (Res.Success && Res.ResultPayloadAs()) + { + this.isRebuildingRoutes = false; + } + }); } // Checked as of : 3.5.0 @@ -831,9 +580,6 @@ public Task BeginInclusion(InclusionOptions Options) GrantSecurityClassesSub = null; AbortSub = null; - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - switch (Options.strategy) { case Enums.InclusionStrategy.Default: @@ -850,15 +596,13 @@ public Task BeginInclusion(InclusionOptions Options) if (ValidateDSKAndEnterPINSub == null || GrantSecurityClassesSub == null || AbortSub == null) { CMDResult Res = new CMDResult(Enums.ErrorCodes.MissingS2Callbacks, "S2 Security require userCallbacks to be provided [validateDSKAndEnterPIN, grantSecurityClasses, abort]", false); - Result.SetResult(Res); - return Result.Task; + return Task.FromResult(Res); } if (_driver.Options != null && _driver.Options.MissingKeys(true, true)) { CMDResult Res = new CMDResult(Enums.ErrorCodes.MissingKeys, "Missing Security Keys in Options", false); - Result.SetResult(Res); - return Result.Task; + return Task.FromResult(Res); } } @@ -868,15 +612,13 @@ public Task BeginInclusion(InclusionOptions Options) if (ValidateDSKAndEnterPINSub == null || GrantSecurityClassesSub == null || AbortSub == null) { CMDResult Res = new CMDResult(Enums.ErrorCodes.MissingS2Callbacks, "S2 Security require userCallbacks to be provided [validateDSKAndEnterPIN, grantSecurityClasses, abort]", false); - Result.SetResult(Res); - return Result.Task; + return Task.FromResult(Res); } if (_driver.Options != null && _driver.Options.MissingKeys(true, false)) { CMDResult Res = new CMDResult(Enums.ErrorCodes.MissingKeys, "Missing Security Keys in Options", false); - Result.SetResult(Res); - return Result.Task; + return Task.FromResult(Res); } } @@ -885,79 +627,55 @@ public Task BeginInclusion(InclusionOptions Options) if (_driver.Options != null && _driver.Options.MissingKeys(false, true)) { CMDResult Res = new CMDResult(Enums.ErrorCodes.MissingKeys, "Missing Security Keys in Options", false); - Result.SetResult(Res); - return Result.Task; + return Task.FromResult(Res); } } if (_driver.Options != null && !_driver.Options.CheckKeyLength()) { CMDResult Res = new CMDResult(Enums.ErrorCodes.InvalidkeyLength, "Invalid Key length. All Security Keys must be a 32 character hexadecimal string (representing 16 bytes)", false); - Result.SetResult(Res); - return Result.Task; + return Task.FromResult(Res); } - _driver.Callbacks.Add(ID, (JO) => - { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary _Options = new Dictionary(); - _Options.Add("strategy", (int)Options.strategy); - _Options.Add("forceSecurity", Options.forceSecurity); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.BeginInclusion); - Request.Add("options", _Options); + var optionsDict = new Dictionary + { + { "strategy", (int)Options.strategy }, + { "forceSecurity", Options.forceSecurity } + }; - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + var request = new Dictionary + { + { "command", Enums.Commands.BeginInclusion }, + { "options", optionsDict } + }; - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 public Task StopInclusion() { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - - _driver.Callbacks.Add(ID, (JO) => - { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.StopInclusion); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + var request = new Dictionary + { + { "command", Enums.Commands.StopInclusion } + }; - return Result.Task; + return _driver.SendRequestAsync(request); } - + // Checked as of : 3.5.0 public Task ProvisionSmartStartNode(SmartStartProvisioningEntry ProvisioningInformation) { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - if (_driver.Options != null && _driver.Options.MissingKeys(true, true)) { CMDResult Res = new CMDResult(Enums.ErrorCodes.MissingKeys, "Missing Security Keys in Options", false); - Result.SetResult(Res); - return Result.Task; + return Task.FromResult(Res); } if (_driver.Options != null && !_driver.Options.CheckKeyLength()) { CMDResult Res = new CMDResult(Enums.ErrorCodes.InvalidkeyLength, "Invalid Key length. All Security Keys must be a 32 character hexadecimal string (representing 16 bytes)", false); - Result.SetResult(Res); - return Result.Task; + return Task.FromResult(Res); } if (ProvisioningInformation.protocol == Protocols.ZWaveLongRange) @@ -965,106 +683,59 @@ public Task ProvisionSmartStartNode(SmartStartProvisioningEntry Provi if (_driver.Options != null && _driver.Options.MissingLRKeys()) { CMDResult Res = new CMDResult(Enums.ErrorCodes.MissingKeys, "Missing LR Security Keys in Options", false); - Result.SetResult(Res); - return Result.Task; + return Task.FromResult(Res); } if (_driver.Options != null && !_driver.Options.CheckKeyLengthLR()) { CMDResult Res = new CMDResult(Enums.ErrorCodes.InvalidkeyLength, "Invalid Key length. All Security Keys must be a 32 character hexadecimal string (representing 16 bytes)", false); - Result.SetResult(Res); - return Result.Task; + return Task.FromResult(Res); } } - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.ProvisionSmartStartNode); - Request.Add("entry", ProvisioningInformation); + { "command", Enums.Commands.ProvisionSmartStartNode }, + { "entry", ProvisioningInformation } + }; - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 public Task BeginExclusion(ExclusionOptions Options) { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - - _driver.Callbacks.Add(ID, (JO) => - { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.BeginExclusion); - Request.Add("options", Options); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + var request = new Dictionary + { + { "command", Enums.Commands.BeginExclusion }, + { "options", Options } + }; - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 public Task StopExclusion() { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - - _driver.Callbacks.Add(ID, (JO) => - { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.StopExclusion); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + var request = new Dictionary + { + { "command", Enums.Commands.StopExclusion } + }; - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 private Task _UnprovisionSmartStartNode(object dskOrNodeId) { - Guid ID = Guid.NewGuid(); - TaskCompletionSource Result = new TaskCompletionSource(); - - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.UnprovisionSmartStartNode); - Request.Add("dskOrNodeId", dskOrNodeId); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + { "command", Enums.Commands.UnprovisionSmartStartNode }, + { "dskOrNodeId", dskOrNodeId } + }; - return Result.Task; + return _driver.SendRequestAsync(request); } // LOCAL diff --git a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Driver.cs b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Driver.cs index db6c40a..3083e01 100644 --- a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Driver.cs +++ b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Driver.cs @@ -371,7 +371,7 @@ private void MapControllerEvents() ControllerEventMap.Add("statistics updated", (JO) => { ControllerStatisticsUpdatedArgs CS = JO.SelectToken("event.statistics").ToObject(); - + Task.Run(() => { this.Controller.Trigger_StatisticsUpdated(CS); @@ -471,13 +471,13 @@ private void MapControllerEvents() InclusionGrant RIG = JO.SelectToken("event.requested").ToObject(); InclusionGrant SIG = this.Controller.Trigger_GrantSecurityClasses(RIG); - Dictionary Request = new Dictionary(); - Request.Add("messageId", Guid.NewGuid().ToString()); - Request.Add("command", Enums.Commands.GrantSecurityClasses); - Request.Add("inclusionGrant", SIG); + var request = new Dictionary + { + { "command", Enums.Commands.GrantSecurityClasses }, + { "inclusionGrant", SIG } + }; - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - ClientWebSocket.SendInstant(RequestPL); + _ = SendRequestAsync(request); }); }); @@ -488,13 +488,13 @@ private void MapControllerEvents() { string DSK = this.Controller.Trigger_ValidateDSK(JO.SelectToken("event.dsk").ToObject()); - Dictionary Request = new Dictionary(); - Request.Add("messageId", Guid.NewGuid().ToString()); - Request.Add("command", Enums.Commands.ValidateDSK); - Request.Add("pin", DSK); + var request = new Dictionary + { + { "command", Enums.Commands.ValidateDSK }, + { "pin", DSK } + }; - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - ClientWebSocket.SendInstant(RequestPL); + _ = SendRequestAsync(request); }); }); @@ -802,16 +802,13 @@ private void SetAPIVersionCB(JObject JO) { if (JO.Value("success")) { - Guid CBID = Guid.NewGuid(); - Callbacks.Add(CBID, StartListetningCB); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", CBID.ToString()); - Request.Add("command", Enums.Commands.StartListetning); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); + var request = new Dictionary + { + { "command", Enums.Commands.StartListetning } + }; - ClientWebSocket.SendInstant(RequestPL); + // fire-and-forget; StartListetningCB will be invoked when response arrives + _ = SendRequestAsync(request, (respJO, res) => StartListetningCB(respJO)); } else { @@ -857,96 +854,52 @@ private void StartListetningCB(JObject JO) public Task ZWJSS_StartListeningLogs() { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - - Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.StartListeningLogs); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - ClientWebSocket.SendInstant(RequestPL); + { "command", Enums.Commands.StartListeningLogs } + }; - return Result.Task; + return SendRequestAsync(request); } public Task ZWJSS_StopListeningLogs() { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - - Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.StopListeningLogs); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - ClientWebSocket.SendInstant(RequestPL); + { "command", Enums.Commands.StopListeningLogs } + }; - return Result.Task; + return SendRequestAsync(request); } public Task HardReset() { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - - Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); + { "command", Enums.Commands.HardReset } + }; - Restart(); + return SendRequestAsync(request, (JO, Res) => + { + try + { + Restart(); + } + catch + { + // swallow to avoid breaking completion + } }); - - Dictionary Request = new Dictionary(); - - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.HardReset); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } public Task SoftReset() { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - - Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.SoftReset); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - ClientWebSocket.SendInstant(RequestPL); + { "command", Enums.Commands.SoftReset } + }; - return Result.Task; + return SendRequestAsync(request); } // Proces Message @@ -989,17 +942,13 @@ private void WebsocketClient_MessageReceived(object sender, ResponseMessage Mess _ZWaveJSDriverVersion = JO.Value("driverVersion"); _ZWaveJSServerVersion = JO.Value("serverVersion"); - Guid CBID = Guid.NewGuid(); - Callbacks.Add(CBID, SetAPIVersionCB); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", CBID.ToString()); - Request.Add("command", Enums.Commands.SetAPIVersion); - Request.Add("schemaVersion", _schemaVersion); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); + var request = new Dictionary + { + { "command", Enums.Commands.SetAPIVersion }, + { "schemaVersion", _schemaVersion } + }; - ClientWebSocket.SendInstant(RequestPL); + _ = SendRequestAsync(request, (respJO, res) => SetAPIVersionCB(respJO)); return; } @@ -1038,5 +987,77 @@ private void WebsocketClient_MessageReceived(object sender, ResponseMessage Mess } } + internal Task SendRequestAsync( + Dictionary request, + Action mapResult = null, + TimeSpan? timeout = null) + { + Guid id = Guid.NewGuid(); + request["messageId"] = id; + + var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + + // Register callback + Callbacks.Add(id, (JO) => + { + try + { + var res = new CMDResult(JO); + try + { + mapResult?.Invoke(JO, res); + } + catch (Exception exMap) + { + // if mapping throws, surface it + tcs.TrySetException(exMap); + return; + } + + tcs.TrySetResult(res); + } + catch (Exception ex) + { + tcs.TrySetException(ex); + } + finally + { + // best-effort cleanup + try { Callbacks.Remove(id); } catch { } + } + }); + + string payload = Newtonsoft.Json.JsonConvert.SerializeObject(request); + + try + { + var sendTask = ClientWebSocket.SendInstant(payload); + sendTask.ContinueWith(t => + { + if (t.IsFaulted) + { + tcs.TrySetException(t.Exception?.GetBaseException() ?? new Exception("SendInstant failed")); + try { Callbacks.Remove(id); } catch { } + } + }, TaskContinuationOptions.ExecuteSynchronously); + } + catch (Exception ex) + { + tcs.TrySetException(ex); + try { Callbacks.Remove(id); } catch { } + } + + if (timeout.HasValue) + { + var cts = new System.Threading.CancellationTokenSource(timeout.Value); + cts.Token.Register(() => + { + tcs.TrySetException(new TimeoutException("Request timed out")); + try { Callbacks.Remove(id); } catch { } + }); + } + + return tcs.Task; + } } } diff --git a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Endpoint.cs b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Endpoint.cs index 18a403e..d8945e9 100644 --- a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Endpoint.cs +++ b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Endpoint.cs @@ -17,67 +17,62 @@ internal Endpoint(Driver driver = null) // Checked as of : 3.5.0 public Task SupportsCCAPI(int CommandClass) { - Guid ID = Guid.NewGuid(); + var request = new Dictionary + { + { "command", Enums.Commands.SupportsCCAPI }, + { "nodeId", this.nodeId }, + { "endpoint", this.index }, + { "commandClass", CommandClass } + }; - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Res.SetPayload(JO.SelectToken("result.supported").ToObject()); } - Result.SetResult(Res); - - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.SupportsCCAPI); - Request.Add("nodeId", this.nodeId); - Request.Add("endpoint", this.index); - Request.Add("commandClass", CommandClass); - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task InvokeCCAPI(int CommandClass, string Method, params object[] Params) { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary + { + { "command", Enums.Commands.InvokeCCAPI }, + { "nodeId", this.nodeId }, + { "endpoint", this.index }, + { "commandClass", CommandClass }, + { "methodName", Method }, + { "args", Params } + }; + + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Res.SetPayload(JO.SelectToken("result").ToObject()); } - Result.SetResult(Res); - - }); + } - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.InvokeCCAPI); - Request.Add("nodeId", this.nodeId); - Request.Add("endpoint", this.index); - Request.Add("commandClass", CommandClass); - Request.Add("methodName", Method); - Request.Add("args", Params); - - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + public Task GetCCs() + { + var request = new Dictionary + { + { "command", Enums.Commands.GetCCs }, + { "nodeId", this.nodeId }, + { "endpoint", this.index } + }; - return Result.Task; + return _driver.SendRequestAsync(request, (JO, Res) => + { + if (Res.Success) + { + Res.SetPayload(JO.SelectToken("result.commandClasses").ToObject>()); + } + }); } [Newtonsoft.Json.JsonProperty] diff --git a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Enums.cs b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Enums.cs index 67060bc..a33c516 100644 --- a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Enums.cs +++ b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Enums.cs @@ -180,6 +180,7 @@ internal class Commands // ---------------- ENDPOINT ---------------- public const string InvokeCCAPI = "endpoint.invoke_cc_api"; public const string SupportsCCAPI = "endpoint.supports_cc_api"; + public const string GetCCs = "endpoint.get_ccs"; // ---------------- MULTICAST GROUP ---------------- public const string MCGetEndpointCount = "multicast_group.get_endpoint_count"; diff --git a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/MethodFactory.cs b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/MethodFactory.cs index 378d7ce..1b8415b 100644 --- a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/MethodFactory.cs +++ b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/MethodFactory.cs @@ -22,92 +22,53 @@ public static Func, Task> CreatePRIMITIVE( public static Func, Task> CreateCLASS(Driver Runtime, string ServerMethod, Type MappedClass, string ObjectPath) { - return (x) => Execute(Runtime, ServerMethod, x,MappedClass, ObjectPath); + return (x) => Execute(Runtime, ServerMethod, x, MappedClass, ObjectPath); } private static Task Execute(Driver Runtime, string ServerMethod, Dictionary Args, string ObjectPath) { - Guid ID = Guid.NewGuid(); + // create a shallow copy to avoid mutating caller dictionary + var request = new Dictionary(Args ?? new Dictionary()); - TaskCompletionSource Result = new TaskCompletionSource(); + // ensure command is set as expected by the server + request.Remove("messageId"); + request["command"] = ServerMethod; - Runtime.Callbacks.Add(ID, (JO) => + return Runtime.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { object Obj = JO.SelectToken(ObjectPath).ToObject(); Res.SetPayload(Obj); } - Result.SetResult(Res); - }); - - Args.Remove("messageId"); - Args.Remove("command"); - - Args.Add("messageId", ID); - Args.Add("command", ServerMethod); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Args); - Runtime.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } private static Task Execute(Driver Runtime, string ServerMethod, Dictionary Args, Type MappedClass, string ObjectPath) { - Guid ID = Guid.NewGuid(); + var request = new Dictionary(Args ?? new Dictionary()); - TaskCompletionSource Result = new TaskCompletionSource(); + request.Remove("messageId"); + request["command"] = ServerMethod; - Runtime.Callbacks.Add(ID, (JO) => + return Runtime.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { object Obj = JO.SelectToken(ObjectPath).ToObject(MappedClass); Res.SetPayload(Obj); } - Result.SetResult(Res); - }); - - Args.Remove("messageId"); - Args.Remove("command"); - - Args.Add("messageId", ID); - Args.Add("command", ServerMethod); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Args); - Runtime.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } private static Task Execute(Driver Runtime, string ServerMethod, Dictionary Args) { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - - Runtime.Callbacks.Add(ID, (JO) => - { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - - }); - - Args.Remove("messageId"); - Args.Remove("command"); - - Args.Add("messageId", ID); - Args.Add("command", ServerMethod); + var request = new Dictionary(Args ?? new Dictionary()); - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Args); - Runtime.ClientWebSocket.SendInstant(RequestPL); + request.Remove("messageId"); + request["command"] = ServerMethod; - return Result.Task; + return Runtime.SendRequestAsync(request); } } } diff --git a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Structures.cs b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Structures.cs index 73b555c..e8975fc 100644 --- a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Structures.cs +++ b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Structures.cs @@ -47,7 +47,7 @@ internal SetValueResult() { } [Newtonsoft.Json.JsonProperty] public Enums.SetValueStatus status { get; internal set; } [Newtonsoft.Json.JsonProperty] - public string remainingDuration { get; internal set; } + public object remainingDuration { get; internal set; } [Newtonsoft.Json.JsonProperty] public string message { get; internal set; } } @@ -362,6 +362,20 @@ internal CommandClass() { } public bool isSecure { get; internal set; } } + public class CommandClassInfo + { + internal CommandClassInfo() { } + + [Newtonsoft.Json.JsonProperty] + public bool isSupported { get; internal set; } + [Newtonsoft.Json.JsonProperty] + public bool isControlled { get; internal set; } + [Newtonsoft.Json.JsonProperty] + public bool secure { get; internal set; } + [Newtonsoft.Json.JsonProperty] + public int version { get; internal set; } + } + public class FirmwareVersion { internal FirmwareVersion() { } diff --git a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Utils.cs b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Utils.cs index 8d9f4b7..f4cbcf9 100644 --- a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Utils.cs +++ b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/Utils.cs @@ -19,30 +19,20 @@ internal Utils(Driver Driver) // Checked as of : 3.5.0 public Task ParseQRCodeString(string QR) { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); + var request = new Dictionary + { + { "command", Enums.Commands.ParseQRCodeString }, + { "qr", QR } + }; - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { QRProvisioningInformation PQR = JO.SelectToken("result.qrProvisioningInformation").ToObject(); Res.SetPayload(PQR); } - Result.SetResult(Res); }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.ParseQRCodeString); - Request.Add("qr", QR); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } } } diff --git a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/VirtualNode.cs b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/VirtualNode.cs index aa67019..bfadde4 100644 --- a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/VirtualNode.cs +++ b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/VirtualNode.cs @@ -17,152 +17,102 @@ internal VirtualNode(Driver driver, int[] Nodes) // Checked as of : 3.5.0 public Task GetEndpointCount() { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); + var request = new Dictionary + { + { "command", Enums.Commands.MCGetEndpointCount }, + { "nodeIDs", this.Nodes } + }; - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Res.SetPayload(JO.SelectToken("result.count").ToObject()); } - Result.SetResult(Res); }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.MCGetEndpointCount); - Request.Add("nodeIDs", this.Nodes); - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task SetValue(ValueID ValueID, object Value, SetValueAPIOptions Options = null) { - Guid ID = Guid.NewGuid(); + var request = new Dictionary + { + { "command", Enums.Commands.MCSetValue }, + { "nodeIDs", this.Nodes }, + { "valueId", ValueID }, + { "value", Value } + }; + + if (Options != null) + { + request.Add("options", Options); + } - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Res.SetPayload(JO.SelectToken("result.result").ToObject()); } - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.MCSetValue); - Request.Add("nodeIDs", this.Nodes); - Request.Add("valueId", ValueID); - Request.Add("value", Value); - - if (Options != null) - { - Request.Add("options", Options); - } - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task GetDefinedValueIDs() { - Guid ID = Guid.NewGuid(); + var request = new Dictionary + { + { "command", Enums.Commands.MCGetDefinedValueIDs }, + { "nodeIDs", this.Nodes } + }; - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Res.SetPayload(JO.SelectToken("result.valueIDs").ToObject()); } - - Result.SetResult(Res); }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.MCGetDefinedValueIDs); - Request.Add("nodeIDs", this.Nodes); - - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task SupportsCCAPI(int CommandClass) { - Guid ID = Guid.NewGuid(); + var request = new Dictionary + { + { "command", Enums.Commands.MCSupportsCCAPI }, + { "nodeIDs", this.Nodes }, + { "commandClass", CommandClass } + }; - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Res.SetPayload(JO.SelectToken("result.supported").ToObject()); - } - Result.SetResult(Res); }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.MCSupportsCCAPI); - Request.Add("nodeIDs", this.Nodes); - Request.Add("commandClass", CommandClass); - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } - + // Checked as of : 3.5.0 public Task InvokeCCAPI(int CommandClass, string Method, params object[] Params) { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary + { + { "command", Enums.Commands.MCInvokeCCAPI }, + { "nodeIDs", this.Nodes }, + { "commandClass", CommandClass }, + { "methodName", Method }, + { "args", Params } + }; + + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Res.SetPayload(JO.SelectToken("result").ToObject()); } - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.MCInvokeCCAPI); - Request.Add("nodeIDs", this.Nodes); - Request.Add("commandClass", CommandClass); - Request.Add("methodName", Method); - Request.Add("args", Params); - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } private int[] Nodes { get; set; } diff --git a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/ZWaveNode.cs b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/ZWaveNode.cs index d53ed43..0766c46 100644 --- a/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/ZWaveNode.cs +++ b/Visual Studio Projects/ZWaveJS.NET/ZWaveJS.NET/ZWaveNode.cs @@ -158,54 +158,31 @@ internal void Trigger_NodeInterviewFailed(NodeInterviewFailedEventArgs Args) // Checked as of : 3.5.0 public Task Ping() { - Guid ID = Guid.NewGuid(); + var request = new Dictionary + { + { "command", Enums.Commands.Ping }, + { "nodeId", this.id } + }; - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Res.SetPayload(JO.SelectToken("result.responded").ToObject()); } - - Result.SetResult(Res); }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.Ping); - Request.Add("nodeId", this.id); - - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task Interview() { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.Interview); - Request.Add("nodeId", this.id); - - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + { "command", Enums.Commands.Interview }, + { "nodeId", this.id } + }; - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 @@ -213,468 +190,287 @@ public Task CheckLifelineHealth(int Rounds, LifelineHealthCheckProgre { LifelineHealthCheckProgressSub = OnProgress; - Guid ID = Guid.NewGuid(); + var request = new Dictionary + { + { "command", Enums.Commands.CheckLifelineHealth }, + { "nodeId", this.id }, + { "rounds", Rounds } + }; - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { LifelineHealthCheckSummary LLHCS = JO.SelectToken("result.summary").ToObject(); Res.SetPayload(LLHCS); } - - Result.SetResult(Res); }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.CheckLifelineHealth); - Request.Add("nodeId", this.id); - Request.Add("rounds", Rounds); - - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task AbortFirmwareUpdate() { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.AbortFirmwareUpdate); - Request.Add("nodeId", this.id); - - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + { "command", Enums.Commands.AbortFirmwareUpdate }, + { "nodeId", this.id } + }; - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 public Task UpdateFirmware(FirmwareUpdate[] Updates) { - foreach(FirmwareUpdate FWU in Updates) { if(FWU.firmwareTarget == null) { - TaskCompletionSource Fail = new TaskCompletionSource(); CMDResult Res = new CMDResult(Enums.ErrorCodes.WrongOverride, "Please use the override that includes 'firmwareTarget'", false); - Fail.SetResult(Res); - - return Fail.Task; + return Task.FromResult(Res); } } - Guid ID = Guid.NewGuid(); + var request = new Dictionary + { + { "command", Enums.Commands.UpdateFirmware }, + { "nodeId", this.id }, + { "updates", Updates } + }; - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Res.SetPayload(JO.SelectToken("result.result").ToObject()); } - - Result.SetResult(Res); }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.UpdateFirmware); - Request.Add("nodeId", this.id); - Request.Add("updates", Updates); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task RefreshInfo(RefreshInfoOptions Options = null) { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.RefreshInfo); - Request.Add("nodeId", this.id); - - if(Options != null) - Request.Add("options", Options); + { "command", Enums.Commands.RefreshInfo }, + { "nodeId", this.id } + }; - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + if (Options != null) + request.Add("options", Options); - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 public Task GetValue(ValueID ValueID) { - Guid ID = Guid.NewGuid(); + var request = new Dictionary + { + { "command", Enums.Commands.GetValue }, + { "valueId", ValueID }, + { "nodeId", this.id } + }; - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Res.SetPayload(JO.SelectToken("result").ToObject()); } - - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.GetValue); - Request.Add("valueId", ValueID); - Request.Add("nodeId", this.id); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task SetValue(ValueID ValueID, object Value, SetValueAPIOptions Options = null) { - Guid ID = Guid.NewGuid(); + var request = new Dictionary + { + { "command", Enums.Commands.SetValue }, + { "nodeId", this.id }, + { "valueId", ValueID }, + { "value", Value } + }; - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + if (Options != null) + { + request.Add("options", Options); + } + + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { SetValueResult SVR = JO.SelectToken("result.result").ToObject(); Res.SetPayload(SVR); } - Result.SetResult(Res); }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.SetValue); - Request.Add("nodeId", this.id); - Request.Add("valueId", ValueID); - Request.Add("value", Value); - - if (Options != null) - { - Request.Add("options", Options); - } - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task PollValue(ValueID ValueID) { - Guid ID = Guid.NewGuid(); + var request = new Dictionary + { + { "command", Enums.Commands.PollValue }, + { "nodeId", this.id }, + { "valueId", ValueID } + }; - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Res.SetPayload(JO.SelectToken("result").ToObject()); } - - Result.SetResult(Res); }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.PollValue); - Request.Add("nodeId", this.id); - Request.Add("valueId", ValueID); - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 - Variant 1: Normal parameter, defined in a config file public Task ZWJSS_SetRawConfigParameterValue(int Parameter, int Value) { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); + { "command", Enums.Commands.SetRawConfigParameterValue }, + { "nodeId", this.id }, + { "parameter", Parameter }, + { "value", Value } + }; - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.SetRawConfigParameterValue); - Request.Add("nodeId", this.id); - Request.Add("parameter", Parameter); - Request.Add("value", Value); - - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 - Variant 2: Normal parameter, not defined in a config file public Task ZWJSS_SetRawConfigParameterValue(int Parameter, int Value, int ValueSize, Enums.ConfigValueFormat ValueFormat) { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.SetRawConfigParameterValue); - Request.Add("nodeId", this.id); - Request.Add("parameter", Parameter); - Request.Add("value", Value); - Request.Add("valueSize", ValueSize); - Request.Add("valueFormat", ValueFormat); - + { "command", Enums.Commands.SetRawConfigParameterValue }, + { "nodeId", this.id }, + { "parameter", Parameter }, + { "value", Value }, + { "valueSize", ValueSize }, + { "valueFormat", ValueFormat } + }; - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 - Variant 3: Partial parameter, must be defined in a config file public Task ZWJSS_SetRawConfigParameterValue(int Parameter, int Bitmask, int Value) { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.SetRawConfigParameterValue); - Request.Add("nodeId", this.id); - Request.Add("parameter", Parameter); - Request.Add("bitMask", Bitmask); - Request.Add("value", Value); - - - string RequestPL = Newtonsoft.Json.JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + { "command", Enums.Commands.SetRawConfigParameterValue }, + { "nodeId", this.id }, + { "parameter", Parameter }, + { "bitMask", Bitmask }, + { "value", Value } + }; - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 public Task RefreshValues() { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.RefreshValues); - Request.Add("nodeId", this.id); - - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + { "command", Enums.Commands.RefreshValues }, + { "nodeId", this.id } + }; - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 public Task RefreshCCValues(int CommandClass) { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.RefreshCCValues); - Request.Add("commandClass", CommandClass); - Request.Add("nodeId", this.id); - + { "command", Enums.Commands.RefreshCCValues }, + { "commandClass", CommandClass }, + { "nodeId", this.id } + }; - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 public Task GetDefinedValueIDs() { - Guid ID = Guid.NewGuid(); + var request = new Dictionary + { + { "command", Enums.Commands.GetDefinedValueIDs }, + { "nodeId", this.id } + }; - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Res.SetPayload(JO.SelectToken("result.valueIds").ToObject()); } - - Result.SetResult(Res); }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.GetDefinedValueIDs); - Request.Add("nodeId", this.id); - - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task GetValueMetadata(ValueID VID) { - Guid ID = Guid.NewGuid(); + var request = new Dictionary + { + { "command", Enums.Commands.GetValueMetadata }, + { "nodeId", this.id }, + { "valueId", VID } + }; - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Res.SetPayload(JO.SelectToken("result").ToObject()); } - - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.GetValueMetadata); - Request.Add("nodeId", this.id); - Request.Add("valueId", VID); - - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task SupportsCCAPI(int CommandClass) { - Guid ID = Guid.NewGuid(); + var request = new Dictionary + { + { "command", Enums.Commands.SupportsCCAPI }, + { "nodeId", this.id }, + { "commandClass", CommandClass } + }; - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Res.SetPayload(JO.SelectToken("result.supported").ToObject()); - } - Result.SetResult(Res); }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.SupportsCCAPI); - Request.Add("nodeId", this.id); - Request.Add("commandClass", CommandClass); - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task InvokeCCAPI(int CommandClass, string Method, params object[] Params) { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary + { + { "command", Enums.Commands.InvokeCCAPI }, + { "nodeId", this.id }, + { "commandClass", CommandClass }, + { "methodName", Method }, + { "args", Params } + }; + + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Res.SetPayload(JO.SelectToken("result").ToObject()); } - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.InvokeCCAPI); - Request.Add("nodeId", this.id); - Request.Add("commandClass", CommandClass); - Request.Add("methodName", Method); - Request.Add("args", Params); - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } @@ -682,172 +478,101 @@ public Task InvokeCCAPI(int CommandClass, string Method, params objec // Checked as of : 3.5.0 public Task GetEndpointCount() { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); + var request = new Dictionary + { + { "command", Enums.Commands.GetEndpointCount }, + { "nodeId", this.id } + }; - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Res.SetPayload(JO.SelectToken("result.count").ToObject()); } - Result.SetResult(Res); }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.GetEndpointCount); - Request.Add("nodeId", this.id); - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task GetHighestSecurityClass() { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); + var request = new Dictionary + { + { "command", Enums.Commands.GetHighestSecurityClass }, + { "nodeId", this.id } + }; - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Enums.SecurityClass Value = JO.SelectToken("result.highestSecurityClass").ToObject(); Res.SetPayload(Value); } - Result.SetResult(Res); - - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.GetHighestSecurityClass); - Request.Add("nodeId", this.id); - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task HasSecurityClass(Enums.SecurityClass Class) { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); + var request = new Dictionary + { + { "command", Enums.Commands.HasSecurityClass }, + { "nodeId", this.id }, + { "securityClass", Class } + }; - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { Res.SetPayload(JO.SelectToken("result.hasSecurityClass").ToObject()); } - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.HasSecurityClass); - Request.Add("nodeId", this.id); - Request.Add("securityClass", Class); - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } // Checked as of : 3.5.0 public Task WaitForWakeup() { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.WaitForWakeUp); - Request.Add("nodeId", this.id); - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); + { "command", Enums.Commands.WaitForWakeUp }, + { "nodeId", this.id } + }; - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 public Task ManuallyIdleNotificationValue(ValueID VID) { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); + { "command", Enums.Commands.ManuallyIdleNotificationValue }, + { "nodeId", this.id }, + { "valueId", VID } + }; - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.ManuallyIdleNotificationValue); - Request.Add("nodeId", this.id); - Request.Add("valueId", VID); - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; + return _driver.SendRequestAsync(request); } // Checked as of : 3.5.0 public Task ManuallyIdleNotificationValue(int notificationType, int prevValue, int? endpointIndex = null) { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); - - _driver.Callbacks.Add(ID, (JO) => + var request = new Dictionary { - CMDResult Res = new CMDResult(JO); - Result.SetResult(Res); - - }); + { "command", Enums.Commands.ManuallyIdleNotificationValue }, + { "nodeId", this.id }, + { "notificationType", notificationType }, + { "prevValue", prevValue } + }; - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.ManuallyIdleNotificationValue); - Request.Add("nodeId", this.id); - Request.Add("notificationType", notificationType); - Request.Add("prevValue", prevValue); if (endpointIndex.HasValue) { - Request.Add("endpointIndex", endpointIndex.Value); + request.Add("endpointIndex", endpointIndex.Value); } - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; + return _driver.SendRequestAsync(request); } // LOCAL @@ -927,95 +652,62 @@ public Endpoint GetEndpoint(int Index) public bool keepAwake { get; internal set; } public Task SetKeepAwake(bool Option) { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); + var request = new Dictionary + { + { "command", Enums.Commands.KeepNodeAwake }, + { "nodeId", this.id }, + { "keepAwake", Option } + }; - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { this.keepAwake = Option; } - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.KeepNodeAwake); - Request.Add("nodeId", this.id); - Request.Add("keepAwake", Option); - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } [Newtonsoft.Json.JsonProperty] public string name { get; internal set; } public Task SetName(string Name, bool UpdateCC = true) { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); + var request = new Dictionary + { + { "command", Enums.Commands.SetName }, + { "nodeId", this.id }, + { "name", Name }, + { "updateCC", UpdateCC } + }; - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { this.name = Name; } - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.SetName); - Request.Add("nodeId", this.id); - Request.Add("name", Name); - Request.Add("updateCC", UpdateCC); - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } [Newtonsoft.Json.JsonProperty] public string location { get; internal set; } public Task SetLocation(string Location, bool UpdateCC = true) { - Guid ID = Guid.NewGuid(); - - TaskCompletionSource Result = new TaskCompletionSource(); + var request = new Dictionary + { + { "command", Enums.Commands.SetLocation }, + { "nodeId", this.id }, + { "location", Location }, + { "updateCC", UpdateCC } + }; - _driver.Callbacks.Add(ID, (JO) => + return _driver.SendRequestAsync(request, (JO, Res) => { - CMDResult Res = new CMDResult(JO); if (Res.Success) { this.location = Location; } - Result.SetResult(Res); - }); - - Dictionary Request = new Dictionary(); - Request.Add("messageId", ID); - Request.Add("command", Enums.Commands.SetLocation); - Request.Add("nodeId", this.id); - Request.Add("location", Location); - Request.Add("updateCC", UpdateCC); - - string RequestPL = JsonConvert.SerializeObject(Request); - _driver.ClientWebSocket.SendInstant(RequestPL); - - return Result.Task; } }