001/* 002 * $URL: svn://fred.webarts.bc.ca/open/trunk/projects/WebARTS/ca/bc/webarts/tools/WeatherStationRestRequester.java $ 003 * $Author: tgutwin $ 004 * $Revision: 1414 $ 005 * $Date: 2020-11-10 23:03:56 -0800 (Tue, 10 Nov 2020) $ 006 */ 007/* 008 * 009 * Written by Tom Gutwin - WebARTS Design. 010 * Copyright (C) 2020 WebARTS Design, Burnaby Canada 011 * http://www.webarts.ca 012 * 013 * This program is free software; you can redistribute it and/or modify 014 * it under the terms of the GNU General Public License as published by 015 * the Free Software Foundation; version 3 of the License, or 016 * (at your option) any later version. 017 * 018 * This program is distributed in the hope that it will be useful, 019 * but WITHOUT ANY WARRANTY; without_ even the implied warranty of 020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 021 * GNU General Public License for more details. 022 * 023 * You should have received a copy of the GNU General Public License 024 * along with this program; if not, write to the Free Software 025 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 026 */ 027 028package ca.bc.webarts.tools; 029 030import java.io.IOException; 031import java.io.File; 032import java.io.FileNotFoundException; 033import java.lang.Integer; 034import java.net.HttpURLConnection; 035import java.net.MalformedURLException; 036import java.net.URL; 037import java.net.URLEncoder; 038import java.util.Arrays; 039import java.util.Comparator; 040import java.util.Hashtable; 041import java.util.Set; 042import java.util.Vector; 043 044 045import ca.bc.webarts.tools.RestRequester; 046import ca.bc.webarts.widgets.Util; 047import ca.bc.webarts.widgets.Quick; 048 049import org.apache.commons.codec.binary.Base64; 050 051import nu.xom.Attribute; 052import nu.xom.Builder; 053import nu.xom.Document; 054import nu.xom.Element; 055import nu.xom.Elements; 056import nu.xom.Node; 057import nu.xom.ParsingException; 058import nu.xom.ValidityException; 059import nu.xom.Serializer; 060import nu.xom.XPathException; 061 062import javax.json.*; 063import javax.json.stream.JsonGenerator; 064import javax.json.stream.JsonParser; 065 066 067 068 069/** 070 * This class wraps the communication to the REST interface to Tom's Weather Station. 071 * The web service root URL is http://weatherstation.webarts.bc.ca/rest/ 072 * 073 * Written by Tom Gutwin - WebARTS Design.<br /> 074 * Copyright © 2020 WebARTS Design, Burnaby Canada<br /> 075 * <a href="http://www.webarts.ca">http://www.webarts.ca</a> 076 * 077 * @author Tom B. Gutwin 078 **/ 079public class WeatherStationRestRequester extends RestRequester 080{ 081 protected static final String CLASSNAME = "ca.bc.webarts.tools.MusicBrainzRestRequester"; //ca.bc.webarts.widgets.Util.getCurrentClassName(); 082 public static final String LOG_TAG = "\n"+CLASSNAME; //+"."+ca.bc.webarts.android.Util.getCurrentClassName(); 083 084 /** DEFAULT IP address to use: 10.0.0.80 .**/ 085 protected static final String DEFAULT_WEATHERSTATION_IP = "weatherstation.webarts.bc.ca"; 086 protected static final String DEFAULT_WEATHERSTATION_REST_URL_PATHSTR = "/rest"; 087 088 089 protected static StringBuilder helpMsg_ = new StringBuilder(SYSTEM_LINE_SEPERATOR); 090 protected static boolean debugOut_ = false; 091 protected static boolean doWrites_ = true; 092 093 /** The start path to use in therest URL. Over-ride this if you extend this class. **/ 094 protected String restUrlPath_ = DEFAULT_WEATHERSTATION_REST_URL_PATHSTR; 095 Builder xmlBuilder_ = new Builder(); 096 097 /** 098 * Default constructor . 099 * 100 **/ 101 public WeatherStationRestRequester() 102 { 103 authenticating_=false; 104 setBaseUrl( "http://"+DEFAULT_WEATHERSTATION_IP+restUrlPath_); 105 setAcceptJSON(true); 106 } 107 108 109 /** 110 * Constructor to customize all connection settings. NOT USED. 111 * 112 **/ 113 public WeatherStationRestRequester(String server, String user, String pass) 114 { 115 setBaseUrl( "http://"+server+restUrlPath_); 116 authenticating_=true; 117 setUsername(user); 118 setPassword( pass); 119 setAcceptJSON(true); 120 } 121 122 123 /** 124 * Class main commandLine entry method that has a test command and some convienience commands, as well as a pure rest command. 125 **/ 126 public static void main(String [] args) 127 { 128 final String methodName = CLASSNAME + ": main()"; 129 130 WeatherStationRestRequester instance = new WeatherStationRestRequester(); 131 132 /* Simple way af parsing the args */ 133 if (args ==null || args.length<1) 134 { 135 System.out.println(getHelpMsgStr()); 136 instance.setAcceptJSON(true); // flase means get XML 137 System.out.println("Can Connect? "+(instance.canConnect()?"Yes":"No")); 138 } 139 /* *************************************** */ 140 else 141 { 142 if (args[0].equalsIgnoreCase("weather")) 143 { 144 instance.debugOut_=false; 145 System.out.println(prettyJson(instance.getWeather().toString())); 146 } 147 /* *************************************** */ 148 else if (args[0].equalsIgnoreCase("temp")) 149 { 150 instance.debugOut_=false; 151 System.out.println("Temperature = "+instance.getTemperature()+" "+instance.getTemperatureUnits()); 152 } 153 /* *************************************** */ 154 else if (args[0].equalsIgnoreCase("Pressure")) 155 { 156 instance.debugOut_=false; 157 System.out.println("Pressure = "+instance.getPressure()+" "+instance.getPressureUnits()); 158 } 159 /* *************************************** */ 160 else if (args[0].equalsIgnoreCase("humidity")) 161 { 162 instance.debugOut_=false; 163 System.out.println("Humidity = "+instance.getHumidity()+" "+instance.getHumidityUnits()); 164 } 165 /* *************************************** */ 166 else if (args[0].equalsIgnoreCase("altitude")) 167 { 168 instance.debugOut_=false; 169 System.out.println("Altitude = "+instance.getAltitude()+" "+instance.getAltitudeUnits()); 170 } 171 /* *************************************** */ 172 else 173 { 174 //Send it directly as a rest request 175 instance.restCMD(args); 176 } 177 } 178 } // main 179 180 181 182 /** 183 * Set Method for class field 'restUrlPath_'. 184 * 185 * @param restUrlPath_ is the value to set this class field to. 186 * 187 **/ 188 public void setRestUrlPath(String restUrlPath) 189 { 190 restUrlPath_ = restUrlPath; 191 } // setRestUrlPath Method 192 193 194 /** 195 * Get Method for class field 'restUrlPath_'. 196 * 197 * @return String - The value the class field 'restUrlPath_'. 198 * 199 **/ 200 public String getRestUrlPath() 201 { 202 return restUrlPath_; 203 } // getRestUrlPath Method 204 205 206 /** Check connectivity to the WeatherStation URL specified by the class parms. 207 * @return true or false 208 **/ 209 public boolean canConnect() 210 { 211 if(debugOut_) System.out.println(LOG_TAG+".canConnect("+getBaseUrl()+")"); 212 213 boolean retVal = false; 214 if(isInit()) 215 { 216 try 217 { 218 if(debugOut_) System.out.println(LOG_TAG+".init = true"); 219 String usrlStr = (getBaseUrl()+"/weather").replace(" " ,"%20"); 220 if(debugOut_) System.out.println("Can Connect to: "+usrlStr); 221 URL url = new URL(usrlStr); 222 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 223 conn.setRequestMethod("GET"); 224 if(acceptJSON_) 225 conn.setRequestProperty("Accept", "application/json"); 226 else 227 conn.setRequestProperty("Accept", "application/xml"); 228 229 conn.setRequestProperty("User-Agent", USER_AGENT+" ( tgutwin@webarts.ca )"); 230 231 if (authenticating_) 232 { 233 //BASE64Encoder enc = new sun.misc.BASE64Encoder(); 234 String userpassword = username_ + ":" + password_; 235 //String encodedAuthorization = android.util.Base64.encodeToString( userpassword.getBytes(), android.util.Base64.DEFAULT ); 236 String encodedAuthorization = new String(Base64.encodeBase64( (userpassword.getBytes()) )); 237 conn.setRequestProperty("Authorization", "Basic "+ encodedAuthorization); 238 } 239 240 if (conn.getResponseCode() == 200) 241 { 242 retVal=true; 243 } // valid http response code 244 conn.disconnect(); 245 } 246 catch (MalformedURLException e) 247 { 248 e.printStackTrace(); 249 } 250 catch (IOException e) 251 { 252 e.printStackTrace(); 253 } 254 } 255 return retVal; 256 } 257 258 259 /** returns all the Weather data. **/ 260 public StringBuilder getWeather() 261 { 262 return serviceGet("/weather"); 263 } 264 265 266 /** Reads and parses out the weather JsonObject from the JSON. **/ 267 private JsonObject getJsonWeather(String restRequest) 268 { 269 JsonObject jsonWeather = null; 270 String restResponse = serviceGet("/"+restRequest).toString(); 271 JsonReader jsonReader = Json.createReader(new java.io.StringReader(restResponse)); 272 JsonObject jsonResponse = jsonReader.readObject(); 273 jsonReader.close(); 274 //System.out.println("jsonOject =\n"+jsonResponse); 275 jsonWeather = jsonResponse.getJsonObject("weather"); 276 277 return jsonWeather; 278 } 279 280 281 /** returns temperature. **/ 282 public double getTemperature() 283 { 284 JsonObject jsonWeather = getJsonWeather("temp"); 285 JsonObject json = jsonWeather.getJsonObject("temperature"); 286 double temp = json.getJsonNumber("value").doubleValue(); 287 return temp; 288 } 289 290 291 /** returns temperature Units. **/ 292 public String getTemperatureUnits() 293 { 294 JsonObject jsonWeather = getJsonWeather("temp"); 295 JsonObject json = jsonWeather.getJsonObject("temperature"); 296 String units = json.getString("units"); 297 return units; 298 } 299 300 301 /** returns pressure. **/ 302 public double getPressure() 303 { 304 JsonObject jsonWeather = getJsonWeather("pressure"); 305 JsonObject json = jsonWeather.getJsonObject("pressure"); 306 double temp = json.getJsonNumber("value").doubleValue(); 307 return temp; 308 } 309 310 311 /** returns pressure Units. **/ 312 public String getPressureUnits() 313 { 314 JsonObject jsonWeather = getJsonWeather("pressure"); 315 JsonObject json = jsonWeather.getJsonObject("pressure"); 316 String units = json.getString("units"); 317 return units; 318 } 319 320 321 /** returns humidity. **/ 322 public double getHumidity() 323 { 324 JsonObject jsonWeather = getJsonWeather("humidity"); 325 JsonObject json = jsonWeather.getJsonObject("humidity"); 326 double temp = json.getJsonNumber("value").doubleValue(); 327 return temp; 328 } 329 330 331 /** returns humidity Units. **/ 332 public String getHumidityUnits() 333 { 334 JsonObject jsonWeather = getJsonWeather("humidity"); 335 JsonObject json = jsonWeather.getJsonObject("humidity"); 336 String units = json.getString("units"); 337 return units; 338 } 339 340 341 /** returns altitude. **/ 342 public double getAltitude() 343 { 344 JsonObject jsonWeather = getJsonWeather("altitude"); 345 JsonObject json = jsonWeather.getJsonObject("altitude"); 346 double temp = json.getJsonNumber("value").doubleValue(); 347 return temp; 348 } 349 350 351 /** returns altitude Units. **/ 352 public String getAltitudeUnits() 353 { 354 JsonObject jsonWeather = getJsonWeather("altitude"); 355 JsonObject json = jsonWeather.getJsonObject("altitude"); 356 String units = json.getString("units"); 357 return units; 358 } 359 360 361 /** returns BatteryVoltage. **/ 362 public double getBatteryVoltage() 363 { 364 JsonObject jsonBatt = null; 365 String restResponse = serviceGet("/batteryVoltage").toString(); 366 JsonReader jsonReader = Json.createReader(new java.io.StringReader(restResponse)); 367 JsonObject jsonResponse = jsonReader.readObject(); 368 jsonReader.close(); 369 //System.out.println("jsonOject =\n"+jsonResponse); 370 jsonBatt = jsonResponse.getJsonObject("batteryVoltage"); 371 double temp = jsonBatt.getJsonNumber("value").doubleValue(); 372 return temp; 373 } 374 375 376 /** returns Battery Voltage Units. **/ 377 public String getBatteryVoltageUnits() 378 { 379 JsonObject jsonBatt = null; 380 String restResponse = serviceGet("/batteryVoltage").toString(); 381 JsonReader jsonReader = Json.createReader(new java.io.StringReader(restResponse)); 382 JsonObject jsonResponse = jsonReader.readObject(); 383 jsonReader.close(); 384 //System.out.println("jsonOject =\n"+jsonResponse); 385 jsonBatt = jsonResponse.getJsonObject("batteryVoltage"); 386 String units = jsonBatt.getString("units"); 387 return units; 388 } 389 390 391 /** returns BatteryPercent. **/ 392 public double getBatteryPercent() 393 { 394 JsonObject jsonBatt = null; 395 String restResponse = serviceGet("/batteryPercent").toString(); 396 JsonReader jsonReader = Json.createReader(new java.io.StringReader(restResponse)); 397 JsonObject jsonResponse = jsonReader.readObject(); 398 jsonReader.close(); 399 //System.out.println("jsonOject =\n"+jsonResponse); 400 jsonBatt = jsonResponse.getJsonObject("batteryPercent"); 401 double temp = jsonBatt.getJsonNumber("value").doubleValue(); 402 return temp; 403 } 404 405 406 /** returns Battery Percent Units. **/ 407 public String getBatteryPercentUnits() 408 { 409 JsonObject jsonBatt = null; 410 String restResponse = serviceGet("/batteryPercent").toString(); 411 JsonReader jsonReader = Json.createReader(new java.io.StringReader(restResponse)); 412 JsonObject jsonResponse = jsonReader.readObject(); 413 jsonReader.close(); 414 //System.out.println("jsonOject =\n"+jsonResponse); 415 jsonBatt = jsonResponse.getJsonObject("batteryPercent"); 416 String units = jsonBatt.getString("units"); 417 return units; 418 } 419 420 421 /** 422 * commandLine command executor method for the default rest Command. 423 * It treats each arg as a part of a single rest command and passes it along to the ISY. 424 * @param args the array of commandLine args that got passed in 425 **/ 426 protected void restCMD(String [] args) 427 { 428 final String methodName = CLASSNAME + ": restCMD(String [])"; 429 // Parse the command 430 String allcommands = args[0]; 431 for (int i=1;i< args.length;i++) allcommands+=" "+args[i]; 432 if (debugOut_) System.out.print("Sending WeatherStation Rest Service request: "+allcommands); 433 String passedCommand = (allcommands.startsWith(restUrlPath_+"/")?allcommands.substring(restUrlPath_.length()):allcommands); 434 if(debugOut_) System.out.println(" ("+passedCommand+")"); 435 passedCommand = (passedCommand.startsWith("/")?passedCommand:"/"+passedCommand); 436 StringBuilder resp = serviceGet(passedCommand); 437 if (resp!=null) 438 { 439 System.out.println(responseIndenter(resp).toString()); 440 System.out.println(); 441 } 442 else 443 { 444 System.out.println("Response Error"); 445 System.out.println(); 446 } 447 448 } 449 450 451 /** 452 * Template method for future commandLine command executor methods. 453 * @param args the array of commandLine args that got passed in 454 **/ 455 protected void templateCMD(String [] args) 456 { 457 final String methodName = CLASSNAME + ": testCMD(String [])"; 458 459 } 460 461 462 /** gets the help as a String. 463 * @return the helpMsg in String form 464 **/ 465 protected static String getHelpMsgStr() {return getHelpMsg().toString();} 466 467 468 /** Makes the JSON string pretty with indenting. **/ 469 public static String prettyJson(String jsonStr) 470 { 471 String retVal = jsonStr; 472 retVal = retVal.replace("[", " [\n"); 473 retVal = retVal.replace("]", " ]" + SYSTEM_LINE_SEPERATOR); 474 retVal = retVal.replace("]\n\"", " ]\"" + SYSTEM_LINE_SEPERATOR); 475 retVal = retVal.replace("{", " {" + SYSTEM_LINE_SEPERATOR + " "); 476 retVal = retVal.replace("}", "}" + SYSTEM_LINE_SEPERATOR); 477 retVal = retVal.replace(",", "," + SYSTEM_LINE_SEPERATOR + " "); 478 retVal = retVal.replace("}" + SYSTEM_LINE_SEPERATOR + "," + SYSTEM_LINE_SEPERATOR, " }," + SYSTEM_LINE_SEPERATOR); 479 retVal = retVal.replace("[\n", " [ "); 480 retVal = retVal.replace(" {", " {"); 481 retVal = retVal.replace("[ {", "[\n {"); 482 retVal = retVal.replace("\n}", "\n }"); 483 return retVal; 484 } 485 486 487 488 /** initializes and gets the helpMsg_ 489 class var. 490 * @return the class var helpMsg_ 491 **/ 492 protected static StringBuilder getHelpMsg() 493 { 494 helpMsg_ = new StringBuilder(SYSTEM_LINE_SEPERATOR); 495 helpMsg_.append("--- WebARTS "+CLASSNAME+" Class -----------------------------------------------------"); 496 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 497 helpMsg_.append("--- + $Revision: 1414 $ $Date: 2020-11-10 23:03:56 -0800 (Tue, 10 Nov 2020) $ ---"); 498 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 499 helpMsg_.append("-------------------------------------------------------------------------------"); 500 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 501 helpMsg_.append("WebARTS ca.bc.webarts.tools.WeatherStationRestRequester Class"); 502 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 503 helpMsg_.append("SYNTAX:"); 504 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 505 helpMsg_.append(" java "); 506 helpMsg_.append(CLASSNAME); 507 helpMsg_.append(" command or {restCommand}"); 508 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 509 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 510 helpMsg_.append("Available commands:"); 511 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 512 helpMsg_.append(" weather"); 513 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 514 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 515 helpMsg_.append(" temp"); 516 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 517 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 518 helpMsg_.append(" Example: java ca.bc.webarts.WeatherStationRestRequester weather "); 519 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 520 helpMsg_.append("---------------------------------------------------------"); 521 helpMsg_.append("----------------------"); 522 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 523 524 return helpMsg_; 525 } 526 527}