package org.wso2.carbon.device.mgt.iot.agent.kura.firealarm.impl.real.operation; import com.pi4j.io.gpio.GpioController; import com.pi4j.io.gpio.GpioFactory; import com.pi4j.io.gpio.GpioPinDigitalMultipurpose; import com.pi4j.io.gpio.PinMode; import com.pi4j.io.gpio.RaspiPin; import com.pi4j.io.i2c.I2CBus; import com.pi4j.io.i2c.I2CDevice; import com.pi4j.io.i2c.I2CFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.wso2.carbon.device.mgt.iot.agent.kura.firealarm.core.operation.AgentOperationManager; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.text.DecimalFormat; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class AgentOperationManagerImpl implements AgentOperationManager { private static final Logger log = LoggerFactory.getLogger(AgentOperationManagerImpl.class); private I2CBus _i2cbus; private I2CDevice _temperatureSensor; private GpioController _gpioController; private GpioPinDigitalMultipurpose _lightActuator; private float _temperatureRef = Float.MIN_VALUE; private float _humidityRef = Float.MIN_VALUE; private ScheduledThreadPoolExecutor _scheduledThreadPoolExecutor; private ScheduledFuture<?> _handle; private Runnable temperatureReader = new Runnable() { @Override public void run() { try { float newTemperature = readTemperature(); if (Math.abs(_temperatureRef - newTemperature) > .1f) { _temperatureRef = newTemperature; } } catch (IOException e) { log.error( "An error occurred whilst trying to read temperature from GPIO Pins."); } } }; @Override public void changeBulbStatus(boolean status) { // String bulbScriptPath = ""; // String pythonCommand = "python " + bulbScriptPath + " -s " + (status ? "ON" : "OFF"); // executeCommand(pythonCommand); _lightActuator.setState(status); } @Override public double getTemperature() { // String temperatureScriptPath = ""; // String pythonCommand = "python " + temperatureScriptPath; // String returnVal = executeCommand(pythonCommand); // _temperatureRef = Float.parseFloat(returnVal.split(":")[0].replace("C", "")); return _temperatureRef; } @Override public double getHumidity() { // String temperatureScriptPath = ""; // String pythonCommand = "python " + temperatureScriptPath; // String returnVal = executeCommand(pythonCommand); // _humidityRef = Float.parseFloat(returnVal.split(":")[1].replace("%", "")); _humidityRef = _temperatureRef; return _humidityRef; } public void init(){ try { _gpioController = GpioFactory.getInstance(); _i2cbus = I2CFactory.getInstance(I2CBus.BUS_1); _temperatureSensor = _i2cbus.getDevice(0x40); _lightActuator = _gpioController.provisionDigitalMultipurposePin(RaspiPin.GPIO_00, "led", PinMode.DIGITAL_OUTPUT); _lightActuator.setShutdownOptions(true); // unexport on shutdown // monitor temperature changes // every change of more than 0.1C will notify SensorChangedListeners _scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1); _handle = _scheduledThreadPoolExecutor.scheduleAtFixedRate(temperatureReader, 0, 100, TimeUnit.MILLISECONDS); } catch (IOException e) { log.error("An error occurred whilst trying to read temperature from GPIO Pins."); } } public void terminate(){ if (_gpioController != null) { log.info("... unexport all GPIOs"); _gpioController.unexportAll(); log.info("... shutdown"); _gpioController.shutdown(); log.info("... DONE."); } if (_handle != null) { _handle.cancel(true); } } private synchronized float readTemperature() throws IOException { float temperature; // Set START (D0) and TEMP (D4) in CONFIG (register 0x03) to begin a // new conversion, i.e., write CONFIG with 0x11 _temperatureSensor.write(0x03, (byte) 0x11); // Poll RDY (D0) in STATUS (register 0) until it is low (=0) int status = -1; while ((status & 0x01) != 0) { status = _temperatureSensor.read(0x00); } // Read the upper and lower bytes of the temperature value from // DATAh and DATAl (registers 0x01 and 0x02), respectively byte[] buffer = new byte[3]; _temperatureSensor.read(buffer, 0, 3); int dataH = buffer[1] & 0xff; int dataL = buffer[2] & 0xff; // s_logger.info("I2C: [{}, {}]", new Object[] {dataH, dataL} ); temperature = (dataH * 256 + dataL) >> 2; temperature = (temperature / 32f) - 50f; // s_logger.info("Temperature: {}", temperature); // truncate to 2 decimals DecimalFormat twoDForm = new DecimalFormat("#.##"); return Float.valueOf(twoDForm.format(temperature)); } private String executeCommand(String command) { StringBuffer output = new StringBuffer(); Process p; try { p = Runtime.getRuntime().exec(command); p.waitFor(); BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); String line = ""; while ((line = reader.readLine()) != null) { output.append(line + "\n"); } } catch (Exception e) { log.info(e.getMessage(), e); } return output.toString(); } }