001/* 002 * $URL: svn://svn.webarts.bc.ca/open/trunk/projects/WebARTS/ca/bc/webarts/tools/isy/ISYRestRequester.java $ 003 * $Author: tgutwin $ 004 * $Revision: 1091 $ 005 * $Date: 2016-05-29 16:26:54 -0700 (Sun, 29 May 2016) $ 006 */ 007/* 008 * 009 * Written by Tom Gutwin - WebARTS Design. 010 * Copyright (C) 2014-2016 WebARTS Design, North Vancouver 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.isy; 029 030import java.io.IOException; 031import java.lang.Integer; 032import java.net.HttpURLConnection; 033import java.net.MalformedURLException; 034import java.net.URL; 035import java.util.Arrays; 036import java.util.Hashtable; 037import java.util.Set; 038import java.util.Vector; 039 040import ca.bc.webarts.tools.RestRequester; 041import ca.bc.webarts.widgets.Quick; 042 043import org.apache.commons.codec.binary.Base64; 044 045import nu.xom.Attribute; 046import nu.xom.Builder; 047import nu.xom.Document; 048import nu.xom.Element; 049import nu.xom.Elements; 050import nu.xom.Node; 051import nu.xom.ParsingException; 052import nu.xom.ValidityException; 053import nu.xom.Serializer; 054 055 056/** 057 * This class wraps the communication to the REST interface of a 058 * <a href="http://www.universal-devices.com">UDI ISY-994</a>. 059 * It provides many prebuilt java methods that wrap a specific REST call or you can request any one that 060 * is specified in the REST API - 061 * <a href="http://wiki.universal-devices.com/index.php?title=ISY_Developers:API:REST_Interface"> 062 * http://wiki.universal-devices.com/index.php?title=ISY_Developers:API:REST_Interface</a>.<br /> 063 * Written by Tom Gutwin - WebARTS Design.<br /> 064 * Copyright © 2014-2016 WebARTS Design, North Vancouver Canada<br /> 065 * <a href="http://www.webarts.ca">http://www.webarts.ca</a> 066 * 067 * @author Tom B. Gutwin 068 **/ 069public class ISYRestRequester extends RestRequester 070{ 071 protected static final String CLASSNAME = "ca.bc.webarts.tools.isy.ISYRestRequester"; //ca.bc.webarts.widgets.Util.getCurrentClassName(); 072 public static final String LOG_TAG = "\n"+CLASSNAME; //+"."+ca.bc.webarts.android.Util.getCurrentClassName(); 073 074 /** DEFAULT ISY994 IP address to use: 10.0.0.207 .**/ 075 protected static final String DEFAULT_ISY994_IP = "10.0.0.207"; 076 /** DEFAULT ISY994 username to use: admin .**/ 077 protected static final String DEFAULT_ISY994_USERNAME = "admin"; 078 /** DEFAULT ISY994 password to use: admin .**/ 079 protected static final String DEFAULT_ISY994_PASSWORD = "admin"; 080 /** DEFAULT ISY994 rest URL to start the URL path: /rest .**/ 081 protected static final String DEFAULT_ISY994_REST_URL_PATHSTR = "/rest"; 082 083 protected static final String TOMS_ISY994_IP = "10.0.0.207"; 084 protected static final String TOMS_ISY994_USERNAME = "admin"; // not really 085 protected static final String TOMS_ISY994_PASSWORD = "admin"; // not really 086 087 protected static StringBuilder helpMsg_ = new StringBuilder(SYSTEM_LINE_SEPERATOR); 088 protected static boolean debugOut_ = false; 089 /** flag to indicate the use of TOMS_isy IP, userID, and password. **/ 090 protected static boolean tomsIsy_ = true; 091 092 public static IsyNodes isyNodes_ = null; 093 public static IsyVars isyIntVars_ = null; 094 public static IsyVars isyStateVars_ = null; 095 096 public static String [] ClimateCoverage = { 097 "", 098 "Areas of", 099 "Brief", 100 "Chance of", 101 "Definite", 102 "Frequent", 103 "Intermittent", 104 "Isolated", 105 "Likely", 106 "Numerous", 107 "Occasional", 108 "Patchy", 109 "Periods of", 110 "Slight chance of", 111 "Scattered", 112 "Nearby", 113 "Widespread" }; 114 115 public static String [] ClimateIntensity = { 116 "", 117 "Very light", 118 "Light", 119 "Heavy", 120 "Very heavy" }; 121 122 123 public static String [] ClimateWeatherConditions = { 124 "", 125 "Hail", 126 "Blowing dust", 127 "Blowing sand", 128 "Mist", 129 "Blowing snow", 130 "Fog", 131 "Frost", 132 "Haze", 133 "Ice Crystals", 134 "Ice fog", 135 "Ice pellets / sleet", 136 "Smoke", 137 "Drizzle", 138 "Rain", 139 "Rain showers", 140 "Rain/snow mix", 141 "Snow/sleet mix", 142 "Wintry mix", 143 "Snow", 144 "Snow showers", 145 "Thunderstorms", 146 "Unknown Precipitation", 147 "Volcanic ash", 148 "Water spouts", 149 "Freezing fog", 150 "Freezing drizzle", 151 "Freezing rain", 152 "Freezing spray" }; 153 154 public static String [] ClimateCloudConditions = { 155 "", 156 "Clear (0-7% of the sky)", 157 "Fair/mostly sunny (7-32%)", 158 "Partly cloudy (32-70%)", 159 "Mostly cloudy (70-95%)", 160 "Cloudy" }; 161 162 163 /** The start path to use in therest URL. Over-ride this if you extend this class. **/ 164 protected String restUrlPath_ = DEFAULT_ISY994_REST_URL_PATHSTR; 165 166 /** 167 * Default constructor that authenticates the default ISY with the default user password (using the class vars) 168 * UNLESS the tomsIsy_ class var is true to over-ride with TOMS _isy IP, userID, and password. 169 * TOMS settings get 1st priority, and DEFAULTS if {@link #tomsIsy_ tomsIsy_} class var is false. 170 * 171 * @see #DEFAULT_ISY994_IP 172 * @see #DEFAULT_ISY994_USERNAME 173 * @see #DEFAULT_ISY994_PASSWORD 174 **/ 175 public ISYRestRequester() 176 { 177 authenticating_=true; 178 setBaseUrl( "http://"+(tomsIsy_?TOMS_ISY994_IP:DEFAULT_ISY994_IP)+restUrlPath_); 179 setUsername( (tomsIsy_?TOMS_ISY994_USERNAME:DEFAULT_ISY994_USERNAME)); 180 setPassword( (tomsIsy_?TOMS_ISY994_PASSWORD:DEFAULT_ISY994_PASSWORD)); 181 } 182 183 184 /** 185 * Default constructor that authenticates and connects the ISY with a choice of either the default user password 186 * (using the class vars) or with TOMS _isy IP, userID, and password.. 187 * 188 * @see #DEFAULT_ISY994_IP 189 * @see #DEFAULT_ISY994_USERNAME 190 * @see #DEFAULT_ISY994_PASSWORD 191 **/ 192 public ISYRestRequester(boolean useDefault) 193 { 194 tomsIsy_=!useDefault; 195 authenticating_=true; 196 setBaseUrl( "http://"+(tomsIsy_?TOMS_ISY994_IP:DEFAULT_ISY994_IP)+restUrlPath_); 197 setUsername( (tomsIsy_?TOMS_ISY994_USERNAME:DEFAULT_ISY994_USERNAME)); 198 setPassword( (tomsIsy_?TOMS_ISY994_PASSWORD:DEFAULT_ISY994_PASSWORD)); 199 } 200 201 202 /** 203 * Constructor to customize all connection settings. 204 * 205 **/ 206 public ISYRestRequester(String server, String user, String pass) 207 { 208 setBaseUrl( "http://"+server+restUrlPath_); 209 authenticating_=true; 210 setUsername(user); 211 setPassword( pass); 212 } 213 214 215 /** 216 * Set Method for class field {@link #tomsIsy_ tomsIsy_}. 217 * 218 * @param tomsIsy is the value to set this class field to. 219 * 220 **/ 221 public static void setTomsIsy_(boolean tomsIsy) 222 { 223 tomsIsy_ = tomsIsy; 224 } // setTomsIsy Method 225 226 227 /** 228 * Get Method for class field 'tomsIsy_'. 229 * 230 * @return boolean - The value the class field {@link #tomsIsy_ tomsIsy_}. 231 * 232 **/ 233 public static boolean getTomsIsy() 234 { 235 return tomsIsy_; 236 } // getTomsIsy Method 237 238 239 /** 240 * Set Method for class field 'restUrlPath_'. 241 * 242 * @param restUrlPath_ is the value to set this class field to. 243 * 244 **/ 245 public void setRestUrlPath(String restUrlPath) 246 { 247 restUrlPath_ = restUrlPath; 248 } // setRestUrlPath Method 249 250 251 /** 252 * Get Method for class field 'restUrlPath_'. 253 * 254 * @return String - The value the class field 'restUrlPath_'. 255 * 256 **/ 257 public String getRestUrlPath() 258 { 259 return restUrlPath_; 260 } // getRestUrlPath Method 261 262 263 /** Check connectivity to the ISY specified by the class parms. 264 * @return true or false 265 **/ 266 public boolean canConnect() 267 { 268 if(debugOut_) System.out.println(LOG_TAG+".canConnect("+getBaseUrl()+", "+getUsername()+", "+getPassword()+")"); 269 270 boolean retVal = false; 271 if(isInit()) 272 { 273 try 274 { 275 if(debugOut_) System.out.println(LOG_TAG+".init = true"); 276 String usrlStr = (baseUrl_+"/sys").replace(" " ,"%20"); 277 URL url = new URL(usrlStr); 278 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 279 conn.setRequestMethod("GET"); 280 if(acceptJSON_) 281 conn.setRequestProperty("Accept", "application/json"); 282 else 283 conn.setRequestProperty("Accept", "application/xml"); 284 285 if (authenticating_) 286 { 287 //BASE64Encoder enc = new sun.misc.BASE64Encoder(); 288 String userpassword = username_ + ":" + password_; 289 //String encodedAuthorization = android.util.Base64.encodeToString( userpassword.getBytes(), android.util.Base64.DEFAULT ); 290 String encodedAuthorization = new String(Base64.encodeBase64( (userpassword.getBytes()) )); 291 conn.setRequestProperty("Authorization", "Basic "+ encodedAuthorization); 292 } 293 294 if (conn.getResponseCode() == 200) 295 { 296 retVal=true; 297 } // valid http response code 298 conn.disconnect(); 299 } 300 catch (MalformedURLException e) 301 { 302 e.printStackTrace(); 303 } 304 catch (IOException e) 305 { 306 e.printStackTrace(); 307 } 308 } 309 return retVal; 310 } 311 312 313 /** Sends a REST call to query all nodes and scenes; '/nodes' . **/ 314 public StringBuilder queryAllNodes() 315 { 316 return serviceGet("/nodes"); 317 } 318 319 320 /** Sends a REST call to query all scenes; '/nodes/scenes' . **/ 321 public StringBuilder queryAllScenes() 322 { 323 return serviceGet("/nodes/scenes"); 324 } 325 326 327 /** Sends a REST call to query all scenes; '/nodes/scenes' . **/ 328 public StringBuilder queryAllNodesAndScenes() 329 { 330 return queryAllNodes().append(queryAllScenes()); 331 } 332 333 334 /** 335 * Parses all the NODEs in the ISY into the isyNodes_ var. If not already parsed, it sends a REST call 336 * to query all nodes abd scenes; '/nodes' and parses the results into the class object to preapre for use. 337 **/ 338 public IsyNodes parseAllNodes(){ return parseAllNodes(false);} 339 /** 340 * Parses all the NODEs in the ISY into the isyNodes_ var. If not already parsed, it sends a REST call 341 * to query all nodes; '/nodes' and parses the results into the class object to preapre for use. 342 * 343 * @param reloadFromISY forces the re- query from the isy (else it just returns the existing isyNodes_. 344 **/ 345 public IsyNodes parseAllNodes(boolean reloadFromISY) 346 { 347 IsyNodes retVal = isyNodes_; 348 if(reloadFromISY || retVal==null) 349 { 350 String s = ""; 351 try 352 { 353 s = queryAllNodes().toString(); 354 s.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>",""); 355 retVal = new IsyNodes(s); 356 isyNodes_ = retVal; 357 } 358 catch( Exception ex) 359 { 360 // leave it as null 361 ex.printStackTrace(); 362 363 } 364 } 365 if(debugOut_) System.out.println("Parsed Nodes:\n"+ isyNodes_); 366 return retVal; 367 } 368 369 370 /** Sends a REST call to query all Variables defined; '/vars/definitions/<varType>' . **/ 371 public StringBuilder queryAllVars(int varType) 372 { 373 parseAllNodes(); // fast return if already parsed 374 return serviceGet("/vars/definitions/"+varType); 375 } 376 377 378 /** Sends a REST call to query all Variables values; 'vars/get/<varType>' . **/ 379 public StringBuilder queryAllVarValues(int varType) 380 { 381 parseAllNodes(); // fast return if already parsed 382 return serviceGet("/vars/get/"+varType); 383 } 384 385 386 /** Fully Queries and loads all Integer vars. **/ 387 public StringBuilder queryAllIntegerVars() 388 { 389 parseAllNodes(); // fast return if already parsed 390 StringBuilder retVal = queryAllVars(IsyVars.VAR_TYPE_INT); 391 StringBuilder vVals = queryAllVarValues(IsyVars.VAR_TYPE_INT); 392 try 393 { 394 isyIntVars_ = new IsyVars(IsyVars.VAR_TYPE_INT, retVal, vVals) ; 395 } 396 catch (Exception ex) 397 { 398 retVal = null; 399 isyIntVars_ = null; 400 System.out.println("ERROR querying Integer Vars"); 401 ex.printStackTrace(); 402 } 403 return retVal; 404 } 405 406 407 /** Fully Queries and loads all state vars. **/ 408 public StringBuilder queryAllStateVars() 409 { 410 parseAllNodes(); // fast return if already parsed 411 StringBuilder retVal = queryAllVars(IsyVars.VAR_TYPE_STATE); 412 StringBuilder vVals = queryAllVarValues(IsyVars.VAR_TYPE_STATE); 413 try 414 { 415 isyStateVars_ = new IsyVars(IsyVars.VAR_TYPE_STATE, retVal, vVals) ; 416 } 417 catch (Exception ex) 418 { 419 retVal = null; 420 isyStateVars_ = null; 421 System.out.println("ERROR querying state Vars"); 422 ex.printStackTrace(); 423 } 424 return retVal; 425 } 426 427 428 /** Returns class var 'isyIntVars_'. 429 * 430 * @return the class IsyVars var holding Integers. 431 **/ 432 public IsyVars getIsyIntVars() 433 { 434 parseAllNodes(); // fast return if already parsed 435 if(isyIntVars_==null) queryAllIntegerVars(); 436 return isyIntVars_; 437 } 438 439 440 /** Returns class var 'isyStateVars_'. 441 * 442 * @return the class IsyVars var holding the State Vars. 443 **/ 444 public IsyVars getIsyStateVars() 445 { 446 parseAllNodes(); // fast return if already parsed 447 if(isyStateVars_==null)queryAllStateVars(); 448 return isyStateVars_; 449 } 450 451 452 /** Not Implemented. **/ 453 public StringBuilder queryAllIntVarVals() 454 { 455 parseAllNodes(); // fast return if already parsed 456 StringBuilder retVal = null; 457 return retVal; 458 } 459 460 461 /** 462 * Sends a REST call turn a Node or scene ON '/nodes/<addressOfNodeName>/cmd/DON' . 463 * 464 * @param nodeName the nodes NAME to turn ON 465 **/ 466 public StringBuilder deviceOn(String nodeName) 467 { 468 parseAllNodes(); // fast return if already parsed 469 String addr = isyNodes_.getNodeAddress(nodeName); 470 if(debugOut_) System.out.println(LOG_TAG+".deviceOn "+nodeName+" "+"("+addr+")"); 471 return deviceAddressOn(addr); 472 } 473 474 475 /** 476 * Sends a REST call turn a Node or scene OFF '/nodes/<addressOfNodeName>/cmd/DOF' . 477 * 478 * @param nodeName the nodes NAME to turn OFF 479 **/ 480 public StringBuilder deviceOff(String nodeName) 481 { 482 parseAllNodes(); // fast return if already parsed 483 String addr = isyNodes_.getNodeAddress(nodeName); 484 if(debugOut_) System.out.println(LOG_TAG+".deviceOff "+nodeName+" "+"("+addr+")"); 485 return deviceAddressOff(addr); 486 } 487 488 489 /** 490 * Sends a REST call turn a Node or scene ON '/nodes/<addressOfNodeName>/cmd/DON' . 491 * 492 * @param addr the nodes address (ie. 16 10 A0 1) to turn OFF 493 **/ 494 public StringBuilder deviceAddressOn(String addr) 495 { 496 parseAllNodes(); // fast return if already parsed 497 return serviceGet("/nodes/"+addr+"/cmd/DON"); 498 } 499 500 501 /** 502 * Sends a REST call turn a Node ON '/nodes/<addressOfNodeName>/cmd/DON' . 503 * 504 * @param addr the nodes address (ie. 16 10 A0 1) to turn On 505 * @param brightness the brightness (0-255) 506 **/ 507 public StringBuilder deviceAddressOn(String addr, int brightness) 508 { 509 parseAllNodes(); // fast return if already parsed 510 if(brightness<0) brightness=0; 511 else if(brightness>255) brightness=255; 512 513 return serviceGet("/nodes/"+addr+"/cmd/DON/"+brightness); 514 } 515 516 517 /** 518 * Sends a REST call turn a Node OFF '/nodes/<addressOfNodeName>/cmd/DOF' . 519 * 520 * @param addr the nodes address (ie. 16 10 A0 1) to turn OFF 521 **/ 522 public StringBuilder deviceAddressOff(String addr) 523 { 524 parseAllNodes(); // fast return if already parsed 525 return serviceGet("/nodes/"+addr+"/cmd/DOF"); 526 } 527 528 529 /** 530 * Toggles the state of the device/node NAMED nodeName. 531 * 532 * @param nodeName the nodes NAME to toggle its state 533 **/ 534 public int deviceToggle(String nodeName) 535 { 536 parseAllNodes(); // fast return if already parsed 537 String addr = isyNodes_.getNodeAddress(nodeName); 538 if(debugOut_) System.out.println(LOG_TAG+".deviceToggle("+nodeName+")"); 539 //ca.bc.webarts.widgets.Util.sleep(400); 540 return deviceAddressToggle(addr); 541 } 542 543 544 /** Toggles the ON/OFF state specified device. **/ 545 public int deviceAddressToggle(String addr) 546 { 547 parseAllNodes(); // fast return if already parsed 548 int retVal = -1; 549 StringBuilder restResponse = null; 550 int offLevel = 5; 551 if(debugOut_) System.out.println(LOG_TAG+".deviceAddressToggle("+addr+")"); 552 int stat = deviceAddressStatus(addr); 553 if(debugOut_) System.out.println(LOG_TAG+".deviceAddressToggle stat="+stat); 554 if (stat<offLevel) restResponse = deviceAddressOn(addr); 555 else restResponse = deviceAddressOff(addr); 556 557 boolean success = false; 558 if(restResponse!=null && restResponse.toString().indexOf("succeeded=\"true\"><status>200</status>")!=-1) success = true; 559 if (success && stat<offLevel) retVal = 100; 560 else if (success) retVal = 0; 561 562 // now to make sure the on level is correct 563 if(retVal!=-1) retVal = deviceAddressStatus(addr); 564 return retVal; 565 } 566 567 568 /** 569 * Queries the status of the device/node NAMED nodeName. 570 * 571 * @param nodeName the nodes NAME to query its status 572 **/ 573 public int deviceStatus(String nodeName) 574 { 575 parseAllNodes(); // fast return if already parsed 576 int retVal = -1; 577 String addr = isyNodes_.getNodeAddress(nodeName); 578 return deviceAddressStatus(addr); 579 } 580 581 582 public int deviceAddressStatus(String addr){ return deviceAddressStatus(addr, true);} 583 /** returns the on/off/% for a specified node address. 584 * @return on=100, off=0, or any number in between 0-100 585 **/ 586 public int deviceAddressStatus(String addr, boolean includeScenes) 587 { 588 parseAllNodes(); // fast return if already parsed 589 int retVal = -1; 590 StringBuilder resp = serviceGet("/status/"+addr); 591 /* The response holds and attribute called formatted that can be one of Off, On , % */ 592 /* <property id="ST" value="114" formatted="45" uom="%/on/off"/> */ 593 //System.out.println(" DEBUG1 respStr: "+resp.toString()); 594 if (resp!=null) 595 { 596 String respStr = resp.toString(); 597 int fSpot = respStr.indexOf("formatted"); 598 String fVal = respStr.substring(fSpot+11,respStr.indexOf("\"", fSpot+12)); 599 if(debugOut_) System.out.println("STATUS: "+ addr+": "+fVal+"\n"+resp.toString()); 600 if(fVal.equalsIgnoreCase("Off") ) retVal = 0; 601 else if (fVal.equalsIgnoreCase("On") ) retVal = 100; 602 else if (fVal.trim().equals("") ) retVal = -1; 603 else if (fVal.trim().indexOf(".")!=-1 ) 604 try{retVal = Integer.parseInt(fVal.substring(0,fVal.indexOf(".")));} 605 catch(Exception ex){System.out.println("ERROR pulling the status value from "+fVal+" "+fVal.substring(0,fVal.indexOf(".")));} 606 else 607 try{retVal = Integer.parseInt(fVal);} 608 catch(Exception ex){System.out.println("ERROR pulling the int status value from "+fVal);} 609 } 610 else if(includeScenes) // try it as a scene/group 611 retVal = groupAddressStatus(addr); 612 613 return retVal; 614 } 615 616 617 /** returns the on/off/% fora specified scene/group address. 618 * @return on=100, off=0, or any number in between 0-100 619 **/ 620 public int groupAddressStatus(String addr) 621 { 622 parseAllNodes(); // fast return if already parsed 623 int retVal = -1; 624 String respStr = ""; 625 String groupMembersXml = ""; 626 String addr2 = ""; 627 int fSpot = -1; 628 String fVal = ""; 629 630 //StringBuilder resp = serviceGet("/nodes/"+addr+"?members=true"); 631 /* The response holds the group members that can be one of Off, On , % */ 632 /* <nodeInfo> 633 <group flag="132"> 634 <address>36083</address> 635 <name>UpUnderCabLights</name> 636 <parent type="3">29673</parent> 637 <deviceGroup>29</deviceGroup> 638 <pnode>36083</pnode> 639 <ELK_ID>F01</ELK_ID> 640 <members> 641 <link type="16">17 54 1 1</link> 642 <link type="16">43 A2 FB 5</link> 643 </members> 644 </group> 645 </nodeInfo> */ 646 // the isyNodes_ now has a method called getGroupMembers(sceneName) that can be used to check status 647 String groupName = isyNodes_.getGroupName(addr); 648 GroupMembers gMems = isyNodes_.getGroupMembers(groupName); 649 String [] members = gMems.getMemberNodes(); 650 int memStats = 0; 651 for(String memAddr : members) 652 { 653 memStats+=deviceAddressStatus(memAddr,false); // this could be recursive if not sent a false 654 } 655 if(members.length>0) 656 retVal = memStats/members.length; 657 else 658 retVal = memStats; 659 660 /*if (resp!=null) 661 { 662 respStr = resp.toString(); 663 System.out.println(" DEBUG2 respStr: "+respStr); 664 groupMembersXml = respStr.substring(respStr.indexOf("<link type="), respStr.indexOf("</members>")); 665 System.out.println(" DEBUG3 groupMembersXml: "+groupMembersXml); 666 addr2 = groupMembersXml.substring(groupMembersXml.indexOf(">")+1, groupMembersXml.indexOf("<")); 667 System.out.println(" DEBUG4 addr: "+addr2); 668 retVal = deviceAddressStatus(addr2); 669 if(debugOut_) System.out.println("STATUS: "+ addr+": "+retVal+"\n"); 670 } 671 */ 672 673 return retVal; 674 } 675 676 677 /** Sets a ISY variable. 678 * @param varName this will lookup the varID 679 * @param varVal 680 * @param varType send a 1 for Integer and 2 for State 681 **/ 682 /* 683 public StringBuilder setVariable(String varName, String varVal, int varType) 684 { 685 parseAllNodes(); // fast return if already parsed 686 return setVariable(getVarId(varName), varVal, varType); 687 } 688 */ 689 690 /** Sets a ISY variable. 691 * @param varName 692 * @param varId 693 * @param varType send a 1 for Integer and 2 for State 694 **/ 695 public StringBuilder setVariable(int varId, String varVal, int varType) 696 { 697 StringBuilder sb = null; 698 if (varId>0 && varVal!=null && (varType==1 || varType==2)) 699 sb = serviceGet("/vars/set/"+varType+"/"+varId+"/"+varVal); 700 return sb; 701 } 702 703 704 /** Gets the current XML (StringBuffer) result for an ISY variable. 705 * @param varID 706 * @param varType send a 1 for Integer and 2 for State 707 * @return the XML returned from the ISY for the var requested , OR null if incorrect varType specified. 708 **/ 709 public StringBuilder getVariable(String varID, int varType) 710 { 711 StringBuilder sb = null; 712 if (varID!=null && !varID.equals("") && 713 (varType==1 || varType==2)) 714 sb = serviceGet("/vars/get/"+varType+"/"+varID); 715 return sb; 716 } 717 718 719 /** Gets the current XML (StringBuffer) result for an ISY variable. 720 * @param varID 721 * @param varType send a 1 for Integer and 2 for State 722 * @return int current value 723 **/ 724 public int getVariableIntValue(String varID, int varType) throws Exception 725 { 726 int retVal = 0; 727 StringBuilder sb = null; 728 if (varID!=null && !varID.equals("") && 729 (varType==1 || varType==2)) 730 sb = serviceGet("/vars/get/"+varType+"/"+varID); 731 int valSpot = sb.toString().indexOf("<val>"); 732 if(valSpot!=-1) 733 { 734 String valStr = sb.toString().substring(valSpot+"<val>".length(),sb.toString().indexOf("</val>")); 735 retVal = Integer.parseInt(valStr); 736 } 737 else throw new Exception((varType == 1?"Integer ":"State ")+"VarID: "+varID +" NOT found."); 738 739 return retVal; 740 } 741 742 743 /** Gets a the next un=used/avaialbe varID. 744 * if already parsed, this method will NOT re-query the vars unless told to. 745 * @return an int for the next ID to use 746 **/ 747 public int getNextAvailableStateVarID(){ return getNextAvailableStateVarID(false);} 748 public int getNextAvailableStateVarID(boolean reQueryVars) 749 { 750 int retVal = 0; 751 if(isyStateVars_==null || reQueryVars) 752 { 753 queryAllStateVars(); 754 } 755 if(isyStateVars_!=null) 756 { 757 retVal = isyStateVars_.getNextUnusedID(); 758 } 759 return retVal; 760 } 761 762 763 /** Gets a the next un=used/avaialbe varID. 764 * if already parsed, this method will NOT re-query the vars unless told to. 765 * @return an int for the next ID to use 766 **/ 767 public int getNextAvailableIntVarID(){ return getNextAvailableIntVarID(false);} 768 public int getNextAvailableIntVarID(boolean reQueryVars) 769 { 770 int retVal = 0; 771 if(isyIntVars_==null || reQueryVars) 772 { 773 queryAllIntegerVars(); 774 } 775 if(isyIntVars_!=null) 776 { 777 retVal = isyIntVars_.getNextUnusedID(); 778 } 779 return retVal; 780 } 781 782 783 /** returns the status for all the nodes. **/ 784 public StringBuilder getStatus() 785 { 786 return serviceGet("/status"); 787 } 788 789 790 /** queries all the nodes. **/ 791 public StringBuilder getQuery() 792 { 793 return serviceGet("/query"); 794 } 795 796 797 /** queries the nodes with name.**/ 798 public StringBuilder getQueryNode(String nodeName) 799 { 800 String nAddr = isyNodes_.getNodeAddress(nodeName); 801 return serviceGet("/query/"+nAddr); 802 } 803 804 805 /** queries the nodes with address.**/ 806 public StringBuilder getQueryNodeFromAddress(String nAddr) 807 { 808 return serviceGet("/query/"+nAddr); 809 } 810 811 812 /** returns all the nodes. **/ 813 public StringBuilder getNodes() 814 { 815 return serviceGet("/nodes"); 816 } 817 818 819 /** returns isy config. **/ 820 public StringBuilder getConfig() 821 { 822 return serviceGet("/config"); 823 } 824 825 826 /** returns a devices property Value (which is the unformatted value) String with /rest/nodes/<node>/<property> . 827 * 828 * @return the property value as an string 829 **/ 830 public String devicePropertyValue(String nodeName, String prop) 831 { 832 parseAllNodes(); // fast return if already parsed 833 String addr = isyNodes_.getNodeAddress(nodeName); 834 IsyDeviceProperty devProp = deviceAddressProperty(addr, prop); 835 return devProp.getValue(); 836 } 837 838 839 /** returns a devices property formatted String with /rest/nodes/<node>/<property> . 840 * 841 * @return the property value as a String 842 **/ 843 public String devicePropertyFormattedValue(String nodeName, String prop) 844 { 845 parseAllNodes(); // fast return if already parsed 846 String addr = isyNodes_.getNodeAddress(nodeName); 847 IsyDeviceProperty devProp = deviceAddressProperty(addr, prop); 848 return devProp.getFormatted(); 849 } 850 851 852 /** returns a devices property XML String with /rest/nodes/<node>/<property> . 853 * 854 * @return the property XML that gets returned from the rest call 855 **/ 856 public String devicePropertyXML(String nodeName, String prop) 857 { 858 parseAllNodes(); // fast return if already parsed 859 String addr = isyNodes_.getNodeAddress(nodeName); 860 return deviceAddressPropertyXML(addr, prop); 861 } 862 863 864 /** returns a devices property XML String with /rest/nodes/<nodeID>/<property> . 865 * 866 * @return the property XML that gets returned from the rest call 867 **/ 868 public String deviceAddressPropertyXML(String addr, String prop) 869 { 870 IsyDeviceProperty devProp = deviceAddressProperty(addr, prop); 871 return devProp.getElementStr(); 872 } 873 874 875 /** returns a devices property int value with /rest/nodes/<nodeID>/<property> . 876 * 877 * @return the property value as an int, or -1 if it is not an Integer type 878 **/ 879 public int deviceAddressIntProperty(String addr, String prop) 880 { 881 IsyDeviceProperty devProp = deviceAddressProperty(addr, prop); 882 return devProp.getIntValue(); 883 } 884 885 886 /** returns a devices property int value with /rest/nodes/<nodeID>/<property> . 887 * 888 * @return the property value unit of measure (uom) 889 **/ 890 public String deviceAddressPropertyUOM(String addr, String prop) 891 { 892 IsyDeviceProperty devProp = deviceAddressProperty(addr, prop); 893 return devProp.getUom(); 894 } 895 896 897 /** returns a devices property formatted String with /rest/nodes/<node>/<property> . 898 * 899 * @return the property formatted value as a String 900 **/ 901 public IsyDeviceProperty deviceProperty(String nodeName, String prop) 902 { 903 parseAllNodes(); // fast return if already parsed 904 String addr = isyNodes_.getNodeAddress(nodeName); 905 return deviceAddressProperty(addr, prop); 906 } 907 908 909 /** returns a devices property with /rest/nodes/<nodeID>/<property> . **/ 910 public IsyDeviceProperty deviceAddressProperty(String addr, String prop) 911 { 912 int retVal = -1; 913 String requestStr = "/nodes/" + addr +"/"+prop; 914 if (debugOut_) System.out.println("Rest Reguest= "+getServiceUrl(requestStr)); 915 getQueryNodeFromAddress(addr); // this makkes sure the node status is up to date 916 StringBuilder resp = serviceGet(requestStr); 917 IsyDeviceProperty devProp = new IsyDeviceProperty(resp.toString()); 918 return devProp; 919 } 920 921 922 /** 923 * Class main commandLine entry method that has a test command and some convienience commands, as well as a pure rest command. 924 **/ 925 public static void main(String [] args) 926 { 927 final String methodName = CLASSNAME + ": main()"; 928 ISYRestRequester instance = new ISYRestRequester(); 929 IsyNodes isyNodes = instance.parseAllNodes(true); 930 931 /* Simple way af parsing the args */ 932 if (args ==null || args.length<1) 933 System.out.println(getHelpMsgStr()); 934 /* *************************************** */ 935 else 936 { 937 if (args[0].equalsIgnoreCase("test")) 938 { 939 instance.testCMD(args); 940 } 941 /* *************************************** */ 942 else if (args[0].equalsIgnoreCase("listNodes") || args[0].equalsIgnoreCase("nodes")) 943 { 944 instance.listNodesCMD(args); 945 } 946 /* *************************************** */ 947 else if (args[0].equalsIgnoreCase("listScenesAndNodes")) 948 { 949 instance.listScenesCMD(args); 950 instance.listNodesCMD(args); 951 } 952 /* *************************************** */ 953 else if (args[0].equalsIgnoreCase("listScenes") || args[0].equalsIgnoreCase("scenes")) 954 { 955 instance.listScenesCMD(args); 956 } 957 /* *************************************** */ 958 else if (args[0].equalsIgnoreCase("getNodeAddress") && args.length>1) 959 { 960 try { System.out.println(args[1]+" : " +isyNodes.getNodeAddress(args[1]));} 961 catch(Exception ex){ System.out.println("Error retrieving Node Address for : "+args[1]+"\n"+Arrays.toString(args));} 962 } 963 /* *************************************** */ 964 else if (args[0].equalsIgnoreCase("listVars")) 965 { 966 instance.listVarsCMD(args); 967 } 968 /* *************************************** */ 969 else if (args[0].equalsIgnoreCase("getVar")) 970 { 971 try { instance.getVarCMD(args);} 972 catch(Exception ex){ System.out.println("Error retrieving VAR: "+Arrays.toString(args));} 973 } 974 /* *************************************** */ 975 else if (args[0].equalsIgnoreCase("getProperty")) 976 { 977 instance.getPropertyCMD(args); 978 } 979 /* *************************************** */ 980 else if (args[0].equalsIgnoreCase("toggle")) 981 { 982 instance.toggleCMD(args); 983 } 984 /* *************************************** */ 985 else if (args[0].equalsIgnoreCase("status")) 986 { 987 instance.statusCMD(args); 988 } 989 /* *************************************** */ 990 else 991 { 992 instance.restCMD(args); 993 } 994 } 995 } // main 996 997 998 /** 999 * commandLine command executor method for the test Command. 1000 * @param args the array of commandLine args that got passed in 1001 **/ 1002 protected void testCMD(String [] args) 1003 { 1004 final String methodName = CLASSNAME + ": testCMD(String [])"; 1005 parseAllNodes(); // fast return if already parsed 1006 1007 1008 System.out.println("Testing ISY Rest Service: "+ "/sys"); 1009 StringBuilder resp = serviceGet("/sys"); 1010 System.out.println(resp.toString()); System.out.println(); 1011 System.out.println("Testing ISY Rest Service: "+ "Turn the Downstairs Kitchen Lights on: "+ isyNodes_.getNodeName(DWNKITCHEN_ADDR) +" ("+DWNKITCHEN_ADDR+")"); 1012 resp = deviceAddressOn(DWNKITCHEN_ADDR); 1013 System.out.println(resp.toString()); System.out.println(); 1014 //ca.bc.webarts.widgets.Util.sleep(400); 1015 System.out.println("Testing ISY Rest Service: "+ "checking status of the "+GAMESROOMLIGHTS_NODENAME); 1016 int devStatus = deviceStatus(GAMESROOMLIGHTS_NODENAME); 1017 System.out.println("GAMESROOMLIGHTS level:"+devStatus); System.out.println(); 1018 1019 } 1020 1021 1022 /** 1023 * commandLine command executor method for the listNodes Command. 1024 * @param args the array of commandLine args that got passed in 1025 **/ 1026 protected void listNodesCMD(String [] args) 1027 { 1028 final String methodName = CLASSNAME + ": listNodesCMD(String [])"; 1029 if (debugOut_) System.out.println("ISY Rest Services: "+ "listNodes"); 1030 parseAllNodes(); // fast return if already parsed 1031 if (isyNodes_!=null) 1032 { 1033 String [] resp = isyNodes_.getNodeNamesCopy(true); // true means sorted 1034 String [] resp2 = isyNodes_.getGroupNamesCopy(true); // true means sorted 1035 if(false) 1036 { 1037 if (debugOut_) System.out.println("---- BEFORE SORT:"); 1038 for(int i=0; i< resp.length;i++) 1039 System.out.println(resp[i]+" ("+isyNodes_.getNodeTypeStr(resp[i])+"): "+isyNodes_.getNodeAddress(resp[i])); 1040 if (debugOut_) System.out.println("\n*******\n---- AFTER SORT:"); 1041 } 1042 //Quick.sort(resp); 1043 if (resp!=null) 1044 for(int i=0; i< resp.length;i++) 1045 System.out.println(resp[i]+" ("+isyNodes_.getNodeTypeStr(resp[i])+"): "+isyNodes_.getNodeAddress(resp[i])); 1046 if (resp2!=null) 1047 for(int i=0; i< resp2.length;i++) 1048 System.out.println(resp2[i]+" : "+isyNodes_.getGroupAddress(resp2[i])); 1049 } 1050 else 1051 System.out.println(" ERROR Parsing isyNodes."); 1052 1053 } 1054 1055 1056 /** 1057 * commandLine command executor method for the listScenes Command. 1058 * @param args the array of commandLine args that got passed in 1059 **/ 1060 protected void listScenesCMD(String [] args) 1061 { 1062 final String methodName = CLASSNAME + ": listScenesCMD(String [])"; 1063 if (debugOut_) System.out.println("ISY Rest Services: "+ "listScenes"); 1064 parseAllNodes(); // fast return if already parsed 1065 if (isyNodes_!=null) 1066 { 1067 String [] resp = isyNodes_.getGroupNamesCopy(true); // true means sorted 1068 //Quick.sort(resp); 1069 if (resp!=null) 1070 for(int i=0; i< resp.length;i++) 1071 System.out.println(resp[i]+": "+isyNodes_.getSceneAddress(resp[i])); 1072 } 1073 else 1074 System.out.println(" ERROR Parsing isyNodes."); 1075 1076 } 1077 1078 1079 /** 1080 * commandLine command executor method for the listVars Command. 1081 * @param args the array of commandLine args that got passed in 1082 **/ 1083 protected void listVarsCMD(String [] args) 1084 { 1085 final String methodName = CLASSNAME + ": listVarsCMD(String [])"; 1086 if (debugOut_) System.out.println("ISY Rest Services: "+ "listVars"); 1087 queryAllIntegerVars(); 1088 queryAllStateVars(); 1089 //System.out.println(instance.isyIntVars_.toString()); 1090 //System.out.println(instance.isyStateVars_.toString()); 1091 1092 if (isyIntVars_!=null) 1093 { 1094 System.out.println("\n"+isyIntVars_.getNumVars()+" INTEGER Vars"); 1095 System.out.println("------------"); 1096 String [] resp = isyIntVars_.getVarNames(); 1097 1098 if (resp!=null) 1099 { 1100 Quick.sort(resp); 1101 for(int i=0; i< resp.length;i++) 1102 { 1103 try{ System.out.println(resp[i]+": "+isyIntVars_.getVarValue(resp[i]));} 1104 catch(Exception ex){System.out.println(resp[i]+": "+"NOT FOUND");} 1105 } 1106 } 1107 } 1108 else 1109 System.out.println(" ERROR Parsing Integer Vars."); 1110 1111 if (isyStateVars_!=null) 1112 { 1113 System.out.println("\n"+isyStateVars_.getNumVars()+" STATE Vars"); 1114 System.out.println("------------"); 1115 String [] resp = isyStateVars_.getVarNames(); 1116 if (resp!=null) 1117 { 1118 Quick.sort(resp); 1119 for(int i=0; i< resp.length;i++) 1120 { 1121 try{ System.out.println(resp[i]+": "+isyStateVars_.getVarValue(resp[i]));} 1122 catch(Exception ex){System.out.println(resp[i]+": "+"NOT FOUND");} 1123 } 1124 } 1125 } 1126 else 1127 System.out.println(" ERROR Parsing State Vars."); 1128 1129 } 1130 1131 1132 /** 1133 * commandLine command executor method for the toggle Command. 1134 * @param args the lightname to toggle 1135 **/ 1136 public int toggleLight(String arg) 1137 { 1138 String [] args = {"toggle", arg}; 1139 return toggleCMD(args); 1140 } 1141 1142 1143 /** 1144 * commandLine command executor method for the toggle Command. 1145 * @param args the array of commandLine args that got passed in 1146 **/ 1147 protected int toggleCMD(String [] args) 1148 { 1149 final String methodName = CLASSNAME + ": toggleCMD(String [])"; 1150 int devStatus = -1; 1151 if (args.length>1 && args[0].equals("toggle")) parseAllNodes(); 1152 if (isyNodes_!=null && args.length>1) 1153 { 1154 StringBuilder nName = new StringBuilder(args[1].trim()); 1155 if (args.length>2) for (int i=2;i<args.length; i++) {nName.append(" ");nName.append(args[i]);} 1156 if ( isyNodes_.hasNodeName(nName.toString()) || isyNodes_.hasGroupName(nName.toString())) 1157 { 1158 String nAddr = isyNodes_.getNodeAddress( nName.toString()); 1159 System.out.println("Toggling: "+ nName.toString()+" ( "+ nAddr+" )"); 1160 devStatus = deviceAddressToggle(nAddr); 1161 //devStatus = deviceAddressStatus(nAddr); 1162 System.out.println(nName.toString().trim()+" level:"+devStatus); 1163 1164 } 1165 else 1166 System.out.println(" ERROR can't find '"+args[1].trim()+"' in isyNodes"); 1167 } 1168 else 1169 System.out.println(" ERROR Parsing isyNodes."); 1170 1171 return devStatus; 1172 } 1173 1174 1175 /** 1176 * commandLine status command method for the status Command. 1177 * @param args the array of commandLine args that got passed in 1178 * 1179 * @param args is an array of stringas that get concatenated into the single NODE name to get status for. 1180 **/ 1181 protected void statusCMD(String [] args) 1182 { 1183 final String methodName = CLASSNAME + ": statusCMD(String [])"; 1184 parseAllNodes(); // fast return if already parsed 1185 if (debugOut_) System.out.println("ISY Rest Services: "+ "node status"); 1186 if (args.length>1 && args[0].equals("status")) parseAllNodes(); 1187 if (isyNodes_!=null && args.length>1) 1188 { 1189 StringBuilder nName = new StringBuilder(args[1]); 1190 if (args.length>2) for (int i=2;i<args.length; i++) {nName.append(" ");nName.append(args[i]);} 1191 if ( isyNodes_.hasNodeName(nName.toString()) || isyNodes_.hasGroupName(nName.toString())) 1192 { 1193 String nAddr = isyNodes_.getNodeAddress( nName.toString()); 1194 //System.out.println(" for node: "+nAddr.toString()+" ( "+ isyNodes.getNodeName( nAddr.toString()+" )")); 1195 int devStatus = deviceAddressStatus(nAddr); 1196 System.out.println(" "+nName.toString()+" ( "+ nAddr+" ) status is "+devStatus); 1197 } 1198 else 1199 System.out.println(" ERROR Can't find that node NAME = "+ nName); 1200 } 1201 else 1202 System.out.println(" ERROR Parsing node NAME "); 1203 } 1204 1205 1206 /** 1207 * commandLine command executor method for the default rest Command. 1208 * It treats each arg as a part of a single rest command and passes it along to the ISY. 1209 * @param args the array of commandLine args that got passed in 1210 **/ 1211 protected void restCMD(String [] args) 1212 { 1213 final String methodName = CLASSNAME + ": restCMD(String [])"; 1214 // Parse the command 1215 String allcommands = args[0]; 1216 for (int i=1;i< args.length;i++) allcommands+=" "+args[i]; 1217 if (debugOut_) System.out.print("Sending ISY Rest Service: "+allcommands); 1218 String passedCommand = (allcommands.startsWith(restUrlPath_+"/")?allcommands.substring(restUrlPath_.length()):allcommands); 1219 System.out.println(" ("+passedCommand+")"); 1220 passedCommand = (passedCommand.startsWith("/")?passedCommand:"/"+passedCommand); 1221 StringBuilder resp = serviceGet(passedCommand); 1222 if (resp!=null) 1223 { 1224 System.out.println(responseIndenter(resp).toString()); 1225 System.out.println(); 1226 } 1227 else 1228 { 1229 System.out.println("Response Error"); 1230 System.out.println(); 1231 } 1232 1233 } 1234 1235 1236 protected int getVarCMD(String arg) throws Exception 1237 { 1238 String [] args = {arg}; 1239 return getVarCMD(args); 1240 } 1241 1242 1243 /** 1244 * commandLine command executor method for the getVar Command. 1245 * @param args the array of commandLine args that got passed in 1246 **/ 1247 protected int getVarCMD(String [] args) throws Exception 1248 { 1249 final String methodName = CLASSNAME + ": getVarCMD(String [])"; 1250 parseAllNodes(); // fast return if already parsed 1251 int retVal = -999; 1252 if (debugOut_) System.out.println("ISY Rest Services: "+ "getVar"); 1253 queryAllIntegerVars(); 1254 queryAllStateVars(); 1255 1256 retVal = isyIntVars_.getVarValue(args[0]); 1257 System.out.println(args[0]+" = "+retVal); 1258 return retVal; 1259 } 1260 1261 1262 /** 1263 * commandLine command executor method for the getProperty Command. 1264 * @param args the array of commandLine args that got passed in 1265 **/ 1266 protected String getPropertyValue(String nodeName, String propName) 1267 { 1268 final String methodName = CLASSNAME + ": getPropertyValue(String [])"; 1269 String retVal = ""; 1270 1271 if(debugOut_) System.out.println("ISY Rest Services: "+ "node property"); 1272 parseAllNodes(); 1273 if (isyNodes_!=null && nodeName!=null && propName!=null 1274 && !"".equals(nodeName) && !"".equals(propName)) 1275 { 1276 String nName = nodeName; 1277 String pName = propName; 1278 1279 if(debugOut_) System.out.println("Looking for property '"+pName+"' on nodeName '"+nName+"'"); 1280 IsyDeviceProperty isyProp = deviceProperty(nName, pName); 1281 String propElementStr = isyProp.getElementStr(); 1282 if(debugOut_) System.out.println(nName); 1283 if(debugOut_) System.out.println(propElementStr); 1284 if(debugOut_) System.out.println(" Value="+isyProp.getValue()); 1285 if(debugOut_) System.out.println(" Formatted Value="+isyProp.getFormatted()+" "+isyProp.getUom()); 1286 if(debugOut_) System.out.println(" Integer Value="+isyProp.getIntValue()); 1287 retVal = isyProp.getValue(); 1288 } 1289 else 1290 System.out.println("ERROR on comnmandLine: getProperty command requires a nodeName and a propertyName"); 1291 1292 return retVal; 1293 } 1294 1295 1296 /** 1297 * commandLine command executor method for the getProperty Command. 1298 * @param args the array of commandLine args that got passed in 1299 **/ 1300 protected String getPropertyCMD(String [] args) 1301 { 1302 final String methodName = CLASSNAME + ": getPropertyCMD(String [])"; 1303 String retVal = ""; 1304 1305 if(debugOut_) System.out.println("ISY Rest Services: "+ "node property"); 1306 if (args.length>2 && args[0].equalsIgnoreCase("getProperty")) parseAllNodes(); 1307 if (isyNodes_!=null && args.length>2) 1308 { 1309 String nName = args[1]; 1310 for (int i=2;i< args.length-1;i++) nName+=" "+args[i]; 1311 String pName = args[args.length-1]; 1312 1313 if(debugOut_) System.out.println("Looking for property '"+pName+"' on nodeName '"+nName+"'"); 1314 IsyDeviceProperty isyProp = deviceProperty(nName, pName); 1315 String propElementStr = isyProp.getElementStr(); 1316 System.out.println(nName); 1317 System.out.println(propElementStr); 1318 System.out.println(" Value="+isyProp.getValue()); 1319 System.out.println(" Formatted Value="+isyProp.getFormatted()+" "+isyProp.getUom()); 1320 System.out.println(" Integer Value="+isyProp.getIntValue()); 1321 retVal = isyProp.getValue(); 1322 } 1323 else 1324 System.out.println("ERROR on comnmandLine: getProperty command requires a nodeName and a propertyName"); 1325 1326 return retVal; 1327 } 1328 1329 1330 /** 1331 * commandLine command executor method for the getProperty Command. 1332 * @param args the array of commandLine args that got passed in 1333 **/ 1334 protected String getPropertyUOM(String [] args) 1335 { 1336 final String methodName = CLASSNAME + ": getPropertyCMD(String [])"; 1337 String retVal = ""; 1338 1339 if(debugOut_) System.out.println("ISY Rest Services: "+ "node property"); 1340 if (args.length>2 && args[0].equalsIgnoreCase("getProperty")) parseAllNodes(); 1341 if (isyNodes_!=null && args.length>2) 1342 { 1343 String nName = args[1]; 1344 for (int i=2;i< args.length-1;i++) nName+=" "+args[i]; 1345 String pName = args[args.length-1]; 1346 1347 if(debugOut_) System.out.println("Looking for property '"+pName+"' on nodeName '"+nName+"'"); 1348 IsyDeviceProperty isyProp = deviceProperty(nName, pName); 1349 String propElementStr = isyProp.getElementStr(); 1350 System.out.println(nName); 1351 System.out.println(propElementStr); 1352 System.out.println(" Value="+isyProp.getValue()); 1353 System.out.println(" Formatted Value="+isyProp.getFormatted()+" "+isyProp.getUom()); 1354 System.out.println(" Integer Value="+isyProp.getIntValue()); 1355 retVal = isyProp.getUom(); 1356 } 1357 else 1358 System.out.println("ERROR on comnmandLine: getProperty command requires a nodeName and a propertyName"); 1359 1360 return retVal; 1361 } 1362 1363 1364 /** 1365 * Template method for future commandLine command executor methods. 1366 * @param args the array of commandLine args that got passed in 1367 **/ 1368 protected void templateCMD(String [] args) 1369 { 1370 final String methodName = CLASSNAME + ": testCMD(String [])"; 1371 1372 } 1373 1374 1375 /** gets the help as a String. 1376 * @return the helpMsg in String form 1377 **/ 1378 protected static String getHelpMsgStr() {return getHelpMsg().toString();} 1379 1380 1381 /** initializes and gets the helpMsg_ 1382 class var. 1383 * @return the class var helpMsg_ 1384 **/ 1385 protected static StringBuilder getHelpMsg() 1386 { 1387 helpMsg_ = new StringBuilder(SYSTEM_LINE_SEPERATOR); 1388 helpMsg_.append("--- WebARTS "+CLASSNAME+" Class -----------------------------------------------------"); 1389 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1390 helpMsg_.append("--- + $Revision: 1091 $ $Date: 2016-05-29 16:26:54 -0700 (Sun, 29 May 2016) $ ---"); 1391 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1392 helpMsg_.append("-------------------------------------------------------------------------------"); 1393 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1394 helpMsg_.append("WebARTS ca.bc.webarts.tools.isy.ISYRestRequester Class"); 1395 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1396 helpMsg_.append("SYNTAX:"); 1397 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1398 helpMsg_.append(" java "); 1399 helpMsg_.append(CLASSNAME); 1400 helpMsg_.append(" command or {restCommand}"); 1401 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1402 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1403 helpMsg_.append("Available commands:"); 1404 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1405 helpMsg_.append(" test"); 1406 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1407 helpMsg_.append(" listNodes "); 1408 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1409 helpMsg_.append(" listScenes "); 1410 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1411 helpMsg_.append(" listScenesAndNodes "); 1412 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1413 helpMsg_.append(" status noneName"); 1414 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1415 helpMsg_.append(" listVars"); 1416 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1417 helpMsg_.append(" getVar varName"); 1418 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1419 helpMsg_.append(" getProperty nodeName propertyName"); 1420 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1421 helpMsg_.append(" toggle nodeName"); 1422 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1423 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1424 helpMsg_.append("Available restCommands:"); 1425 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1426 helpMsg_.append(" see: http://wiki.universal-devices.com/index.php?title=ISY_Developers:API:REST_Interface"); 1427 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1428 helpMsg_.append(" Example: java ca.bc.webarts.android.ISYRestRequester /sys "); 1429 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1430 helpMsg_.append("---------------------------------------------------------"); 1431 helpMsg_.append("----------------------"); 1432 helpMsg_.append(SYSTEM_LINE_SEPERATOR); 1433 1434 return helpMsg_; 1435 } 1436 1437 public static final String TVDIM_ADDR = "42032"; 1438 public static final String GAMESROOMLIGHTS_NODENAME = "Game"; // "26534"; 1439 public static final String GAMESROOMLIGHTS_ADDR = "15 39 FB 1"; // "26534"; 1440 public static final String DWNKITCHEN_NODENAME = "DwnKitchen"; 1441 public static final String DWNKITCHEN_ADDR = "16 45 A4 1"; 1442 public static final String THERMOSTAT_ADDR = "14 13 C6 1"; 1443 public static final String FAMILYMAINLIGHTS_ADDR = "13 A8 32 1"; 1444 public static final String VALENCEFRONTLIGHTS_ADDR = "16 43 93 1"; 1445 public static final String VALENCESURROUNDLIGHTS_ADDR = "16 46 AE 1"; 1446} 1447 1448 1449/* ********************************************************************* */ 1450 1451/** An object to represent a ISY Node with name, Address, type, folder, and group - to simply help with name lookups. 1452 * NO rest requests or call to the ISy are initiated from this class. 1453 **/ 1454class IsyDeviceProperty extends Object 1455{ 1456 String id_ = ""; 1457 String value_ = ""; 1458 String formatted_ = ""; 1459 String uom_ = ""; 1460 boolean isInteger_ = false; 1461 int intValue_=-1; 1462 String elementStr_ = ""; 1463 1464 public IsyDeviceProperty() 1465 { 1466 } 1467 1468 1469 public IsyDeviceProperty(String id,String value,String formatted,String uom) 1470 { 1471 id_ = id; 1472 value_ = value; 1473 formatted_ = formatted; 1474 uom_ = uom; 1475 } 1476 1477 1478 /** 1479 * Reads in Property values from the the XML property element from the rest response. 1480 * 1481 *<pre> 1482 * <property id="ST" value="0" formatted="Off" uom="%/on/off"/> 1483 *</pre> 1484 **/ 1485 public IsyDeviceProperty(String properyXmlStr) 1486 { 1487 int valueVal = -1; 1488 int formattedVal = -1; 1489 /* Parse Out id */ 1490 int iSpot = properyXmlStr.indexOf(" id"); 1491 String iVal = properyXmlStr.substring(iSpot+5,properyXmlStr.indexOf("\"", iSpot+6)); 1492 setId(iVal); 1493 1494 /* Parse Out value */ 1495 int vSpot = properyXmlStr.indexOf(" value"); 1496 String vVal = properyXmlStr.substring(vSpot+8,properyXmlStr.indexOf("\"", vSpot+9)); 1497 if(vVal.equalsIgnoreCase("Off") ) valueVal = 0; 1498 else if (vVal.equalsIgnoreCase("On") ) valueVal = 100; 1499 else if (vVal.trim().equals("") ) valueVal = -1; 1500 else if (vVal.trim().indexOf(".")!=-1 ) 1501 try{valueVal = Integer.parseInt(vVal.substring(0,vVal.indexOf(".")));} 1502 catch(Exception ex){System.out.println("ERROR pulling the value from "+vVal+" "+vVal.substring(0,vVal.indexOf(".")));} 1503 else 1504 try{valueVal = Integer.parseInt(vVal);} 1505 catch(Exception ex){System.out.println("ERROR pulling the int value from "+vVal);} 1506 setValue(vVal); 1507 1508 /* Parse Out formatted */ 1509 int fSpot = properyXmlStr.indexOf(" formatted"); 1510 String fVal = properyXmlStr.substring(fSpot+12,properyXmlStr.indexOf("\"", fSpot+13)); 1511 if(fVal.equalsIgnoreCase("Off") ) formattedVal = 0; 1512 else if (fVal.equalsIgnoreCase("On") ) formattedVal = 100; 1513 else if (fVal.trim().equals("") ) formattedVal = -1; 1514 else if (fVal.trim().indexOf(".")!=-1 ) 1515 try{formattedVal = Integer.parseInt(fVal.substring(0,fVal.indexOf(".")));} 1516 catch(Exception ex){System.out.println("ERROR pulling the formattedValue from "+fVal+" "+fVal.substring(0,fVal.indexOf(".")));} 1517 else 1518 try{formattedVal = Integer.parseInt(fVal);} 1519 catch(Exception ex){System.out.println("ERROR pulling the int vformattedValue from "+fVal);} 1520 setFormatted(fVal); 1521 if(formattedVal!=-1) setIntValue(formattedVal); 1522 1523 /* Parse Out uom */ 1524 int uSpot = properyXmlStr.indexOf(" uom"); 1525 String uVal = properyXmlStr.substring(uSpot+6,properyXmlStr.indexOf("\"", uSpot+7)); 1526 setUom(uVal); 1527 } 1528 1529 1530 public String getElementStr() 1531 { 1532 return "<property id=\""+getId()+"\" value=\""+getValue()+"\" formatted=\""+getFormatted()+"\" uom=\""+getUom()+"\"/>"; 1533 } 1534 1535 1536 /** 1537 * Set Method for class field 'id_'. 1538 * 1539 * @param name_ is the value to set this class field to. 1540 * 1541 **/ 1542 public void setId(String id) 1543 { 1544 this.id_ = id; 1545 } // setId Method 1546 1547 1548 /** 1549 * Get Method for class field 'id_'. 1550 * 1551 * @return String - The value the class field 'id_'. 1552 * 1553 **/ 1554 public String getId() 1555 { 1556 return id_; 1557 } // getId Method 1558 1559 1560 /** 1561 * Set Method for class field 'value_'. 1562 * 1563 * @param value_ is the value to set this class field to. 1564 * 1565 **/ 1566 public void setValue(String value) 1567 { 1568 this.value_ = value; 1569 } // setValue Method 1570 1571 1572 /** 1573 * Get Method for class field 'value_'. 1574 * 1575 * @return String - The value the class field 'value_'. 1576 * 1577 **/ 1578 public String getValue() 1579 { 1580 return value_; 1581 } // getValue Method 1582 1583 /** 1584 * Set Method for class field 'formatted_'. 1585 * 1586 * @param formatted_ is the value to set this class field to. 1587 * 1588 **/ 1589 public void setFormatted(String formatted) 1590 { 1591 this.formatted_ = formatted; 1592 } // setFormatted Method 1593 1594 1595 /** 1596 * Get Method for class field 'formatted_'. 1597 * 1598 * @return String - The value the class field 'formatted_'. 1599 * 1600 **/ 1601 public String getFormatted() 1602 { 1603 return formatted_; 1604 } // getFormatted Method 1605 1606 1607 /** 1608 * Set Method for class field 'uom_'. 1609 * 1610 * @param uom_ is the value to set this class field to. 1611 * 1612 **/ 1613 public void setUom(String uom) 1614 { 1615 this.uom_ = uom; 1616 } // setUom Method 1617 1618 1619 /** 1620 * Get Method for class field 'uom_'. 1621 * 1622 * @return String - The value the class field 'uom_'. 1623 * 1624 **/ 1625 public String getUom() 1626 { 1627 return uom_; 1628 } // getUom Method 1629 1630 1631 /** 1632 * Set Method for class field 'isInteger_'. 1633 * 1634 * @param isInteger_ is the value to set this class field to. 1635 * 1636 **/ 1637 public void setIsInteger(boolean isInteger) 1638 { 1639 this.isInteger_ = isInteger; 1640 } // setIsInteger Method 1641 1642 1643 /** 1644 * Get Method for class field 'isInteger_'. 1645 * 1646 * @return boolean - The value the class field 'isInteger_'. 1647 * 1648 **/ 1649 public boolean getIsInteger() 1650 { 1651 return isInteger_; 1652 } // getIsInteger Method 1653 1654 1655 /** 1656 * Set Method for class field 'intValue_'. 1657 * 1658 * @param intValue_ is the value to set this class field to. 1659 * 1660 **/ 1661 public void setIntValue(int intValue) 1662 { 1663 this.intValue_ = intValue; 1664 if (intValue!=-1) setIsInteger(true); 1665 } // setIntValue Method 1666 1667 1668 /** 1669 * Get Method for class field 'intValue_'. 1670 * 1671 * @return int - The value the class field 'intValue_'. 1672 * 1673 **/ 1674 public int getIntValue() 1675 { 1676 return intValue_; 1677 } // getIntValue Method 1678 1679} 1680 1681 1682/* ********************************************************************* */ 1683 1684/** An object to represent a ISY Node with name, Address, type, folder, and group - to simply help with name lookups. 1685 * NO rest requests or call to the ISy are initiated from this class. 1686 **/ 1687class IsyNodes extends Object 1688{ 1689 public static final int SWITCH_TYPE = 1; 1690 public static final int DIMMER_TYPE = 2; 1691 public static final int PLUG_TYPE = 3; 1692 public static final int SENSOR_TYPE = 4; 1693 public static final int THERMOSTAT_TYPE = 5; 1694 public static final int METER_TYPE = 6; 1695 Document nodeDoc_ = null; 1696 Element rootElem_ = null; 1697 Builder xmlBuilder_ = new Builder(); 1698 String [] elementNames_ = {"root","folder","node","group"}; 1699 String [] nodeNames_ = null; 1700 String [] nodeAddresses_ = null; 1701 int [] nodeTypes_ = null; 1702 String [] folderNames_ = null; 1703 String [] folderAddresses_ = null; 1704 String [] groupNames_ = null; 1705 String [] groupAddresses_ = null; 1706 GroupMembers [] groupMembers_ = null; 1707 Elements folderElements_ = null; 1708 Elements nodeElements_ = null; 1709 Elements groupElements_ = null; 1710 1711 public IsyNodes() 1712 { 1713 /* 1714 StringBuilder nodeXmlSB = ISYRestRequester.serviceGet("/nodes"); 1715 if(nodeXmlSB!=null && nodeXmlSB.length()>7) 1716 { 1717 nodeDoc_ = parseXMLNodes(nodeXmlSB.toString()); 1718 } 1719 */ 1720 } 1721 1722 1723 public IsyNodes(String nodeXmlStr) throws ParsingException, IOException 1724 { 1725 if(nodeXmlStr!=null && nodeXmlStr.length()>7) 1726 { 1727 1728 nodeDoc_ = parseXMLNodes(nodeXmlStr); 1729 } 1730 } 1731 1732 1733 public IsyNodes(StringBuilder nodeXmlSB) throws ParsingException, IOException 1734 { 1735 if(nodeXmlSB!=null && nodeXmlSB.length()>7) 1736 { 1737 nodeDoc_ = parseXMLNodes(nodeXmlSB.toString()); 1738 } 1739 } 1740 1741 1742 public String toString() 1743 { 1744 String retVal = ""; 1745 for (int i=0; i<nodeNames_.length; i++) 1746 { 1747 retVal+=nodeNames_[i]; 1748 retVal+=" {"; 1749 retVal+=nodeTypes_[i]; 1750 retVal+=") : "; 1751 retVal+= getNodeAddress(nodeNames_[i]); 1752 retVal+="\n"; 1753 } 1754 return retVal; 1755 } 1756 1757 1758 protected boolean hasNodeName(String nodeName) 1759 { 1760 boolean retVal = false; 1761 //System.out.println("Checking "); 1762 for(int i=0; i< nodeNames_.length;i++) 1763 { 1764 //System.out.print(" "+nodeNames_[i]); 1765 if(nodeNames_[i].equalsIgnoreCase(nodeName)) { retVal = true;i=nodeNames_.length;} 1766 //System.out.println(" "+retVal); 1767 } 1768 return retVal; 1769 } 1770 1771 1772 protected boolean hasGroupName(String groupName) 1773 { 1774 boolean retVal = false; 1775 //System.out.println("Checking "); 1776 for(int i=0; i< groupNames_.length;i++) 1777 { 1778 //System.out.print(" "+nodeNames_[i]); 1779 if(groupNames_[i].equalsIgnoreCase(groupName)) { retVal = true;i=groupNames_.length;} 1780 //System.out.println(" "+retVal); 1781 } 1782 return retVal; 1783 } 1784 1785 protected boolean hasSceneName(String sceneName) 1786 { 1787 return hasGroupName(sceneName); 1788 } 1789 1790 1791 /** Returns the class var nodeNames_. **/ 1792 protected String [] getNodeNames() 1793 { 1794 return nodeNames_; 1795 } 1796 1797 1798 /** Returns the class var nodeAddresses_. **/ 1799 protected String [] getNodeAddresses() 1800 { 1801 return nodeAddresses_; 1802 } 1803 1804 1805 /** Returns a verbatim COPY of the class var nodeNames_. **/ 1806 protected String [] getNodeNamesCopy(){ return getNodeNamesCopy(false);} 1807 /** Returns a verbatim COPY of the class var nodeNames_. **/ 1808 protected String [] getNodeNamesCopy(boolean sorted) 1809 { 1810 String [] retVal = new String[nodeNames_.length]; 1811 java.lang.System.arraycopy(nodeNames_, 0, retVal, 0, nodeNames_.length); 1812 if(sorted) Quick.sort(retVal); 1813 return retVal; 1814 } 1815 1816 1817 /** Returns a verbatim COPY of the class var sceneNames_. **/ 1818 protected String [] getSceneNamesCopy(){ return getSceneNamesCopy(false);} 1819 /** Returns a verbatim COPY of the class var sceneNames_. **/ 1820 protected String [] getSceneNamesCopy(boolean sorted) 1821 { 1822 return getGroupNamesCopy(sorted); 1823 } 1824 1825 1826 /** Returns a verbatim COPY of the class var nodeAddresses_. **/ 1827 protected String [] getNodeAddressesCopy() 1828 { 1829 String [] retVal = new String[nodeAddresses_.length]; 1830 java.lang.System.arraycopy(nodeAddresses_, 0, retVal, 0, nodeAddresses_.length); 1831 return retVal; 1832 } 1833 1834 1835 /** Returns a verbatim COPY of the class var groupAddresses_. **/ 1836 protected String [] getSceneAddressesCopy() 1837 { 1838 return getGroupAddressesCopy(); 1839 } 1840 1841 1842 /** Returns the class var folderNames_. **/ 1843 protected String [] getFolderNames() 1844 { 1845 return folderNames_; 1846 } 1847 1848 1849 /** Returns a verbatim COPY of the class var folderNames_. **/ 1850 protected String [] getFolderNamesCopy(){ return getNodeNamesCopy(false);} 1851 /** Returns a verbatim COPY of the class var folderNames_. **/ 1852 protected String [] getFolderNamesCopy(boolean sorted) 1853 { 1854 String [] retVal = new String[folderNames_.length]; 1855 java.lang.System.arraycopy(folderNames_, 0, retVal, 0, folderNames_.length); 1856 if(sorted) Quick.sort(retVal); 1857 return retVal; 1858 } 1859 1860 1861 /** Returns the class var groupNames_. **/ 1862 protected String [] getGroupNames() 1863 { 1864 return groupNames_; 1865 } 1866 1867 1868 /** Returns a verbatim COPY of the class var groupNames_. **/ 1869 protected String [] getGroupNamesCopy(){ return getNodeNamesCopy(false);} 1870 /** Returns a verbatim COPY of the class var groupNames_. **/ 1871 protected String [] getGroupNamesCopy(boolean sorted) 1872 { 1873 String [] retVal = new String[groupNames_.length]; 1874 java.lang.System.arraycopy(groupNames_, 0, retVal, 0, groupNames_.length); 1875 if(sorted) Quick.sort(retVal); 1876 return retVal; 1877 } 1878 1879 1880 /** Returns a verbatim COPY of the class var groupAddresses_. **/ 1881 protected String [] getGroupAddressesCopy() 1882 { 1883 String [] retVal = new String[groupAddresses_.length]; 1884 java.lang.System.arraycopy(groupAddresses_, 0, retVal, 0, groupAddresses_.length); 1885 return retVal; 1886 } 1887 1888 1889 protected Element getNodeWithName(String nodeName) 1890 { 1891 Element retVal = null; 1892 if (nodeNames_!=null && nodeNames_.length>0) 1893 { 1894 int i=0; 1895 while( retVal==null && i<nodeNames_.length) 1896 { 1897 if(nodeNames_[i].equals(nodeName)) retVal=nodeElements_.get(i); 1898 i++; 1899 } 1900 } 1901 return retVal; 1902 } 1903 1904 1905 protected Element getSceneWithName(String sceneName) 1906 { 1907 Element retVal = null; 1908 if (groupNames_!=null && groupNames_.length>0) 1909 { 1910 int i=0; 1911 while( retVal==null && i<groupNames_.length) 1912 { 1913 if(groupNames_[i].equals(sceneName)) retVal=groupElements_.get(i); 1914 i++; 1915 } 1916 } 1917 return retVal; 1918 } 1919 1920 1921 protected String getSceneAddress(String sceneName) { return getGroupAddress(sceneName); } 1922 protected String getGroupAddress(String sceneName) 1923 { 1924 String retVal = ""; 1925 if (groupNames_!=null && groupNames_.length>0) 1926 { 1927 //System.out.print("\n >>> getGroupAddress( "+sceneName+" ) "); 1928 //System.out.println("\n groupNames_.length="+groupNames_.length); 1929 int i=0; 1930 while( retVal.equals("") && i<groupNames_.length ) 1931 { 1932 if(groupNames_[i].equalsIgnoreCase(sceneName)) 1933 { 1934 retVal=groupAddresses_[i]; 1935 //System.out.print(""+i+"] "+groupNames_[i]+"="+retVal); 1936 } 1937 i++; 1938 } 1939 } 1940 //System.out.print("\n"); 1941 return retVal; 1942 } 1943 1944 1945 protected String getNodeAddress(String nodeName) 1946 { 1947 String retVal = ""; 1948 if (nodeNames_!=null && nodeNames_.length>0) 1949 { 1950 //System.out.print("\n >>> getNodeAddress( "+nodeName+" ) "); 1951 //System.out.println("\n nodeNames_.length="+nodeNames_.length); 1952 int i=0; 1953 while( retVal.equals("") && i<nodeNames_.length ) 1954 { 1955 if(nodeNames_[i].equalsIgnoreCase(nodeName)) 1956 { 1957 retVal=nodeAddresses_[i]; 1958 //System.out.print(""+i+"] "+nodeNames_[i]+"="+retVal); 1959 } 1960 i++; 1961 } 1962 } 1963 // not found in NODES, look in groups 1964 if("".equals(retVal)) 1965 { 1966 retVal = getGroupAddress(nodeName); 1967 } 1968 //System.out.print("\n"); 1969 return retVal; 1970 } 1971 1972 1973 protected int getNodeRef(String nodeName) 1974 { 1975 int retVal=-1; 1976 int i=0; 1977 if (nodeNames_!=null && nodeNames_.length>0) 1978 { 1979 //System.out.print("\n >>> getNodeAddress( "+nodeName+" ) "); 1980 //System.out.println("\n nodeNames_.length="+nodeNames_.length); 1981 while( retVal==-1 && i<nodeNames_.length ) 1982 { 1983 if(nodeNames_[i].equalsIgnoreCase(nodeName)) 1984 { 1985 retVal=i; 1986 //System.out.print(""+i+"] "+nodeNames_[i]+"="+retVal); 1987 } 1988 i++; 1989 } 1990 } 1991 return i; 1992 } 1993 1994 1995 /** gets the array ref num for the given scene Name. 1996 * 1997 * @return the ref num for the array OR -1 if scene not found 1998 **/ 1999 protected int getGroupRef(String sceneName) 2000 { 2001 int retVal=-1; 2002 int i=0; 2003 if (groupNames_!=null && groupNames_.length>0) 2004 { 2005 //System.out.print("\n >>> getGroupAddress( "+sceneName+" ) "); 2006 //System.out.println("\n groupNames_.length="+groupNames_.length); 2007 while( retVal==-1 && i<groupNames_.length ) 2008 { 2009 if(groupNames_[i].equalsIgnoreCase(sceneName)) 2010 { 2011 retVal=i; 2012 //System.out.print(""+i+"] "+groupNames_[i]+"="+retVal); 2013 } 2014 i++; 2015 } 2016 } 2017 //System.out.print("\n"); 2018 return retVal; 2019 } 2020 2021 2022 GroupMembers getGroupMembers(String sceneName) 2023 { 2024 GroupMembers retVal = null; 2025 if(getGroupRef(sceneName)>-1) retVal = groupMembers_[getGroupRef(sceneName)]; 2026 return retVal; 2027 } 2028 2029 2030 protected int getNodeType(String nodeName) 2031 { 2032 int retVal = -1; 2033 if (nodeNames_!=null && nodeNames_.length>0) 2034 { 2035 int i=0; 2036 while( retVal==-1 && i<nodeNames_.length) 2037 { 2038 if(nodeNames_[i].equals(nodeName)) retVal=nodeTypes_[i]; 2039 i++; 2040 } 2041 } 2042 return retVal; 2043 } 2044 2045 2046 protected String getNodeTypeStr(String nodeName) 2047 { 2048 String retVal = ""; 2049 int t = getNodeType( nodeName); 2050 if (t==SWITCH_TYPE) retVal="SWITCH_TYPE"; 2051 else if (t==DIMMER_TYPE) retVal="DIMMER_TYPE"; 2052 else if (t==PLUG_TYPE) retVal="PLUG_TYPE"; 2053 else if (t==SENSOR_TYPE) retVal="SENSOR_TYPE"; 2054 else if (t==THERMOSTAT_TYPE) retVal="THERMOSTAT_TYPE"; 2055 else if (t==METER_TYPE) retVal="METER_TYPE"; 2056 return retVal; 2057 } 2058 2059 2060 protected String getNodeName(String nodeAddress) 2061 { 2062 String retVal = ""; 2063 if (nodeAddresses_!=null && nodeAddresses_.length>0) 2064 { 2065 int i=0; 2066 while( retVal.equals("") && i<nodeAddresses_.length) 2067 { 2068 if(nodeAddresses_[i].equals(nodeAddress)) retVal=nodeNames_[i]; 2069 i++; 2070 } 2071 } 2072 return retVal; 2073 } 2074 2075 2076 protected String getGroupName(String sceneAddress) { return getSceneName(sceneAddress);} 2077 protected String getSceneName(String sceneAddress) 2078 { 2079 String retVal = ""; 2080 if (groupAddresses_!=null && groupAddresses_.length>0) 2081 { 2082 int i=0; 2083 while( retVal.equals("") && i<groupAddresses_.length) 2084 { 2085 if(groupAddresses_[i].equals(sceneAddress)) retVal=groupNames_[i]; 2086 i++; 2087 } 2088 } 2089 return retVal; 2090 } 2091 2092 2093 /** 2094 * Reads in the XML Config file. 2095 * 2096 *<pre> 2097 * <node flag="128"> 2098 * <address>1 81 CF 1</address> 2099 * <name>HangingLight-E</name> 2100 * <parent type="3">28566</parent> 2101 * <type>1.7.55.0</type> 2102 * <enabled>true</enabled> 2103 * <deviceClass>0</deviceClass> 2104 * <wattage>0</wattage> 2105 * <dcPeriod>0</dcPeriod> 2106 * <pnode>1 81 CF 1</pnode> 2107 * <ELK_ID>C07</ELK_ID> 2108 * <property id="ST" value="0" formatted="Off" uom="%/on/off" /> 2109 * </node> 2110 *</pre> 2111 **/ 2112 protected nu.xom.Document parseXMLNodes(String nodeXmlStr) throws ParsingException, IOException 2113 { 2114 //String methodName = className_+"."+Util.getCurrentMethodName(); 2115 //log_.startMethod(methodName); 2116 try 2117 { 2118 nodeDoc_ = xmlBuilder_.build(nodeXmlStr,null); 2119 } 2120 catch (nu.xom.ParsingException xomEx) 2121 { 2122 xomEx.printStackTrace(); 2123 System.out.println("MAJor Error: parsing nodeXmlStr"); 2124 System.out.println(nodeXmlStr); 2125 System.out.println("MAJor Error: parsing nodeXmlStr"); 2126 } 2127 if (nodeDoc_!=null) 2128 { 2129 rootElem_ = nodeDoc_.getRootElement(); 2130 // load the data 2131 if (rootElem_ != null && rootElem_ instanceof Element && rootElem_.getLocalName().equals("nodes")) 2132 { 2133 folderElements_ = rootElem_.getChildElements("folder"); 2134 nodeElements_ = rootElem_.getChildElements("node"); 2135 groupElements_ = rootElem_.getChildElements("group"); 2136 2137 Element currE = null; 2138 Element stateE = null; 2139 int numNodes = nodeElements_.size(); 2140 if (nodeElements_!=null && nodeElements_.size()>0) 2141 { 2142 nodeNames_ = new String[numNodes]; 2143 nodeAddresses_ = new String[numNodes]; 2144 nodeTypes_ = new int[numNodes]; 2145 2146 //System.out.println("\nParsing Nodes:"); 2147 for (int i=0; i< numNodes; i++) 2148 { 2149 currE = null; 2150 currE = nodeElements_.get(i); 2151 if (currE !=null) 2152 { 2153 try 2154 { 2155 nodeNames_[i] = currE.getFirstChildElement("name").getValue(); 2156 nodeAddresses_[i] = currE.getFirstChildElement("address").getValue(); 2157 2158 //System.out.println(" > "+nodeNames_[i]+" "+nodeAddresses_[i]); 2159 2160 stateE = currE.getFirstChildElement("property"); // should be the 'ST' property 2161 if(nodeNames_[i].toUpperCase().indexOf("PLUG")!=-1){ nodeTypes_[i] = PLUG_TYPE;} 2162 else if(nodeNames_[i].toUpperCase().indexOf("SENSE")!=-1){nodeTypes_[i] = SENSOR_TYPE;} 2163 else if(nodeNames_[i].contains("Thermostat")|| 2164 (stateE!=null&&stateE.getAttribute("uom").getValue().equals("degrees")) ) 2165 { nodeTypes_[i] = THERMOSTAT_TYPE;} 2166 else if((stateE!=null&&stateE.getAttribute("uom").getValue().indexOf("%")!=-1 )) { nodeTypes_[i] = DIMMER_TYPE;} 2167 else if((stateE!=null&&stateE.getAttribute("uom").getValue().equals("W") )) { nodeTypes_[i] = METER_TYPE;} 2168 else { nodeTypes_[i] = SWITCH_TYPE;} 2169 } 2170 catch(java.lang.NullPointerException npEx) 2171 { 2172 System.out.println("Minor Error: problem parsing "+i+"\n nodeName: "+nodeNames_[i]+"\n nodeAddresses_"+nodeAddresses_[i]); 2173 System.out.println(" child Element "+stateE); 2174 } 2175 } 2176 } 2177 } 2178 if (folderElements_!=null && folderElements_.size()>0) 2179 { 2180 folderNames_ = new String[folderElements_.size()]; 2181 folderAddresses_ = new String[folderElements_.size()]; 2182 for (int i=0; i< folderElements_.size(); i++) 2183 { 2184 currE = null; 2185 currE = folderElements_.get(i); 2186 if (currE !=null) 2187 { 2188 folderNames_[i] = currE.getFirstChildElement("name").getValue(); 2189 folderAddresses_[i] = currE.getFirstChildElement("address").getValue(); 2190 } 2191 } 2192 } 2193 if (groupElements_!=null && groupElements_.size()>0) 2194 { 2195 groupNames_ = new String[groupElements_.size()]; 2196 groupAddresses_ = new String[groupElements_.size()]; 2197 groupMembers_ = new GroupMembers[groupElements_.size()]; 2198 for (int i=0; i< groupElements_.size(); i++) 2199 { 2200 currE = null; 2201 currE = groupElements_.get(i); 2202 if (currE !=null) 2203 { 2204 Element members = null; 2205 Elements links = null; 2206 try 2207 { 2208 groupNames_[i] = currE.getFirstChildElement("name").getValue(); 2209 groupAddresses_[i] = currE.getFirstChildElement("address").getValue(); 2210 // the group nodes are wrapped in: 2211 /* 2212 <members> 2213 <link type="16">13 EB 11 1</link> 2214 <link type="16">43 A2 FB 3</link> 2215 <link type="32">13 57 A7 1</link> 2216 <link type="32">20 B8 93 1</link> 2217 </members> 2218 // type is a relationship type 2219 // 16 is a switch/controller 2220 // 32 is a node 2221 */ 2222 members = currE.getFirstChildElement("members"); 2223 links = members.getChildElements("link"); 2224 groupMembers_[i] = new GroupMembers(links); 2225 } 2226 catch(java.lang.NullPointerException npEx) 2227 { 2228 System.out.println("Minor Error: problem parsing "+i+"\n groupName: "+groupNames_[i]+"\n groupAddresses: "+groupAddresses_[i]); 2229 System.out.println(" members Element "+members); 2230 System.out.println(" links "+links); 2231 System.out.println(" currE "+currE); 2232 npEx.printStackTrace(); 2233 } 2234 } 2235 } 2236 } 2237 } 2238 } 2239 2240 //log_.endMethod(methodName); 2241 return nodeDoc_; 2242 } 2243} 2244 2245/* ********************************************************************* */ 2246 2247/* holds the addresses of scene/group member nodes and switches */ 2248class GroupMembers extends Object 2249{ 2250 String [] memberNodes_ = null; 2251 String [] memberSwitchNodes_ = null; 2252 boolean debugOut_ = false; 2253 2254 public GroupMembers(Elements links) 2255 { 2256 int devCount = 0; 2257 int swCount = 0; 2258 for (int i = 0; i<links.size(); i++) 2259 { 2260 // ONLY include switchable nodes type='32' 2261 try 2262 { 2263 if("32".equals(links.get(i).getAttribute("type").getValue())) devCount++; 2264 else swCount++; 2265 } 2266 catch(java.lang.NullPointerException npEx) {if(debugOut_) npEx.printStackTrace();} 2267 } 2268 memberNodes_ = new String[devCount]; 2269 memberSwitchNodes_ = new String[swCount]; 2270 devCount = 0; 2271 swCount = 0; 2272 for (int i = 0; i<links.size(); i++) 2273 { 2274 // ONLY include switchable nodes type='32' 2275 try 2276 { 2277 if("32".equals(links.get(i).getAttribute("type").getValue())) 2278 { 2279 memberNodes_[devCount++] = links.get(i).getValue(); 2280 } 2281 else 2282 { 2283 memberSwitchNodes_[swCount++] = links.get(i).getValue(); 2284 } 2285 } 2286 catch(java.lang.NullPointerException npEx) {if(debugOut_) npEx.printStackTrace();} 2287 } 2288 2289 }// constructor 2290 2291 String [] getMemberNodes() { return memberNodes_;} 2292 String [] getMemberSwitchNodes() { return memberSwitchNodes_;} 2293 public String toString() 2294 { 2295 String retVal = "node addresses: "; 2296 for(String memAddr : memberNodes_) retVal += memAddr+", "; 2297 retVal=retVal.substring(0,retVal.length()-2); 2298 retVal += System.getProperty("line.separator")+"switch/controller addresses: "; 2299 for(String memAddr : memberSwitchNodes_) retVal += memAddr+", "; 2300 retVal=retVal.substring(0,retVal.length()-2); 2301 return retVal; 2302 } 2303} // class GroupMembers 2304 2305 2306/* ********************************************************************* */ 2307 2308 2309/** an object to represent an ISY Node. **/ 2310class IsyVars extends Object 2311{ 2312 public static final int VAR_TYPE_INT = 1; 2313 public static final int VAR_TYPE_STATE = 2; 2314 int varType_ = VAR_TYPE_INT; 2315 int maxID_ = 0; 2316 Document varDoc_ = null; 2317 Document varValueDoc_ = null; 2318 Element rootElem_ = null; 2319 Builder xmlBuilder_ = new Builder(); 2320 Hashtable <String, Integer> varName_ = null; 2321 String [] varValue_ = null; 2322 Elements varElements_ = null; 2323 2324 2325 public IsyVars() 2326 { 2327 2328 } 2329 2330 2331 public IsyVars( int varType, StringBuilder varXmlSB, StringBuilder varValuesXmlSB) throws ParsingException, IOException 2332 { 2333 if( (varType==VAR_TYPE_INT || varType==VAR_TYPE_STATE) && varXmlSB!=null && varXmlSB.length()>7 && varValuesXmlSB!=null && varValuesXmlSB.length()>7 ) 2334 { 2335 varType_ = varType; 2336 parseXMLVars(varXmlSB.toString(),varValuesXmlSB.toString()); 2337 } 2338 } 2339 2340 2341 /** 2342 * Reads in the XML Config files - a definition XML and a var Value XML. 2343 * 2344 *<pre> 2345 * <CList type="VAR_INT"> 2346 * <e id="1" name="ir9Count" /> 2347 * <e id="2" name="Int_UpKeypadTemp" /> 2348 * <e id="3" name="Int_DwnKeypadTemp" /> 2349 * <e id="4" name="VacationMode" /> 2350 * <e id="5" name="iMeterCurrentValue" /> 2351 * <e id="6" name="PowerFailure" /> 2352 * <e id="7" name="LastPowerFailure" /> 2353 * <e id="8" name="ChristmasMode" /> 2354 * <e id="9" name="StairSensor" /> 2355 * <e id="10" name="PowerFailureEmailSent" /> 2356 * <e id="11" name="WakeWarp4" /> 2357 * <e id="12" name="tomsMorningLights" /> 2358 * <e id="13" name="iDay.Of.Year" /> 2359 * <e id="14" name="iDay.Of.Month" /> 2360 * <e id="15" name="iYear" /> 2361 * <e id="17" name="iDay.Of.Week" /> 2362 * <e id="16" name="iLeap.Year" /> 2363 * <e id="19" name="iDay.Counter" /> 2364 * <e id="18" name="iMonth" /> 2365 * <e id="21" name="iEvery.Third.Day.Counter" /> 2366 * <e id="20" name="iEvery.Other.Day.Counter" /> 2367 * <e id="23" name="iEvery.Fifth.Day.Counter" /> 2368 * <e id="22" name="iEvery.Fourth.Day.Counter" /> 2369 * <e id="25" name="iWeek.Counter" /> 2370 * <e id="24" name="iWeek.Of.Month" /> 2371 * <e id="27" name="iEvery.Third.Week.Counter" /> 2372 * <e id="26" name="iEvery.Other.Week.Counter" /> 2373 * <e id="29" name="iOdd.Even.Day" /> 2374 * <e id="28" name="iEvery.Fourth.Week.Counter" /> 2375 * <e id="31" name="iSync" /> 2376 * <e id="30" name="iHoliday" /> 2377 * <e id="34" name="elk.zone.down.window.violated" /> 2378 * <e id="35" name="elk.zone.water.violated" /> 2379 * <e id="32" name="elk.zone.door.violated" /> 2380 * <e id="33" name="elk.zone.up.window.violated" /> 2381 * <e id="36" name="elk.zone.smoke.violated" /> 2382 * <e id="37" name="elk.zone.up.bedroomWindows.bypass" /> 2383 * </CList> 2384 * 2385 * <vars> 2386 * <var type="1" id="1"> 2387 * <init>0</init> 2388 * <val>0</val> 2389 * <ts>20160131 17:15:16</ts> 2390 * </var> 2391 * <var type="1" id="2"> 2392 * <init>0</init> 2393 * <val>22</val> 2394 * <ts>20160313 09:58:26</ts> 2395 * </var> 2396 * .... 2397 * </vars> 2398 *</pre> 2399 **/ 2400 protected void parseXMLVars(String varXmlStr, String varValuesXmlStr) throws ParsingException, IOException 2401 { 2402 //String methodName = className_+"."+Util.getCurrentMethodName(); 2403 //log_.startMethod(methodName); 2404 String tmpNm = ""; 2405 String tmpId = ""; 2406 varDoc_ = xmlBuilder_.build(varXmlStr,null); 2407 if (varDoc_!=null) 2408 { 2409 rootElem_ = varDoc_.getRootElement(); 2410 // load the var definitions 2411 if (rootElem_ != null && rootElem_ instanceof Element && rootElem_.getLocalName().equals("CList")) 2412 { 2413 varElements_ = rootElem_.getChildElements("e"); 2414 2415 Element currE = null; 2416 if (varElements_!=null && varElements_.size()>0) 2417 { 2418 varName_ = new Hashtable<String, Integer>(); 2419 for (int i=0; i< varElements_.size(); i++) 2420 { 2421 currE = varElements_.get(i); 2422 if (currE !=null) 2423 { 2424 tmpNm = currE.getAttribute("name").getValue(); 2425 tmpId = currE.getAttribute("id").getValue().trim(); 2426 //System.out.println("Adding "+tmpNm+":"+tmpId); 2427 varName_.put(tmpNm, new Integer(tmpId)); 2428 if(Integer.parseInt(tmpId)>maxID_) maxID_ = Integer.parseInt(tmpId); 2429 } 2430 } 2431 } 2432 } 2433 } 2434 varValueDoc_ = xmlBuilder_.build(varValuesXmlStr,null); 2435 if (varDoc_!=null) 2436 { 2437 rootElem_ = varValueDoc_.getRootElement(); 2438 // load the var definitions 2439 if (rootElem_ != null && rootElem_ instanceof Element && rootElem_.getLocalName().equals("vars")) 2440 { 2441 varElements_ = rootElem_.getChildElements("var"); 2442 } 2443 } 2444 } 2445 2446 2447 public int getNumVars() 2448 { 2449 int retVal = 0; 2450 if(varName_!=null) retVal = varName_.size(); 2451 return retVal; 2452 } 2453 2454 2455 public String [] getVarNames() 2456 { 2457 String [] retVal = new String[varName_.size()]; 2458 Set<String> namesSet = varName_.keySet(); 2459 retVal = (String []) namesSet.toArray(retVal); 2460 return retVal; 2461 } 2462 2463 2464 public int getVarValue(String varName) throws Exception 2465 { 2466 int retVal = 0; 2467 //System.out.println(" DEBUG: Varname: "+varName+" VarVal: "); 2468 int varID = 0; 2469 Integer vI = null; 2470 2471 Set<String> namesSet = varName_.keySet(); 2472 //System.out.println(Arrays.toString(namesSet.toArray())); 2473 if(varName_!=null && varName_.containsKey(varName)) 2474 { 2475 try 2476 { 2477 vI = ((Integer)varName_.get(varName)); 2478 if(vI !=null) 2479 varID = vI.intValue(); 2480 else 2481 System.out.println("\nCrapped Out on ("+varName+") "+varName_.get(varName)); 2482 } 2483 catch ( java.lang.NullPointerException nEx) 2484 { 2485 System.out.println("\nERROR with "+varName); 2486 nEx.printStackTrace(); 2487 throw new Exception("VarName not found"); 2488 } 2489 } 2490 else throw new Exception("VarName not found"); 2491 2492 if (varID>0) 2493 { 2494 Element currE = null; 2495 Attribute currID = null; 2496 if (varElements_!=null && varElements_.size()>0) 2497 { 2498 // varName_ = new Hashtable<String, Integer>(); 2499 for (int i=0; i< varElements_.size(); i++) 2500 { 2501 currE = varElements_.get(i); 2502 if (currE !=null) 2503 { 2504 currID = currE.getAttribute("id"); 2505 if( currID!=null && Integer.parseInt(currID.getValue())==varID) 2506 { 2507 retVal = Integer.parseInt(currE.getFirstChildElement("val").getValue()); 2508 i = varElements_.size(); 2509 } 2510 } 2511 } 2512 } 2513 } 2514 return retVal; 2515 } 2516 2517 2518 /** the max ID value held as a class var. **/ 2519 public int getMaxID() 2520 { 2521 return maxID_; 2522 } 2523 2524 2525 /** the next unused var id value that can be used to create a new var. **/ 2526 public int getNextUnusedID() 2527 { 2528 return getMaxID()+1; 2529 } 2530 2531 2532 public String toString() 2533 { 2534 return varName_.toString().replace(", ",",\n ").replace("{","{\n ").replace("}","\n}"); 2535 } 2536 2537 2538}