Skip to content

Commit a9bfa25

Browse files
committed
Implement Protection v1
1 parent 7dda002 commit a9bfa25

File tree

6 files changed

+188
-3
lines changed

6 files changed

+188
-3
lines changed

SupportedCommandClasses.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ DCP_CONFIG | 0 | 1 | None
2222
DCP_MONITOR | 0 | 1 | None
2323
**DEVICE_RESET_LOCALLY** | **1** | **1** | **Full**
2424
**DOOR_LOCK** | **4** | **4** | **Full**
25-
DOOR_LOCK_LOGGING | 0 | 1 | None
25+
**DOOR_LOCK_LOGGING** | **1** | **1** | **Full**
2626
**ENERGY_PRODUCTION** | **1** | **1** | **Full**
2727
**ENTRY_CONTROL** | **1** | **1** | **Full**
2828
*FIRMWARE_UPDATE_MD* | *1* | *8* | *Partial*
@@ -55,7 +55,7 @@ METER_TBL_PUSH | 0 | 1 | None
5555
**NOTIFICATION** | **8** | **8** | **Full**
5656
PREPAYMENT | 0 | 1 | None
5757
**PROPRIETARY** | **1** | **1** | **Full**
58-
PROTECTION | 0 | 2 | None
58+
*PROTECTION* | *1* | *2* | *Full*
5959
RATE_TBL_CONFIG | 0 | 1 | None
6060
RATE_TBL_MONITOR | 0 | 1 | None
6161
**SCENE_ACTIVATION** | **1** | **1** | **Full**
@@ -98,5 +98,5 @@ TARIFF_TBL_MONITOR | 0 | 1 | None
9898
**WINDOW_COVERING** | **1** | **1** | **Full**
9999
**ZWAVEPLUS_INFO** | **2** | **2** | **Full**
100100

101-
- Full Support for 71/97 Command Classes.
101+
- Full Support for 73/97 Command Classes.
102102
- Partial Support for 2/97 Command Classes.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// ZWaveDotNet Copyright (C) 2024
2+
//
3+
// This program is free software: you can redistribute it and/or modify
4+
// it under the terms of the GNU Affero General Public License as published by
5+
// the Free Software Foundation, either version 3 of the License, or any later version.
6+
// This program is distributed in the hope that it will be useful,
7+
// but WITHOUT ANY WARRANTY, without even the implied warranty of
8+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9+
// See the GNU Affero General Public License for more details.
10+
// You should have received a copy of the GNU Affero General Public License
11+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
12+
13+
using System.Buffers.Binary;
14+
using System.Data;
15+
using ZWaveDotNet.CommandClasses.Enums;
16+
using ZWaveDotNet.CommandClassReports.Enums;
17+
using ZWaveDotNet.Util;
18+
19+
namespace ZWaveDotNet.CommandClassReports
20+
{
21+
public class ProtectionReport : ICommandClassReport
22+
{
23+
public readonly LocalProtectionState LocalControl;
24+
public readonly RFProtectionState RemoteControl;
25+
26+
internal ProtectionReport(Span<byte> payload)
27+
{
28+
if (payload.Length < 1)
29+
throw new DataException($"The Protection Report was not in the expected format. Payload: {MemoryUtil.Print(payload)}");
30+
31+
//Version 1
32+
LocalControl = (LocalProtectionState)(payload[0] & 0xF);
33+
34+
//Version 2
35+
if (payload.Length > 1)
36+
RemoteControl = (RFProtectionState)(payload[1] & 0xF);
37+
else
38+
RemoteControl = RFProtectionState.Unprotected;
39+
}
40+
41+
public override string ToString()
42+
{
43+
return $"Protection State:{LocalControl}";
44+
}
45+
}
46+
}

ZWaveDotNet/CommandClasses/CommandClassBase.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ public static CommandClassBase Create(CommandClass cc, Node node, byte endpoint,
116116
return new DeviceResetLocally(node);
117117
case CommandClass.DoorLock:
118118
return new DoorLock(node, endpoint);
119+
case CommandClass.DoorLockLogging:
120+
return new DoorLockLogging(node, endpoint);
119121
case CommandClass.EnergyProduction:
120122
return new EnergyProduction(node, endpoint);
121123
case CommandClass.EntryControl:
@@ -168,6 +170,8 @@ public static CommandClassBase Create(CommandClass cc, Node node, byte endpoint,
168170
//Covered in Alarm
169171
case CommandClass.Proprietary:
170172
return new Proprietary(node, endpoint);
173+
case CommandClass.Protection:
174+
return new Protection(node, endpoint);
171175
case CommandClass.SceneActivation:
172176
return new SceneActivation(node, endpoint);
173177
case CommandClass.SceneActuatorConf:
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// ZWaveDotNet Copyright (C) 2024
2+
//
3+
// This program is free software: you can redistribute it and/or modify
4+
// it under the terms of the GNU Affero General Public License as published by
5+
// the Free Software Foundation, either version 3 of the License, or any later version.
6+
// This program is distributed in the hope that it will be useful,
7+
// but WITHOUT ANY WARRANTY, without even the implied warranty of
8+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9+
// See the GNU Affero General Public License for more details.
10+
// You should have received a copy of the GNU Affero General Public License
11+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
12+
13+
namespace ZWaveDotNet.CommandClasses.Enums
14+
{
15+
public enum LocalProtectionState
16+
{
17+
Unprotected = 0x0,
18+
ProtectedBySequence = 0x1,
19+
NoOperationPossible = 0x2
20+
}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// ZWaveDotNet Copyright (C) 2024
2+
//
3+
// This program is free software: you can redistribute it and/or modify
4+
// it under the terms of the GNU Affero General Public License as published by
5+
// the Free Software Foundation, either version 3 of the License, or any later version.
6+
// This program is distributed in the hope that it will be useful,
7+
// but WITHOUT ANY WARRANTY, without even the implied warranty of
8+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9+
// See the GNU Affero General Public License for more details.
10+
// You should have received a copy of the GNU Affero General Public License
11+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
12+
13+
namespace ZWaveDotNet.CommandClasses.Enums
14+
{
15+
public enum RFProtectionState
16+
{
17+
Unprotected = 0x0,
18+
IgnoreRuntimeCommands = 0x1,
19+
NoRF = 0x2
20+
}
21+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// ZWaveDotNet Copyright (C) 2024
2+
//
3+
// This program is free software: you can redistribute it and/or modify
4+
// it under the terms of the GNU Affero General Public License as published by
5+
// the Free Software Foundation, either version 3 of the License, or any later version.
6+
// This program is distributed in the hope that it will be useful,
7+
// but WITHOUT ANY WARRANTY, without even the implied warranty of
8+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9+
// See the GNU Affero General Public License for more details.
10+
// You should have received a copy of the GNU Affero General Public License
11+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
12+
13+
using Serilog;
14+
using System.Collections;
15+
using ZWaveDotNet.CommandClasses.Enums;
16+
using ZWaveDotNet.CommandClassReports;
17+
using ZWaveDotNet.CommandClassReports.Enums;
18+
using ZWaveDotNet.Entities;
19+
using ZWaveDotNet.Enums;
20+
using ZWaveDotNet.SerialAPI;
21+
22+
namespace ZWaveDotNet.CommandClasses
23+
{
24+
/// <summary>
25+
/// The Protection Command Class version 1 used to protect a device against unintentional control by e.g. a child.
26+
/// </summary>
27+
[CCVersion(CommandClass.Protection, 1)]
28+
public class Protection : CommandClassBase
29+
{
30+
public event CommandClassEvent<ProtectionReport>? Report;
31+
32+
enum ProtectionCommand : byte
33+
{
34+
Set = 0x1,
35+
Get = 0x2,
36+
Report = 0x3,
37+
SupportedGet = 0x4,
38+
SupportedReport = 0x5,
39+
ECSet = 0x6,
40+
ECGet = 0x7,
41+
ECReport = 0x8,
42+
TimeoutSet = 0x9,
43+
TimeoutGet = 0x10,
44+
TimeoutReport = 0x11,
45+
}
46+
47+
public Protection(Node node, byte endpoint) : base(node, endpoint, CommandClass.Protection) { }
48+
49+
/// <summary>
50+
/// <b>Version 1</b>: Request the protection state from a device.
51+
/// </summary>
52+
/// <param name="cancellationToken"></param>
53+
/// <returns></returns>
54+
public async Task<ProtectionReport> Get(CancellationToken cancellationToken = default)
55+
{
56+
ReportMessage response = await SendReceive(ProtectionCommand.Get, ProtectionCommand.Report, cancellationToken);
57+
return new ProtectionReport(response.Payload.Span);
58+
}
59+
60+
/// <summary>
61+
/// <b>Version 1</b>: Set the protection state in a device.
62+
/// </summary>
63+
/// <param name="protectionState"></param>
64+
/// <param name="cancellationToken"></param>
65+
/// <returns></returns>
66+
public async Task Set(LocalProtectionState protectionState, CancellationToken cancellationToken = default)
67+
{
68+
await SendCommand(ProtectionCommand.Set, cancellationToken, (byte)protectionState);
69+
}
70+
71+
/// <summary>
72+
/// <b>Version 2</b>: Set the protection state in a device.
73+
/// </summary>
74+
/// <param name="protectionState"></param>
75+
/// <param name="cancellationToken"></param>
76+
/// <returns></returns>
77+
public async Task Set(LocalProtectionState localProtection, RFProtectionState remoteProtection, CancellationToken cancellationToken = default)
78+
{
79+
await SendCommand(ProtectionCommand.Set, cancellationToken, (byte)localProtection, (byte)remoteProtection);
80+
}
81+
82+
protected override async Task<SupervisionStatus> Handle(ReportMessage message)
83+
{
84+
if (message.Command == (byte)ProtectionCommand.Report)
85+
{
86+
ProtectionReport rpt = new ProtectionReport(message.Payload.Span);
87+
await FireEvent(Report, rpt);
88+
return SupervisionStatus.Success;
89+
}
90+
return SupervisionStatus.NoSupport;
91+
}
92+
}
93+
}

0 commit comments

Comments
 (0)