From 1e07d1af03fff4410b84d950479b1474595fa1e9 Mon Sep 17 00:00:00 2001 From: Silviu Chingaru Date: Fri, 4 Nov 2022 20:01:39 +0200 Subject: [PATCH] [paradoxalarm] Handle multiple panels (#13641) * Fixes #13640 Working with multiple Paradox panels Tested with: - rename things files; - thing disable / enable on same instance of OpenHab; - disable on one OpenHab instance > enable on other; Everything works as espected. All test passed even if no Login/Logout commands were sent to IP module Signed-off-by: Silviu Chingaru --- .../internal/communication/CommunicationState.java | 2 -- .../discovery/ParadoxDiscoveryService.java | 2 +- .../internal/handlers/EntityBaseHandler.java | 3 ++- .../handlers/ParadoxIP150BridgeHandler.java | 7 ++++++- .../internal/handlers/ParadoxPanelHandler.java | 3 ++- .../internal/handlers/ParadoxPartitionHandler.java | 4 +++- .../internal/handlers/ParadoxZoneHandler.java | 4 +++- .../paradoxalarm/internal/model/Entity.java | 8 +++++++- .../paradoxalarm/internal/model/ParadoxPanel.java | 14 +++----------- .../paradoxalarm/internal/model/Partition.java | 8 +++----- .../binding/paradoxalarm/internal/model/Zone.java | 4 ++-- .../src/test/java/main/Main.java | 9 +++++---- 12 files changed, 37 insertions(+), 31 deletions(-) diff --git a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/communication/CommunicationState.java b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/communication/CommunicationState.java index 147ba6477ae..067501a1959 100644 --- a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/communication/CommunicationState.java +++ b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/communication/CommunicationState.java @@ -22,7 +22,6 @@ import org.openhab.binding.paradoxalarm.internal.communication.messages.HeaderMe import org.openhab.binding.paradoxalarm.internal.communication.messages.IPPacket; import org.openhab.binding.paradoxalarm.internal.communication.messages.IpMessagesConstants; import org.openhab.binding.paradoxalarm.internal.communication.messages.ParadoxIPPacket; -import org.openhab.binding.paradoxalarm.internal.model.ParadoxPanel; import org.openhab.binding.paradoxalarm.internal.util.ParadoxUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -368,7 +367,6 @@ public enum CommunicationState implements IResponseReceiver { if (communicator != null) { communicator.close(); } - ParadoxPanel.getInstance().dispose(); } }; diff --git a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/discovery/ParadoxDiscoveryService.java b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/discovery/ParadoxDiscoveryService.java index f96073f210f..a3f388dede8 100644 --- a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/discovery/ParadoxDiscoveryService.java +++ b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/discovery/ParadoxDiscoveryService.java @@ -53,7 +53,7 @@ public class ParadoxDiscoveryService extends AbstractDiscoveryService { protected void startScan() { IParadoxCommunicator communicator = ip150BridgeHandler.getCommunicator(); if (communicator != null && communicator.isOnline()) { - ParadoxPanel panel = ParadoxPanel.getInstance(); + ParadoxPanel panel = ip150BridgeHandler.getPanel(); discoverPanel(panel.getPanelInformation()); discoverPartitions(panel.getPartitions()); discoverZones(panel.getZones()); diff --git a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/EntityBaseHandler.java b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/EntityBaseHandler.java index 4d51a9b4166..7d5d82f6e8f 100644 --- a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/EntityBaseHandler.java +++ b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/EntityBaseHandler.java @@ -59,7 +59,8 @@ public abstract class EntityBaseHandler extends BaseThingHandler { private void initializeDelayed() { logger.debug("Start initializeDelayed() in {}", getThing().getUID()); - ParadoxPanel panel = ParadoxPanel.getInstance(); + ParadoxIP150BridgeHandler bridge = (ParadoxIP150BridgeHandler) getBridge().getHandler(); + ParadoxPanel panel = bridge.getPanel(); // Asynchronous update not yet done if (panel.getPanelInformation() == null) { // Retry until reach MAX_WAIT_TIME diff --git a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxIP150BridgeHandler.java b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxIP150BridgeHandler.java index 90821126697..c107dac3c02 100644 --- a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxIP150BridgeHandler.java +++ b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxIP150BridgeHandler.java @@ -69,6 +69,7 @@ public class ParadoxIP150BridgeHandler extends BaseBridgeHandler private final Logger logger = LoggerFactory.getLogger(ParadoxIP150BridgeHandler.class); private IParadoxCommunicator communicator; + private ParadoxPanel panel = new ParadoxPanel(); private ParadoxIP150BridgeConfiguration config; private @Nullable ScheduledFuture refreshCacheUpdateSchedule; @@ -169,7 +170,6 @@ public class ParadoxIP150BridgeHandler extends BaseBridgeHandler .withMaxPartitions(config.getMaxPartitions()).withMaxZones(config.getMaxZones()) .withScheduler(scheduler).withEncryption(config.isEncrypt()).build(); - ParadoxPanel panel = ParadoxPanel.getInstance(); panel.setCommunicator(communicator); Collection listeners = Arrays.asList(panel, this); @@ -208,6 +208,7 @@ public class ParadoxIP150BridgeHandler extends BaseBridgeHandler public void dispose() { cancelSchedule(refreshCacheUpdateSchedule); CommunicationState.logout(communicator); + panel.dispose(); super.dispose(); } @@ -323,6 +324,10 @@ public class ParadoxIP150BridgeHandler extends BaseBridgeHandler return communicator; } + public ParadoxPanel getPanel() { + return panel; + } + @Override public void onSocketTimeOutOccurred(IOException exception) { logger.warn("TIMEOUT! {} received message for socket timeout. ", this, exception); diff --git a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxPanelHandler.java b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxPanelHandler.java index 54228b9dfef..a15b0140894 100644 --- a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxPanelHandler.java +++ b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxPanelHandler.java @@ -49,7 +49,8 @@ public class ParadoxPanelHandler extends EntityBaseHandler { @Override protected void updateEntity() { - ParadoxPanel panel = ParadoxPanel.getInstance(); + ParadoxIP150BridgeHandler bridge = (ParadoxIP150BridgeHandler) getBridge().getHandler(); + ParadoxPanel panel = bridge.getPanel(); StringType panelState = panel.isOnline() ? STATE_ONLINE : STATE_OFFLINE; updateState(PANEL_STATE_CHANNEL_UID, panelState); ParadoxInformation panelInformation = panel.getPanelInformation(); diff --git a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxPartitionHandler.java b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxPartitionHandler.java index ebf3280ce79..2dd9bcc8be1 100644 --- a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxPartitionHandler.java +++ b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxPartitionHandler.java @@ -80,7 +80,9 @@ public class ParadoxPartitionHandler extends EntityBaseHandler { protected Partition getPartition() { int index = calculateEntityIndex(); - List partitions = ParadoxPanel.getInstance().getPartitions(); + ParadoxIP150BridgeHandler bridge = (ParadoxIP150BridgeHandler) getBridge().getHandler(); + ParadoxPanel panel = bridge.getPanel(); + List partitions = panel.getPartitions(); if (partitions == null) { logger.debug( "Partitions collection of Paradox Panel object is null. Probably not yet initialized. Skipping update."); diff --git a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxZoneHandler.java b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxZoneHandler.java index 5e7e9c5833f..8b16cb9e13f 100644 --- a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxZoneHandler.java +++ b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/handlers/ParadoxZoneHandler.java @@ -42,7 +42,9 @@ public class ParadoxZoneHandler extends EntityBaseHandler { @Override protected void updateEntity() { int index = calculateEntityIndex(); - List zones = ParadoxPanel.getInstance().getZones(); + ParadoxIP150BridgeHandler bridge = (ParadoxIP150BridgeHandler) getBridge().getHandler(); + ParadoxPanel panel = bridge.getPanel(); + List zones = panel.getZones(); if (zones == null) { logger.debug( "Zones collection of Paradox Panel object is null. Probably not yet initialized. Skipping update."); diff --git a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/Entity.java b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/Entity.java index 7ddbac3fff5..64c2efa4318 100644 --- a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/Entity.java +++ b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/Entity.java @@ -24,10 +24,12 @@ import org.slf4j.LoggerFactory; public abstract class Entity { private final Logger logger = LoggerFactory.getLogger(Entity.class); + private ParadoxPanel panel; private int id; private String label; - public Entity(int id, String label) { + public Entity(ParadoxPanel panel, int id, String label) { + this.panel = panel; this.id = id; this.label = label.trim(); logger.debug("Creating entity with label: {} and ID: {}", label, id); @@ -49,6 +51,10 @@ public abstract class Entity { this.label = label; } + public ParadoxPanel getPanel() { + return panel; + } + @Override public String toString() { return "Entity [id=" + id + ", label=" + label + "]"; diff --git a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/ParadoxPanel.java b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/ParadoxPanel.java index ccd962b4ea1..99a8ff69324 100644 --- a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/ParadoxPanel.java +++ b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/ParadoxPanel.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.Map; import java.util.TimeZone; -import org.eclipse.jdt.annotation.NonNull; import org.openhab.binding.paradoxalarm.internal.communication.IDataUpdateListener; import org.openhab.binding.paradoxalarm.internal.communication.IParadoxCommunicator; import org.openhab.binding.paradoxalarm.internal.exceptions.ParadoxRuntimeException; @@ -38,9 +37,6 @@ public class ParadoxPanel implements IDataUpdateListener { private final Logger logger = LoggerFactory.getLogger(ParadoxPanel.class); - @NonNull - private static ParadoxPanel paradoxPanel = new ParadoxPanel(); - private ParadoxInformation panelInformation; private List partitions; private List zones; @@ -51,7 +47,7 @@ public class ParadoxPanel implements IDataUpdateListener { private double dcLevel; private ZonedDateTime panelTime; - private ParadoxPanel() { + public ParadoxPanel() { this.parser = new EvoParser(); } @@ -69,10 +65,6 @@ public class ParadoxPanel implements IDataUpdateListener { } } - public static ParadoxPanel getInstance() { - return paradoxPanel; - } - public boolean isPanelSupported() { PanelType panelType = panelInformation.getPanelType(); return panelType == PanelType.EVO48 || panelType == PanelType.EVO192 || panelType == PanelType.EVOHD; @@ -123,7 +115,7 @@ public class ParadoxPanel implements IDataUpdateListener { zones = new ArrayList<>(); Map zoneLabels = communicator.getZoneLabels(); for (int i = 0; i < zoneLabels.size(); i++) { - Zone zone = new Zone(i + 1, zoneLabels.get(i)); + Zone zone = new Zone(this, i + 1, zoneLabels.get(i)); zones.add(zone); } return zones; @@ -133,7 +125,7 @@ public class ParadoxPanel implements IDataUpdateListener { partitions = new ArrayList<>(); Map partitionLabels = communicator.getPartitionLabels(); for (int i = 0; i < partitionLabels.size(); i++) { - Partition partition = new Partition(i + 1, partitionLabels.get(i)); + Partition partition = new Partition(this, i + 1, partitionLabels.get(i)); partitions.add(partition); logger.debug("Partition {}:\t{}", i + 1, partition.getState().getMainState()); } diff --git a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/Partition.java b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/Partition.java index 79c6a51b9e6..42966d2bc91 100644 --- a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/Partition.java +++ b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/Partition.java @@ -12,7 +12,6 @@ */ package org.openhab.binding.paradoxalarm.internal.model; -import org.openhab.binding.paradoxalarm.internal.communication.IParadoxCommunicator; import org.openhab.binding.paradoxalarm.internal.communication.PartitionCommandRequest; import org.openhab.binding.paradoxalarm.internal.communication.RequestType; import org.openhab.binding.paradoxalarm.internal.communication.messages.CommandPayload; @@ -35,8 +34,8 @@ public class Partition extends Entity implements Commandable { private PartitionState state = new PartitionState(); - public Partition(int id, String label) { - super(id, label); + public Partition(ParadoxPanel panel, int id, String label) { + super(panel, id, label); } public PartitionState getState() { @@ -62,7 +61,6 @@ public class Partition extends Entity implements Commandable { ParadoxIPPacket packet = new ParadoxIPPacket(payload.getBytes()) .setMessageType(HeaderMessageType.SERIAL_PASSTHRU_REQUEST); PartitionCommandRequest request = new PartitionCommandRequest(RequestType.PARTITION_COMMAND, packet, null); - IParadoxCommunicator communicator = ParadoxPanel.getInstance().getCommunicator(); - communicator.submitRequest(request); + getPanel().getCommunicator().submitRequest(request); } } diff --git a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/Zone.java b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/Zone.java index 70f6e1cb6f9..51ec5028dcf 100644 --- a/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/Zone.java +++ b/bundles/org.openhab.binding.paradoxalarm/src/main/java/org/openhab/binding/paradoxalarm/internal/model/Zone.java @@ -28,8 +28,8 @@ public class Zone extends Entity { private ZoneState zoneState; - public Zone(int id, String label) { - super(id, label); + public Zone(ParadoxPanel panel, int id, String label) { + super(panel, id, label); } public ZoneState getZoneState() { diff --git a/bundles/org.openhab.binding.paradoxalarm/src/test/java/main/Main.java b/bundles/org.openhab.binding.paradoxalarm/src/test/java/main/Main.java index 3236947b9e9..40dcc75141d 100644 --- a/bundles/org.openhab.binding.paradoxalarm/src/test/java/main/Main.java +++ b/bundles/org.openhab.binding.paradoxalarm/src/test/java/main/Main.java @@ -46,6 +46,7 @@ public class Main { private static ScheduledExecutorService scheduler; private static IParadoxCommunicator communicator; + private static ParadoxPanel panel; public static void main(String[] args) { readArguments(args); @@ -59,14 +60,14 @@ public class Main { .withTcpPort(port).withMaxPartitions(4).withMaxZones(20).withScheduler(scheduler) .withEncryption(true).build(); - ParadoxPanel panel = ParadoxPanel.getInstance(); + panel = new ParadoxPanel(); panel.setCommunicator(communicator); communicator.setListeners(Arrays.asList(panel)); communicator.startLoginSequence(); scheduler.scheduleWithFixedDelay(() -> { - refreshMemoryMap(communicator, false); + refreshMemoryMap(panel, false); }, 7, 5, TimeUnit.SECONDS); } catch (Exception e) { logger.error("Exception: ", e); @@ -74,10 +75,10 @@ public class Main { } } - private static void refreshMemoryMap(IParadoxCommunicator communicator, boolean withEpromValues) { + private static void refreshMemoryMap(ParadoxPanel panel, boolean withEpromValues) { logger.debug("Refreshing memory map"); + IParadoxCommunicator communicator = panel.getCommunicator(); communicator.refreshMemoryMap(); - ParadoxPanel panel = ParadoxPanel.getInstance(); panel.getPartitions().stream().forEach(partition -> logger.debug("Partition={}", partition)); panel.getZones().stream().filter(zone -> zone.getId() == 19).forEach(zone -> logger.debug("Zone={}", zone)); logger.debug("PanelTime={}, ACLevel={}, DCLevel={}, BatteryLevel={}", panel.getPanelTime(), panel.getVdcLevel(),