Skip to content

Commit dfb8d42

Browse files
committed
GetCommandClass is no longer nullable
1 parent 196cbe4 commit dfb8d42

File tree

9 files changed

+33
-34
lines changed

9 files changed

+33
-34
lines changed

Examples.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,33 +48,32 @@ _Line 2 Begins smart start inclusion._
4848
The list of command classes can be enumerated or you can get a specific command class directly and call commands.
4949
```c#
5050
CancellationTokenSource cts = new CancellationTokenSource(5000);
51-
List<CommandClass> lst = await controller.Nodes[3].GetCommandClass<Security2>()!.GetSupportedCommands(cts.Token);
51+
List<CommandClass> lst = await controller.Nodes[3].GetCommandClass<Security2>().GetSupportedCommands(cts.Token);
5252
```
5353

5454
#### Notifications:
5555
Command classes have events which can be subscribed to for events/notifications.
5656
```c#
57-
controller.Nodes[3].GetCommandClass<Meter>()!.Update += Meter_Update;
57+
controller.Nodes[3].GetCommandClass<Meter>().Update += Meter_Update;
5858

59-
async Task Meter_Update(Node sender, CommandClassEventArgs args)
59+
async Task Meter_Updated(Node sender, CommandClassEventArgs<MeterReport> args)
6060
{
61-
MeterReport mr = (MeterReport)args.Report!;
62-
Console.WriteLine($"Meter Update: {mr.Value} {mr.Unit}");
61+
Console.WriteLine($"Meter Update: {args.Report!.Value} {args.Report!.Unit}");
6362
}
6463
```
6564

6665
#### Broadcast Commands:
6766
The controller contains a broadcast node with a set of command classes prepopulated. Broadcast commands do not reflect what command classes the network may or may not support.
6867
```c#
69-
await controller.BroadcastNode.GetCommandClass<SwitchBinary>()!.Set(true);
68+
await controller.BroadcastNode.GetCommandClass<SwitchBinary>().Set(true);
7069
```
7170
_This example turns on all switches in the network_
7271

7372
#### Multicast Commands:
7473
The controller can create Multicast Groups of multiple Nodes. Multicast Command Classes will be the minimum set supported by all group members.
7574
```c#
7675
1: NodeGroup group = controller.CreateGroup(node1, node2);
77-
2: await group.GetCommandClass<SwitchBinary>()!.Set(true, TimeSpan.FromSeconds(1));
76+
2: await group.GetCommandClass<SwitchBinary>().Set(true, TimeSpan.FromSeconds(1));
7877
```
7978
_Line 1 Creates a group with two members._\
80-
_Line 2 Turn on all binary switches in the group with a single multicast command._
79+
_Line 2 Turn on both binary switches in the group with a single multicast command._

TestConsole/TestConsole.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,19 +147,19 @@ private static async Task Controller_NodeReady(Node node)
147147
private static void AttachListeners(Node node)
148148
{
149149
if (node.HasCommandClass(CommandClass.SensorMultiLevel))
150-
node.GetCommandClass<SensorMultiLevel>()!.Updated += Node_Updated;
150+
node.GetCommandClass<SensorMultiLevel>().Updated += Node_Updated;
151151
if (node.HasCommandClass(CommandClass.Meter))
152152
node.GetCommandClass<Meter>()!.Updated += Node_Updated;
153153
if (node.HasCommandClass(CommandClass.Notification) && node.GetCommandClass<Notification>() is Notification not) //ZWave Weirdness
154154
not.Updated += Node_Updated;
155155
if (node.HasCommandClass(CommandClass.Battery))
156-
node.GetCommandClass<Battery>()!.Status += Node_Updated;
156+
node.GetCommandClass<Battery>().Status += Node_Updated;
157157
if (node.HasCommandClass(CommandClass.SensorBinary))
158-
node.GetCommandClass<SensorBinary>()!.Updated += Node_Updated;
158+
node.GetCommandClass<SensorBinary>().Updated += Node_Updated;
159159
if (node.HasCommandClass(CommandClass.SensorAlarm))
160-
node.GetCommandClass<SensorAlarm>()!.Alarm += Node_Updated;
160+
node.GetCommandClass<SensorAlarm>().Alarm += Node_Updated;
161161
if (node.HasCommandClass(CommandClass.SwitchBinary))
162-
node.GetCommandClass<SwitchBinary>()!.SwitchReport += Node_Updated;
162+
node.GetCommandClass<SwitchBinary>().SwitchReport += Node_Updated;
163163
}
164164

165165
private static Task Node_Updated<T>(Node sender, CommandClassEventArgs<T> args) where T : ICommandClassReport

ZWaveDotNet/CommandClasses/CommandClassBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,9 +357,9 @@ internal async Task<bool> SendCommand(CommandMessage data, CancellationToken tok
357357
throw new InvalidOperationException("Secure command requires security manager");
358358
SecurityManager.NetworkKey key = controller.SecurityManager.GetHighestKey(node.ID) ?? throw new InvalidOperationException($"Command classes are secure but no keys exist for node {node.ID}");
359359
if (key.Key == SecurityManager.RecordType.S0)
360-
await node.GetCommandClass<Security0>()!.Encapsulate(data.Payload, token).ConfigureAwait(false);
360+
await node.GetCommandClass<Security0>().Encapsulate(data.Payload, token).ConfigureAwait(false);
361361
else if (key.Key > SecurityManager.RecordType.S0)
362-
await node.GetCommandClass<Security2>()!.Encapsulate(data.Payload, key.Key, token).ConfigureAwait(false);
362+
await node.GetCommandClass<Security2>().Encapsulate(data.Payload, key.Key, token).ConfigureAwait(false);
363363
else
364364
throw new InvalidOperationException("Security required but no keys are available");
365365
}

ZWaveDotNet/CommandClasses/Security0.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ internal async Task Encapsulate(List<byte> payload, CancellationToken cancellati
169169
{
170170
Log.Verbose("Providing Next Nonce");
171171
using CancellationTokenSource cts = new CancellationTokenSource(3000);
172-
await controller.Nodes[msg.SourceNodeID].GetCommandClass<Security0>()!.SendCommand(Security0Command.NonceReport, cts.Token, controller.SecurityManager.CreateS0Nonce(msg.SourceNodeID)).ConfigureAwait(false);
172+
await controller.Nodes[msg.SourceNodeID].GetCommandClass<Security0>().SendCommand(Security0Command.NonceReport, cts.Token, controller.SecurityManager.CreateS0Nonce(msg.SourceNodeID)).ConfigureAwait(false);
173173
}
174174

175175
Log.Verbose("Decrypted: " + msg.ToString());

ZWaveDotNet/CommandClasses/Security2.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ internal async Task Encapsulate(List<byte> payload, SecurityManager.RecordType?
276276
else if (controller.SecurityManager.HasKey(msg.SourceNodeID, SecurityManager.RecordType.ECDH_TEMP))
277277
{
278278
using (CancellationTokenSource cts = new CancellationTokenSource(3000))
279-
await controller.Nodes[msg.SourceNodeID].GetCommandClass<Security2>()!.KexFail(KexFailType.KEX_FAIL_KEY_VERIFY).ConfigureAwait(false);
279+
await controller.Nodes[msg.SourceNodeID].GetCommandClass<Security2>().KexFail(KexFailType.KEX_FAIL_KEY_VERIFY).ConfigureAwait(false);
280280
if (networkKey.Key != SecurityManager.RecordType.ECDH_TEMP)
281281
controller.SecurityManager.RevokeKey(msg.SourceNodeID, networkKey.Key);
282282
return null;
@@ -288,7 +288,7 @@ internal async Task Encapsulate(List<byte> payload, SecurityManager.RecordType?
288288
Log.Warning("Declaring SPAN failed and sending SOS");
289289
controller.SecurityManager.PurgeRecords(msg.SourceNodeID, networkKey.Key);
290290
using (CancellationTokenSource cts = new CancellationTokenSource(3000))
291-
await controller.Nodes[msg.SourceNodeID].GetCommandClass<Security2>()!.SendNonceReport(true, false, false, cts.Token).ConfigureAwait(false);
291+
await controller.Nodes[msg.SourceNodeID].GetCommandClass<Security2>().SendNonceReport(true, false, false, cts.Token).ConfigureAwait(false);
292292
}
293293
catch (Exception e)
294294
{

ZWaveDotNet/CommandClasses/TransportService.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ internal static async Task<bool> Transmit (DataMessage message, CancellationToke
8282
for (int i = 0; i < message.Data.Count; i += MAX_SEGMENT)
8383
{
8484
DataMessage segment = new DataMessage(message.Controller, message.DestinationNodeID, message.Data.GetRange(i, Math.Min(message.Data.Count, i + MAX_SEGMENT) - i), true, (message.Options & TransmitOptions.ExploreNPDUs) == TransmitOptions.ExploreNPDUs);
85-
success &= await message.Controller.Nodes[message.SourceNodeID].GetCommandClass<TransportService>()!.TransmitSegment(segment, sessionId, i, message.Data.Count, token);
85+
success &= await message.Controller.Nodes[message.SourceNodeID].GetCommandClass<TransportService>().TransmitSegment(segment, sessionId, i, message.Data.Count, token);
8686
}
8787
return success;
8888
}
@@ -176,7 +176,7 @@ private async Task<bool> TransmitSegment(DataMessage msg, byte sessionId, int of
176176
if (!msg.IsMulticastMethod)
177177
{
178178
CancellationTokenSource cts = new CancellationTokenSource(5000);
179-
await controller.Nodes[msg.SourceNodeID].GetCommandClass<TransportService>()!.RequestRetransmission(sessionId, 0, cts.Token);
179+
await controller.Nodes[msg.SourceNodeID].GetCommandClass<TransportService>().RequestRetransmission(sessionId, 0, cts.Token);
180180
}
181181
return null;
182182
}
@@ -196,7 +196,7 @@ private async Task<bool> TransmitSegment(DataMessage msg, byte sessionId, int of
196196
buffers.Remove(key);
197197
segments.Remove(key);
198198
CancellationTokenSource cts = new CancellationTokenSource(5000);
199-
await controller.Nodes[msg.SourceNodeID].GetCommandClass<TransportService>()!.SendComplete(sessionId, cts.Token);
199+
await controller.Nodes[msg.SourceNodeID].GetCommandClass<TransportService>().SendComplete(sessionId, cts.Token);
200200
return fullMessage;
201201
}
202202
break;
@@ -232,7 +232,7 @@ internal override async Task<SupervisionStatus> Handle(ReportMessage msg)
232232
Log.Information("Retransmitting segment " + offset + " for session " + (msg.Payload.Span[0] >> 4));
233233

234234
DataMessage segment = new DataMessage(message.Controller, message.DestinationNodeID, message.Data.GetRange(offset, Math.Min(message.Data.Count, offset + MAX_SEGMENT) - offset), true, (message.Options & TransmitOptions.ExploreNPDUs) == TransmitOptions.ExploreNPDUs);
235-
await message.Controller.Nodes[message.SourceNodeID].GetCommandClass<TransportService>()!.TransmitSegment(segment, (byte)(msg.Payload.Span[0] >> 4), offset, message.Data.Count);
235+
await message.Controller.Nodes[message.SourceNodeID].GetCommandClass<TransportService>().TransmitSegment(segment, (byte)(msg.Payload.Span[0] >> 4), offset, message.Data.Count);
236236
}
237237
break;
238238
}
@@ -255,7 +255,7 @@ private static async Task<bool> CheckComplete(Controller controller, ushort sour
255255
if (requestMissing)
256256
{
257257
Log.Information($"Requesting retransmission for session {sessionId} at index {current}");
258-
await controller.Nodes[sourceNodeId].GetCommandClass<TransportService>()!.RequestRetransmission(sessionId, current, combo.Token);
258+
await controller.Nodes[sourceNodeId].GetCommandClass<TransportService>().RequestRetransmission(sessionId, current, combo.Token);
259259
}
260260
else
261261
Log.Information("Broadcast transport class was incomplete. Ignoring...");

ZWaveDotNet/Entities/Controller.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,7 @@ private async Task<bool> BootstrapS0(Node node)
835835
{
836836
try
837837
{
838-
Security0 sec0 = node.GetCommandClass<Security0>()!;
838+
Security0 sec0 = node.GetCommandClass<Security0>();
839839
await sec0.SchemeGet(cts.Token).ConfigureAwait(false);
840840
_ = Task.Run(() => sec0.KeySet(cts.Token));
841841
await sec0.WaitForKeyVerified(cts.Token).ConfigureAwait(false);
@@ -858,7 +858,7 @@ private async Task<bool> BootstrapS0(Node node)
858858
private async Task<bool> BootstrapS2(Node node)
859859
{
860860
await Task.Delay(1000); //Give including node a chance to get ready
861-
Security2 sec2 = node.GetCommandClass<Security2>()!;
861+
Security2 sec2 = node.GetCommandClass<Security2>();
862862
Log.Information("Starting Secure S2 Inclusion");
863863
try
864864
{

ZWaveDotNet/Entities/Node.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -306,18 +306,18 @@ public bool HasCommandClass(CommandClass commandClass)
306306
/// </summary>
307307
/// <typeparam name="T"></typeparam>
308308
/// <returns></returns>
309-
public T? GetCommandClass<T>() where T : CommandClassBase
309+
public T GetCommandClass<T>() where T : CommandClassBase
310310
{
311311
CommandClass commandClass = ((CCVersion)typeof(T).GetCustomAttribute(typeof(CCVersion))!).commandClass;
312312
if (commandClasses.TryGetValue(commandClass, out CommandClassBase? ccb))
313313
{
314314
if (typeof(T) == typeof(Notification) && ccb.Version <= 2)
315-
return null;
315+
throw new ArgumentException("Notification command class is not present. Fetch alarm instead");
316316
if (typeof(T) == typeof(Alarm) && ccb.Version > 2)
317-
return null;
317+
throw new ArgumentException("Alarm command class is not present. Fetch Notification instead");
318318
return (T)ccb;
319319
}
320-
return null;
320+
throw new ArgumentNullException("Command class does not exist on this node");
321321
}
322322

323323
internal NodeJSON Serialize()
@@ -537,7 +537,7 @@ private async Task Interview(bool newlyIncluded, SecurityManager.NetworkKey? key
537537
if (HasCommandClass(CommandClass.WakeUp))
538538
{
539539
Log.Information("Security query complete. Sleeping before continuing");
540-
await GetCommandClass<WakeUp>()!.WaitForAwake(cancellationToken);
540+
await GetCommandClass<WakeUp>().WaitForAwake(cancellationToken);
541541
}
542542
}
543543
else
@@ -552,10 +552,10 @@ private async Task Interview(bool newlyIncluded, SecurityManager.NetworkKey? key
552552
if (HasCommandClass(CommandClass.MultiChannel))
553553
{
554554
Log.Information("Requesting MultiChannel EndPoints");
555-
EndPointReport epReport = await GetCommandClass<MultiChannel>()!.GetEndPoints(cancellationToken);
555+
EndPointReport epReport = await GetCommandClass<MultiChannel>().GetEndPoints(cancellationToken);
556556
for (int i = 0; i < epReport.IndividualEndPoints; i++)
557557
{
558-
EndPointCapabilities caps = await GetCommandClass<MultiChannel>()!.GetCapabilities((byte)(i + 1), cancellationToken);
558+
EndPointCapabilities caps = await GetCommandClass<MultiChannel>().GetCapabilities((byte)(i + 1), cancellationToken);
559559
endPoints.Add(new EndPoint((byte)(i + 1), this, caps.CommandClasses));
560560
}
561561
}

ZWaveDotNet/Untested/FirmwareUpdate.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public async Task<FirmwareDataReport> GetData(byte numberOfReports, ushort repor
106106
public async Task DownloadAsync(string destination, CancellationToken cancellationToken = default)
107107
{
108108
FirmwareMetadataReport report = await Get(cancellationToken);
109-
VersionReport version = await node.GetCommandClass<Version>()!.Get(cancellationToken);
109+
VersionReport version = await node.GetCommandClass<Version>().Get(cancellationToken);
110110
Log.Information($"Downloading Manufacturer {report.Manufacturer}, Firmware {report.FirmwareIDs[0]}, Version {version.Firmware[0]}");
111111
using (FileStream fs = new FileStream(destination, FileMode.Create, FileAccess.Write))
112112
{
@@ -125,7 +125,7 @@ public async Task UploadAsync(string source, CancellationToken cancellationToken
125125
ushort checksum = 0x42; //TODO
126126

127127
FirmwareMetadataReport report = await Get(cancellationToken);
128-
VersionReport version = await node.GetCommandClass<Version>()!.Get(cancellationToken);
128+
VersionReport version = await node.GetCommandClass<Version>().Get(cancellationToken);
129129
Log.Information($"@Downloading Manufacturer {report.Manufacturer}, Firmware {report.FirmwareIDs[0]}, Version {version.Firmware[0]}, HW {report.HardwareVersion}");
130130
FirmwareUpdateStatus start = await StartUpdate(report.Manufacturer, report.FirmwareIDs[0], checksum, 0x0, 28, false, report.HardwareVersion, cancellationToken);
131131
if (start != FirmwareUpdateStatus.Success)

0 commit comments

Comments
 (0)