diff --git a/bundles/org.openhab.binding.matter/README.md b/bundles/org.openhab.binding.matter/README.md
index 25c1fe13cc7d4..6d717847d8f38 100644
--- a/bundles/org.openhab.binding.matter/README.md
+++ b/bundles/org.openhab.binding.matter/README.md
@@ -227,9 +227,10 @@ Possible channels include:
| colorcontrol-temperature | Dimmer | Color Temperature | Sets the color temperature of the light | ColorLight | | | |
| colorcontrol-temperature-abs | Number:Temperature | Color Temperature | Sets the color temperature of the light in mirek | ColorLight | | %.0f %unit% | |
| doorlock-alarm | Trigger | Door Lock Alarm | Event that fires when a lock alarm occurs | | | | 0=Lock Jammed, 1=Lock Factory Reset, 3=Lock Radio Power Cycled, 4=Wrong Code Entry Limit, 5=Front Escutcheon Removed, 6=Door Forced Open, 7=Door Ajar, 8=Forced User |
+| doorlock-boltstate | Switch | Door Bolt State | Bolts and unbolts the door and maintains the bolt state | Door | | | |
| doorlock-doorstate | Contact | Door Sensor State | Door Sensor State | Door | true | | |
| doorlock-lockoperationerror | Trigger | Lock Operation Error | Event that fires when a lock operation error occurs | | | | 0=Lock, 1=Unlock, 2=Non Access User Event, 3=Forced User Event, 4=Unlatch |
-| doorlock-lockstate | Switch | Door Lock State | Locks and unlocks the door and maintains the lock state | Door | | | |
+| doorlock-lockstate | Switch | Door Lock State | Locks and unlocks the door and maintains the lock state. If the door lock supports unbolting, this will reflect the latched state. | Door | | | |
| electricalenergymeasurement-cumulativeenergyexported-energy | Number:Energy | Cumulative Energy Exported | The cumulative energy exported measurement | Energy | true | %.1f %unit% | |
| electricalenergymeasurement-cumulativeenergyimported-energy | Number:Energy | Cumulative Energy Imported | The cumulative energy imported measurement | Energy | true | %.1f %unit% | |
| electricalenergymeasurement-energymeasurmement-energy | Number:Energy | Energy | The measured energy | Energy | true | %.1f %unit% | |
@@ -308,6 +309,7 @@ Possible channels include:
| threadnetworkdiagnostics-routingrole | Number | Routing Role | The Thread routing role | Network | true | %d | 0=Unspecified, 1=Unassigned, 2=Sleepy End Device, 3=End Device, 4=Reed, 5=Router, 6=Leader |
| wifinetworkdiagnostics-rssi | Number:Power | Signal | Wi-Fi signal strength indicator. | QualityOfService | true | %d %unit% | |
| windowcovering-lift | Rollershutter | Window Covering Lift | Sets the window covering level - supporting open/close and up/down type commands | Blinds | | %.0f %% | |
+>>>>>>> main
## Supported Matter Device Types
diff --git a/bundles/org.openhab.binding.matter/src/main/java/org/openhab/binding/matter/internal/MatterBindingConstants.java b/bundles/org.openhab.binding.matter/src/main/java/org/openhab/binding/matter/internal/MatterBindingConstants.java
index 853997fdb067f..c7290607bafe8 100644
--- a/bundles/org.openhab.binding.matter/src/main/java/org/openhab/binding/matter/internal/MatterBindingConstants.java
+++ b/bundles/org.openhab.binding.matter/src/main/java/org/openhab/binding/matter/internal/MatterBindingConstants.java
@@ -196,6 +196,9 @@ public class MatterBindingConstants {
public static final String CHANNEL_ID_DOORLOCK_STATE = "doorlock-lockstate";
public static final ChannelTypeUID CHANNEL_DOORLOCK_STATE = new ChannelTypeUID(BINDING_ID,
CHANNEL_ID_DOORLOCK_STATE);
+ public static final String CHANNEL_ID_DOORLOCK_BOLTSTATE = "doorlock-boltstate";
+ public static final ChannelTypeUID CHANNEL_DOORLOCK_BOLTSTATE = new ChannelTypeUID(BINDING_ID,
+ CHANNEL_ID_DOORLOCK_BOLTSTATE);
public static final String CHANNEL_ID_DOORLOCK_DOORSTATE = "doorlock-doorstate";
public static final ChannelTypeUID CHANNEL_DOORLOCK_DOORSTATE = new ChannelTypeUID(BINDING_ID,
CHANNEL_ID_DOORLOCK_DOORSTATE);
diff --git a/bundles/org.openhab.binding.matter/src/main/java/org/openhab/binding/matter/internal/controller/devices/converter/DoorLockConverter.java b/bundles/org.openhab.binding.matter/src/main/java/org/openhab/binding/matter/internal/controller/devices/converter/DoorLockConverter.java
index 6b5f29314deae..080f1970fd625 100644
--- a/bundles/org.openhab.binding.matter/src/main/java/org/openhab/binding/matter/internal/controller/devices/converter/DoorLockConverter.java
+++ b/bundles/org.openhab.binding.matter/src/main/java/org/openhab/binding/matter/internal/controller/devices/converter/DoorLockConverter.java
@@ -63,6 +63,7 @@
import org.openhab.core.types.StateDescription;
import org.openhab.core.types.StateDescriptionFragmentBuilder;
import org.openhab.core.types.StateOption;
+import org.openhab.core.types.UnDefType;
/**
* A converter for translating {@link DoorLockCluster} events and attributes to
@@ -189,15 +190,32 @@ public DoorLockConverter(DoorLockCluster cluster, MatterBaseThingHandler handler
channels.put(doorStateChannel, null);
}
+ if (initializingCluster.featureMap.unbolting) {
+ Channel boltStateChannel = ChannelBuilder
+ .create(new ChannelUID(channelGroupUID, CHANNEL_ID_DOORLOCK_BOLTSTATE), CoreItemFactory.SWITCH)
+ .withType(CHANNEL_DOORLOCK_BOLTSTATE).build();
+ channels.put(boltStateChannel, null);
+ }
+
return channels;
}
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
if (command instanceof OnOffType onOffType) {
+ String channelId = channelUID.getIdWithoutGroup();
OctetString pinCode = getPinCodeForRemoteOperation();
- ClusterCommand doorLockCommand = onOffType == OnOffType.ON ? DoorLockCluster.lockDoor(pinCode)
- : DoorLockCluster.unlockDoor(pinCode);
+ ClusterCommand doorLockCommand;
+
+ if (channelId.equals(CHANNEL_ID_DOORLOCK_BOLTSTATE)) {
+ // Bolt state: lock (bolt) or unbolt
+ doorLockCommand = onOffType == OnOffType.ON ? DoorLockCluster.lockDoor(pinCode)
+ : DoorLockCluster.unboltDoor(pinCode);
+ } else {
+ // Lock state: lock or unlock (which unlatches)
+ doorLockCommand = onOffType == OnOffType.ON ? DoorLockCluster.lockDoor(pinCode)
+ : DoorLockCluster.unlockDoor(pinCode);
+ }
handler.sendClusterCommand(endpointNumber, DoorLockCluster.CLUSTER_NAME, doorLockCommand);
}
super.handleCommand(channelUID, command);
@@ -208,8 +226,7 @@ public void onEvent(AttributeChangedMessage message) {
switch (message.path.attributeName) {
case DoorLockCluster.ATTRIBUTE_LOCK_STATE:
if (message.value instanceof DoorLockCluster.LockStateEnum lockState) {
- updateState(CHANNEL_ID_DOORLOCK_STATE,
- lockState == DoorLockCluster.LockStateEnum.LOCKED ? OnOffType.ON : OnOffType.OFF);
+ updateLockState(lockState);
}
break;
case DoorLockCluster.ATTRIBUTE_DOOR_STATE:
@@ -277,8 +294,7 @@ public void onEvent(EventTriggeredMessage message) {
@Override
public void initState() {
- updateState(CHANNEL_ID_DOORLOCK_STATE,
- initializingCluster.lockState == DoorLockCluster.LockStateEnum.LOCKED ? OnOffType.ON : OnOffType.OFF);
+ updateLockState(initializingCluster.lockState);
if (initializingCluster.featureMap.doorPositionSensor) {
updateState(CHANNEL_ID_DOORLOCK_DOORSTATE,
@@ -964,4 +980,42 @@ private String buildPinCodePattern(int minLength, int maxLength) {
private String buildPinCodeDescription(String descriptionKey) {
return handler.getTranslation(descriptionKey, minPinCodeLength, maxPinCodeLength);
}
+
+ /**
+ * Updates the lock state and bolt state channels based on the lock state enum.
+ *
+ * @param lockState The lock state from the door lock cluster
+ */
+ private void updateLockState(DoorLockCluster.LockStateEnum lockState) {
+ switch (lockState) {
+ case LOCKED:
+ // Both the lock and bolt state are locked
+ updateState(CHANNEL_ID_DOORLOCK_STATE, OnOffType.ON);
+ if (initializingCluster.featureMap.unbolting) {
+ updateState(CHANNEL_ID_DOORLOCK_BOLTSTATE, OnOffType.ON);
+ }
+ break;
+ case UNLOCKED:
+ // Both the lock and bolt state are unlocked
+ updateState(CHANNEL_ID_DOORLOCK_STATE, OnOffType.OFF);
+ if (initializingCluster.featureMap.unbolting) {
+ updateState(CHANNEL_ID_DOORLOCK_BOLTSTATE, OnOffType.OFF);
+ }
+ break;
+ case UNLATCHED:
+ // The lock state is locked (latched), but the bolt state is unlocked
+ updateState(CHANNEL_ID_DOORLOCK_STATE, OnOffType.ON);
+ if (initializingCluster.featureMap.unbolting) {
+ updateState(CHANNEL_ID_DOORLOCK_BOLTSTATE, OnOffType.OFF);
+ }
+ break;
+ case NOT_FULLY_LOCKED:
+ // We don't know the state of the lock or bolt, something is wrong
+ updateState(CHANNEL_ID_DOORLOCK_STATE, UnDefType.UNDEF);
+ if (initializingCluster.featureMap.unbolting) {
+ updateState(CHANNEL_ID_DOORLOCK_BOLTSTATE, UnDefType.UNDEF);
+ }
+ break;
+ }
+ }
}
diff --git a/bundles/org.openhab.binding.matter/src/main/resources/OH-INF/i18n/matter.properties b/bundles/org.openhab.binding.matter/src/main/resources/OH-INF/i18n/matter.properties
index 46cdaf0c3dd48..85a8351d1744d 100644
--- a/bundles/org.openhab.binding.matter/src/main/resources/OH-INF/i18n/matter.properties
+++ b/bundles/org.openhab.binding.matter/src/main/resources/OH-INF/i18n/matter.properties
@@ -83,12 +83,14 @@ channel-type.matter.concentrationmeasurement-peakmeasuredvalue.label = Peak Conc
channel-type.matter.concentrationmeasurement-peakmeasuredvalue.description = Indicates the peak (maximum) concentration measured during the measurement window.
channel-type.matter.doorlock-alarm.label = Door Lock Alarm
channel-type.matter.doorlock-alarm.description = Event that fires when a lock alarm occurs with a payload containing the alarm code
+channel-type.matter.doorlock-boltstate.label = Door Bolt State
+channel-type.matter.doorlock-boltstate.description = Bolts and unbolts the door and maintains the bolt state.
channel-type.matter.doorlock-doorstate.label = Door Sensor State
channel-type.matter.doorlock-doorstate.description = Door Sensor State
channel-type.matter.doorlock-lockoperationerror.label = Door Lock Lock Operation Error
channel-type.matter.doorlock-lockoperationerror.description = Event that fires when a lock operation error occurs with a payload containing the lock operation type
channel-type.matter.doorlock-lockstate.label = Door Lock State
-channel-type.matter.doorlock-lockstate.description = Locks and unlocks the door and maintains the lock state
+channel-type.matter.doorlock-lockstate.description = Locks and unlocks the door and maintains the lock state. If the door lock supports unbolting, this will reflect the latched state.
channel-type.matter.electricalenergymeasurement-energymeasurmement-energy.label = Energy
channel-type.matter.electricalpowermeasurement-activecurrent.label = Active Current
channel-type.matter.electricalpowermeasurement-activepower.label = Active Power
diff --git a/bundles/org.openhab.binding.matter/src/main/resources/OH-INF/thing/channels.xml b/bundles/org.openhab.binding.matter/src/main/resources/OH-INF/thing/channels.xml
index 8e00aff4b23b6..78bb8528dfd73 100644
--- a/bundles/org.openhab.binding.matter/src/main/resources/OH-INF/thing/channels.xml
+++ b/bundles/org.openhab.binding.matter/src/main/resources/OH-INF/thing/channels.xml
@@ -393,7 +393,19 @@
Switch
- Locks and unlocks the door and maintains the lock state
+ Locks and unlocks the door and maintains the lock state. If the door lock supports unbolting, this will
+ reflect the latched state.
+
+ Status
+ LockState
+
+ veto
+
+
+
+ Switch
+
+ Bolts and unbolts the door and maintains the bolt state.StatusLockState