/*
* Dog - Device Driver
*
* Copyright (c) 2011-2014 Luigi De Russis 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.knx.onoffdevice;
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.Buzzer;
import it.polito.elite.dog.core.library.model.devicecategory.ElectricalSystem;
import it.polito.elite.dog.core.library.model.devicecategory.Lamp;
import it.polito.elite.dog.core.library.model.devicecategory.MainsPowerOutlet;
import it.polito.elite.dog.core.library.model.devicecategory.OnOffOutput;
import it.polito.elite.dog.core.library.model.devicecategory.SimpleLamp;
import it.polito.elite.dog.core.library.model.state.OnOffState;
import it.polito.elite.dog.core.library.model.state.State;
import it.polito.elite.dog.core.library.model.statevalue.OffStateValue;
import it.polito.elite.dog.core.library.model.statevalue.OnStateValue;
import it.polito.elite.dog.core.library.util.LogHelper;
import it.polito.elite.dog.drivers.knx.network.KnxIPDriverInstance;
import it.polito.elite.dog.drivers.knx.network.info.KnxIPDeviceInfo;
import it.polito.elite.dog.drivers.knx.network.interfaces.KnxIPNetwork;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.osgi.framework.BundleContext;
import org.osgi.service.log.LogService;
import tuwien.auto.calimero.dptxlator.DPTXlatorBoolean;
/**
* The driver for KNX on/off devices (Lamps, MainsPowerOutlet, etc.) using the KNXNet/IP protocol. It extends the
* KNXIPDriver abstract class that performs common network operations for such a driver.
*
* @author <a href="mailto:luigi.derussis@polito.it">Luigi De Russis</a>
* @see <a href="http://elite.polito.it">http://elite.polito.it</a>
*
*/
public class KnxIPOnOffDeviceDriverInstance extends KnxIPDriverInstance implements Lamp, SimpleLamp, Buzzer, MainsPowerOutlet
{
// the driver logger
LogHelper logger;
// the log identifier, unique for the class
public static String logId = "[KnxIPOnOffDriverInstance]: ";
/**
* The class constructor. It calls the super-class constructor to obtain common initialization variables and
* methods.
*
* @param network
* the network driver to use (as described by the {@link KnxIPNetwork} interface.
* @param device
* the device to which this driver is attached/associated
* @param gwIpAddress
*/
public KnxIPOnOffDeviceDriverInstance(KnxIPNetwork network, ControllableDevice device, String gatewayAddress,
BundleContext context)
{
// the super-call constructor
super(network, device, gatewayAddress);
// init the logger
this.logger = new LogHelper(context);
// set default initial state to off...
currentState = new DeviceStatus(device.getDeviceId());
currentState.setState(OnOffState.class.getSimpleName(), new OnOffState(new OffStateValue()));
// ... then ask the (real) initial state to the KNX gateway
this.getInitialState();
}
/**
* Handle the on command
*/
@Override
public void on()
{
this.sendKnxCommand("on");
}
/**
* Handle the off command
*/
@Override
public void off()
{
this.sendKnxCommand("off");
}
/**
* Send a command (on or off, in this case) by performing a write on the KNX network
*
* @param commandName
* The command name (i.e., on or off)
*/
private void sendKnxCommand(String commandName)
{
// get the KNX IP Device Info (group address, etc.) associated to the
// required command name
KnxIPDeviceInfo command = this.commandName2CommandMap.get(commandName);
String commandAddress = null;
if (command != null)
{
// get the corresponding group address
commandAddress = command.getGroupAddress();
}
else
{
commandAddress = this.globalGroupAddress;
}
if (commandAddress != null)
{
try
{
KnxIPDeviceInfo devInfo = new KnxIPDeviceInfo(this.device.getDeviceId(), commandAddress);
devInfo.setGatewayIPAddress(InetAddress.getByName(this.gwAddress));
// write the command on the network
this.network.write(devInfo, commandName);
}
catch (Exception e)
{
//TODO handle exception
}
}
}
/**
* Get the current state from DogState (not querying the "real" KNX device)
*/
@Override
public DeviceStatus getState()
{
return this.currentState;
}
/*
* Handle the driver behavior when it received a new message from the KNX IP network: typically it involves a state
* change.
*
* (non-Javadoc)
*
* @see it.polito.elite.dog.drivers.knx.network.KnxIPDriver# newMessageFromHouse(java.lang.String,
* java.lang.String, java.lang.String)
*/
@Override
public void newMessageFromHouse(String source, String destination, String value)
{
if ((value != null) && (!value.isEmpty()))
{
// TODO Check if source and destination are allowed?
if (value.equalsIgnoreCase(OnOffState.ON))
{
this.changeCurrentState(OnOffState.ON);
}
else if (value.equalsIgnoreCase(OnOffState.OFF))
{
this.changeCurrentState(OnOffState.OFF);
}
}
}
/**
* Check if the current state has been changed. In that case, fire a state change message, otherwise it does nothing
*
* @param OnOffValue
* KnxOnOffDeviceDriver.ON or KnxOnOffDeviceDriver.OFF
*/
private void changeCurrentState(String OnOffValue)
{
String currentStateValue = (String) this.currentState.getState(OnOffState.class.getSimpleName())
.getCurrentStateValue()[0].getValue();
// debug
this.logger.log(LogService.LOG_INFO, KnxIPOnOffDeviceDriverInstance.logId + "Received new state value: "
+ OnOffValue + " old: " + currentStateValue);
// if the current states it is different from the new state
if (!currentStateValue.equalsIgnoreCase(OnOffValue))
{
State newState;
// set the new state to on or off...
if (OnOffValue.equalsIgnoreCase(OnOffState.ON))
{
newState = new OnOffState(new OnStateValue());
this.notifyOn();
}
else
{
newState = new OnOffState(new OffStateValue());
this.notifyOff();
}
// ... then set the new state for the device and throw a state
// changed notification
this.currentState.setState(newState.getStateName(), newState);
this.updateStatus();
// log
this.logger.log(LogService.LOG_INFO, KnxIPOnOffDeviceDriverInstance.logId + "Notified new state: "
+ newState.getCurrentStateValue()[0].getValue());
}
}
@Override
public void updateStatus()
{
((ElectricalSystem) this.device).updateStatus();
}
@Override
public void notifyOn()
{
if(this.device instanceof Lamp)
{
((Lamp) this.device).notifyOn();
}
else if(this.device instanceof Buzzer)
{
((Buzzer) this.device).notifyOn();
}
else
((OnOffOutput) this.device).notifyOn();
}
@Override
public void notifyOff()
{
if(this.device instanceof Lamp)
{
((Lamp) this.device).notifyOff();
}
else if(this.device instanceof Buzzer)
{
((Buzzer) this.device).notifyOff();
}
else
((OnOffOutput) this.device).notifyOff();
}
@Override
protected void addToNetworkDriver(KnxIPDeviceInfo deviceInfo)
{
try
{
KnxIPDeviceInfo devInfo = new KnxIPDeviceInfo(this.device.getDeviceId(), deviceInfo.getGroupAddress());
devInfo.setGatewayIPAddress(InetAddress.getByName(this.gwAddress));
this.network.addDriver(devInfo, 1, DPTXlatorBoolean.DPT_SWITCH, this);
}
catch (UnknownHostException e)
{
// TODO handle exception here
}
}
@Override
protected void specificConfiguration()
{
// intentionally left empty, no specific configuration for this driver
}
@Override
public void storeScene(Integer sceneNumber)
{
// intentionally left empty
}
@Override
public void deleteScene(Integer sceneNumber)
{
// intentionally left empty
}
@Override
public void deleteGroup(Integer groupID)
{
// intentionally left empty
}
@Override
public void storeGroup(Integer groupID)
{
// intentionally left empty
}
@Override
public void notifyStoredScene(Integer sceneNumber)
{
// intentionally left empty
}
@Override
public void notifyDeletedScene(Integer sceneNumber)
{
// intentionally left empty
}
@Override
public void notifyJoinedGroup(Integer groupNumber)
{
// intentionally left empty
}
@Override
public void notifyLeftGroup(Integer groupNumber)
{
// intentionally left empty
}
}