[remoteopenhab] Consider ItemStateChangedEvent events when relevant (#9243)

Fix #9190

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
This commit is contained in:
lolodomo 2020-12-09 19:58:34 +01:00 committed by GitHub
parent aba5e2c996
commit 7edfbc6391
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 11 deletions

View File

@ -22,7 +22,9 @@ import java.time.format.DateTimeParseException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -112,6 +114,8 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
private @Nullable ScheduledFuture<?> checkConnectionJob; private @Nullable ScheduledFuture<?> checkConnectionJob;
private RemoteopenhabRestClient restClient; private RemoteopenhabRestClient restClient;
private Map<ChannelUID, State> channelsLastStates = new HashMap<>();
public RemoteopenhabBridgeHandler(Bridge bridge, HttpClient httpClient, HttpClient httpClientTrustingCert, public RemoteopenhabBridgeHandler(Bridge bridge, HttpClient httpClient, HttpClient httpClientTrustingCert,
ClientBuilder clientBuilder, SseEventSourceFactory eventSourceFactory, ClientBuilder clientBuilder, SseEventSourceFactory eventSourceFactory,
RemoteopenhabChannelTypeProvider channelTypeProvider, RemoteopenhabChannelTypeProvider channelTypeProvider,
@ -181,6 +185,7 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
logger.debug("Disposing remote openHAB handler for bridge {}", getThing().getUID()); logger.debug("Disposing remote openHAB handler for bridge {}", getThing().getUID());
stopStreamingUpdates(); stopStreamingUpdates();
stopCheckConnectionJob(); stopCheckConnectionJob();
channelsLastStates.clear();
} }
@Override @Override
@ -192,7 +197,7 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
try { try {
if (command instanceof RefreshType) { if (command instanceof RefreshType) {
String state = restClient.getRemoteItemState(channelUID.getId()); String state = restClient.getRemoteItemState(channelUID.getId());
updateChannelState(channelUID.getId(), null, state); updateChannelState(channelUID.getId(), null, state, false);
} else if (isLinked(channelUID)) { } else if (isLinked(channelUID)) {
restClient.sendCommandToRemoteItem(channelUID.getId(), command); restClient.sendCommandToRemoteItem(channelUID.getId(), command);
String commandStr = command.toFullString(); String commandStr = command.toFullString();
@ -332,7 +337,7 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
try { try {
items = restClient.getRemoteItems("name,state"); items = restClient.getRemoteItems("name,state");
for (RemoteopenhabItem item : items) { for (RemoteopenhabItem item : items) {
updateChannelState(item.name, null, item.state); updateChannelState(item.name, null, item.state, false);
} }
} catch (RemoteopenhabException e) { } catch (RemoteopenhabException e) {
logger.debug("{}", e.getMessage()); logger.debug("{}", e.getMessage());
@ -411,8 +416,8 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
} }
@Override @Override
public void onItemStateEvent(String itemName, String stateType, String state) { public void onItemStateEvent(String itemName, String stateType, String state, boolean onlyIfStateChanged) {
updateChannelState(itemName, stateType, state); updateChannelState(itemName, stateType, state, onlyIfStateChanged);
} }
@Override @Override
@ -435,7 +440,8 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
} }
} }
private void updateChannelState(String itemName, @Nullable String stateType, String state) { private void updateChannelState(String itemName, @Nullable String stateType, String state,
boolean onlyIfStateChanged) {
Channel channel = getThing().getChannel(itemName); Channel channel = getThing().getChannel(itemName);
if (channel == null) { if (channel == null) {
logger.trace("No channel for item {}", itemName); logger.trace("No channel for item {}", itemName);
@ -555,6 +561,12 @@ public class RemoteopenhabBridgeHandler extends BaseBridgeHandler
} }
} }
if (channelState != null) { if (channelState != null) {
if (onlyIfStateChanged && channelState.equals(channelsLastStates.get(channel.getUID()))) {
logger.trace("ItemStateChangedEvent ignored for item {} as state is identical to the last state",
itemName);
return;
}
channelsLastStates.put(channel.getUID(), channelState);
updateState(channel.getUID(), channelState); updateState(channel.getUID(), channelState);
String channelStateStr = channelState.toFullString(); String channelStateStr = channelState.toFullString();
logger.debug("updateState {} with {}", channel.getUID(), logger.debug("updateState {} with {}", channel.getUID(),

View File

@ -27,7 +27,7 @@ public interface RemoteopenhabItemsDataListener {
/** /**
* A new ItemStateEvent was published. * A new ItemStateEvent was published.
*/ */
void onItemStateEvent(String itemName, String stateType, String state); void onItemStateEvent(String itemName, String stateType, String state, boolean onlyIfStateChanged);
/** /**
* A new ItemAddedEvent was published. * A new ItemAddedEvent was published.

View File

@ -359,14 +359,20 @@ public class RemoteopenhabRestClient {
case "ItemStateEvent": case "ItemStateEvent":
itemName = extractItemNameFromTopic(event.topic, event.type, "state"); itemName = extractItemNameFromTopic(event.topic, event.type, "state");
payload = jsonParser.fromJson(event.payload, RemoteopenhabEventPayload.class); payload = jsonParser.fromJson(event.payload, RemoteopenhabEventPayload.class);
itemsListeners itemsListeners.forEach(
.forEach(listener -> listener.onItemStateEvent(itemName, payload.type, payload.value)); listener -> listener.onItemStateEvent(itemName, payload.type, payload.value, false));
break;
case "ItemStateChangedEvent":
itemName = extractItemNameFromTopic(event.topic, event.type, "statechanged");
payload = jsonParser.fromJson(event.payload, RemoteopenhabEventPayload.class);
itemsListeners.forEach(
listener -> listener.onItemStateEvent(itemName, payload.type, payload.value, true));
break; break;
case "GroupItemStateChangedEvent": case "GroupItemStateChangedEvent":
itemName = extractItemNameFromTopic(event.topic, event.type, "statechanged"); itemName = extractItemNameFromTopic(event.topic, event.type, "statechanged");
payload = jsonParser.fromJson(event.payload, RemoteopenhabEventPayload.class); payload = jsonParser.fromJson(event.payload, RemoteopenhabEventPayload.class);
itemsListeners itemsListeners.forEach(
.forEach(listener -> listener.onItemStateEvent(itemName, payload.type, payload.value)); listener -> listener.onItemStateEvent(itemName, payload.type, payload.value, false));
break; break;
case "ItemAddedEvent": case "ItemAddedEvent":
itemName = extractItemNameFromTopic(event.topic, event.type, "added"); itemName = extractItemNameFromTopic(event.topic, event.type, "added");
@ -414,7 +420,6 @@ public class RemoteopenhabRestClient {
.forEach(listener -> listener.onChannelTriggered(triggerEvent.channel, triggerEvent.event)); .forEach(listener -> listener.onChannelTriggered(triggerEvent.channel, triggerEvent.event));
break; break;
case "ItemStatePredictedEvent": case "ItemStatePredictedEvent":
case "ItemStateChangedEvent":
case "ItemCommandEvent": case "ItemCommandEvent":
case "ThingStatusInfoEvent": case "ThingStatusInfoEvent":
case "ThingUpdatedEvent": case "ThingUpdatedEvent":