diff --git a/hal.conf.example b/hal.conf.example index 919a078a..76e4ee75 100755 --- a/hal.conf.example +++ b/hal.conf.example @@ -5,5 +5,5 @@ sync_port=6666 #tellstick.com_port=COM5 #nutups.host= #nutups.port= -# Network scanning is disabled by default as it is not appropriate for all networks -#netscan.scanip=true \ No newline at end of file +# Network scanning should probably be disabled in some networks (default on) +#netscan.ipscan=false \ No newline at end of file diff --git a/src/se/hal/HalContext.java b/src/se/hal/HalContext.java index b4bc41e7..15b012d6 100755 --- a/src/se/hal/HalContext.java +++ b/src/se/hal/HalContext.java @@ -182,6 +182,12 @@ public class HalContext { public static int getIntegerProperty(String key){ return Integer.parseInt(getStringProperty(key)); } + public static boolean getBooleanProperty(String key) { + return Boolean.parseBoolean(getStringProperty(key)); + } + public static boolean containsProperty(String key) { + return getStringProperty(key) != null; + } public static void setProperty(String key, String value) throws SQLException { PreparedStatement stmt = db.getPreparedStatement("REPLACE INTO conf (key, value) VALUES (?, ?)"); stmt.setObject(1, key); @@ -190,6 +196,9 @@ public class HalContext { dbConf.setProperty(key, value); } + + + public static DBConnection getDB(){ return db; } @@ -202,4 +211,5 @@ public class HalContext { HalContext.db = db; } + } diff --git a/src/se/hal/plugin/netscan/NetScanController.java b/src/se/hal/plugin/netscan/NetScanController.java index 6ec30e4a..c8d2b9ad 100755 --- a/src/se/hal/plugin/netscan/NetScanController.java +++ b/src/se/hal/plugin/netscan/NetScanController.java @@ -1,7 +1,9 @@ package se.hal.plugin.netscan; +import se.hal.HalContext; import se.hal.intf.*; import se.hal.struct.devicedata.SwitchEventData; +import zutil.InetUtil; import zutil.log.LogUtil; import zutil.net.InetScanner; import zutil.net.InetScanner.InetScanListener; @@ -9,9 +11,10 @@ import zutil.osal.MultiCommandExecutor; import java.io.IOException; import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.SocketException; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -24,47 +27,54 @@ public class NetScanController implements HalEventController, HalAutoScannableCo public static Logger logger = LogUtil.getLogger(); private static final int NETWORK_SYNC_INTERVAL = 3 * 60 * 60 * 1000; // 3 hours private static final int PING_INTERVAL = 10 * 1000; // 10 sec + private static final String PARAM_IPSCAN = "netscan.ipscan"; private ScheduledExecutorService executor; private HalEventReportListener listener; - private ArrayList devices = new ArrayList<>(); + /** A register and a cache of previous state **/ + private HashMap devices = new HashMap<>(); @Override public boolean isAvailable() { - return ! InetScanner.getLocalInet4Address().isEmpty(); + return ! InetUtil.getLocalInet4Address().isEmpty(); } @Override public void initialize() throws Exception { executor = Executors.newScheduledThreadPool(1); - executor.scheduleAtFixedRate(new Runnable() { - @Override - public void run() { - try { - logger.fine("Starting network scan..."); - InetScanner scanner = new InetScanner(); - scanner.setListener(NetScanController.this); - scanner.scan(InetScanner.getLocalInet4Address().get(0)); - logger.fine("Network scan done"); - } catch (Exception e) { - e.printStackTrace(); + executor.scheduleAtFixedRate(NetScanController.this, 10_000, PING_INTERVAL, TimeUnit.MILLISECONDS); + if (!HalContext.containsProperty(PARAM_IPSCAN) || HalContext.getBooleanProperty(PARAM_IPSCAN)) { + executor.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + try { + logger.fine("Starting network scan..."); + InetScanner scanner = new InetScanner(); + scanner.setListener(NetScanController.this); + scanner.scan(InetUtil.getLocalInet4Address().get(0)); + logger.fine("Network scan done"); + } catch (Exception e) { + e.printStackTrace(); + } } - } - }, 30_000, NETWORK_SYNC_INTERVAL, TimeUnit.MILLISECONDS); - executor.scheduleAtFixedRate(NetScanController.this, 10_001, PING_INTERVAL, TimeUnit.MILLISECONDS); + }, 30_000, NETWORK_SYNC_INTERVAL, TimeUnit.MILLISECONDS); + } } @Override public void run() { try(MultiCommandExecutor executor = new MultiCommandExecutor();){ - for (int i = 0; i < devices.size(); i++) { - LocalNetworkDevice device = devices.get(i); + for (Map.Entry entry : devices.entrySet()) { if (listener != null) { - logger.fine("Pinging ip: "+device.getHost()); - boolean online = InetScanner.isReachable(device.getHost(), executor); - listener.reportReceived(device, new SwitchEventData(online, System.currentTimeMillis())); + boolean online = InetScanner.isReachable(entry.getKey().getHost(), executor); + if (entry.getValue() == null || entry.getValue().isOn() == online) { + entry.setValue( + new SwitchEventData(online, System.currentTimeMillis())); + logger.fine("IP "+entry.getKey().getHost() +" state has changed to "+ entry.getValue()); + listener.reportReceived(entry.getKey(), entry.getValue()); + } } } } catch (IOException e) { @@ -85,7 +95,7 @@ public class NetScanController implements HalEventController, HalAutoScannableCo @Override public void register(HalEventConfig event) { if (event instanceof LocalNetworkDevice) - devices.add((LocalNetworkDevice) event); + devices.put((LocalNetworkDevice) event, null); } @Override public void deregister(HalEventConfig event) {