Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion bundles/org.openhab.binding.matter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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% | |
Expand Down Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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:
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,19 @@
<channel-type id="doorlock-lockstate">
<item-type>Switch</item-type>
<label>Door Lock State</label>
<description>Locks and unlocks the door and maintains the lock state</description>
<description>Locks and unlocks the door and maintains the lock state. If the door lock supports unbolting, this will
reflect the latched state.</description>
<tags>
<tag>Status</tag>
<tag>LockState</tag>
</tags>
<autoUpdatePolicy>veto</autoUpdatePolicy>
</channel-type>

<channel-type id="doorlock-boltstate">
<item-type>Switch</item-type>
<label>Door Bolt State</label>
<description>Bolts and unbolts the door and maintains the bolt state.</description>
<tags>
<tag>Status</tag>
<tag>LockState</tag>
Expand Down