Guest User

Untitled

a guest
Nov 21st, 2017
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.87 KB | None | 0 0
  1. package global;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import java.util.Map;
  6. import java.util.Scanner;
  7. import java.awt.AWTException;
  8. import java.awt.GraphicsEnvironment;
  9. import java.awt.HeadlessException;
  10. import java.awt.Rectangle;
  11. import java.awt.Robot;
  12. import java.awt.Toolkit;
  13. import java.awt.image.BufferedImage;
  14. import java.awt.peer.RobotPeer;
  15. import java.io.*;
  16.  
  17. import javax.imageio.ImageIO;
  18.  
  19. import com.philips.lighting.hue.listener.PHLightListener;
  20. import com.philips.lighting.hue.sdk.*;
  21. import com.philips.lighting.hue.sdk.utilities.PHUtilities;
  22. import com.philips.lighting.model.PHBridge;
  23. import com.philips.lighting.model.PHBridgeResource;
  24. import com.philips.lighting.model.PHHueError;
  25. import com.philips.lighting.model.PHHueParsingError;
  26. import com.philips.lighting.model.PHLight;
  27. import com.philips.lighting.model.PHLight.PHLightAlertMode;
  28. import com.philips.lighting.model.PHLight.PHLightColorMode;
  29. import com.philips.lighting.model.PHLight.PHLightEffectMode;
  30. import com.philips.lighting.model.PHLightState;
  31.  
  32. public class HueThread extends Thread implements PHSDKListener
  33. {
  34. public boolean exit;
  35. public PHHueSDK ph;
  36.  
  37. public void run()
  38. {
  39. ph = PHHueSDK.getInstance();
  40. ph.setAppName("Command Line Hue Controller");
  41. ph.setDeviceName("Command Line");
  42. ph.getNotificationManager().registerSDKListener(this);
  43. Scanner s = new Scanner(System.in);
  44. while(!exit)
  45. {
  46. System.out.print("hue command: ");
  47. String[] splitArguements = s.nextLine().split(" ");
  48. takeCommand(splitArguements);
  49. }
  50. s.close();
  51. }
  52.  
  53.  
  54. public void takeCommand(String[] arguements)
  55. {
  56. try
  57. {
  58. switch(arguements[0].toLowerCase())
  59. {
  60. case "connect":
  61. connect();
  62. break;
  63. case "reset":
  64. resetConnectionInfo();
  65. break;
  66. case "help":
  67. System.out.println("connect - start a connection");
  68. System.out.println("reset - reset connection info");
  69. System.out.println("quit - exit program");
  70. case "set":
  71. set(arguements);
  72. break;
  73. case "colorloop":
  74. colorloop();
  75. break;
  76. case "capture":
  77. screenCapture(false, arguements[1], arguements[2]);
  78. break;
  79. case "capturedone":
  80. screenCapture(true, arguements[1], arguements[2]);
  81. break;
  82. case "killcapture":
  83. killCapture();
  84. break;
  85. case "off":
  86. allOff();
  87. break;
  88. case "quit":
  89. System.exit(0);
  90. break;
  91. }
  92. }
  93. catch(Exception e)
  94. {
  95. System.out.println("error");
  96. }
  97. }
  98.  
  99. public class PrimitiveConditionVariable
  100. {
  101. public boolean condition;
  102.  
  103. public void waitOnCondition()
  104. {
  105. synchronized(this)
  106. {
  107. condition=false;
  108. while(!condition)
  109. {
  110. try
  111. {
  112. wait(0);
  113. }
  114. catch (InterruptedException e)
  115. {
  116. }
  117. }
  118. }
  119. }
  120.  
  121. public void setAndNotifyAll()
  122. {
  123. synchronized(this)
  124. {
  125. condition=true;
  126. notifyAll();
  127. }
  128. }
  129. }
  130.  
  131. public void resetConnectionInfo()
  132. {
  133. awaitingPushlink.setAndNotifyAll();
  134. connecting.setAndNotifyAll();
  135. ph.destroySDK();
  136. ph = PHHueSDK.getInstance();
  137. ph.setAppName("Command Line Hue Controller");
  138. ph.setDeviceName("Command Line");
  139. ph.getNotificationManager().registerSDKListener(this);
  140. }
  141.  
  142. public PrimitiveConditionVariable connecting=new PrimitiveConditionVariable();
  143. public boolean newConnection = false;
  144. private final String filename = "connectioninfo.txt";
  145.  
  146. public void saveConnection(String ip, String username)
  147. {
  148. File f = new File(filename);
  149. try
  150. {
  151. FileWriter w = new FileWriter(f);
  152. w.write(ip+"\n"+username+"\n");
  153. w.close();
  154. }
  155. catch (IOException e)
  156. {
  157. System.out.println("Could not save connection");
  158. }
  159.  
  160. }
  161.  
  162. public void connect() throws FileNotFoundException, InterruptedException
  163. {
  164. File f = new File(filename);
  165. if(f.isFile())
  166. {
  167. Scanner s = new Scanner(f);
  168.  
  169. PHAccessPoint access = new PHAccessPoint();
  170.  
  171. access.setIpAddress(s.nextLine());
  172. access.setUsername(s.nextLine());
  173.  
  174. System.out.println("Connecting..");
  175. ph.connect(access);
  176.  
  177. s.close();
  178. }
  179. else
  180. {
  181. newConnection=true;
  182. System.out.println("Searching for bridge...");
  183. ((PHBridgeSearchManager) ph.getSDKService(PHHueSDK.SEARCH_BRIDGE)).search(true, true);
  184. }
  185. connecting.waitOnCondition();
  186. }
  187.  
  188. public void allOff()
  189. {
  190. PHLightState state = new PHLightState();
  191. state.setOn(false);
  192. ph.getSelectedBridge().setLightStateForDefaultGroup(state);
  193. System.out.println("Off.");
  194. }
  195.  
  196. public void colorloop()
  197. {
  198. PHLightState state = new PHLightState();
  199. state.setOn(true);
  200. state.setEffectMode(PHLightEffectMode.EFFECT_COLORLOOP);
  201. ph.getSelectedBridge().setLightStateForDefaultGroup(state);
  202. System.out.println("Colorloop.");
  203. }
  204.  
  205. public void set(String[] arguements)
  206. {
  207. if(arguements.length<3)
  208. {
  209. System.out.println("Need to provide identifier and hue");
  210. return;
  211. }
  212. if(arguements.length==3)
  213. {
  214. set(arguements[1], Integer.parseInt(arguements[2]));
  215. }
  216. if(arguements.length==4)
  217. {
  218. set(arguements[1], Float.parseFloat(arguements[2]), Float.parseFloat(arguements[3]));
  219. }
  220.  
  221. }
  222.  
  223. public void set(String identifier, int hue)
  224. {
  225. PHLightState state = new PHLightState();
  226. state.setColorMode(PHLightColorMode.COLORMODE_HUE_SATURATION);
  227. state.setHue(hue);
  228. state.setBrightness(254);
  229. state.setSaturation(254);
  230. state.setOn(true);
  231. state.setEffectMode(PHLightEffectMode.EFFECT_NONE);
  232. state.setAlertMode(PHLightAlertMode.ALERT_NONE);
  233. set(identifier, state);
  234. }
  235.  
  236. public void clear()
  237. {
  238. PHLightState state = new PHLightState();
  239. state.setColorMode(PHLightColorMode.COLORMODE_XY);
  240. state.setOn(true);
  241. state.setEffectMode(PHLightEffectMode.EFFECT_NONE);
  242. state.setAlertMode(PHLightAlertMode.ALERT_NONE);
  243. state.setTransitionTime(0);
  244. set("all", state);
  245. }
  246.  
  247. public void set(String identifier, float x, float y)
  248. {
  249. PHLightState state = new PHLightState();
  250. state.setColorMode(PHLightColorMode.COLORMODE_XY);
  251. state.setX(x);
  252. state.setY(y);
  253. state.setOn(true);
  254. //state.setEffectMode(PHLightEffectMode.EFFECT_NONE);
  255. //state.setAlertMode(PHLightAlertMode.ALERT_NONE);
  256. state.setTransitionTime(0);
  257. set(identifier, state);
  258. }
  259.  
  260. public void set(String identifier, PHLightState state)
  261. {
  262. if(identifier.equals("all"))
  263. {
  264. ph.getSelectedBridge().setLightStateForDefaultGroup(state);
  265. }
  266. else
  267. {
  268. final PrimitiveConditionVariable awaitState = new PrimitiveConditionVariable();
  269. PHLightListener listener = new PHLightListener()
  270. {
  271.  
  272. @Override
  273. public void onError(int code, String message)
  274. {
  275. //System.out.println("Error: Code: " + code + "Message: " + message);
  276. awaitState.setAndNotifyAll();
  277. }
  278.  
  279. @Override
  280. public void onStateUpdate(Map<String, String> successAttribute, List<PHHueError> errorAttribute)
  281. {
  282. }
  283.  
  284. @Override
  285. public void onSuccess()
  286. {
  287. awaitState.setAndNotifyAll();
  288. }
  289.  
  290. @Override
  291. public void onReceivingLightDetails(PHLight light)
  292. {
  293.  
  294. }
  295.  
  296. @Override
  297. public void onReceivingLights(List<PHBridgeResource> lights)
  298. {
  299.  
  300. }
  301.  
  302. @Override
  303. public void onSearchComplete()
  304. {
  305.  
  306. }
  307.  
  308. };
  309. ph.getSelectedBridge().updateLightState(identifier, state, listener);
  310. if(!awaitState.condition)
  311. {
  312. //awaitState.waitOnCondition();
  313. }
  314. }
  315. }
  316.  
  317. public void captureSet(String identifier, float x, float y)
  318. {
  319. PHLightState state = new PHLightState();
  320. state.setColorMode(PHLightColorMode.COLORMODE_XY);
  321. state.setX(x);
  322. state.setY(y);
  323. int transitionTime = 1000/targetFPS/20;
  324. //transitionTime=0;
  325. state.setTransitionTime(transitionTime);
  326. set(identifier, state);
  327. }
  328.  
  329. ScreenCaptureThread captureThread;
  330.  
  331. public void screenCapture(boolean wait, String left, String right)
  332. {
  333. captureThread = new ScreenCaptureThread(new ToolkitScreenAccessor(), left, right);
  334. System.out.println("Started screen capture routine.");
  335. clear();
  336. captureThread.start();
  337. if(wait)
  338. {
  339. try
  340. {
  341. captureThread.join();
  342. }
  343. catch (InterruptedException e)
  344. {
  345. }
  346. }
  347. }
  348.  
  349. public void killCapture()
  350. {
  351. System.out.println("Killing...");
  352. captureThread.interrupt();
  353. try
  354. {
  355. captureThread.join();
  356. }
  357. catch (InterruptedException e)
  358. {
  359. e.printStackTrace();
  360. }
  361. System.out.println("Killed.");
  362. }
  363.  
  364. public interface ScreenAccessor
  365. {
  366. public Rectangle getScreensize();
  367. public int[] getRGBPixels(Rectangle selection);
  368. }
  369.  
  370. public class ToolkitScreenAccessor implements ScreenAccessor
  371. {
  372. Toolkit toolkit;
  373. Rectangle screenRect;
  374. RobotPeer peer;
  375.  
  376. public ToolkitScreenAccessor()
  377. {
  378. toolkit = Toolkit.getDefaultToolkit();
  379. screenRect = new Rectangle(toolkit.getScreenSize());
  380. try
  381. {
  382. peer = ((sun.awt.ComponentFactory) toolkit).createRobot(null, GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice());
  383. }
  384. catch (HeadlessException | AWTException e)
  385. {
  386. // TODO Auto-generated catch block
  387. e.printStackTrace();
  388. }
  389. }
  390.  
  391. @Override
  392. public Rectangle getScreensize()
  393. {
  394. return screenRect;
  395. }
  396.  
  397. @Override
  398. public int[] getRGBPixels(Rectangle selection)
  399. {
  400. return peer.getRGBPixels(selection);
  401. }
  402. }
  403.  
  404. final int samplesPerFrame = 10000;
  405. final int targetFPS = 15;
  406.  
  407. //describe the granularity to distinguish color changes
  408. final double granularity=0.05;
  409. //describe the portion of the color gamut you want
  410. final double relevantWidth = 0.6;
  411. final double relevantHeight = 0.6;
  412.  
  413. //option to offset the calculated color values
  414. final double yoffset = 0;
  415. final double xoffset = .1;
  416.  
  417. //ignore grayscale values where RGB are all this close to the average 0-255
  418. final double grayscaleThreshold = 20;
  419.  
  420. public class ScreenCaptureThread extends Thread
  421. {
  422. String leftLightId;
  423. String rightLightId;
  424. ScreenAccessor screenAccessor;
  425.  
  426. //takes light ids
  427. public ScreenCaptureThread(ScreenAccessor screenAccessor, String left, String right)
  428. {
  429. this.screenAccessor = screenAccessor;
  430. leftLightId = left;
  431. rightLightId = right;
  432. }
  433.  
  434. public void run()
  435. {
  436. int numWidths = (int) (relevantWidth/granularity)+1;
  437. int numHeights = (int) (relevantHeight/granularity)+1;
  438.  
  439. int[][] counts = new int[numWidths][numHeights];
  440. float[][] sumx = new float[numWidths][numHeights];
  441. float[][] sumy = new float[numWidths][numHeights];
  442.  
  443. long targetTime = 1000/targetFPS;
  444.  
  445. String model = ph.getSelectedBridge().getResourceCache().getLights().get(leftLightId).getModelNumber();
  446.  
  447. Rectangle screenRect = screenAccessor.getScreensize();
  448. int pixelJumpPerFrame = (screenRect.width*screenRect.height)/samplesPerFrame;
  449.  
  450. while(!isInterrupted())
  451. {
  452. long startTime = System.currentTimeMillis();
  453. int[] pixels = screenAccessor.getRGBPixels(screenRect);
  454. long captureTime = System.currentTimeMillis()-startTime;
  455.  
  456. //clear the counts
  457. for(int i=0; i<numWidths; i++)
  458. {
  459. for(int j=0; j<numHeights; j++)
  460. {
  461. counts[i][j]=0;
  462. sumx[i][j]=0;
  463. sumy[i][j]=0;
  464. }
  465. }
  466.  
  467. int maxCountX = 0;
  468. int maxCountY = 0;
  469. int maxCount = 0;
  470.  
  471. for(int i=0; i<samplesPerFrame; i++)
  472. {
  473. int rgb = pixels[i*pixelJumpPerFrame];
  474.  
  475. int r = (rgb>>16)&0xff;
  476. int g = (rgb>>8)&0xff;
  477. int b = rgb&0xff;
  478.  
  479. //check it isn't grayscale
  480. int average = (r+g+b)/3;
  481. if(Math.abs(average-r)<grayscaleThreshold && Math.abs(average-g)<grayscaleThreshold && Math.abs(average-b)<grayscaleThreshold)
  482. {
  483. continue;
  484. }
  485.  
  486. float[] xy = PHUtilities.calculateXYFromRGB(r,g,b,model);
  487.  
  488. int graphx = (int)((xy[0]-xoffset)/granularity);
  489. int graphy = (int)((xy[1]-yoffset)/granularity);
  490.  
  491. counts[graphx][graphy]++;
  492. sumx[graphx][graphy]+=xy[0];
  493. sumy[graphx][graphy]+=xy[1];
  494.  
  495. if(counts[graphx][graphy]>maxCount)
  496. {
  497. maxCountX=graphx;
  498. maxCountY=graphy;
  499. maxCount = counts[graphx][graphy];
  500. }
  501.  
  502. }
  503. //take the average of the highest frequency subdivision of the gamut
  504. float x = sumx[maxCountX][maxCountY]/maxCount;
  505. float y = sumy[maxCountX][maxCountY]/maxCount;
  506.  
  507. //System.out.println("(" + x+","+y+")");
  508. captureSet(leftLightId, x, y);
  509. captureSet(rightLightId, x, y);
  510. if(System.currentTimeMillis()-startTime>targetTime)
  511. {
  512. System.out.println("Not reaching fps goal");
  513. System.out.println("Capture Time " + (captureTime));
  514. System.out.println("Run Time " + (System.currentTimeMillis()-startTime));
  515. }
  516. else
  517. {
  518. try
  519. {
  520. sleep(targetTime-(System.currentTimeMillis()-startTime));
  521. }
  522. catch(Exception e)
  523. {
  524.  
  525. }
  526. }
  527. }
  528. }
  529. }
  530.  
  531. /*Main Listener Code*/
  532.  
  533.  
  534. @Override
  535. public void onAccessPointsFound(List<PHAccessPoint> accessPoints)
  536. {
  537. PHAccessPoint selection = accessPoints.get(0);
  538. System.out.println("Connecting...");
  539. ph.connect(selection);
  540. }
  541.  
  542. public PrimitiveConditionVariable awaitingPushlink = new PrimitiveConditionVariable();
  543.  
  544. @Override
  545. public void onAuthenticationRequired(PHAccessPoint accessPoint)
  546. {
  547. AuthenticationThread t = new AuthenticationThread();
  548. ph.startPushlinkAuthentication(accessPoint);
  549. t.start();
  550. }
  551.  
  552. public class AuthenticationThread extends Thread
  553. {
  554. public void run()
  555. {
  556. System.out.println("Pushlink required please push.");
  557. int time = 30;
  558. awaitingPushlink.condition=false;
  559. synchronized(awaitingPushlink)
  560. {
  561. while(!awaitingPushlink.condition && time>0)
  562. {
  563. System.out.println("Awaiting Push "+time+" seconds remaining");
  564. try
  565. {
  566. awaitingPushlink.wait(1000);
  567. }
  568. catch (InterruptedException e)
  569. {
  570. time++;
  571. }
  572. time--;
  573. }
  574. if(time==0)
  575. {
  576. System.out.println("Timed out pushlink, please begin connection again.");
  577. awaitingPushlink.setAndNotifyAll();
  578. connecting.setAndNotifyAll();
  579. }
  580. }
  581. }
  582. }
  583.  
  584.  
  585. @Override
  586. public void onBridgeConnected(PHBridge bridge, String username)
  587. {
  588. System.out.println("Connection successful");
  589. ph.setSelectedBridge(bridge);
  590. //PHHeartbeatManager beat = PHHeartbeatManager.getInstance();
  591. //beat.enableLightsHeartbeat(bridge, PHHueSDK.HB_INTERVAL);
  592. if(newConnection)
  593. {
  594. newConnection=false;
  595. saveConnection(bridge.getResourceCache().getBridgeConfiguration().getIpAddress(), username);
  596. }
  597. awaitingPushlink.setAndNotifyAll();
  598. connecting.setAndNotifyAll();
  599. }
  600.  
  601.  
  602. @Override
  603. public void onCacheUpdated(List<Integer> cacheNotifications, PHBridge bridge)
  604. {
  605. // TODO Auto-generated method stub
  606. }
  607.  
  608.  
  609. @Override
  610. public void onConnectionLost(PHAccessPoint access)
  611. {
  612. System.out.println("Connection lost please connect again.");
  613. resetConnectionInfo();
  614. }
  615.  
  616.  
  617. @Override
  618. public void onConnectionResumed(PHBridge bridge)
  619. {
  620. // TODO Auto-generated method stub
  621. }
  622.  
  623. ArrayList<Integer> ignoredCodes;
  624.  
  625. @Override
  626. public void onError(int code, String message)
  627. {
  628. if(ignoredCodes == null)
  629. {
  630. ignoredCodes = new ArrayList<Integer>();
  631. ignoredCodes.add(101);
  632. }
  633. if(!ignoredCodes.contains(code))
  634. {
  635. System.out.println("Error, please connect again:\n"+message);
  636. resetConnectionInfo();
  637. }
  638. }
  639.  
  640.  
  641. @Override
  642. public void onParsingErrors(List<PHHueParsingError> parsingErrors)
  643. {
  644. System.out.println("Error found, please connect again.");
  645. resetConnectionInfo();
  646. }
  647.  
  648. /*End Main Listener Code*/
  649. }
Add Comment
Please, Sign In to add comment