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
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
*/
@NonNullByDefault
public abstract class BaseDevice implements StateChangeListener {
// The "source" sent with command events so rules can identify them as coming from Matter
public static final String MATTER_SOURCE = "org.openhab.binding.matter";

protected final Logger logger = LoggerFactory.getLogger(getClass());

protected final GenericItem primaryItem;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public void updateState(Item item, State state) {
private void updateBrightness(PercentType brightness) {
if (primaryItem instanceof ColorItem colorItem) {
lastB = brightness;
colorItem.send(brightness);
colorItem.send(brightness, MATTER_SOURCE);
}
}

Expand All @@ -176,7 +176,7 @@ private synchronized void updateOnOff(boolean onOff) {
}
});
}
colorItem.send(OnOffType.from(onOff));
colorItem.send(OnOffType.from(onOff), MATTER_SOURCE);
}
}

Expand Down Expand Up @@ -212,7 +212,7 @@ private synchronized void updateHSB() {
if (b.intValue() == 0) {
b = new PercentType(100);
}
colorItem.send(new HSBType(h, s, b));
colorItem.send(new HSBType(h, s, b), MATTER_SOURCE);
}
this.lastH = null;
this.lastS = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,17 +120,17 @@ public void updateState(Item item, State state) {
private void updateOnOff(OnOffType onOffType) {
lastOnOffState = onOffType;
if (primaryItem instanceof GroupItem groupItem) {
groupItem.send(onOffType);
groupItem.send(onOffType, MATTER_SOURCE);
} else {
((SwitchItem) primaryItem).send(onOffType);
((SwitchItem) primaryItem).send(onOffType, MATTER_SOURCE);
}
}

private void updateLevel(PercentType level) {
if (primaryItem instanceof GroupItem groupItem) {
groupItem.send(level);
groupItem.send(level, MATTER_SOURCE);
} else {
((DimmerItem) primaryItem).send(level);
((DimmerItem) primaryItem).send(level, MATTER_SOURCE);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ public void handleMatterEvent(String clusterName, String attributeName, Object d
int lockInt = ((Double) data).intValue();
boolean locked = DoorLockCluster.LockStateEnum.LOCKED.getValue() == lockInt;
if (primaryItem instanceof GroupItem groupItem) {
groupItem.send(OnOffType.from(locked));
groupItem.send(OnOffType.from(locked), MATTER_SOURCE);
} else {
((SwitchItem) primaryItem).send(OnOffType.from(locked));
((SwitchItem) primaryItem).send(OnOffType.from(locked), MATTER_SOURCE);
}
}
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ public void handleMatterEvent(String clusterName, String attributeName, Object d
int mode = ((Double) data).intValue();
String mappedMode = fanModeMapper.toCustomValue(mode);
if (item instanceof NumberItem numberItem) {
numberItem.send(new DecimalType(mappedMode));
numberItem.send(new DecimalType(mappedMode), MATTER_SOURCE);
} else if (item instanceof StringItem stringItem) {
stringItem.send(new StringType(mappedMode));
stringItem.send(new StringType(mappedMode), MATTER_SOURCE);
} else if (item instanceof SwitchItem switchItem) {
switchItem.send(mode > 0 ? OnOffType.ON : OnOffType.OFF);
switchItem.send(mode > 0 ? OnOffType.ON : OnOffType.OFF, MATTER_SOURCE);
}
} catch (FanModeMappingException e) {
logger.debug("Could not convert {} to custom value", data);
Expand All @@ -90,15 +90,15 @@ public void handleMatterEvent(String clusterName, String attributeName, Object d
case FanControlCluster.ATTRIBUTE_PERCENT_SETTING:
int level = ((Double) data).intValue();
if (item instanceof GroupItem groupItem) {
groupItem.send(new PercentType(level));
groupItem.send(new PercentType(level), MATTER_SOURCE);
} else if (item instanceof DimmerItem dimmerItem) {
dimmerItem.send(new PercentType(level));
dimmerItem.send(new PercentType(level), MATTER_SOURCE);
}
break;
case OnOffCluster.ATTRIBUTE_ON_OFF:
if (item instanceof SwitchItem switchItem) {
OnOffType onOff = OnOffType.from((Boolean) data);
switchItem.send(onOff);
switchItem.send(onOff, MATTER_SOURCE);
lastOnOff = onOff;
}
break;
Expand All @@ -114,7 +114,7 @@ public void handleMatterEvent(String clusterName, String attributeName, Object d
GenericItem genericItem = itemForAttribute(OnOffCluster.CLUSTER_PREFIX,
OnOffCluster.ATTRIBUTE_ON_OFF);
if (genericItem instanceof SwitchItem switchItem) {
switchItem.send(OnOffType.from(level > 0));
switchItem.send(OnOffType.from(level > 0), MATTER_SOURCE);
}
// try and update the fan mode if set
genericItem = itemForAttribute(FanControlCluster.CLUSTER_PREFIX,
Expand All @@ -124,11 +124,11 @@ public void handleMatterEvent(String clusterName, String attributeName, Object d
.toCustomValue(level > 0 ? FanControlCluster.FanModeEnum.ON.getValue()
: FanControlCluster.FanModeEnum.OFF.getValue());
if (genericItem instanceof NumberItem numberItem) {
numberItem.send(new DecimalType(mappedMode));
numberItem.send(new DecimalType(mappedMode), MATTER_SOURCE);
} else if (genericItem instanceof StringItem stringItem) {
stringItem.send(new StringType(mappedMode));
stringItem.send(new StringType(mappedMode), MATTER_SOURCE);
} else if (genericItem instanceof SwitchItem switchItem) {
switchItem.send(OnOffType.from(level > 0));
switchItem.send(OnOffType.from(level > 0), MATTER_SOURCE);
}
} catch (FanModeMappingException e) {
logger.debug("Could not convert {} to custom value", data);
Expand All @@ -141,14 +141,14 @@ public void handleMatterEvent(String clusterName, String attributeName, Object d
FanControlCluster.ATTRIBUTE_PERCENT_SETTING);
PercentType level = mode > 0 ? PercentType.HUNDRED : PercentType.ZERO;
if (genericItem instanceof GroupItem groupItem) {
groupItem.send(level);
groupItem.send(level, MATTER_SOURCE);
} else if (genericItem instanceof DimmerItem dimmerItem) {
dimmerItem.send(level);
dimmerItem.send(level, MATTER_SOURCE);
}
// try and update the on/off state if set
genericItem = itemForAttribute(OnOffCluster.CLUSTER_PREFIX, OnOffCluster.ATTRIBUTE_ON_OFF);
if (genericItem instanceof SwitchItem switchItem) {
switchItem.send(OnOffType.from(mode > 0));
switchItem.send(OnOffType.from(mode > 0), MATTER_SOURCE);
}
}
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,26 +173,26 @@ private void updateMode(Integer mode) {
String value = modeMappings.get(mode);
if (value != null) {
if (primaryItem instanceof GroupItem groupItem) {
groupItem.send(new StringType(value));
groupItem.send(new StringType(value), MATTER_SOURCE);
} else if (primaryItem instanceof StringItem stringItem) {
stringItem.send(new StringType(value));
stringItem.send(new StringType(value), MATTER_SOURCE);
} else if (primaryItem instanceof NumberItem numberItem) {
numberItem.send(new DecimalType(value));
numberItem.send(new DecimalType(value), MATTER_SOURCE);
} else if (primaryItem instanceof SwitchItem switchItem) {
switchItem.send(OnOffType.from(value));
switchItem.send(OnOffType.from(value), MATTER_SOURCE);
} else if (primaryItem instanceof RollershutterItem rollershutterItem) {
switch (value.toUpperCase()) {
case "UP":
case "DOWN":
rollershutterItem.send(UpDownType.valueOf(value.toUpperCase()));
rollershutterItem.send(UpDownType.valueOf(value.toUpperCase()), MATTER_SOURCE);
break;
case "STOP":
case "MOVE":
rollershutterItem.send(StopMoveType.valueOf(value.toUpperCase()));
rollershutterItem.send(StopMoveType.valueOf(value.toUpperCase()), MATTER_SOURCE);
break;
default:
try {
rollershutterItem.send(new PercentType(Integer.parseInt(value)));
rollershutterItem.send(new PercentType(Integer.parseInt(value)), MATTER_SOURCE);
} catch (NumberFormatException ignored) {
}
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,18 @@ public void handleMatterEvent(String clusterName, String attributeName, Object d
switch (attributeName) {
case OnOffCluster.ATTRIBUTE_ON_OFF: {
if (primaryItem instanceof GroupItem groupItem) {
groupItem.send(OnOffType.from(Boolean.valueOf(data.toString())));
groupItem.send(OnOffType.from(Boolean.valueOf(data.toString())), MATTER_SOURCE);
} else if (primaryItem instanceof SwitchItem switchItem) {
switchItem.send(OnOffType.from(Boolean.valueOf(data.toString())));
switchItem.send(OnOffType.from(Boolean.valueOf(data.toString())), MATTER_SOURCE);
}
}
break;
case LevelControlCluster.ATTRIBUTE_CURRENT_LEVEL: {
OnOffType onOff = OnOffType.from(((Double) data).intValue() > 0);
if (primaryItem instanceof GroupItem groupItem) {
groupItem.send(onOff);
groupItem.send(onOff, MATTER_SOURCE);
} else if (primaryItem instanceof SwitchItem switchItem) {
switchItem.send(onOff);
switchItem.send(onOff, MATTER_SOURCE);
}
}
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,19 @@ public void handleMatterEvent(String clusterName, String attributeName, Object d
if (item instanceof NumberItem numberItem) {
QuantityType<Temperature> t = ValueUtils
.valueToTemperature(Float.valueOf(data.toString()).intValue());
numberItem.send(t);
numberItem.send(t, MATTER_SOURCE);
}
break;
case ThermostatCluster.ATTRIBUTE_SYSTEM_MODE:
try {
int mode = ((Double) data).intValue();
String mappedMode = systemModeMapper.toCustomValue(mode);
if (item instanceof NumberItem numberItem) {
numberItem.send(new DecimalType(mappedMode));
numberItem.send(new DecimalType(mappedMode), MATTER_SOURCE);
} else if (item instanceof StringItem stringItem) {
stringItem.send(new StringType(mappedMode));
stringItem.send(new StringType(mappedMode), MATTER_SOURCE);
} else if (item instanceof SwitchItem switchItem) {
switchItem.send(OnOffType.from(mode > 0));
switchItem.send(OnOffType.from(mode > 0), MATTER_SOURCE);
}
} catch (SystemModeMappingException e) {
logger.debug("Could not convert {} to custom value", data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,16 @@ public void handleMatterEvent(String clusterName, String attributeName, Object d
int targetPercent = percentType.intValue();
Metadata primaryItemMetadata = this.primaryItemMetadata;
if (primaryItem instanceof GroupItem groupItem) {
groupItem.send(percentType);
groupItem.send(percentType, MATTER_SOURCE);
} else if (primaryItem instanceof DimmerItem dimmerItem) {
dimmerItem.send(percentType);
dimmerItem.send(percentType, MATTER_SOURCE);
} else if (primaryItem instanceof RollershutterItem rollerShutterItem) {
if (targetPercent == 100) {
rollerShutterItem.send(UpDownType.DOWN);
rollerShutterItem.send(UpDownType.DOWN, MATTER_SOURCE);
} else if (targetPercent == 0) {
rollerShutterItem.send(UpDownType.UP);
rollerShutterItem.send(UpDownType.UP, MATTER_SOURCE);
} else {
rollerShutterItem.send(percentType);
rollerShutterItem.send(percentType, MATTER_SOURCE);
}
} else if (primaryItem instanceof SwitchItem switchItem) {
// anything > 0 is considered partially open and ON , otherwise completely open and OFF (unless
Expand All @@ -116,13 +116,13 @@ public void handleMatterEvent(String clusterName, String attributeName, Object d
if (invert) {
isOn = !isOn;
}
switchItem.send(isOn ? OnOffType.ON : OnOffType.OFF);
switchItem.send(isOn ? OnOffType.ON : OnOffType.OFF, MATTER_SOURCE);
} else if (primaryItem instanceof StringItem stringItem) {
Object value = targetPercent == 0 ? "OPEN" : "CLOSED";
if (primaryItemMetadata != null) {
value = primaryItemMetadata.getConfiguration().getOrDefault(value, value);
}
stringItem.send(new StringType(value.toString()));
stringItem.send(new StringType(value.toString()), MATTER_SOURCE);
}
lastTargetPercent = targetPercent;
break;
Expand All @@ -133,7 +133,7 @@ public void handleMatterEvent(String clusterName, String attributeName, Object d
if (map.get("global") instanceof Integer value) {
if (WindowCoveringCluster.MovementStatus.STOPPED.getValue().equals(value)
&& primaryItem instanceof RollershutterItem rollerShutterItem) {
rollerShutterItem.send(StopMoveType.STOP);
rollerShutterItem.send(StopMoveType.STOP, MATTER_SOURCE);
cancelTimer();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.openhab.binding.matter.internal.bridge.devices.BaseDevice.MATTER_SOURCE;

import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -89,29 +90,30 @@ void testDeviceType() {
@Test
void testHandleMatterEventOnOff() {
device.handleMatterEvent("onOff", "onOff", true);
verify(colorItem).send(OnOffType.ON);
verify(colorItem).send(OnOffType.ON, MATTER_SOURCE);

device.handleMatterEvent("onOff", "onOff", false);
verify(colorItem).send(OnOffType.OFF);
verify(colorItem).send(OnOffType.OFF, MATTER_SOURCE);
}

@Test
void testHandleMatterEventColor() {
// Turn device on first and wait for future completion
device.handleMatterEvent("onOff", "onOff", true);
verify(colorItem).send(OnOffType.ON);
verify(colorItem).send(OnOffType.ON, MATTER_SOURCE);
device.updateState(colorItem, initialHSBState);

device.handleMatterEvent("colorControl", "currentHue", Double.valueOf(127));
device.handleMatterEvent("colorControl", "currentSaturation", Double.valueOf(127));

verify(colorItem).send(new HSBType(new DecimalType(180), new PercentType(50), new PercentType(50)));
verify(colorItem).send(new HSBType(new DecimalType(180), new PercentType(50), new PercentType(50)),
MATTER_SOURCE);
}

@Test
void testHandleMatterEventLevel() {
device.handleMatterEvent("levelControl", "currentLevel", Double.valueOf(127));
verify(colorItem).send(new PercentType(50));
verify(colorItem).send(new PercentType(50), MATTER_SOURCE);
}

@Test
Expand Down
Loading