extensions/net.sf.basedb.labenv/trunk/src/net/sf/basedb/labenv/util/LabSensorUtil.java

Code
Comments
Other
Rev Date Author Line
2303 02 Apr 14 olle 1 /**
2303 02 Apr 14 olle 2   $Id $
2303 02 Apr 14 olle 3
2303 02 Apr 14 olle 4   Copyright (C) 2014 Olle MÃ¥nsson
2303 02 Apr 14 olle 5
2303 02 Apr 14 olle 6   This file is part of the LabEnv extension for BASE.
2303 02 Apr 14 olle 7   Available at http://baseplugins.thep.lu.se/
2303 02 Apr 14 olle 8   BASE main site: http://base.thep.lu.se/
2303 02 Apr 14 olle 9   -----------------------------------------------------------
2303 02 Apr 14 olle 10   
2303 02 Apr 14 olle 11   This is free software; you can redistribute it and/or
2303 02 Apr 14 olle 12   modify it under the terms of the GNU General Public License
2303 02 Apr 14 olle 13   as published by the Free Software Foundation; either version 3
2303 02 Apr 14 olle 14   of the License, or (at your option) any later version.
2303 02 Apr 14 olle 15   
2303 02 Apr 14 olle 16   The software is distributed in the hope that it will be useful,
2303 02 Apr 14 olle 17   but WITHOUT ANY WARRANTY; without even the implied warranty of
2303 02 Apr 14 olle 18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2303 02 Apr 14 olle 19   GNU General Public License for more details.
2303 02 Apr 14 olle 20   
2303 02 Apr 14 olle 21   You should have received a copy of the GNU General Public License
2303 02 Apr 14 olle 22   along with BASE. If not, see <http://www.gnu.org/licenses/>.
2303 02 Apr 14 olle 23
2303 02 Apr 14 olle 24 */
2303 02 Apr 14 olle 25 package net.sf.basedb.labenv.util;
2303 02 Apr 14 olle 26
2303 02 Apr 14 olle 27 import java.util.Date;
2303 02 Apr 14 olle 28
2303 02 Apr 14 olle 29 import net.sf.basedb.labenv.dao.LabEnvironmentData;
5517 19 Jun 19 nicklas 30 import net.sf.basedb.util.FileUtil;
2303 02 Apr 14 olle 31 import net.sf.basedb.labenv.converter.Base64Coder;
3019 09 Dec 14 nicklas 32
2303 02 Apr 14 olle 33 import org.json.simple.JSONObject;
2303 02 Apr 14 olle 34 import org.json.simple.parser.ParseException;
2303 02 Apr 14 olle 35 import org.json.simple.parser.JSONParser;
5517 19 Jun 19 nicklas 36 import org.apache.http.HttpEntity;
5517 19 Jun 19 nicklas 37 import org.apache.http.client.config.RequestConfig;
5517 19 Jun 19 nicklas 38 import org.apache.http.impl.client.CloseableHttpClient;
5517 19 Jun 19 nicklas 39 import org.apache.http.impl.client.HttpClients;
5517 19 Jun 19 nicklas 40 import org.apache.http.util.EntityUtils;
5517 19 Jun 19 nicklas 41 import org.apache.http.client.methods.CloseableHttpResponse;
5517 19 Jun 19 nicklas 42 import org.apache.http.client.methods.HttpGet;
2328 08 Apr 14 olle 43 import org.slf4j.Logger;
2328 08 Apr 14 olle 44 import org.slf4j.LoggerFactory;
2303 02 Apr 14 olle 45
2303 02 Apr 14 olle 46 public class LabSensorUtil
2303 02 Apr 14 olle 47 {
2328 08 Apr 14 olle 48   private static final Logger log = LoggerFactory.getLogger(LabSensorUtil.class);
2303 02 Apr 14 olle 49   private int timeoutInSeconds = 5;
2303 02 Apr 14 olle 50
2303 02 Apr 14 olle 51   public int getTimeoutInSeconds()
2303 02 Apr 14 olle 52   {
2303 02 Apr 14 olle 53     return this.timeoutInSeconds;
2303 02 Apr 14 olle 54   }
2303 02 Apr 14 olle 55
2303 02 Apr 14 olle 56   
2303 02 Apr 14 olle 57   public void setTimeoutInSeconds(int timeoutInSeconds)
2303 02 Apr 14 olle 58   {
2303 02 Apr 14 olle 59     this.timeoutInSeconds = timeoutInSeconds;
2303 02 Apr 14 olle 60   }
2303 02 Apr 14 olle 61
2303 02 Apr 14 olle 62   
2303 02 Apr 14 olle 63   public LabSensorUtil()
2303 02 Apr 14 olle 64   {}
2303 02 Apr 14 olle 65
2303 02 Apr 14 olle 66
2303 02 Apr 14 olle 67   public LabSensorUtil(int timeoutInSeconds)
2303 02 Apr 14 olle 68   {
2303 02 Apr 14 olle 69     setTimeoutInSeconds(timeoutInSeconds);
2303 02 Apr 14 olle 70   }
2303 02 Apr 14 olle 71
2303 02 Apr 14 olle 72
2303 02 Apr 14 olle 73   public String fetchLabSensorName(String sensorUrl)
2303 02 Apr 14 olle 74   {
2303 02 Apr 14 olle 75     // Initialize lab sensor name
2303 02 Apr 14 olle 76     String labSensorName = "";
2303 02 Apr 14 olle 77
2303 02 Apr 14 olle 78     // Add url suffix to get current temperature and humidity data
2303 02 Apr 14 olle 79     sensorUrl += "params.inc";
2303 02 Apr 14 olle 80     String content = fetchDataFromUrl(sensorUrl);
2303 02 Apr 14 olle 81     if (content != null)
2303 02 Apr 14 olle 82     {
2303 02 Apr 14 olle 83       // Parse output for sensor values
2303 02 Apr 14 olle 84       try
2303 02 Apr 14 olle 85       {
2303 02 Apr 14 olle 86         String jsonStr = "" + content;
2303 02 Apr 14 olle 87         // Remove odd character(s) before first left brace "{"
2303 02 Apr 14 olle 88         int leftBraceIndex = jsonStr.indexOf("{");
2303 02 Apr 14 olle 89         if (leftBraceIndex >= 0)
2303 02 Apr 14 olle 90         {
2303 02 Apr 14 olle 91           jsonStr = jsonStr.substring(leftBraceIndex);
2303 02 Apr 14 olle 92         }
2303 02 Apr 14 olle 93         jsonStr = jsonStr.replaceAll("\\'", "\\\"");
2303 02 Apr 14 olle 94         JSONParser parser = new JSONParser();
2303 02 Apr 14 olle 95         JSONObject jsonOutput = (JSONObject) parser.parse(jsonStr);
2303 02 Apr 14 olle 96         String c04 = (String) jsonOutput.get("C04");
2303 02 Apr 14 olle 97         String d30 = (String) jsonOutput.get("D30");
2303 02 Apr 14 olle 98         String d31 = (String) jsonOutput.get("D31");
2303 02 Apr 14 olle 99         String c05 = (String) jsonOutput.get("C05");
2303 02 Apr 14 olle 100         // Decode Base64-encoded data
2303 02 Apr 14 olle 101         byte[] d30ByteArray = Base64Coder.decode(d30.toCharArray());
2303 02 Apr 14 olle 102         // Get sensor name from beginning of Base64-decoded byte array
2303 02 Apr 14 olle 103         int arraySize = d30ByteArray.length;
2303 02 Apr 14 olle 104         for (int i = 0; i < arraySize; i++)
2303 02 Apr 14 olle 105         {
2303 02 Apr 14 olle 106           char curChar = (char) d30ByteArray[i];
2303 02 Apr 14 olle 107           if (curChar != (char) 0x00)
2303 02 Apr 14 olle 108           {
2303 02 Apr 14 olle 109             labSensorName += curChar;
2303 02 Apr 14 olle 110           }
2303 02 Apr 14 olle 111           else
2303 02 Apr 14 olle 112           {
2303 02 Apr 14 olle 113             // Stop after first null byte
2303 02 Apr 14 olle 114             break;
2303 02 Apr 14 olle 115           }
2303 02 Apr 14 olle 116         }
2303 02 Apr 14 olle 117       }
2303 02 Apr 14 olle 118       catch (ParseException e)
2303 02 Apr 14 olle 119       {
2303 02 Apr 14 olle 120         log.debug("JSON ParseException e = " + e);
2303 02 Apr 14 olle 121       }
2303 02 Apr 14 olle 122     }
2303 02 Apr 14 olle 123     return labSensorName;
2303 02 Apr 14 olle 124   }
2303 02 Apr 14 olle 125
2303 02 Apr 14 olle 126
3020 09 Dec 14 nicklas 127   public LabEnvironmentData createLabEnvironmentData(String sensorUrl, boolean fetchSensorName)
2303 02 Apr 14 olle 128   {
2303 02 Apr 14 olle 129     // Get lab sensor name from sensor
3020 09 Dec 14 nicklas 130     String internalLabSensorName = fetchSensorName ? fetchLabSensorName(sensorUrl) : "";
2303 02 Apr 14 olle 131     // If no lab sensor name could be obtained, the connection is most likely broken
2303 02 Apr 14 olle 132     LabEnvironmentData labEnvironmentData = null;
2303 02 Apr 14 olle 133     if (internalLabSensorName != null)
2303 02 Apr 14 olle 134     {
2303 02 Apr 14 olle 135       labEnvironmentData = createLabEnvironmentData(sensorUrl, internalLabSensorName);
2303 02 Apr 14 olle 136     }
2303 02 Apr 14 olle 137     return labEnvironmentData;
2303 02 Apr 14 olle 138   }
2303 02 Apr 14 olle 139
2303 02 Apr 14 olle 140
2303 02 Apr 14 olle 141   public LabEnvironmentData createLabEnvironmentData(String sensorUrl, String sensorName)
2303 02 Apr 14 olle 142   {
2303 02 Apr 14 olle 143     // Initialize lab temperature and humidity data
2303 02 Apr 14 olle 144     String serialNumber = "";
2303 02 Apr 14 olle 145     Date dateTime = null;
2303 02 Apr 14 olle 146     double temperature = -1.0;
2303 02 Apr 14 olle 147     double humidity = -1.0;
2303 02 Apr 14 olle 148     LabEnvironmentData labEnvironmentData = null;
2303 02 Apr 14 olle 149     // Add url suffix to get current temperature and humidity data
2303 02 Apr 14 olle 150     sensorUrl += "current.inc";
2303 02 Apr 14 olle 151     String content = fetchDataFromUrl(sensorUrl);
2303 02 Apr 14 olle 152     if (content != null)
2303 02 Apr 14 olle 153     {
2303 02 Apr 14 olle 154       // Parse output for sensor values
2303 02 Apr 14 olle 155       try
2303 02 Apr 14 olle 156       {
2303 02 Apr 14 olle 157         String jsonStr = "" + content;
2303 02 Apr 14 olle 158         // Remove odd character(s) before first left brace "{"
2303 02 Apr 14 olle 159         int leftBraceIndex = jsonStr.indexOf("{");
2303 02 Apr 14 olle 160         if (leftBraceIndex >= 0)
2303 02 Apr 14 olle 161         {
2303 02 Apr 14 olle 162           jsonStr = jsonStr.substring(leftBraceIndex);
2303 02 Apr 14 olle 163         }
2303 02 Apr 14 olle 164         jsonStr = jsonStr.replaceAll("\\'", "\\\"");
2303 02 Apr 14 olle 165         JSONParser parser = new JSONParser();
2303 02 Apr 14 olle 166         JSONObject jsonOutput = (JSONObject) parser.parse(jsonStr);
2303 02 Apr 14 olle 167         String c02 = (String) jsonOutput.get("C02");
2303 02 Apr 14 olle 168         String d20 = (String) jsonOutput.get("D20");
2303 02 Apr 14 olle 169         String d21 = (String) jsonOutput.get("D21");
2303 02 Apr 14 olle 170         String c03 = (String) jsonOutput.get("C03");
2303 02 Apr 14 olle 171         // Decode Base64-encoded data
2303 02 Apr 14 olle 172         byte[] d20ByteArray = Base64Coder.decode(d20.toCharArray());
2303 02 Apr 14 olle 173         byte[] d21ByteArray = Base64Coder.decode(d21.toCharArray());
2303 02 Apr 14 olle 174         // Get sensor serial number from Base64-decoded byte array
2303 02 Apr 14 olle 175         int arraySize = d21ByteArray.length;
2303 02 Apr 14 olle 176         for (int i = 0; i < 8 && (10 + i) < arraySize ; i++)
2303 02 Apr 14 olle 177         {
2303 02 Apr 14 olle 178           char curChar = (char) d21ByteArray[10 + i];
2303 02 Apr 14 olle 179           if (curChar != (char) 0x00)
2303 02 Apr 14 olle 180           {
2303 02 Apr 14 olle 181             serialNumber += curChar;
2303 02 Apr 14 olle 182           }
2303 02 Apr 14 olle 183         }
2303 02 Apr 14 olle 184         // Get raw variable values from Base64-decoded byte array
2540 03 Jul 14 olle 185         if (d20ByteArray.length >= 44)
2540 03 Jul 14 olle 186         {          
2540 03 Jul 14 olle 187           int ch1 = (d20ByteArray[26] & 0xFF) | ((d20ByteArray[27] & 0xFF) << 8);
2540 03 Jul 14 olle 188           int ch2 = (d20ByteArray[42] & 0xFF) | ((d20ByteArray[43] & 0xFF) << 8);
2540 03 Jul 14 olle 189           // Variable nowTime is the number of seconds since 1070-01-01 00:00:00
2540 03 Jul 14 olle 190           long nowTime = (d20ByteArray[6] & 0xFF) | ((d20ByteArray[7] & 0xFF) << 8) | ((d20ByteArray[8] & 0xFF) << 16) | ((d20ByteArray[9] & 0xFF) << 24);
2540 03 Jul 14 olle 191           // Get variable values from raw variable values
2540 03 Jul 14 olle 192           temperature = (ch1 - 1000)/10.0;
2540 03 Jul 14 olle 193           humidity = (ch2 - 1000)/10.0;
2540 03 Jul 14 olle 194           // Convert nowTime to number of ms since 1070-01-01 00:00:00 before getting dateTime
2540 03 Jul 14 olle 195           dateTime = new Date(nowTime*1000);
2540 03 Jul 14 olle 196           labEnvironmentData = new LabEnvironmentData(sensorUrl, sensorName, serialNumber, dateTime, temperature, humidity);
2540 03 Jul 14 olle 197         }
2540 03 Jul 14 olle 198         else
2540 03 Jul 14 olle 199         {
2540 03 Jul 14 olle 200           log.debug("createLabEnvironmentData(" + sensorUrl + ", " + sensorName + "): d20ByteArray.length = " + d20ByteArray.length + " < 44");
2540 03 Jul 14 olle 201         }
2303 02 Apr 14 olle 202       }
2303 02 Apr 14 olle 203       catch (ParseException e)
2303 02 Apr 14 olle 204       {
2303 02 Apr 14 olle 205         log.debug("JSON ParseException e = " + e);
2303 02 Apr 14 olle 206       }
2303 02 Apr 14 olle 207     }
2303 02 Apr 14 olle 208     return labEnvironmentData;
2303 02 Apr 14 olle 209   }
2303 02 Apr 14 olle 210
2303 02 Apr 14 olle 211
2303 02 Apr 14 olle 212   private String fetchDataFromUrl(String url)
2303 02 Apr 14 olle 213   {
2303 02 Apr 14 olle 214     // Execute request
2303 02 Apr 14 olle 215     String content = null;
2303 02 Apr 14 olle 216     String ioErrorString = null;
2303 02 Apr 14 olle 217     // Apache HttpClient stuff
5517 19 Jun 19 nicklas 218     int timeoutMillis = timeoutInSeconds * 1000;
5517 19 Jun 19 nicklas 219     
5517 19 Jun 19 nicklas 220     RequestConfig config = RequestConfig.custom().setConnectTimeout(timeoutMillis).setSocketTimeout(timeoutMillis).build();
5517 19 Jun 19 nicklas 221     CloseableHttpClient client = null;
5517 19 Jun 19 nicklas 222     CloseableHttpResponse response = null;
2303 02 Apr 14 olle 223     try
2303 02 Apr 14 olle 224     {
2303 02 Apr 14 olle 225       // Prepare HTTP get
5517 19 Jun 19 nicklas 226       HttpGet getMethod = new HttpGet(url);
5517 19 Jun 19 nicklas 227
5517 19 Jun 19 nicklas 228       client = HttpClients.custom().setDefaultRequestConfig(config).build();
5517 19 Jun 19 nicklas 229       response = client.execute(getMethod);
5517 19 Jun 19 nicklas 230       int status = response.getStatusLine().getStatusCode();
5517 19 Jun 19 nicklas 231       
5517 19 Jun 19 nicklas 232       if (status != 200)
2303 02 Apr 14 olle 233       {
5517 19 Jun 19 nicklas 234         log.error("fetchDataFromUrl(" + url + "): Error when trying to execute GetMethod: " + response.getStatusLine());
2303 02 Apr 14 olle 235       }
3019 09 Dec 14 nicklas 236       else
3019 09 Dec 14 nicklas 237       {
3019 09 Dec 14 nicklas 238         // Display response
3019 09 Dec 14 nicklas 239         // Time consuming step
5517 19 Jun 19 nicklas 240         HttpEntity entity = response.getEntity();
5517 19 Jun 19 nicklas 241         if (entity != null) content = EntityUtils.toString(response.getEntity());
3019 09 Dec 14 nicklas 242       }
2303 02 Apr 14 olle 243     }
2303 02 Apr 14 olle 244     catch (Exception e1)
2303 02 Apr 14 olle 245     {
3019 09 Dec 14 nicklas 246       log.error("fetchDataFromUrl(" + url + "): Exception when trying to execute HttpClient method : ", e1);
2303 02 Apr 14 olle 247       ioErrorString = e1.getMessage();
2303 02 Apr 14 olle 248     }
2303 02 Apr 14 olle 249     finally
2303 02 Apr 14 olle 250     {
5517 19 Jun 19 nicklas 251       FileUtil.close(response);
5517 19 Jun 19 nicklas 252       FileUtil.close(client);
2303 02 Apr 14 olle 253     }
2540 03 Jul 14 olle 254     //log.debug("fetchDataFromUrl(" + url + "): content = " + content);
2303 02 Apr 14 olle 255     return content;
2303 02 Apr 14 olle 256   }
2303 02 Apr 14 olle 257 }