Guest User

My tweaks to HS100.java (http://www.insxnity.net/hs-100.html

a guest
Feb 17th, 2018
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.59 KB | None | 0 0
  1. package net.insxnity.hs100;
  2.  
  3. import com.google.gson.JsonElement;
  4. import com.google.gson.JsonObject;
  5. import com.google.gson.JsonParser;
  6.  
  7.  
  8.  
  9. import java.io.IOException;
  10. import java.io.InputStream;
  11. import java.io.OutputStream;
  12. import java.net.InetAddress;
  13. import java.net.InetSocketAddress;
  14. import java.net.Socket;
  15. import java.net.SocketTimeoutException;
  16. import java.nio.ByteBuffer;
  17. import java.util.HashMap;
  18. import java.util.Map;
  19.  
  20. /**
  21.  * TP-Link HS100
  22.  *
  23.  * @author Insxnity
  24.  * @copyright Copyright (c) 2016, Insxnity Development
  25.  */
  26. public class HS100 {
  27.  
  28.     public static final String COMMAND_SWITCH_ON = "{\"system\":{\"set_relay_state\":{\"state\":1}}}}";
  29.     public static final String COMMAND_SWITCH_OFF = "{\"system\":{\"set_relay_state\":{\"state\":0}}}}";
  30.     public static final String COMMAND_INFO = "{\"system\":{\"get_sysinfo\":null}}";
  31.  
  32.     /**
  33.      * ON Status
  34.      */
  35.     public static final int STATE_ON = 1;
  36.  
  37.     /**
  38.      * OFF Status
  39.      */
  40.     public static final int STATE_OFF = 2;
  41.  
  42.     /**
  43.      * IP of the Plug
  44.      */
  45.     private String ip;
  46.  
  47.     /**
  48.      * Port
  49.      */
  50.     private int port = 9999;
  51.  
  52.     /**
  53.      * @param ip IP Address
  54.      */
  55.     public HS100(String ip) {
  56.         this.ip = ip;
  57.     }
  58.  
  59.     /**
  60.      * @param ip IP Address
  61.      * @param port TCP Port Number
  62.      */
  63.     public HS100(String ip, int port) {
  64.         this.ip = ip;
  65.         this.port = port;
  66.     }
  67.  
  68.     /**
  69.      * get current IP Address of the Plug
  70.      *
  71.      * @return IP Address
  72.      */
  73.     public String getIp() {
  74.         return ip;
  75.     }
  76.  
  77.     /**
  78.      * set IP Address of the Plug
  79.      *
  80.      * @param ip IP Address
  81.      */
  82.     public void setIp(String ip) {
  83.         this.ip = ip;
  84.     }
  85.  
  86.     /**
  87.      * get current Port of the Plug
  88.      *
  89.      * @return Port
  90.      */
  91.     public int getPort() {
  92.         return port;
  93.     }
  94.  
  95.     /**
  96.      * set port of the Plug
  97.      *
  98.      * @param port Port
  99.      */
  100.     public void setPort(int port) {
  101.         this.port = port;
  102.     }
  103.  
  104.     /**
  105.      * return if the Plug is valid and present
  106.      *
  107.      * @return present
  108.      */
  109.     public boolean isPresent() {
  110.         try {
  111.             Socket sock = new Socket();
  112.             sock.connect(new InetSocketAddress(getIp(), getPort()), 1500);
  113.             return true;
  114.         } catch (IOException ex) {
  115.             return false;
  116.         }
  117. //        try {
  118. //
  119. //            InetAddress ip = InetAddress.getByName(getIp());
  120. //            return ip.isReachable(1500);
  121. //        } catch (IOException ex) {}
  122. //        return false;
  123.     }
  124.  
  125.     /**
  126.      * send "On" signal to plug
  127.      *
  128.      * @return true if successful
  129.      */
  130.     public boolean switchOn() throws IOException {
  131.  
  132.         String jsonData = sendCommand(COMMAND_SWITCH_ON);
  133.         if(jsonData.length() > 0) {
  134.  
  135.             JsonObject jo = new JsonParser().parse(jsonData).getAsJsonObject();
  136.             int errorCode = jo.get("system").getAsJsonObject().get("set_relay_state").getAsJsonObject().get("err_code").getAsInt();
  137.             return errorCode == 0;
  138.         }
  139.         return false;
  140.     }
  141.  
  142.     /**
  143.      * send "Off" signal to plug
  144.      *
  145.      * @return true if successful
  146.      */
  147.     public boolean switchOff() throws IOException {
  148.  
  149.         String jsonData = sendCommand(COMMAND_SWITCH_OFF);
  150.         if(jsonData.length() > 0) {
  151.  
  152.             JsonObject jo = new JsonParser().parse(jsonData).getAsJsonObject();
  153.             int errorCode = jo.get("system").getAsJsonObject().get("set_relay_state").getAsJsonObject().get("err_code").getAsInt();
  154.             return errorCode == 0;
  155.         }
  156.         return false;
  157.     }
  158.  
  159.     /**
  160.      * check if the plug is off (added by flying-geek)
  161.      *
  162.      * @return STATE_ON oder STATE_OFF
  163.      */
  164.     public boolean isOff() throws IOException {
  165.         return !isOn();
  166.     }
  167.    
  168.    
  169.     /**
  170.      * check if the plug is on (relay_state == 1; if relay_state == 0 the plug is off)
  171.      *
  172.      * @return STATE_ON oder STATE_OFF
  173.      */
  174.     public boolean isOn() throws IOException {
  175.  
  176.         String jsonData = sendCommand(COMMAND_INFO);
  177.         if(jsonData.length() > 0) {
  178.  
  179.             JsonObject jo = new JsonParser().parse(jsonData).getAsJsonObject();
  180.             int state = jo.get("system").getAsJsonObject().get("get_sysinfo").getAsJsonObject().get("relay_state").getAsInt();
  181.             return state == 1 ? true : false;
  182.         }
  183.         return false;
  184.     }
  185.  
  186.     /**
  187.      * Return a map containing plug system information
  188.      *
  189.      * @return Map of Information
  190.      */
  191.     public Map<String, String> getInfo() throws IOException {
  192.  
  193.         Map<String, String> result = new HashMap<String, String>();
  194.         String jsonData = sendCommand(COMMAND_INFO);
  195.         if(jsonData.length() > 0) {
  196.  
  197.             JsonObject jo = new JsonParser().parse(jsonData).getAsJsonObject();
  198.             JsonObject systemInfo = jo.get("system").getAsJsonObject().get("get_sysinfo").getAsJsonObject();
  199.             for(Map.Entry<String, JsonElement> entry : systemInfo.entrySet()) {
  200.  
  201.                 result.put(entry.getKey(), entry.getValue().getAsString());
  202.             }
  203.         }
  204.         return result;
  205.     }
  206.  
  207.     /**
  208.      * send <code>command</code> to plug
  209.      *
  210.      * @param command Command
  211.      * @return Json String of the returned data
  212.      * @throws IOException
  213.      */
  214.     protected String sendCommand(String command) throws IOException {
  215.  
  216. //        Socket socket = new Socket(getIp(), 9999);        // flying-geek
  217.         Socket socket = new Socket(getIp(), getPort() );    // flying-geek
  218.         socket.setSoTimeout(1000);                          // flying-geek
  219.         OutputStream outputStream = socket.getOutputStream();
  220.         outputStream.write(encryptWithHeader(command));
  221.  
  222.         InputStream inputStream = socket.getInputStream();
  223.         String data = decrypt(inputStream);
  224.  
  225.         outputStream.close();
  226.         inputStream.close();
  227.         socket.close();
  228.  
  229.         return data;
  230.     }
  231.    
  232.    
  233.     /**
  234.      * Decrypt given data from InputStream
  235.      *  
  236.      * @param inputStream
  237.      * @return
  238.      * @throws IOException
  239.      */
  240.     private String decrypt(InputStream inputStream) throws IOException {
  241.  
  242.         int in;
  243.         int key = 0x2B;
  244.         int nextKey;
  245.         StringBuilder sb = new StringBuilder();
  246.         try {                               // flying-geek
  247.             while((in = inputStream.read()) != -1) {
  248.      
  249.                 nextKey = in;
  250.                 in = in ^ key;
  251.                 key = nextKey;
  252.                 sb.append((char) in);
  253.             }
  254.         } catch(SocketTimeoutException e) {} // flying-geek
  255.        
  256.         return "{" + sb.toString().substring(5);
  257.     }
  258.  
  259.    
  260.    
  261.     /**
  262.      * Encrypt a command into plug-readable bytecode
  263.      *
  264.      * @param command
  265.      * @return
  266.      */
  267.     private int[] encrypt(String command) {
  268.  
  269.         int[] buffer = new int[command.length()];
  270.         int key = 0xAB;
  271.         for(int i = 0; i < command.length(); i++) {
  272.  
  273.             buffer[i] = command.charAt(i) ^ key;
  274.             key = buffer[i];
  275.         }
  276.         return buffer;
  277.     }
  278.     /**
  279.      * Encrypt a command into plug-readable bytecode with header
  280.      *
  281.      * @param command
  282.      * @return
  283.      */
  284.     private byte[] encryptWithHeader(String command) {
  285.  
  286.         int[] data = encrypt(command);
  287.         byte[] bufferHeader = ByteBuffer.allocate(4).putInt(command.length()).array();
  288.         ByteBuffer byteBuffer = ByteBuffer.allocate(bufferHeader.length + data.length).put(bufferHeader);
  289.         for(int in : data) {
  290.  
  291.             byteBuffer.put((byte) in);
  292.         }
  293.         return byteBuffer.array();
  294.     }
  295. }
Add Comment
Please, Sign In to add comment