/** * Copyright (c) 2010-2016 by the respective copyright holders. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.openhab.binding.tellstick.internal.device; import java.util.ArrayList; import java.util.Collections; import java.util.EventListener; import java.util.List; import org.openhab.binding.tellstick.internal.JNA; import org.openhab.binding.tellstick.internal.JNA.DataType; import org.openhab.binding.tellstick.internal.JNA.Method; import org.openhab.binding.tellstick.internal.device.iface.DeviceChangeListener; import org.openhab.binding.tellstick.internal.device.iface.SensorListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.sun.jna.Pointer; /** * A callback listener to telldus that distributes to other listeners. * * @author jarlebh * @since 1.5.0 */ public class TellsticEventHandler { private static final Logger logger = LoggerFactory.getLogger(TellsticEventHandler.class); List<TellstickDevice> list; List<EventListener> changeListeners = new ArrayList<EventListener>(); private int handleSensor; private int handleDeviceChange; private JNA.CLibrary.TDDeviceChangeEvent deviceChangeHandler; private int handleDeviceEvent; private JNA.CLibrary.TDDeviceEvent deviceEventHandler; private JNA.CLibrary.TDSensorEvent sensorEventHandler; public TellsticEventHandler(List<TellstickDevice> deviceList) { this.list = java.util.Collections.synchronizedList(deviceList); this.setupListeners(); } public void setDeviceList(List<TellstickDevice> deviceList) { list = java.util.Collections.synchronizedList(deviceList); } public void addListener(EventListener listener) { this.changeListeners.add(listener); } public void removeListener(EventListener listener) { this.changeListeners.remove(listener); } public void remove() { JNA.CLibrary.INSTANCE.tdUnregisterCallback(handleDeviceEvent); JNA.CLibrary.INSTANCE.tdUnregisterCallback(handleDeviceChange); JNA.CLibrary.INSTANCE.tdUnregisterCallback(handleSensor); sensorEventHandler = null; deviceChangeHandler = null; deviceEventHandler = null; } public List<EventListener> getAllListeners() { return changeListeners; } private void notifyListeners(TellstickDevice ts, Method m, String dataStr) { for (EventListener changeListener : changeListeners) { if (changeListener instanceof DeviceChangeListener) { ((DeviceChangeListener) changeListener).onRequest(new TellstickDeviceEvent(ts, m, dataStr)); } } } private void notifySensorListeners(int deviceId, String protocol, String model, DataType type, String dataStr) { for (EventListener changeListener : changeListeners) { if (changeListener instanceof SensorListener) { ((SensorListener) changeListener) .onRequest(new TellstickSensorEvent(deviceId, dataStr, type, protocol, model)); } } } public void setupListeners() { deviceEventHandler = new JNA.CLibrary.TDDeviceEvent() { @Override public void invoke(int deviceId, int method, Pointer data, int callbackId, Pointer context) throws SupportedMethodsException { try { TellstickDevice ts = TellstickDevice.getDevice(deviceId); int idx = Collections.binarySearch(list, ts); if (idx > -1) { list.set(idx, ts); } Method m = Method.getMethodById(method); String dataStr = null; if (m == Method.DIM) { dataStr = data.getString(0); } notifyListeners(ts, m, dataStr); // The device is not supported. } catch (Exception e) { logger.error("Failed in TDDeviceEvent", e); } } }; handleDeviceEvent = JNA.CLibrary.INSTANCE.tdRegisterDeviceEvent(deviceEventHandler, null); deviceChangeHandler = new JNA.CLibrary.TDDeviceChangeEvent() { @Override public void invoke(int deviceId, int method, int changeType, int callbackId, Pointer context) throws SupportedMethodsException { try { TellstickDevice ts = null; if (method == JNA.CLibrary.TELLSTICK_DEVICE_CHANGED || method == JNA.CLibrary.TELLSTICK_DEVICE_STATE_CHANGED) { ts = TellstickDevice.getDevice(deviceId); int idx = Collections.binarySearch(list, ts); if (idx > -1) { list.set(idx, ts); } } if (method == JNA.CLibrary.TELLSTICK_DEVICE_ADDED) { ts = TellstickDevice.getDevice(deviceId); list.add(ts); } if (method == JNA.CLibrary.TELLSTICK_DEVICE_ADDED) { for (int i = 0; i < list.size(); i++) { if (list.get(i).getId() == deviceId) { ts = list.remove(i); return; } } } Method m = Method.getMethodById(method); notifyListeners(ts, m, null); // The device is not supported. } catch (Exception e) { logger.error("Failed in TDDeviceChangeEvent", e); } } }; handleDeviceChange = JNA.CLibrary.INSTANCE.tdRegisterDeviceChangeEvent(deviceChangeHandler, null); sensorEventHandler = new JNA.CLibrary.TDSensorEvent() { @Override public void invoke(String protocol, String model, int deviceId, int dataType, Pointer value, int timeStamp, int callbackId, Pointer context) throws SupportedMethodsException { try { DataType m = DataType.getDataTypeId(dataType); notifySensorListeners(deviceId, protocol, model, m, value.getString(0)); } catch (Exception e) { logger.error("Failed in TDSensorEvent", e); } } }; handleSensor = JNA.CLibrary.INSTANCE.tdRegisterSensorEvent(sensorEventHandler, null); } }