001/* 002 * $Source: $ 003 * $Name: $ 004 * $Revision: 1032 $ 005 * $Date: 2015-11-08 19:15:20 -0800 (Sun, 08 Nov 2015) $ 006 * $Locker: $ 007 */ 008/* 009 * ISY99CLI -- A simple commandline access that turns on/off Insteon 010 * devices and scenes.. 011 * 012 * Copyright (C) 2012 WebARTS Design, North Vancouver Canada 013 * http://www.webarts.ca 014 * 015 * This program is free software; you can redistribute it and/or modify 016 * it under the terms of Version 2 of the GNU General Public License as 017 * published by the Free Software Foundation. 018 * 019 * This program is distributed in the hope that it will be useful, 020 * but WITHOUT ANY WARRANTY; without even the implied warranty of 021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 022 * GNU General Public License for more details. 023 * 024 * You should have received a copy of the GNU General Public License 025 * along with this program; if not, write to the Free Software 026 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 027 */ 028package ca.bc.webarts.tools.isy; 029 030//import ca.bc.webarts.widgets.Util; 031 032import java.io.File; 033import java.lang.StringBuilder; 034import java.net.URLEncoder; 035import java.util.Enumeration; 036import java.util.Iterator; 037import java.util.NoSuchElementException; 038import java.util.Set; 039import java.util.StringTokenizer; 040import java.util.Vector; 041 042import com.udi.insteon.client.InsteonConstants; 043import com.udi.isy.jsdk.insteon.ISYInsteonClient; 044import com.universaldevices.client.NoDeviceException; 045import com.universaldevices.common.UDUtil; 046import com.universaldevices.device.model.ProductInfo; 047import com.universaldevices.device.model.UDGroup; 048import com.universaldevices.device.model.UDNode; 049import com.universaldevices.resources.errormessages.Errors; 050import com.universaldevices.soap.*; 051import com.universaldevices.upnp.*; 052import com.universaldevices.rest.UDRestResponse; 053 054import com.nanoxml.XMLElement; 055 056/** 057 * A simple wrapper for sending commands to an Insteon device on or off 058 * via a Universal Devices ISy-99i. This app requires 059 * a few other libraries: webarts as well as the UDI JSDK 060 * implementation on your system. 061 * 062 * @author tgutwin 063 */ 064public class ISY99CLI 065{ 066 /* A Class holder for its name (used in Logging). */ 067 private static String className_ = "ISY99CLI"; 068 069 /** A holder for this clients System File Separator. */ 070 public final static String SYSTEM_FILE_SEPERATOR = File.separator; 071 072 /** A holder for this clients System line termination separator. */ 073 public final static String SYSTEM_LINE_SEPERATOR = 074 System.getProperty("line.separator"); 075 private static IsyInsteonClient myISY = null; 076 private boolean stillRunning_ = false; 077 078 private String[] insteonAddresses_ = {"14.2B.31.1"}; 079 private String lastDevice_=""; 080 private int numNodes_ = insteonAddresses_.length; 081 082 083 private Thread startupThread_ = new Thread () 084 { 085 public void run() 086 { 087 try 088 { 089 myISY.start(); 090 } 091 catch (Exception ex) 092 { 093 // nothing 094 } 095 } 096 097 }; 098 099 100 public boolean stillRunning() 101 { 102 return this.stillRunning_; 103 } 104 105 106 public boolean startIsy( ) 107 { 108 System.out.print(" **Starting Client..."); 109 //startupThread_.start(); 110 myISY.start(); 111 UDUtil.sleep(1000); 112 int timeOut = 0; 113 //timeOut+=1000; 114 while (!myISY.isReadyToGo() && timeOut < 10000) 115 { 116 UDUtil.sleep(200); 117 timeOut+=200; 118 } 119 if (timeOut>9999) 120 System.out.println(" Startup Timed Out."); 121 else 122 System.out.println(" Startup Successful."); 123 this.stillRunning_ = myISY.isReadyToGo(); 124 UDUtil.sleep(2000); 125 return this.stillRunning_ ; 126 } 127 128 129 /** 130 * Cleans up any ISY cleanup procedures in prep for exit. 131 */ 132 protected void isyCleanup() 133 { 134 System.out.print("\nCleaning up before Exit... "); 135 try 136 { 137 startupThread_ = null; 138 this.stillRunning_ = false; 139 UDUtil.sleep(250); 140 myISY.unsubscribeFromEvents(); 141 myISY.cleanUp(); 142 myISY.stop(); 143 //startupThread_.stop(); 144 //Util.sleep(5000); 145 //if (myISY.isReadyToGo()) { System.out.println(" waiting...");UDUtil.sleep(2000);} 146 147 Set<Thread> threadSet = Thread.getAllStackTraces().keySet(); 148 Thread currThread = null; 149 Iterator iter = threadSet.iterator(); 150 while (iter.hasNext()) 151 { 152 currThread = (Thread) iter.next(); 153 System.out.print(currThread.getName()); 154 try 155 { 156 if (currThread.getName().startsWith("Thread")) 157 { 158 System.out.print("[X]"); 159 currThread.interrupt(); 160 } 161 System.out.print(" "); 162 } 163 catch (Exception ex) 164 { 165 // nothing 166 } 167 } 168 } 169 catch (Exception ex) 170 { 171 // nothing 172 } 173 System.out.println("done!"); 174 175 } 176 177 178 179 /** 180 * Notifies the user of a syntax error 181 */ 182 protected void syntaxError() 183 { 184 System.err.println("Syntax error. Try again."); 185 } 186 187 188 189 /** Constructor * */ 190 public ISY99CLI() 191 { 192 myISY = new IsyInsteonClient(); 193 194 } 195 196 197 /** 198 * The main program for the ISY99Buttons class. 199 * 200 * @param arg The command line arguments 201 */ 202 public static void main( String[] arg ) 203 { 204 System.out.println( "Starting "+className_ ); 205 if (arg.length==0) 206 { 207 System.out.println(""); 208 System.out.println("SYNTAX: java ca.bc.webarts.tools.isy.ISY99CLI [command] [DeviceName]"); 209 System.out.println(" command can be one of:\n dump, status, dim, bright, toggle, on, off"); 210 System.out.println(" DeviceName is the name of the device for the command (NOT the address)"); 211 System.out.println(" dump will dump out all the characteristics of the ISY as well as the connected Devices"); 212 } 213 else 214 { 215 ISY99CLI instance = new ISY99CLI(); 216 Errors.addErrorListener(new MyISYErrorHandler()); 217 218 String command = ""; 219 String device = ""; 220 String cmdOption = ""; 221 222 try 223 { 224 //System.out.println("starting ISY"); 225 instance.startIsy(); // this starts and BLOCKS until started 226 //System.out.println("waiting for the ISY to settle ..."); 227 //Thread.sleep(500); 228 int timeOut = 0; 229 //timeOut+=1000; 230 while (!instance.stillRunning_ && timeOut < 10000) 231 { 232 UDUtil.sleep(200); 233 timeOut+=200; 234 } 235 if (timeOut>9999) System.out.print("\n*!*Startup Timed Out."); 236 237 //System.out.println("continuing..."); 238 if (instance.stillRunning_ && instance.myISY.isReadyToGo()) 239 { 240 instance.loadNodeAddresses(); 241 // System.out.println(dumpIsyProductInfo(isyProductInfo).toString()); 242 //instance.startIsy(); // this starts and BLOCKS until started 243 System.out.println("Commanded to do: "+arg[0]); 244 command = arg[0]; 245 if(!command.equals("dump")) device = arg[1]; 246 247 //System.out.println("Action From: "+command); 248 boolean dim = command.trim().startsWith("dim"); 249 boolean bright = command.trim().startsWith("bright"); 250 251 /* *********************************** */ 252 if(command.equals("dump")) 253 { 254 //com.universaldevices.upnp.UDProxyDevice isyDevice = instance.myISY.getDevice(); 255 //ProductInfo isyProductInfo = isyDevice.getProductInfo(); 256 System.out.println(instance.dumpIsyProductInfo().toString()); 257 System.out.println(" Switchable Nodes"); 258 System.out.println(" ~~~~~~~~~~~~~~~~"); 259 for (int i=0; i< instance.insteonAddresses_.length; i++) 260 { 261 System.out.println(" "+ instance.getNodeName(instance.insteonAddresses_[i])+" ("+instance.insteonAddresses_[i]+")"); 262 } 263 264 System.out.println(instance.dumpVariablesInfo().toString()); 265 System.out.println(instance.dumpElkInfo().toString()); 266 } 267 268 /* *********************************** */ 269 else if (dim || bright) 270 { 271 String deviceAddress = instance.getNodeAddress(device); 272 if (dim) 273 { 274 //myISY.dimDevice(lastDevice_); 275 instance.myISY.dimDevice(deviceAddress.replace("."," ")); 276 } 277 else if (bright) 278 { 279 //myISY.brightenDevice(lastDevice_); 280 instance.myISY.brightenDevice(deviceAddress.replace("."," ")); 281 } 282 283 } 284 285 /* *********************************** */ 286 else if(command.equals("toggle")) 287 { 288 String deviceAddress = instance.getNodeAddress(device); 289 290 System.out.print("Toggle: "+device+ " ("+deviceAddress+") " ); 291 { 292 String deviceStatus = instance.getStatus(instance.getNode(deviceAddress)); 293 // System.out.println(" to turn "+(onOffToggle_.getState()?"On":"Off") ); 294 if (deviceStatus!=null) System.out.println(" to turn "+(deviceStatus.equals("0")?"On":"Off") ); 295 System.out.println(" Device Status: "+deviceStatus); 296 //processCommand( onOffCommand+" "+Util.tokenReplace(deviceAddress," ",".") ); 297 298 //if (onOffToggle_.getState()) 299 if (deviceStatus==null||deviceStatus.equals("0")) 300 { 301 //myISY.turnDeviceOn(deviceAddress); 302 instance.myISY.turnDeviceOn(deviceAddress.replace("."," ")); 303 } 304 else 305 { 306 //myISY.turnDeviceOff(deviceAddress); 307 instance.myISY.turnDeviceOff(deviceAddress.replace("."," ")); 308 } 309 } 310 } 311 312 /* *********************************** */ 313 else if(command.equals("on")||command.equals("off")) 314 { 315 String deviceAddress = instance.getNodeAddress(device); 316 317 if (command.equals("on")) 318 { 319 //myISY.turnDeviceOn(deviceAddress); 320 instance.myISY.turnDeviceOn(deviceAddress.replace("."," ")); 321 } 322 else 323 { 324 //myISY.turnDeviceOff(deviceAddress); 325 instance.myISY.turnDeviceOff(deviceAddress.replace("."," ")); 326 } 327 UDUtil.sleep(1000); 328 String deviceStatus = instance.getStatus(instance.getNode(deviceAddress)); 329 if (deviceStatus!=null) System.out.println(device + " is now "+(deviceStatus.equals("0")?"Off":"On") ); 330 } 331 332 /* *********************************** */ 333 else if(command.equalsIgnoreCase("status")) 334 { 335 String deviceAddress = instance.getNodeAddress(device); 336 System.out.println(" Device : "+device+" "+deviceAddress); 337 //UDUtil.sleep(500); 338 String deviceStatus = instance.getStatus(instance.getNode(deviceAddress)); 339 if (deviceStatus!=null) System.out.println(" STATUS: " + device + " is now "+(deviceStatus.equals("0")?"Off":"On") ); 340 //UDUtil.sleep(500); 341 UDNode udn = instance.getNode(deviceAddress); 342 343 344 deviceStatus = instance.getiMeterPower(udn); 345 if (deviceStatus!=null && !deviceStatus.equals("") ) System.out.println(" iMeter Power: " + device + " is now "+deviceStatus+" Watts" ); 346 //UDUtil.sleep(500); 347 deviceStatus = instance.getiMeterEnergy(udn); 348 if (deviceStatus!=null && !deviceStatus.equals("") ) System.out.println(" iMeter Energy: " + device + " is now "+deviceStatus+" Whr" ); 349 } 350 351 } 352 } 353 catch (Exception e) 354 { 355 e.printStackTrace(); 356 } 357 finally 358 { 359 instance.isyCleanup(); 360 int timeOut = 0; 361 System.out.print("Waiting To Shutdown CLI..."); 362 UDUtil.sleep(250); 363 timeOut+=250; 364 while (instance.stillRunning() && timeOut < 3000) 365 { 366 System.out.print("."); 367 UDUtil.sleep(250); 368 timeOut+=250; 369 } 370 System.out.println("!"); 371 } 372 } 373 } 374 375 376 public StringBuilder dumpVariablesInfo() { return dumpVariablesInfo(this.myISY);} 377 378 379 public static StringBuilder dumpVariablesInfo(ISYInsteonClient isyIClient) 380 { 381 StringBuilder retVal = new StringBuilder("\n"); 382 383 if (isyIClient!=null) 384 { 385 UDProxyDevice isyDevice = isyIClient.getDevice(); 386 ProductInfo prod = isyDevice.getProductInfo(); 387 388 if (prod!=null && prod.isVariablesEnabled()) 389 { 390 String vars = isyDevice.getVariables(1); //VarType... 1=Integer Variable 2=State Variable 391 retVal.append(" Variables Information\n"); 392 retVal.append(" ~~~~~~~~~~~~~~~~~~~~~~\n\n"); 393 if (vars!=null) retVal.append(" Integers\n"+vars+"\n"); 394 vars = isyDevice.getVariables(2); //VarType... 1=Integer Variable 2=State Variable 395 if (vars!=null) retVal.append(" StateVars\n"+vars+"\n"); 396 } 397 } 398 return retVal; 399 } 400 401 402 public StringBuilder dumpElkInfo() { return dumpElkInfo(this.myISY);} 403 404 public static StringBuilder dumpElkInfo(ISYInsteonClient isyIClient) 405 { 406 StringBuilder retVal = new StringBuilder("\n"); 407 408 if (isyIClient!=null) 409 { 410 UDProxyDevice isyDevice = isyIClient.getDevice(); 411 ProductInfo prod = isyDevice.getProductInfo(); 412 413 if (prod!=null && prod.isElkEnabled()) 414 { 415 retVal.append(" ELK Module Information\n"); 416 retVal.append(" ~~~~~~~~~~~~~~~~~~~~~~\n\n"); 417 String elkRest = "/rest/elk"; 418 String elkCmd = "/system/get/status"; 419 420 retVal.append(" ELK Rest Command: "+elkRest+elkCmd+"\n"); 421 retVal.append(" ELK Rest Response: \n"); 422 UDRestResponse res = isyDevice.submitRESTRequest(elkRest+elkCmd); 423 //UDRestResponse has 3 public methods 424 // String getBody() 425 // int getStatus() - returns an HTTP status code 426 // boolean isSucceeded() 427 if (res!=null && res.getBody()!=null && res.isSucceeded()) 428 { 429 retVal.append(res.getBody().replace("><",">\n<")); 430 } 431 else if (res!=null) retVal.append("ELK Rest ERROR Response: http status="+res.getStatus() + " success:"+res.isSucceeded()); 432 433 elkCmd = "/get/status"; 434 retVal.append("\n\n ELK Rest Command: "+elkRest+elkCmd+"\n"); 435 retVal.append(" ELK Rest Response: \n"); 436 res = isyDevice.submitRESTRequest(elkRest+elkCmd); 437 if (res!=null && res.getBody()!=null && res.isSucceeded()) 438 { 439 try 440 { 441 XMLElement xmlelement = new XMLElement(); 442 xmlelement.parseString(res.getBody()); 443 boolean bool = true; 444 Enumeration enumeration = xmlelement.getChildren().elements(); 445 while (enumeration.hasMoreElements()) 446 { 447 XMLElement xmlElement = (XMLElement) enumeration.nextElement(); 448 if (xmlElement.getTagName().equals("ae")) 449 { 450 retVal.append(xmlElement.toString()); 451 } 452 else if (xmlElement.getTagName().equals("ze")) 453 retVal.append(xmlElement.toString()); 454 else if (xmlElement.getTagName().equals("ke")) 455 retVal.append(xmlElement.toString()); 456 else if (xmlElement.getTagName().equals("oe")) 457 retVal.append(xmlElement.toString()); 458 else if (xmlElement.getTagName().equals("se")) 459 retVal.append(xmlElement.toString()); 460 } 461 } 462 catch (Exception exception) 463 { 464 /* empty */ 465 } 466 //retVal.append(Util.tokenReplace(res.getBody(),"><",">\n<")); 467 } 468 else if (res!=null) retVal.append("ELK Rest ERROR Response: http status="+res.getStatus() + " success:"+res.isSucceeded()); 469 470 } 471 else 472 { 473 retVal.append(" ELK Module NOT INSTALLED"); 474 } 475 } 476 477 return retVal; 478 } 479 480 481 public StringBuilder dumpIsyProductInfo() { return dumpIsyProductInfo(this.myISY);} 482 483 484 public static StringBuilder dumpIsyProductInfo(ISYInsteonClient isyIClient) 485 { 486 StringBuilder retVal = new StringBuilder("\n=================\nISY Product Info\n=================\n"); 487 488 if (isyIClient!=null) 489 { 490 com.universaldevices.upnp.UDProxyDevice isyDevice = isyIClient.getDevice(); 491 ProductInfo prod = isyDevice.getProductInfo(); 492 493 if (prod!=null) 494 { 495 retVal.append(" - "); 496 retVal.append(isyDevice.uuid); 497 retVal.append(SYSTEM_LINE_SEPERATOR); 498 retVal.append(" - Description: "); 499 retVal.append(prod.getDesc()); 500 retVal.append((prod.isIrEnabled()?" with IR enabled":" without IR enabled")); 501 502 retVal.append(SYSTEM_LINE_SEPERATOR); 503 retVal.append(" - ProductId: "); 504 retVal.append(isyDevice.getProductId()); 505 retVal.append(SYSTEM_LINE_SEPERATOR); 506 507 retVal.append(" - Make / model "); 508 retVal.append(isyDevice.getMake()); 509 retVal.append(" / " ); 510 retVal.append(isyDevice.getModel()); 511 retVal.append(SYSTEM_LINE_SEPERATOR); 512 513 retVal.append(" - Platform: "); 514 retVal.append(isyDevice.getPlatform()); 515 retVal.append(SYSTEM_LINE_SEPERATOR); 516 517 retVal.append(" - Application & Version: "); 518 retVal.append(isyDevice.getApplication()); 519 retVal.append(" - " ); 520 retVal.append(isyDevice.getAppVersion()); 521 retVal.append(" build: " ); 522 retVal.append(isyDevice.getBuildTimestamp() ); 523 retVal.append(SYSTEM_LINE_SEPERATOR); 524 525 retVal.append(" - SSL Certificate URL: "); 526 retVal.append(prod.getSSLCertificateURL()); 527 retVal.append(SYSTEM_LINE_SEPERATOR); 528 529 retVal.append(SYSTEM_LINE_SEPERATOR); 530 531 retVal.append(" Network Configuration"); 532 retVal.append(SYSTEM_LINE_SEPERATOR); 533 retVal.append(" ~~~~~~~~~~~~~~~~"); 534 retVal.append(SYSTEM_LINE_SEPERATOR); 535 retVal.append(" - IP: " ); 536 retVal.append(isyDevice.getNetworkConfig().ip); 537 retVal.append(SYSTEM_LINE_SEPERATOR); 538 retVal.append(" - " ); 539 retVal.append(isyDevice.getNetworkConfig().toString().replace("<br>","\n - ")); 540 retVal.append("Gateway: " ); 541 retVal.append(isyDevice.getNetworkConfig().gateway); 542 retVal.append(SYSTEM_LINE_SEPERATOR); 543 retVal.append(" - DNS: " ); 544 retVal.append(isyDevice.getNetworkConfig().dns); 545 retVal.append(SYSTEM_LINE_SEPERATOR); 546 retVal.append(SYSTEM_LINE_SEPERATOR); 547 548 retVal.append(" File System Status"); 549 retVal.append(SYSTEM_LINE_SEPERATOR); 550 retVal.append(" ~~~~~~~~~~~~~~~~"); 551 retVal.append(SYSTEM_LINE_SEPERATOR); 552 553 com.universaldevices.device.model.FileSystemStat fss = isyDevice.getFileSystemStatus(); 554 retVal.append(" - Active: "); 555 retVal.append((fss.isActive()?"YES":"NO")); 556 retVal.append(SYSTEM_LINE_SEPERATOR); 557 558 retVal.append(" - Total: "); 559 retVal.append(fss.getTotal()); 560 retVal.append(SYSTEM_LINE_SEPERATOR); 561 562 retVal.append(" - Free: "); 563 retVal.append(fss.getFree()); 564 retVal.append(SYSTEM_LINE_SEPERATOR); 565 566 retVal.append(" - Reserved: "); 567 retVal.append(fss.getReserved()); 568 retVal.append(SYSTEM_LINE_SEPERATOR); 569 570 retVal.append(" - Bad: "); 571 retVal.append(fss.getBad()); 572 retVal.append(SYSTEM_LINE_SEPERATOR); 573 574 retVal.append(SYSTEM_LINE_SEPERATOR); 575 576 retVal.append(" Enabled Features"); 577 retVal.append(SYSTEM_LINE_SEPERATOR); 578 retVal.append(" ~~~~~~~~~~~~~~~~"); 579 retVal.append(SYSTEM_LINE_SEPERATOR); 580 581 retVal.append(" - D2d: "); 582 retVal.append((prod.isD2dEnabled()?"YES":"NO")); 583 retVal.append(SYSTEM_LINE_SEPERATOR); 584 585 retVal.append(" - Zigbee SEP Device: "); 586 retVal.append((prod.isZigbeeSEPDeviceEnabled()?"YES":"NO")); 587 retVal.append(SYSTEM_LINE_SEPERATOR); 588 589 retVal.append(" - BroadBand SEP Device: "); 590 retVal.append((prod.isBroadBandSEPDeviceEnabled()?"YES":"NO")); 591 retVal.append(SYSTEM_LINE_SEPERATOR); 592 593 retVal.append(" - Any SEP Device: "); 594 retVal.append((prod.isAnySEPDeviceEnabled()?"YES":"NO")); 595 retVal.append(SYSTEM_LINE_SEPERATOR); 596 597 retVal.append(" - Open DR: "); 598 retVal.append((prod.isOpenDREnabled()?"YES":"NO")); 599 retVal.append(SYSTEM_LINE_SEPERATOR); 600 601 retVal.append(" - URL Access: "); 602 retVal.append((prod.isURLAccessEnabled()?"YES":"NO")); 603 retVal.append(SYSTEM_LINE_SEPERATOR); 604 605 retVal.append(" - Variables Enabled: "); 606 retVal.append((prod.isVariablesEnabled()?"YES":"NO")); 607 retVal.append(SYSTEM_LINE_SEPERATOR); 608 609 retVal.append(" - ElectricMeter Enabled: "); 610 retVal.append((prod.isElectricityMeterEnabled() ?"YES":"NO")); 611 retVal.append(SYSTEM_LINE_SEPERATOR); 612 retVal.append(SYSTEM_LINE_SEPERATOR); 613 614 retVal.append(" Modules"); 615 retVal.append(SYSTEM_LINE_SEPERATOR); 616 retVal.append(" ~~~~~~~"); 617 retVal.append(SYSTEM_LINE_SEPERATOR); 618 619 retVal.append(" - Web: "); 620 retVal.append((prod.isWebModulesEnabled()?"YES":"NO")); 621 retVal.append(SYSTEM_LINE_SEPERATOR); 622 623 retVal.append(" - Weather: "); 624 retVal.append((prod.isWeatherEnabled()?"YES":"NO")); 625 retVal.append(SYSTEM_LINE_SEPERATOR); 626 627 retVal.append(" - A10: "); 628 retVal.append((prod.isInsteonA10Enabled()?"YES":"NO")); 629 retVal.append(SYSTEM_LINE_SEPERATOR); 630 631 retVal.append(" - Energy Monitoring: "); 632 retVal.append((prod.isEnergyMonitoringEnabled()?"YES":"NO")); 633 retVal.append(SYSTEM_LINE_SEPERATOR); 634 635 retVal.append(" - ELK Security: "); 636 retVal.append((prod.isElkEnabled()?"YES":"NO")); 637 retVal.append(SYSTEM_LINE_SEPERATOR); 638 639 retVal.append(" - Energy Monitoring: "); 640 retVal.append((prod.isEnergyMonitoringEnabled()?"YES":"NO")); 641 retVal.append(SYSTEM_LINE_SEPERATOR); 642 643 retVal.append(" - Energy Monitoring: "); 644 retVal.append((prod.isEnergyMonitoringEnabled()?"YES":"NO")); 645 retVal.append(SYSTEM_LINE_SEPERATOR); 646 } 647 } 648 else 649 { 650 retVal.append(SYSTEM_LINE_SEPERATOR); 651 retVal.append("ERROR: No IsyInsteonClient"); 652 retVal.append(SYSTEM_LINE_SEPERATOR); 653 } 654 655 return retVal; 656 } 657 658 659 /** 660 * Returns all <code>UDNode</code>s that are associated in the client. 661 * @return the Enumeration UDNode if found, null otherwise 662 */ 663 protected Enumeration <UDNode> getNodes()// throws com.universaldevices.client.NoDeviceException 664 { 665 Enumeration <UDNode> isyNodes = null; 666 try 667 { 668 isyNodes = myISY.getNodes().elements(); // UDClient.getNodes 669 } 670 catch (Exception ex) // probably com.universaldevices.client.NoDeviceException 671 { 672 // send empty 673 } 674 return isyNodes; 675 676 //return myISY.getNodes().elements(); 677 } 678 679 680 /** 681 * Returns all NON-ControlLinc or Non-SwitchLinc <code>UDNode</code>s that are associated in the client. 682 * @return the Enumeration UDNode if found, null otherwise 683 */ 684 protected Enumeration <UDNode> getMyNodes()// throws com.universaldevices.client.NoDeviceException 685 { 686 Enumeration <UDNode> isyNodes = null; 687 Vector <UDNode> myNodes =new Vector<UDNode>(); 688 689 try 690 { 691 isyNodes = myISY.getNodes().elements(); 692 UDNode node = null; 693 694 while ( isyNodes.hasMoreElements()) 695 { 696 node = (UDNode) isyNodes.nextElement(); 697 // System.out.println(" Check To Add "+node.address + ":" + node.name+" type="+node.typeReadable+" -->"+ !node.typeReadable.startsWith("00.")); 698 if (!node.typeReadable.startsWith("00.00") && /* ContolLinc */ 699 !node.typeReadable.startsWith("00.05") && /* RemoteLinc */ 700 !node.typeReadable.startsWith("01.09") /* SwitchLinc */ ) 701 myNodes.add(node); 702 } 703 } 704 catch (Exception ex) // probably com.universaldevices.client.NoDeviceException 705 { 706 // send empty 707 } 708 return myNodes.elements(); 709 } 710 711 712 /** 713 * Counts all the NON-ContolLinc Nodes that the ISY is aware of. 714 * @return the number of NON-ContolLinc nodes that the ISY is aware of. 715 **/ 716 private int countNodes() 717 { 718 int retVal = 0; 719 try 720 { 721 Enumeration <UDNode> e = getNodes(); 722 UDNode node = null; 723 while ( e.hasMoreElements()) 724 { 725 node = e.nextElement(); 726 retVal++; 727 } 728 } 729 catch (Exception ex) 730 { 731 ex.printStackTrace(); 732 } 733 return retVal; 734 } 735 736 737 /** 738 * Counts all the NON-ContolLinc Nodes that the ISY is aware of. 739 * @return the number of NON-ContolLinc nodes that the ISY is aware of. 740 **/ 741 private int countMyNodes() 742 { 743 int retVal = 0; 744 try 745 { 746 Enumeration <UDNode> e = getMyNodes(); 747 UDNode node = null; 748 while ( e.hasMoreElements()) 749 { 750 node = e.nextElement(); 751 retVal++; 752 } 753 } 754 catch (Exception ex) 755 { 756 ex.printStackTrace(); 757 } 758 return retVal; 759 } 760 761 762 /** 763 * Puts all the Node Address at this ISY into the insteonAddresses_ array so they can get assigned to buttons. 764 **/ 765 private void loadNodeAddresses() 766 { 767 try 768 { 769 int numNodes = countMyNodes(); 770 insteonAddresses_ = new String[numNodes]; 771 System.out.println("Loading "+numNodes+" Controllable Devices"); 772 int count = 0; 773 Enumeration <UDNode> e = getMyNodes(); 774 while (e.hasMoreElements()) 775 { 776 UDNode node = e.nextElement(); 777 insteonAddresses_[count++] = node.address.replace(" ","."); 778 //System.out.println(" "+node.address + ":" + node.name+" type="+node.typeReadable); 779 } 780 numNodes_ = numNodes; 781 } 782 catch (Exception ex) 783 { 784 ex.printStackTrace(); 785 } 786 787 } 788 789 790 /** 791 * Returns the current value of Insteon Devicse (its state) 792 * @param tk - the StringTokenzier 793 */ 794 protected void processStatus(StringTokenizer tk) 795 { 796 String tmp = tk.nextToken(); //device address 797 UDNode node = getNode(tmp); 798 if (node == null) { 799 return; 800 } 801 802 tmp = (String) myISY.getCurrValue(node, InsteonConstants.DEVICE_STATUS); 803 System.out.println("The current status for " + node.address + "/" + node.name + " is " + tmp); 804 } 805 806 807 /** 808 * Returns the current value of an iMeters Energy Level (wattMins) 809 * @param node - the UDNode to query 810 * @return the energy level in WattHrs 811 **/ 812 protected String getiMeterEnergy(UDNode node ) 813 { 814 String retVal = ""; 815 if (!(node==null || !node.typeReadable.equals("09.07"))) // iMeter Device Type 816 { 817 //System.out.println("iMeter type="+ node.typeReadable); 818 // myISY.queryNode( node.address); // do an update 819 retVal = (String) myISY.getCurrValue(node, InsteonConstants.TOTAL_POWER); // This returns Watt Seconds 820 retVal = ""+(Integer.parseInt(retVal)*10/36); 821 //system.out.println("The current status for " + node.address + "/" + node.name + " is " + retVal); 822 } 823 return retVal; 824 } 825 826 827 /** 828 * Returns the current value of an iMeters Power Level (Watts 829 * @param node - the UDNode to query 830 * @return the power level in Watts 831 **/ 832 protected String getiMeterPower(UDNode node ) 833 { 834 StringBuilder retVal = new StringBuilder(""); 835 if (!(node==null || !node.typeReadable.equals("09.07"))) // iMeter Device Type 836 { 837 System.out.println(" iMeter type: "+ node.typeReadable); // + " [" +node.type + "] (UDI DeviceType for a iMeter="+com.udi.insteon.client.DeviceTypes.DEV_SCAT_IMETER_SOLO +") "); 838 myISY.queryNode( node.address); // do an update 839 String ret = (String) myISY.getCurrValue(node, InsteonConstants.CURRENT_POWER); 840 841 if (ret != null && !ret.equals("")&& !ret.equals("null")) 842 { 843 retVal.append(ret); 844 System.out.println(" POWER reading="+ ret); 845 } 846 else 847 { 848 retVal = new StringBuilder(""); 849 //system.out.println("The current status for " + node.address + "/" + node.name + " is " + retVal); 850 851 // Now try the rest response 852 UDProxyDevice isyDevice = myISY.getDevice(); 853 String prop = "ST"; 854 855 //retVal.append("\n ISY Rest Command: "+restNodePropertyCommandString(prop, node) +"\n"); 856 //retVal.append("\n ISY Rest Response: "); 857 UDRestResponse res = isyDevice.submitRESTRequest(restNodePropertyCommandString(prop, node)); 858 if (res!=null && res.getBody()!=null && res.isSucceeded()) 859 { 860 try 861 { 862 XMLElement xmlelement = new XMLElement(); 863 xmlelement.parseString(res.getBody()); 864 //boolean bool = true; 865 Enumeration enumeration = xmlelement.getChildren().elements(); 866 while (enumeration.hasMoreElements()) 867 { 868 XMLElement xmlElement = (XMLElement) enumeration.nextElement(); 869 double defaultDbl = 0.0; 870 retVal.append(""+xmlElement.getProperty("VALUE",defaultDbl)); 871 if (enumeration.hasMoreElements()) retVal.append("\n"); 872 } 873 } 874 catch (Exception exception) 875 { 876 /* empty */ 877 } 878 //retVal.append(Util.tokenReplace(res.getBody(),"><",">\n<")); 879 } 880 else if (res!=null) retVal.append("ISY Rest ERROR Response: http status="+res.getStatus() + " success:"+res.isSucceeded()); 881 } 882 } 883 return retVal.toString(); 884 } 885 886 /** Strings together a rest 'noded' service string (with the spaces encoded) for the given node. 887 * 888 * @param node the node to query for (null to query all) 889 * @return the rest service string with the spaces encoded (/rest/node/12%2089%2044%201) 890 **/ 891 public String restNodePropertyCommandString(String propName, UDNode node) 892 { 893 return restNodesCommandString(node)+"/"+ propName; 894 } 895 896 /** Strings together a rest 'noded' service string (with the spaces encoded) for the given node. 897 * 898 * @param node the node to query for (null to query all) 899 * @return the rest service string with the spaces encoded (/rest/node/12%2089%2044%201) 900 **/ 901 public String restNodesCommandString(UDNode node) 902 { 903 return restCommandString("nodes", node); 904 } 905 906 907 /** Strings together a rest 'status' service string (with the spaces encoded) for the given node. 908 * 909 * @param node the node to query for (null to query all) 910 * @return the rest service string with the spaces encoded (/rest/node/12%2089%2044%201) 911 **/ 912 public String restStatusCommandString(UDNode node) 913 { 914 return restCommandString("status", node); 915 } 916 917 918 /** Strings together a rest 'query' service string (with the spaces encoded) for the given node. 919 * 920 * @param node the node to query for (null to query all) 921 * @return the rest service string with the spaces encoded (/rest/node/12%2089%2044%201) 922 **/ 923 public String restQueryCommandString(UDNode node) 924 { 925 return restCommandString("query", node); 926 } 927 928 929 /** Strings together a rest service string (with the spaces encoded) for the givven node. 930 * 931 * @param node the node to query for (null to query all) 932 * @return the rest service string with the spaces encoded (/rest/node/12%2089%2044%201) 933 **/ 934 public String restCommandString(String command, UDNode node) 935 { 936 String retVal = "/rest/"; 937 retVal+= command; 938 if (node!=null) 939 { 940 String nodeAddr = getNodeAddress(node.name); 941 retVal += "/"+ node.address.replace(" ","%20"); 942 } 943 return retVal; 944 } 945 946 947 /** 948 * Returns the current value of an Insteon Device (its state) 949 * @param node - the UDNode to query 950 * @return the status 951 **/ 952 protected String getStatus(UDNode node ) { 953 if (node == null) { 954 return ""; 955 } 956 957 String tmp = (String) myISY.getCurrValue(node, InsteonConstants.DEVICE_STATUS); 958 //stem.out.println("The current status for " + node.address + "/" + node.name + " is " + tmp); 959 960 return tmp; 961 } 962 963 964 /** Duh! 965 * @param the node's address to query. 966 * @return the name assigned to the node at the address requested. 967 **/ 968 protected String getNodeName(String address) 969 { 970 if (address == null) 971 { 972 System.err.println("Missing Device/Scene address"); 973 return ""; 974 } 975 UDNode node = getNode(address); 976 return node.name; 977 } 978 979 980 /** Duh! 981 * @param the node's address to query. 982 * @return the name assigned to the node at the address requested. 983 **/ 984 protected String getNodeAddress(String nodeName) 985 { 986 String retVal =""; 987 UDNode node = null; 988 if (nodeName == null) 989 { 990 System.err.println("Missing Device/Scene address"); 991 return ""; 992 } 993 for (int i=0; i< insteonAddresses_.length; i++) 994 { 995 node = getNode(insteonAddresses_[i]); 996 if(node.name.equals(nodeName)) 997 { 998 retVal = node.address; 999 retVal = retVal.replace(" ","."); 1000 } 1001 } 1002 //retVal.replace(" ","."); 1003 return retVal; 1004 } 1005 1006 1007 /** 1008 * Returns a <code>UDGroup</code> or a <code>UDNode</code> based on the 1009 * given address 1010 * @param address - the address of the node/scene to be retrieved 1011 * @return the UDNode if found, null otherwise 1012 */ 1013 protected UDNode getNode(String address) 1014 { 1015 if (address == null) 1016 { 1017 System.err.println("Missing Device/Scene address"); 1018 return null; 1019 } 1020 if (address.indexOf(".") > 0) 1021 { 1022 //this is an insteon device 1023 address = address.replace(".", " "); //normalize it to our format 1024 1025 try 1026 { 1027 UDNode node = myISY.getNodes().get(address); 1028 if (node == null) 1029 { 1030 System.err.println("Address points to a non existing Insteon Device"); 1031 return null; 1032 } 1033 return node; 1034 } 1035 catch (NoDeviceException e) 1036 { 1037 System.out.println(e); 1038 return null; 1039 } 1040 } 1041 1042 //this is an insteon scene 1043 try 1044 { 1045 UDGroup group = myISY.getGroups().get(address); 1046 if (group == null) 1047 { 1048 System.err.println("Address points to a non-existing scene"); 1049 return null; 1050 } 1051 return group; 1052 } 1053 catch (Exception e) 1054 { 1055 System.err.println(e); 1056 return null; 1057 } 1058 } 1059 1060 protected char INSTEON_MASTER_MODE = 0xF0; 1061 protected char INSTEON_SLAVE_MODE = 0x0F; 1062 1063 /** 1064 * Returns the mode based on the input 1065 * @param mode 1066 * @return - the mode (INSTEON_MASTER_MODE, INSTEON_SLAVE_MODE) 1067 */ 1068 protected char getMode(String mode) 1069 { 1070 if (mode.equals("M")) 1071 { 1072 return INSTEON_MASTER_MODE; 1073 } 1074 1075 if (mode.equals("S")) 1076 { 1077 return INSTEON_SLAVE_MODE; 1078 } 1079 1080 System.err.println("Please specify M (for Master mode) or S (for Slave mode)"); 1081 return 0; 1082 } 1083 1084 /** 1085 * Processes an Insteon command 1086 * @param cmd - the command to be processed 1087 * @param tk - the StringTokenizer 1088 */ 1089 protected void processInsteonCommand(String cmd, StringTokenizer tk) 1090 { 1091 String address = tk.nextToken(); 1092 System.out.println("tk addr:"+address); 1093 UDNode node = getNode(address); 1094 if (node == null) 1095 { 1096 return; 1097 } 1098 1099 //it's a group 1100 if (node instanceof UDGroup) 1101 { 1102 myISY.changeGroupState(cmd, null, node.address); 1103 } 1104 else 1105 { 1106 myISY.changeNodeState(cmd, null, node.address); 1107 } 1108 } 1109 1110 /** 1111 * Abstracts the actual sending of the ISY Command. 1112 * 1113 * @param command This apps Command (not necessarily an Insteon Command (but could Be) 1114 */ 1115 public void processCommand( String command) 1116 { 1117 if (command == null || command.length() < 1) 1118 { 1119 return; 1120 } 1121 1122 System.out.println("Button Command:"+command); 1123 StringTokenizer tk = new StringTokenizer(command, " "); 1124 try 1125 { 1126 String cmd = tk.nextToken(); 1127 if ( cmd.startsWith(InsteonConstants.DEVICE_ON) || 1128 cmd.startsWith(InsteonConstants.DEVICE_OFF) || 1129 cmd.startsWith(InsteonConstants.DEVICE_FAST_ON) || 1130 cmd.startsWith(InsteonConstants.DEVICE_FAST_OFF) || 1131 cmd.startsWith(InsteonConstants.LIGHT_DIM) || 1132 cmd.startsWith(InsteonConstants.LIGHT_BRIGHT)) 1133 { 1134 System.out.println("Processing Cmd:"+cmd+" tk:"+tk.toString()); 1135 processInsteonCommand(cmd, tk); 1136 } 1137 else if (cmd.equalsIgnoreCase("StartLinking")) 1138 { 1139 myISY.startLinking(); 1140 } 1141 else if (cmd.equalsIgnoreCase("StopLinking")) 1142 { 1143 myISY.stopLinking(); 1144 } 1145 else if (cmd.startsWith("SetLinkingMode")) 1146 { 1147 //setLinkingMode(tk); 1148 } 1149 else if (cmd.startsWith("Rename")) 1150 { 1151 //processRename(tk); 1152 } 1153 else if (cmd.startsWith("Delete")) 1154 { 1155 // processDelete(tk); 1156 } 1157 else if (cmd.startsWith("Remove")) 1158 { 1159 //processRemoveFromScene(tk); 1160 } 1161 else if (cmd.startsWith("Move")) 1162 { 1163 // processMove(tk); 1164 } 1165 else if (cmd.startsWith("NewScene")) 1166 { 1167 // processNewScene(tk); 1168 } 1169 else if (cmd.startsWith("SetSceneOnLevel")) 1170 { 1171 //processSceneOnLevel(tk); 1172 } 1173 else if (cmd.startsWith("SetSceneRampRate")) 1174 { 1175 // processSceneRampRate(tk); 1176 } 1177 else if (cmd.startsWith("SetSceneControllerOnLevel")) 1178 { 1179 // processSceneControllerOnLevel(tk); 1180 } 1181 else if (cmd.startsWith("SetSceneControllerRampRate")) 1182 { 1183 //processSceneControllerRampRate(tk); 1184 } 1185 else if (cmd.equalsIgnoreCase("ListNodes")) 1186 { 1187 // processListNodes(); 1188 } 1189 else if (cmd.equalsIgnoreCase("ListScenes")) 1190 { 1191 // processListScenes(); 1192 } 1193 else if (cmd.startsWith("GetStatus")) 1194 { 1195 //processStatus(tk); 1196 } 1197 else if (cmd.equalsIgnoreCase("Exit")) 1198 { 1199 myISY.stop(); 1200 System.exit(0); 1201 } 1202 else 1203 { 1204 syntaxError(); 1205 } 1206 } // try 1207 catch (Exception e) 1208 { 1209 e.printStackTrace(); 1210 syntaxError(); 1211 } 1212 } 1213 1214} 1215