/* * Dog - Z-Wave * * Copyright 2013 Davide Aimone and Dario Bonino * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package it.polito.elite.dog.drivers.zwave.movementsensor; import it.polito.elite.dog.core.library.model.ControllableDevice; import it.polito.elite.dog.core.library.model.DeviceStatus; import it.polito.elite.dog.core.library.model.devicecategory.Controllable; import it.polito.elite.dog.core.library.model.devicecategory.MovementSensor; import it.polito.elite.dog.core.library.model.state.MovementState; import it.polito.elite.dog.core.library.model.state.State; import it.polito.elite.dog.core.library.model.statevalue.MovingStateValue; import it.polito.elite.dog.core.library.model.statevalue.NotMovingStateValue; import it.polito.elite.dog.core.library.util.LogHelper; import it.polito.elite.dog.drivers.zwave.ZWaveAPI; import it.polito.elite.dog.drivers.zwave.model.zway.json.CommandClasses; import it.polito.elite.dog.drivers.zwave.model.zway.json.Controller; import it.polito.elite.dog.drivers.zwave.model.zway.json.Device; import it.polito.elite.dog.drivers.zwave.model.zway.json.Instance; import it.polito.elite.dog.drivers.zwave.network.ZWaveDriverInstance; import it.polito.elite.dog.drivers.zwave.network.info.ZWaveNodeInfo; import it.polito.elite.dog.drivers.zwave.network.interfaces.ZWaveNetwork; import java.util.HashMap; import java.util.HashSet; import java.util.Set; import org.osgi.framework.BundleContext; import org.osgi.service.log.LogService; public class ZWaveMovementSensorDriverInstance extends ZWaveDriverInstance implements MovementSensor { // the class logger private LogHelper logger; public ZWaveMovementSensorDriverInstance(ZWaveNetwork network, ControllableDevice device, int deviceId, Set<Integer> instancesId, int gatewayNodeId, int updateTimeMillis, BundleContext context) { super(network, device, deviceId, instancesId, gatewayNodeId, updateTimeMillis, context); // create a logger logger = new LogHelper(context); // initialize states this.initializeStates(); } /** * Initializes the state asynchronously as required by OSGi */ private void initializeStates() { // initialize the state this.currentState.setState(MovementState.class.getSimpleName(), new MovementState(new NotMovingStateValue())); // get the initial state of the device Runnable worker = new Runnable() { public void run() { network.read(nodeInfo, true); } }; Thread workerThread = new Thread(worker); workerThread.start(); } @Override public void newMessageFromHouse(Device deviceNode, Instance instanceNode, Controller controllerNode, String sValue) { this.deviceNode = deviceNode; // Read the value associated with the right CommandClass. CommandClasses ccEntry = instanceNode .getCommandClass(ZWaveAPI.COMMAND_CLASS_SENSOR_BINARY); if (ccEntry != null) // notify open/close only if changed if (changeMovementState((ccEntry.getLevelAsBoolean() ? MovementState.ISMOVING : MovementState.NOTMOVING))) // notify state changed this.updateStatus(); } /** * Check if the current state has been changed. In that case, fire a state * change message, otherwise it does nothing * * @param movementState * .ISMOVING or MovementState.NOTMOVING */ private boolean changeMovementState(String movementState) { // the state change flag boolean stateChanged = false; // the current state String currentStateValue = ""; State state = currentState .getState(MovementState.class.getSimpleName()); if (state != null) currentStateValue = (String) state.getCurrentStateValue()[0] .getValue(); // if the current states it is different from the new state if (!currentStateValue.equalsIgnoreCase(movementState)) { // set the new state to open or close... if (movementState.equalsIgnoreCase(MovementState.ISMOVING)) { // update the state MovementState movState = new MovementState( new MovingStateValue()); currentState.setState(MovementState.class.getSimpleName(), movState); this.notifyStartedMovement(); // notify moving } else { // update the state MovementState movState = new MovementState( new NotMovingStateValue()); currentState.setState(MovementState.class.getSimpleName(), movState); this.notifyCeasedMovement(); // notify not moving } logger.log(LogService.LOG_DEBUG, "Device " + device.getDeviceId() + " value is now " + movementState); stateChanged = true; } return stateChanged; } @Override protected void specificConfiguration() { // prepare the device state map currentState = new DeviceStatus(device.getDeviceId()); } @Override protected void addToNetworkDriver(ZWaveNodeInfo nodeInfo) { network.addDriver(nodeInfo, updateTimeMillis, this); } @Override protected boolean isController() { return false; } @Override public DeviceStatus getState() { return currentState; } @Override protected ZWaveNodeInfo createNodeInfo(int deviceId, Set<Integer> instancesId, boolean isController) { HashMap<Integer, Set<Integer>> instanceCommand = new HashMap<Integer, Set<Integer>>(); HashSet<Integer> ccSet = new HashSet<Integer>(); ccSet.add(ZWaveAPI.COMMAND_CLASS_SENSOR_BINARY); // binary switch has its own command class for (Integer instanceId : instancesId) { instanceCommand.put(instanceId, ccSet); } ZWaveNodeInfo nodeInfo = new ZWaveNodeInfo(deviceId, instanceCommand, isController); return nodeInfo; } @Override public void notifyCeasedMovement() { ((MovementSensor) device).notifyCeasedMovement(); } @Override public void notifyStartedMovement() { ((MovementSensor) device).notifyStartedMovement(); } @Override public void updateStatus() { // update the monitor admin status snapshot ((Controllable) this.device).updateStatus(); } }