/* * Dog - Device Driver * * Copyright (c) 2012-2014 Dario Bonino and Luigi De Russis * * 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.modbus.co2sensor; import it.polito.elite.dog.core.library.model.CNParameters; 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.Co2Sensor; import it.polito.elite.dog.core.library.model.notification.Co2MeasurementNotification; import it.polito.elite.dog.core.library.model.state.Co2MeasurementState; import it.polito.elite.dog.core.library.model.statevalue.Co2MeasurementStateValue; import it.polito.elite.dog.core.library.util.LogHelper; import it.polito.elite.dog.drivers.modbus.network.ModbusDriverInstance; import it.polito.elite.dog.drivers.modbus.network.info.ModbusRegisterInfo; import it.polito.elite.dog.drivers.modbus.network.interfaces.ModbusNetwork; import java.lang.reflect.Method; import java.util.Set; import javax.measure.DecimalMeasure; import javax.measure.Measure; import javax.measure.quantity.Dimensionless; import javax.measure.unit.Unit; import org.osgi.framework.BundleContext; import org.osgi.service.log.LogService; /** * * @author <a href="mailto:dario.bonino@polito.it">Dario Bonino</a> * @see <a href="http://elite.polito.it">http://elite.polito.it</a> * */ public class ModbusCo2SensorDriverInstance extends ModbusDriverInstance implements Co2Sensor { // the class logger private LogHelper logger; /** * @param network * @param device * @param gatewayAddress * @param context */ public ModbusCo2SensorDriverInstance(ModbusNetwork network, ControllableDevice device, String gatewayAddress, String gatewayPort, String gatewayProtocol, BundleContext context) { super(network, device, gatewayAddress, gatewayPort, gatewayProtocol); // create a logger this.logger = new LogHelper(context); // TODO: get the initial state of the device....(states can be updated // by reading notification group addresses) this.initializeStates(); } /* * (non-Javadoc) * * @see it.polito.elite.domotics.model.devicecategory.Co2Sensor#getCo2 () */ @Override public Measure<?, ?> getCo2Concentration() { return (Measure<?, ?>) this.currentState.getState(Co2MeasurementState.class.getSimpleName()) .getCurrentStateValue()[0].getValue(); } /* * (non-Javadoc) * * @see it.polito.elite.domotics.model.devicecategory.Co2Sensor#getState() */ @Override public DeviceStatus getState() { return this.currentState; } /* * (non-Javadoc) * * @see it.polito.elite.domotics.model.devicecategory.Co2Sensor# * notifyNewCo2Value(javax.measure.Measure) */ @Override public void notifyChangedCo2Concentration(Measure<?, ?> co2Concentration) { // update the state Co2MeasurementStateValue pValue = new Co2MeasurementStateValue(); pValue.setValue(co2Concentration); this.currentState.setState(Co2MeasurementState.class.getSimpleName(), new Co2MeasurementState(pValue)); // notify the new measure ((Co2Sensor) this.device).notifyChangedCo2Concentration(co2Concentration); } /* * (non-Javadoc) * * @see it.polito.elite.dog.drivers.modbus.network.ModbusDriver# * newMessageFromHouse (it.polito.elite.dog.drivers.modbus.network.info * .ModbusRegisterInfo, java.lang.String) */ @Override public void newMessageFromHouse(ModbusRegisterInfo register, String value) { if (value != null) { // gets the corresponding notification set... Set<CNParameters> notificationInfos = this.register2Notification.get(register); // handle the notifications for (CNParameters notificationInfo : notificationInfos) { // black magic here... String notificationName = notificationInfo.getName(); // get the hypothetical class method name String notifyMethod = "notify" + Character.toUpperCase(notificationName.charAt(0)) + notificationName.substring(1); // search the method and execute it try { // log notification this.logger.log(LogService.LOG_DEBUG, ModbusCo2SensorDriver.logId + "Device: " + this.device.getDeviceId() + " is notifying " + notificationName + " value:" + register.getXlator().getValue()); // get the method Method notify = ModbusCo2SensorDriverInstance.class.getDeclaredMethod(notifyMethod, Measure.class); // invoke the method notify.invoke(this, DecimalMeasure.valueOf(register.getXlator().getValue())); } catch (Exception e) { // log the error this.logger.log(LogService.LOG_WARNING, ModbusCo2SensorDriver.logId + "Unable to find a suitable notification method for the datapoint: " + register + ":\n" + e); } // notify the monitor admin this.updateStatus(); } } } /* * (non-Javadoc) * * @see it.polito.elite.dog.drivers.modbus.network.ModbusDriver# * specificConfiguration() */ @Override protected void specificConfiguration() { // prepare the device state map this.currentState = new DeviceStatus(device.getDeviceId()); } /* * (non-Javadoc) * * @see * it.polito.elite.dog.core.library.model.devicecategory.Co2Sensor#updateStatus * () */ @Override public void updateStatus() { ((Co2Sensor) this.device).updateStatus(); } /* * (non-Javadoc) * * @see it.polito.elite.dog.drivers.modbus.network.ModbusDriver# * addToNetworkDriver (it.polito.elite.dog.drivers.modbus.network.info. * ModbusRegisterInfo) */ @Override protected void addToNetworkDriver(ModbusRegisterInfo register) { this.network.addDriver(register, this); } private void initializeStates() { // Since this driver handles the device metering according to a well // defined interface, we can get the unit of measure from all the // notifications handled by this device except from state notifications Unit<Dimensionless> PPM = Unit.ONE.alternate("ppm"); String Co2UOM = PPM.toString(); // search the energy unit of measures declared in the device // configuration for (ModbusRegisterInfo register : this.register2Notification.keySet()) { Set<CNParameters> notificationInfos = this.register2Notification.get(register); for (CNParameters notificationInfo : notificationInfos) { if (notificationInfo.getName().equalsIgnoreCase(Co2MeasurementNotification.notificationName)) { Co2UOM = register.getXlator().getUnitOfMeasure(); } } } // create all the states Co2MeasurementStateValue pValue = new Co2MeasurementStateValue(); pValue.setValue(DecimalMeasure.valueOf("0 " + Co2UOM)); this.currentState.setState(Co2MeasurementState.class.getSimpleName(), new Co2MeasurementState(pValue)); // read the initial state this.network.readAll(this.register2Notification.keySet()); } }