bulbMacAdd[7] = (byte)0x00;
- IoTDeviceAddress devAddr = new IoTDeviceAddress("192.168.1.17", 56700, 56700, false, false);
+ IoTDeviceAddress devAddr = new IoTDeviceAddress("192.168.1.4", 56700, 56700, false, false);
IoTUDP udp = new IoTUDP(devAddr);
LightBulb bulb = new LifxLightBulb(udp, bulbMacAdd);
--- /dev/null
+import java.security.InvalidParameterException;
+
+public class BulbColor {
+
+ private int hue;
+ private int saturation;
+ private int brightness;
+ private int kelvin;
+
+ public BulbColor(int _hue, int _saturation, int _brightness, int _kelvin) {
+
+ if ((hue > 65535) || (hue < 0)) {
+ throw new InvalidParameterException("BulbColor: Invalid parameter value for _hue (0-65535)");
+ }
+
+ if ((saturation > 65535) || (saturation < 0)) {
+ throw new InvalidParameterException("BulbColor: Invalid parameter value for _saturation (0-65535)");
+ }
+
+ if ((brightness > 65535) || (brightness < 0)) {
+ throw new InvalidParameterException("BulbColor: Invalid parameter value for _brightness (0-65535)");
+ }
+
+ if ((kelvin > 65535) || (kelvin < 0)) {
+ throw new InvalidParameterException("BulbColor: Invalid parameter value for _kelvin (0-65535)");
+ }
+
+ hue = _hue;
+ saturation = _saturation;
+ brightness = _brightness;
+ kelvin = _kelvin;
+ }
+
+ public BulbColor(byte[] data) {
+ hue = ((data[1] & 0xFF) << 8);
+ hue |= (data[0] & 0xFF);
+
+ saturation = ((data[3] & 0xFF) << 8);
+ saturation |= (data[2] & 0xFF);
+
+ brightness = ((data[5] & 0xFF) << 8);
+ brightness |= (data[4] & 0xFF);
+
+ kelvin = ((data[7] & 0xFF) << 8);
+ kelvin |= (data[6] & 0xFF);
+ }
+
+ public int getHue() {
+ return hue;
+ }
+
+ public int getSaturation() {
+ return saturation;
+ }
+
+ public int getBrightness() {
+ return brightness;
+ }
+
+ public int getKelvin() {
+ return kelvin;
+ }
+}
+
+
--- /dev/null
+
+
+import java.util.Scanner;
+import iotcloud.*;
+
+class BulbSwitch {
+ public static void main(String[] args) throws Exception {
+
+
+ System.out.println(Integer.parseInt(args[0]));
+
+ Table t1 = new Table("http://dc-6.calit2.uci.edu/test.iotcloud/", "reallysecret", Integer.parseInt(args[0]), -1);
+ t1.rebuild(); // update
+
+
+ String a = "bulb";
+ String b = "fan";
+ IoTString ib = new IoTString(b);
+ IoTString ia = new IoTString(a);
+
+ t1.createNewKey(ia, 321);
+
+
+ String valueA = "on";
+ String valueB = "off";
+ IoTString iValueA = new IoTString(valueA);
+ IoTString iValueB = new IoTString(valueB);
+
+
+
+ System.out.println("Starting System");
+ Scanner keyboard = new Scanner(System.in);
+
+ while (true) {
+
+
+ System.out.println("Enter 0 for off, 1 for on for bulb");
+ System.out.println("Enter 3 for off, 2 for on for fan");
+ int myint = keyboard.nextInt();
+
+ if (myint == 0) {
+ t1.update();
+ t1.startTransaction();
+ t1.addKV(ia, iValueB);
+ t1.commitTransaction();
+
+ } else if (myint == 1) {
+ t1.update();
+ t1.startTransaction();
+ t1.addKV(ia, iValueA);
+ t1.commitTransaction();
+ }
+ else if (myint == 2) {
+ t1.update();
+ t1.startTransaction();
+ t1.addKV(ib, iValueA);
+ t1.commitTransaction();
+ }
+ else if (myint == 3) {
+ t1.update();
+ t1.startTransaction();
+ t1.addKV(ib, iValueB);
+ t1.commitTransaction();
+ }
+
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+public class DeviceStateGroup {
+ byte[] group = new byte[16];
+ final String label;
+ final long updatedAt;
+
+ public DeviceStateGroup(byte[] _location, String _label, long _updatedAt) {
+ group = _location;
+ label = _label;
+ updatedAt = _updatedAt;
+ }
+
+ public byte[] getGroup() {
+ return group;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public long getUpdatedAt() {
+ return updatedAt;
+ }
+}
--- /dev/null
+public class DeviceStateHostFirmware {
+ // time of build in nanosecond accuracy
+ // after some tests
+ final long build;
+ final long version; // firmware version
+
+ public DeviceStateHostFirmware(long _build, long _version) {
+ build = _build;
+ version = _version;
+ }
+
+ public long getBuild() {
+ return build;
+ }
+
+ public long getVersion() {
+ return version;
+ }
+}
--- /dev/null
+
+
+public class DeviceStateHostInfo {
+ final long signal;
+ final long tx;
+ final long rx;
+
+ public DeviceStateHostInfo(long _signal, long _tx, long _rx) {
+ signal = _signal;
+ tx = _tx;
+ rx = _rx;
+ }
+
+ public long getSignal() {
+ return signal;
+ }
+
+ public long getTx() {
+ return tx;
+ }
+
+ public long getRx() {
+ return rx;
+ }
+}
--- /dev/null
+
+
+public class DeviceStateInfo {
+ // all values are in nanoseconds
+ private final long time;
+ private final long upTime;
+ private final long downTime;
+
+ public DeviceStateInfo(long _time, long _upTime, long _downTime) {
+ time = _time;
+ upTime = _upTime;
+ downTime = _downTime;
+ }
+
+ public long getTime() {
+ return time;
+ }
+
+ public long getUpTime() {
+ return upTime;
+ }
+
+ public long getDownTime() {
+ return downTime;
+ }
+}
--- /dev/null
+
+
+public class DeviceStateLocation {
+ byte[] location = new byte[16];
+ final String label;
+ final long updatedAt;
+
+ public DeviceStateLocation(byte[] _location, String _label, long _updatedAt) {
+ location = _location;
+ label = _label;
+ updatedAt = _updatedAt;
+ }
+
+ public byte[] getLocation() {
+ return location;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public long getUpdatedAt() {
+ return updatedAt;
+ }
+}
--- /dev/null
+
+
+public class DeviceStateService {
+ private final int service;
+ private final long port;
+
+ public DeviceStateService(int _service, long _port) {
+ service = _service;
+ port = _port;
+ }
+
+ public int getService() {
+ return service;
+ }
+
+ public long getPort() {
+ return port;
+ }
+}
--- /dev/null
+
+
+public class DeviceStateVersion {
+ final long vender;
+ final long product;
+ final long version;
+
+ public DeviceStateVersion(long _vender, long _product, long _version) {
+ vender = _vender;
+ product = _product;
+ version = _version;
+ }
+
+ public long getVender() {
+ return vender;
+ }
+
+ public long getProduct() {
+ return product;
+ }
+
+ public long getVersion() {
+ return version;
+ }
+}
--- /dev/null
+
+
+public class DeviceStateWifiFirmware {
+ // time of build in nanosecond accuracy
+ // after some tests
+ final long build;
+ final long version; // firmware version
+
+ public DeviceStateWifiFirmware(long _build, long _version) {
+ build = _build;
+ version = _version;
+ }
+
+ public long getBuild() {
+ return build;
+ }
+
+ public long getVersion() {
+ return version;
+ }
+}
--- /dev/null
+
+
+public class DeviceStateWifiInfo {
+ final long signal;
+ final long tx;
+ final long rx;
+
+ public DeviceStateWifiInfo(long _signal, long _tx, long _rx) {
+ signal = _signal;
+ tx = _tx;
+ rx = _rx;
+ }
+
+ public long getSignal() {
+ return signal;
+ }
+
+ public long getTx() {
+ return tx;
+ }
+
+ public long getRx() {
+ return rx;
+ }
+}
--- /dev/null
+\r
+// Java packages\r
+import java.net.Socket;\r
+import java.net.ServerSocket;\r
+import java.net.InetAddress;\r
+import java.net.UnknownHostException;\r
+\r
+/** Class IoTAddress is a wrapper class to pass\r
+ * IoTSet of any addresses from master to slave\r
+ *\r
+ * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>\r
+ * @version 1.0\r
+ * @since 2016-04-22\r
+ */\r
+public class IoTAddress {\r
+\r
+ /**\r
+ * IoTDeviceAddress class properties\r
+ */\r
+ protected final InetAddress inetAddress;\r
+\r
+ /**\r
+ * Class constructor\r
+ *\r
+ * @param sAddress String address\r
+ */\r
+ protected IoTAddress(String sAddress) throws UnknownHostException {\r
+\r
+ inetAddress = InetAddress.getByName(sAddress);\r
+ }\r
+\r
+ /**\r
+ * getHostAddress() method\r
+ *\r
+ * @return String\r
+ */\r
+ public String getHostAddress() {\r
+\r
+ return inetAddress.getHostAddress();\r
+\r
+ }\r
+\r
+ /**\r
+ * getHostName() method\r
+ *\r
+ * @return String\r
+ */\r
+ public String getHostName() {\r
+\r
+ return inetAddress.getHostName();\r
+\r
+ }\r
+\r
+ /**\r
+ * getUrl() method\r
+ *\r
+ * @return String\r
+ */\r
+ public String getURL(String strURLComplete) {\r
+\r
+ //e.g. http:// + inetAddress.getHostAddress() + strURLComplete\r
+ // http://192.168.2.254/cgi-bin/mjpg/video.cgi?\r
+ return "http://" + inetAddress.getHostAddress() + strURLComplete;\r
+ \r
+ }\r
+\r
+ /**\r
+ * getCompleteAddress() method\r
+ *\r
+ * @return String\r
+ */\r
+ public String getCompleteAddress() {\r
+\r
+ return inetAddress.toString();\r
+\r
+ }\r
+}\r
--- /dev/null
+// Java packages\r
+import java.net.Socket;\r
+import java.net.ServerSocket;\r
+import java.net.InetAddress;\r
+import java.net.UnknownHostException;\r
+\r
+/** Class IoTDeviceAddress is a wrapper class to pass\r
+ * IoTSet of device addresses from master to slave\r
+ *\r
+ * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>\r
+ * @version 1.0\r
+ * @since 2016-02-18\r
+ */\r
+public class IoTDeviceAddress extends IoTAddress {\r
+\r
+ /**\r
+ * IoTDeviceAddress class properties\r
+ */\r
+ private int iSrcPort;\r
+ private int iDstPort;\r
+ private final String sAddress;\r
+\r
+ // the wildcard status of this address\r
+ private final boolean isSrcPortWildCard;\r
+ private final boolean isDstPortWildCard;\r
+\r
+\r
+ /**\r
+ * Class constructor\r
+ *\r
+ * @param sAddress String address\r
+ * @param _iSrcPort Source port number\r
+ * @param _iDstPort Destination port number\r
+ * @param _isSrcPortWildCard Is this source port a wild card (=can change port number)?\r
+ * @param _isDstPortWildCard Is this destination port a wild card (=can change port number)?\r
+ */\r
+ protected IoTDeviceAddress(String _sAddress, int _iSrcPort, int _iDstPort, boolean _isSrcPortWildCard, \r
+ boolean _isDstPortWildCard) throws UnknownHostException {\r
+\r
+ super(_sAddress);\r
+ sAddress = _sAddress;\r
+ iSrcPort = _iSrcPort;\r
+ iDstPort = _iDstPort;\r
+\r
+ isSrcPortWildCard = _isSrcPortWildCard;\r
+ isDstPortWildCard = _isDstPortWildCard;\r
+ }\r
+\r
+ /**\r
+ * getSourcePortNumber() method\r
+ *\r
+ * @return int\r
+ */\r
+ public int getSourcePortNumber() {\r
+\r
+ return iSrcPort;\r
+\r
+ }\r
+\r
+ /**\r
+ * getDestinationPortNumber() method\r
+ *\r
+ * @return int\r
+ */\r
+ public int getDestinationPortNumber() {\r
+\r
+ return iDstPort;\r
+\r
+ }\r
+\r
+ /**\r
+ * setSrcPort() method\r
+ *\r
+ * @param port Port number\r
+ * @return void\r
+ */\r
+ public void setSrcPort(int port) {\r
+ if (isSrcPortWildCard) {\r
+ iSrcPort = port;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * setDstPort() method\r
+ *\r
+ * @param port Port number\r
+ * @return void\r
+ */\r
+ public void setDstPort(int port) {\r
+ if (isDstPortWildCard) {\r
+ iDstPort = port;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * getAddress() method\r
+ *\r
+ * @return String\r
+ */\r
+ public String getAddress() {\r
+ return sAddress;\r
+ }\r
+\r
+ /**\r
+ * getHostAddress() method\r
+ *\r
+ * @return String\r
+ */\r
+ public static String getLocalHostAddress() {\r
+\r
+ String strLocalHostAddress = null;\r
+ try {\r
+ strLocalHostAddress = InetAddress.getLocalHost().getHostAddress();\r
+ } catch (UnknownHostException ex) {\r
+ ex.printStackTrace();\r
+ } \r
+ return strLocalHostAddress;\r
+ }\r
+\r
+ /**\r
+ * getIsSrcPortWildcard() method\r
+ *\r
+ * @return boolean\r
+ */\r
+ public boolean getIsSrcPortWildcard() {\r
+ return isSrcPortWildCard;\r
+ }\r
+\r
+ /**\r
+ * getIsDstPortWildcard() method\r
+ *\r
+ * @return boolean\r
+ */\r
+ public boolean getIsDstPortWildcard() {\r
+ return isDstPortWildCard;\r
+ }\r
+\r
+\r
+ /**\r
+ * getUrl() method\r
+ *\r
+ * @return String\r
+ */\r
+ public String getURL(String strURLComplete) {\r
+\r
+ //e.g. http:// + inetAddress.getHostAddress() + strURLComplete\r
+ // http://192.168.2.254/cgi-bin/mjpg/video.cgi?\r
+ return "http://" + inetAddress.getHostAddress() + ":" + iDstPort + strURLComplete;\r
+ \r
+ }\r
+}\r
--- /dev/null
+\r
+// Java packages\r
+import java.io.InputStream;\r
+import java.io.OutputStream;\r
+import java.io.IOException;\r
+import java.net.HttpURLConnection;\r
+import java.net.MalformedURLException;\r
+import java.net.UnknownHostException;\r
+import java.net.URL;\r
+import java.net.ProtocolException;\r
+\r
+\r
+/** Class IoTHTTP is a wrapper class that provides\r
+ * minimum interfaces for user to interact with IoT\r
+ * devices in our system\r
+ *\r
+ * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>\r
+ * @version 1.0\r
+ * @since 2016-02-18\r
+ */\r
+public class IoTHTTP {\r
+\r
+ /**\r
+ * IoTHTTP class properties\r
+ */\r
+ private IoTDeviceAddress iotDevAdd;\r
+ private URL url;\r
+ private HttpURLConnection httpConnection;\r
+\r
+ /**\r
+ * Class constructor\r
+ */\r
+ public IoTHTTP(IoTDeviceAddress _iotDevAdd) {\r
+\r
+ iotDevAdd = _iotDevAdd;\r
+ url = null;\r
+ httpConnection = null;\r
+ }\r
+\r
+ /**\r
+ * setURL() method\r
+ *\r
+ * @param strUrlComplete String to complete the URL\r
+ * @return void\r
+ */\r
+ public void setURL(String strUrlComplete) throws MalformedURLException {\r
+\r
+ url = new URL(iotDevAdd.getURL(strUrlComplete));\r
+ System.out.println(url.toString());\r
+\r
+ }\r
+\r
+ /**\r
+ * openConnection() method\r
+ */\r
+ public void openConnection() throws IOException {\r
+\r
+ httpConnection = (HttpURLConnection) url.openConnection();\r
+\r
+ }\r
+\r
+ /**\r
+ * setDoInput() method inherited from HttpURLConnection class\r
+ *\r
+ * @param bSetDoInput\r
+ * @return void\r
+ */\r
+ public void setDoInput(boolean bSetDoInput) {\r
+\r
+ httpConnection.setDoInput(bSetDoInput);\r
+\r
+ }\r
+\r
+ /**\r
+ * setRequestProperty() method inherited from HttpURLConnection class\r
+ *\r
+ * @param strProperty String property\r
+ * @param strHttpAuthCredentials String HTTP authentication credentials\r
+ * @return void\r
+ */\r
+ public void setRequestProperty(String strProperty, String strHttpAuthCredentials) {\r
+\r
+ httpConnection.setRequestProperty(strProperty, strHttpAuthCredentials);\r
+\r
+ }\r
+\r
+ /**\r
+ * setRequestMethod() method inherited from HttpURLConnection class\r
+ *\r
+ * @param strMethod String method\r
+ * @return void\r
+ */\r
+ public void setRequestMethod(String strMethod) throws ProtocolException {\r
+\r
+ httpConnection.setRequestMethod(strMethod);\r
+\r
+ }\r
+\r
+ /**\r
+ * setDoOutput() method inherited from HttpURLConnection class\r
+ *\r
+ * @param doOut\r
+ * @return void\r
+ */\r
+ public void setDoOutput(boolean doOut) {\r
+\r
+ httpConnection.setDoOutput(doOut);\r
+\r
+ }\r
+\r
+ /**\r
+ * getOutputStream() method inherited from HttpURLConnection class\r
+ *\r
+ * @return OutputStream\r
+ */\r
+ public OutputStream getOutputStream() throws IOException {\r
+\r
+ return httpConnection.getOutputStream();\r
+\r
+ }\r
+\r
+ /**\r
+ * getInputStream() method inherited from HttpURLConnection class\r
+ *\r
+ * @return InputStream\r
+ */\r
+ public InputStream getInputStream() throws IOException {\r
+\r
+ return httpConnection.getInputStream();\r
+\r
+ }\r
+\r
+ /**\r
+ * connect() method inherited from HttpURLConnection class\r
+ */\r
+ public void connect() throws IOException {\r
+\r
+ httpConnection.connect();\r
+\r
+ }\r
+\r
+ /**\r
+ * disconnect() method inherited from HttpURLConnection class\r
+ */\r
+ public void disconnect() throws IOException {\r
+\r
+ httpConnection.disconnect();\r
+\r
+ }\r
+}\r
--- /dev/null
+import java.lang.UnsupportedOperationException;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Spliterator;
+
+
+/** Class IoTSet is the actual implementation of @config IoTSet<...>.
+ * Upon extracting DB information, SetInstrumenter class will use
+ * this class to actually instantiate the Set as IoTSet that uses
+ * Java Set<T> to implement; we don't provide interfaces to modify
+ * the contents, but we do provide means to read them out
+ *
+ * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
+ * @version 1.0
+ * @since 2015-12-01
+ */
+public final class IoTSet<T> {
+
+ /**
+ * Reference to an object Set<T>
+ */
+ private Set<T> set;
+
+ /**
+ * Class constructor (pass the reference to this immutable wrapper)
+ */
+ protected IoTSet(Set<T> s) {
+
+ set = s;
+ }
+
+ /**
+ * contains() method inherited from Set interface
+ */
+ public boolean contains(T o) {
+
+ return set.contains(o);
+
+ }
+
+ /**
+ * isEmpty() method inherited from Set interface
+ */
+ public boolean isEmpty() {
+
+ return set.isEmpty();
+
+ }
+
+ /**
+ * iterator() method inherited from Set interface
+ */
+ public Iterator<T> iterator() {
+
+ return new HashSet<T>(set).iterator();
+
+ }
+
+ /**
+ * size() method inherited from Set interface
+ */
+ public int size() {
+
+ return set.size();
+
+ }
+
+ /**
+ * values() method to return Set object values for easy iteration
+ */
+ public Set<T> values() {
+
+ return new HashSet<T>(set);
+
+ }
+}
--- /dev/null
+
+// Java packages
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+
+
+/** Class IoTUDP is a wrapper class that provides
+ * minimum interfaces for user to interact with IoT
+ * devices in our system - adapted from my colleague's
+ * work (Ali Younis - ayounis @ uci.edu)
+ *
+ * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
+ * @version 1.0
+ * @since 2016-02-20
+ */
+public class IoTUDP {
+
+ /**
+ * IoTUDP class properties
+ */
+ private final String strHostAddress;
+ private final int iSrcPort;
+ private final int iDstPort;
+ private DatagramSocket socket; // the socket interface that we are guarding
+ private boolean didClose; // make sure that the clean up was done correctly
+
+ /**
+ * Class constructor
+ */
+ public IoTUDP(IoTDeviceAddress iotDevAdd) throws SocketException, IOException {
+
+ strHostAddress = iotDevAdd.getHostAddress();
+ iSrcPort = iotDevAdd.getSourcePortNumber();
+ iDstPort = iotDevAdd.getDestinationPortNumber();
+
+ socket = new DatagramSocket(iSrcPort);
+ didClose = false;
+ }
+
+ /**
+ * sendData() method
+ *
+ * @param bData Byte type that passes the data to be sent
+ * @return void
+ */
+ public void sendData(byte[] bData) throws UnknownHostException, IOException {
+
+ DatagramPacket dpSendPacket = new DatagramPacket(bData, bData.length, InetAddress.getByName(strHostAddress), iDstPort);
+ socket.send(dpSendPacket);
+ }
+
+ /**
+ * recieveData() method
+ *
+ * @param iMaxDataLength Integer maximum data length as reference
+ * @return byte[]
+ */
+ public byte[] recieveData(int iMaxDataLength) throws IOException {
+
+ byte[] bReceiveData = new byte[iMaxDataLength];
+ DatagramPacket dpReceivePacket = new DatagramPacket(bReceiveData, bReceiveData.length);
+ socket.receive(dpReceivePacket);
+
+ return dpReceivePacket.getData();
+ }
+
+ /**
+ * setSoTimeout() method
+ *
+ * @param iTimeout Integer timeout time
+ */
+ public void setSoTimeout(int iTimeout) throws SocketException {
+
+ socket.setSoTimeout(iTimeout);
+
+ }
+
+ /**
+ * setSendBufferSize() method
+ *
+ * @param iSize Integer buffer size
+ */
+ public void setSendBufferSize(int iSize) throws SocketException {
+
+ socket.setSendBufferSize(iSize);
+
+ }
+
+ /**
+ * setReceiveBufferSize() method
+ *
+ * @param iSize Integer buffer size
+ */
+ public void setReceiveBufferSize(int iSize) throws SocketException {
+
+ socket.setReceiveBufferSize(iSize);
+
+ }
+
+ /**
+ * setReuseAddress(boolean on) method
+ */
+ public void setReuseAddress(boolean on) throws SocketException {
+
+ socket.setReuseAddress(on);
+ }
+
+ /**
+ * close() method
+ */
+ public void close() {
+
+ socket.close();
+ didClose = true;
+
+ }
+
+ /**
+ * close() called by the garbage collector right before trashing object
+ */
+ public void finalize() throws SocketException {
+
+ if (!didClose) {
+ close();
+ throw new SocketException("Socket not closed before object destruction, must call close method.");
+ }
+
+ }
+}
--- /dev/null
+
+
+import java.security.InvalidParameterException;
+
+public class LifxHeader {
+ // Frame Variables
+ private int size;
+ private int origin;
+ private boolean tagged;
+ private boolean addressable;
+ private int protocol;
+ private long source;
+
+ //Frame Adress Variables
+ private byte[] macAddress = new byte[8];
+ private boolean ack_required;
+ private boolean res_required;
+ private int sequence;
+
+ //Protocol Header
+ private int type;
+
+ public LifxHeader() {
+ // needed values as per spec
+ origin = 0;
+ addressable = true;
+ protocol = 1024;
+ }
+
+ public void setSize(int _size) {
+ if (_size < 0) {
+ throw new InvalidParameterException("Header: size cannot be less than 0");
+ } else if (_size > 65535) {
+ throw new InvalidParameterException("Header: size to large");
+ }
+ size = _size;
+ }
+
+ public void setOrigin(int _origin) {
+ if (_origin < 0) {
+ throw new InvalidParameterException("Header: origin cannot be less than 0");
+ } else if (_origin > 3) {
+ throw new InvalidParameterException("Header: origin to large");
+ }
+
+ origin = _origin;
+ }
+
+ public void setTagged(boolean _tagged) {
+ tagged = _tagged;
+ }
+
+ public void setAddressable(boolean _addressable) {
+ addressable = _addressable;
+ }
+
+ public void setProtocol(int _protocol) {
+ if (_protocol < 0) {
+ throw new InvalidParameterException("Header: protocol cannot be less than 0");
+ } else if (_protocol > 4095) {
+ throw new InvalidParameterException("Header: protocol to large");
+ }
+
+ protocol = _protocol;
+ }
+
+ public void setSource(long _source) {
+ if (_source < 0) {
+ throw new InvalidParameterException("Header: source cannot be less than 0");
+ } else if (_source > (long)4294967295l) {
+ throw new InvalidParameterException("Header: source to large");
+ }
+ source = _source;
+ }
+
+ public void setSequence(int _sequence) {
+ if (_sequence < 0) {
+ throw new InvalidParameterException("Header: sequence cannot be less than 0");
+ } else if (_sequence > 255) {
+ throw new InvalidParameterException("Header: sequence to large");
+ }
+ sequence = _sequence;
+ }
+
+ public void setType(int _type) {
+ if (_type < 0) {
+ throw new InvalidParameterException("Header: type cannot be less than 0");
+ } else if (_type > 65535) {
+ throw new InvalidParameterException("Header: type to large");
+ }
+ type = _type;
+ }
+
+ public void setAck_required(boolean _ack_required) {
+ ack_required = _ack_required;
+ }
+
+ public void setRes_required(boolean _res_required) {
+ res_required = _res_required;
+ }
+
+ public void setMacAddress(byte[] _macAddress) {
+ macAddress = _macAddress;
+ }
+
+ public int getSize() {
+ return size;
+ }
+
+ public int getOrigin() {
+ return origin;
+ }
+
+ public boolean getTagged() {
+ return tagged;
+ }
+
+ public boolean getAddressable() {
+ return addressable;
+ }
+
+ public int getProtocol() {
+ return protocol;
+ }
+
+ public long getSource() {
+ return source;
+ }
+
+ public int getSequence() {
+ return sequence;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public byte[] getMacAddress() {
+ return macAddress;
+ }
+
+ public boolean getAck_required() {
+ return ack_required;
+ }
+
+ public boolean getRes_required() {
+ return res_required;
+ }
+
+ public byte[] getHeaderBytes() {
+ byte[] headerBytes = new byte[36];
+ headerBytes[0] = (byte)(size & 0xFF);
+ headerBytes[1] = (byte)((size >> 8) & 0xFF);
+
+
+ headerBytes[2] = (byte)(protocol & 0xFF);
+ headerBytes[3] = (byte)((protocol >> 8) & 0x0F);
+
+ headerBytes[3] |= (byte)((origin & 0x03) << 6);
+
+ if (tagged) {
+ headerBytes[3] |= (1 << 5);
+ }
+
+ if (addressable) {
+ headerBytes[3] |= (1 << 4);
+ }
+
+ headerBytes[4] = (byte)((source >> 0) & 0xFF);
+ headerBytes[5] = (byte)((source >> 8) & 0xFF);
+ headerBytes[6] = (byte)((source >> 16) & 0xFF);
+ headerBytes[7] = (byte)((source >> 24) & 0xFF);
+
+
+ // fix in a bit
+ headerBytes[8] = macAddress[0];
+ headerBytes[9] = macAddress[1];
+ headerBytes[10] = macAddress[2];
+ headerBytes[11] = macAddress[3];
+ headerBytes[12] = macAddress[4];
+ headerBytes[13] = macAddress[5];
+ headerBytes[14] = macAddress[6];
+ headerBytes[15] = macAddress[7];
+
+ // Reserved and set to 0
+ // headerBytes[16] = 0;
+ // headerBytes[17] = 0;
+ // headerBytes[18] = 0;
+ // headerBytes[19] = 0;
+ // headerBytes[20] = 0;
+ // headerBytes[21] = 0;
+
+ if (ack_required) {
+ headerBytes[22] = (1 << 1);
+ }
+
+ if (res_required) {
+ headerBytes[22] |= (1);
+ }
+
+ headerBytes[23] = (byte)(sequence & 0xFF);
+
+ // Reserved and set to 0
+ //headerBytes[24] = 0;
+ //headerBytes[25] = 0;
+ //headerBytes[26] = 0;
+ //headerBytes[27] = 0;
+ //headerBytes[28] = 0;
+ //headerBytes[29] = 0;
+ //headerBytes[30] = 0;
+ //headerBytes[31] = 0;
+
+ headerBytes[32] = (byte)((type >> 0) & 0xFF);
+ headerBytes[33] = (byte)((type >> 8) & 0xFF);
+
+ // Reserved and set to 0
+ //headerBytes[34] = 0;
+ //headerBytes[35] = 0;
+
+ return headerBytes;
+ }
+
+ public void setFromBytes(byte[] dataBytes) {
+ if (dataBytes.length != 36) {
+ throw new InvalidParameterException("Header: invalid number of bytes");
+ }
+
+ size = dataBytes[0] & 0xFF;
+ size |= ((dataBytes[1] & 0xFF) << 8);
+ size &= 0xFFFF;
+
+ origin = (dataBytes[3] >> 6) & 0x03;
+ tagged = ((dataBytes[3] >> 5) & 0x01) == 1;
+ addressable = ((dataBytes[3] >> 4) & 0x01) == 1;
+
+
+ protocol = (dataBytes[3] & 0x0F) << 8;
+ protocol |= dataBytes[2];
+ protocol &= 0x0FFF;
+
+ source = (dataBytes[7] & 0xFFl) << 24;
+ source |= ((dataBytes[6] & 0xFFl) << 16);
+ source |= ((dataBytes[5] & 0xFFl) << 8);
+ source |= ((dataBytes[4] & 0xFFl));
+
+ macAddress[0] = dataBytes[8];
+ macAddress[1] = dataBytes[9];
+ macAddress[2] = dataBytes[10];
+ macAddress[3] = dataBytes[11];
+ macAddress[4] = dataBytes[12];
+ macAddress[5] = dataBytes[13];
+ macAddress[6] = dataBytes[14];
+ macAddress[7] = dataBytes[15];
+
+ ack_required = (dataBytes[22] & 0x02) == 0x02;
+ res_required = (dataBytes[22] & 0x01) == 0x01;
+
+ sequence = (dataBytes[23] & 0xFF);
+
+ type = ((dataBytes[33] & 0xFF) << 8);
+ type |= (dataBytes[32] & 0xFF);
+ }
+}
--- /dev/null
+
+
+// Standard Java Packages
+import java.io.*;
+import java.net.*;
+import java.util.concurrent.Semaphore;
+import java.security.InvalidParameterException;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+
+// IoT Packages
+//import iotcode.annotation.*;
+
+// String to byte conversion
+import javax.xml.bind.DatatypeConverter;
+
+
+public class LifxLightBulb implements LightBulb {
+
+ /*******************************************************************************************************************************************
+ **
+ ** Constants
+ **
+ *******************************************************************************************************************************************/
+ public static final long GET_BULB_VERSION_RESEND_WAIT_SECONDS = 10;
+
+
+
+ /*******************************************************************************************************************************************
+ **
+ ** Variables
+ **
+ *******************************************************************************************************************************************/
+ private IoTUDP communicationSockect;
+ private byte[] bulbMacAddress = new byte[8];
+ static Semaphore socketMutex = new Semaphore(1);
+ static boolean sendSocketFlag = false;
+ private long lastSentGetBulbVersionRequest = 0; // time last request sent
+
+ // Current Bulb Values
+ private int currentHue = 0;
+ private int currentSaturation = 0;
+ private int currentBrightness = 65535;
+ private int currentTemperature = 9000;
+ private boolean bulbIsOn = false;
+
+
+
+ private AtomicBoolean didAlreadyInit = new AtomicBoolean(false);
+
+ private AtomicBoolean didGetBulbVersion = new AtomicBoolean(false);
+ static Semaphore settingBulbColorMutex = new Semaphore(1);
+ static Semaphore settingBulbTempuraturerMutex = new Semaphore(1);
+ static Semaphore bulbStateMutex = new Semaphore(1);
+
+ // color and temperature ranges for the bulbs
+ private int hueLowerBound = 0;
+ private int hueUpperBound = 0;
+ private int saturationLowerBound = 0;
+ private int saturationUpperBound = 0;
+ private int brightnessLowerBound = 0;
+ private int brightnessUpperBound = 0;
+ private int temperatureLowerBound = 2500;
+ private int temperatureUpperBound = 9000;
+
+
+
+ // Check if a state change was requested, used to poll the bulb for if the bulb did
+ // preform the requested state change
+ private boolean stateDidChange = false;
+
+ /*******************************************************************************************************************************************
+ **
+ ** Threads
+ **
+ *******************************************************************************************************************************************/
+
+ // Main worker thread will do the receive loop
+ Thread workerThread = null;
+
+ /*******************************************************************************************************************************************
+ **
+ ** IoT Sets and Relations
+ **
+ *******************************************************************************************************************************************/
+
+ // IoTSet of Device Addresses.
+ // Will be filled with only 1 address.
+ private IoTSet<IoTDeviceAddress> lb_addresses;
+
+ /**
+ * Used for testing only
+ */
+ public LifxLightBulb(IoTUDP udp, byte[] macAddress) {
+ communicationSockect = udp;
+ bulbMacAddress = macAddress;
+ }
+
+ public LifxLightBulb(String macAddress) {
+ communicationSockect = null;
+
+ // Set the Mac Address to a default value
+ // Probably not needed for anything
+ /*bulbMacAdd[0] = (byte)0x00;
+ bulbMacAdd[1] = (byte)0x00;
+ bulbMacAdd[2] = (byte)0x00;
+ bulbMacAdd[3] = (byte)0x00;
+ bulbMacAdd[4] = (byte)0x00;
+ bulbMacAdd[5] = (byte)0x00;
+ bulbMacAdd[6] = (byte)0x00;
+ bulbMacAdd[7] = (byte)0x00;*/
+
+ bulbMacAddress = DatatypeConverter.parseHexBinary(macAddress);
+ }
+
+
+
+ /*******************************************************************************************************************************************
+ ** Sending
+ ** Device Messages
+ **
+ *******************************************************************************************************************************************/
+ private void sendGetServicePacket() {
+ LifxHeader header = new LifxHeader();
+ header.setSize(36);
+ header.setTagged(true);
+ header.setMacAddress(bulbMacAddress);
+ header.setSource(0); // randomly picked
+ header.setAck_required(false);
+ header.setRes_required(false);
+ header.setSequence(0);
+ header.setType(2);
+
+ byte[] dataBytes = header.getHeaderBytes();
+ sendPacket(dataBytes);
+ }
+
+ private void sendGetHostInfoPacket() {
+ LifxHeader header = new LifxHeader();
+ header.setSize(36);
+ header.setTagged(false);
+ header.setMacAddress(bulbMacAddress);
+ header.setSource(10); // randomly picked
+ header.setAck_required(false);
+ header.setRes_required(false);
+ header.setSequence(0);
+ header.setType(12);
+
+ byte[] dataBytes = header.getHeaderBytes();
+ sendPacket(dataBytes);
+ }
+
+ private void sendGetHostFirmwarePacket() {
+ LifxHeader header = new LifxHeader();
+ header.setSize(36);
+ header.setTagged(false);
+ header.setMacAddress(bulbMacAddress);
+ header.setSource(10); // randomly picked
+ header.setAck_required(false);
+ header.setRes_required(false);
+ header.setSequence(0);
+ header.setType(14);
+
+ byte[] dataBytes = header.getHeaderBytes();
+ sendPacket(dataBytes);
+ }
+
+ private void sendGetWifiInfoPacket() {
+ LifxHeader header = new LifxHeader();
+ header.setSize(36);
+ header.setTagged(false);
+ header.setMacAddress(bulbMacAddress);
+ header.setSource(10); // randomly picked
+ header.setAck_required(false);
+ header.setRes_required(false);
+ header.setSequence(0);
+ header.setType(16);
+
+ byte[] dataBytes = header.getHeaderBytes();
+ sendPacket(dataBytes);
+ }
+
+ private void sendGetWifiFirmwarePacket() {
+ LifxHeader header = new LifxHeader();
+ header.setSize(36);
+ header.setTagged(false);
+ header.setMacAddress(bulbMacAddress);
+ header.setSource(10); // randomly picked
+ header.setAck_required(false);
+ header.setRes_required(false);
+ header.setSequence(0);
+ header.setType(18);
+
+ byte[] dataBytes = header.getHeaderBytes();
+ sendPacket(dataBytes);
+ }
+
+ private void sendGetPowerPacket() {
+ LifxHeader header = new LifxHeader();
+ header.setSize(36);
+ header.setTagged(false);
+ header.setMacAddress(bulbMacAddress);
+ header.setSource(10); // randomly picked
+ header.setAck_required(false);
+ header.setRes_required(false);
+ header.setSequence(0);
+ header.setType(20);
+
+ byte[] dataBytes = header.getHeaderBytes();
+ sendPacket(dataBytes);
+ }
+
+ private void sendSetPowerPacket(int level) {
+ // Currently only 0 and 65535 are supported
+ // This is a fix for now
+ if ((level != 65535) && (level != 0)) {
+ throw new InvalidParameterException("Invalid parameter values");
+ }
+
+ if ((level > 65535) || (level < 0)) {
+ throw new InvalidParameterException("Invalid parameter values");
+ }
+
+ byte[] packetBytes = new byte[38];
+
+ LifxHeader header = new LifxHeader();
+ header.setSize(38);
+ header.setTagged(false);
+ header.setMacAddress(bulbMacAddress);
+ header.setSource(10); // randomly picked
+ header.setAck_required(false);
+ header.setRes_required(false);
+ header.setSequence(0);
+ header.setType(21);
+ byte[] headerBytes = header.getHeaderBytes();
+
+ for (int i = 0; i < 36; i++) {
+ packetBytes[i] = headerBytes[i];
+ }
+
+ packetBytes[36] = (byte)(level & 0xFF);
+ packetBytes[37] = (byte)((level >> 8) & 0xFF);
+
+ sendPacket(packetBytes);
+ }
+
+ private void sendGetLabelPacket() {
+ LifxHeader header = new LifxHeader();
+ header.setSize(36);
+ header.setTagged(false);
+ header.setMacAddress(bulbMacAddress);
+ header.setSource(10); // randomly picked
+ header.setAck_required(false);
+ header.setRes_required(false);
+ header.setSequence(0);
+ header.setType(23);
+
+ byte[] dataBytes = header.getHeaderBytes();
+ sendPacket(dataBytes);
+ }
+
+ private void sendSetLabelPacket(String label) {
+ // Currently only 0 and 65535 are supported
+ // This is a fix for now
+ if (label.length() != 32) {
+ throw new InvalidParameterException("Invalid parameter values, label must be 32 bytes long");
+ }
+
+ byte[] packetBytes = new byte[68];
+
+ LifxHeader header = new LifxHeader();
+ header.setSize(68);
+ header.setTagged(false);
+ header.setMacAddress(bulbMacAddress);
+ header.setSource(10); // randomly picked
+ header.setAck_required(false);
+ header.setRes_required(false);
+ header.setSequence(0);
+ header.setType(24);
+ byte[] headerBytes = header.getHeaderBytes();
+
+ for (int i = 0; i < 36; i++) {
+ packetBytes[i] = headerBytes[i];
+ }
+
+ for (int i = 0; i < 32; i++) {
+ packetBytes[i + 36] = label.getBytes()[i];
+ }
+
+ sendPacket(packetBytes);
+ }
+
+ private void sendGetVersionPacket() {
+ LifxHeader header = new LifxHeader();
+ header.setSize(36);
+ header.setTagged(false);
+ header.setMacAddress(bulbMacAddress);
+ header.setSource(10); // randomly picked
+ header.setAck_required(false);
+ header.setRes_required(false);
+ header.setSequence(0);
+ header.setType(32);
+
+ byte[] dataBytes = header.getHeaderBytes();
+ sendPacket(dataBytes);
+ }
+
+ private void sendGetInfoPacket() {
+ LifxHeader header = new LifxHeader();
+ header.setSize(36);
+ header.setTagged(false);
+ header.setMacAddress(bulbMacAddress);
+ header.setSource(10); // randomly picked
+ header.setAck_required(false);
+ header.setRes_required(false);
+ header.setSequence(0);
+ header.setType(34);
+
+ byte[] dataBytes = header.getHeaderBytes();
+ sendPacket(dataBytes);
+ }
+
+ private void sendGetLocationPacket() {
+ LifxHeader header = new LifxHeader();
+ header.setSize(36);
+ header.setTagged(false);
+ header.setMacAddress(bulbMacAddress);
+ header.setSource(10); // randomly picked
+ header.setAck_required(false);
+ header.setRes_required(false);
+ header.setSequence(0);
+ header.setType(34);
+
+ byte[] dataBytes = header.getHeaderBytes();
+ sendPacket(dataBytes);
+ }
+
+ private void sendGetGroupPacket() {
+ LifxHeader header = new LifxHeader();
+ header.setSize(36);
+ header.setTagged(false);
+ header.setMacAddress(bulbMacAddress);
+ header.setSource(10); // randomly picked
+ header.setAck_required(false);
+ header.setRes_required(false);
+ header.setSequence(0);
+ header.setType(51);
+
+ byte[] dataBytes = header.getHeaderBytes();
+ sendPacket(dataBytes);
+ }
+
+
+ /*******************************************************************************************************************************************
+ ** Sending
+ ** Light Messages
+ **
+ *******************************************************************************************************************************************/
+ private void sendGetLightStatePacket() {
+ LifxHeader header = new LifxHeader();
+ header.setSize(36);
+ header.setTagged(false);
+ header.setMacAddress(bulbMacAddress);
+ header.setSource(10); // randomly picked
+ header.setAck_required(false);
+ header.setRes_required(false);
+ header.setSequence(0);
+ header.setType(101);
+
+ byte[] dataBytes = header.getHeaderBytes();
+ sendPacket(dataBytes);
+ }
+
+ private void sendSetLightColorPacket(BulbColor bulbColor, long duration) {
+
+ if ((duration > 4294967295l) || (duration < 0)) {
+ throw new InvalidParameterException("Invalid parameter value, duration out of range (0 - 4294967295)");
+ }
+
+ byte[] packetBytes = new byte[49];
+
+ LifxHeader header = new LifxHeader();
+ header.setSize(49);
+ header.setTagged(false);
+ header.setMacAddress(bulbMacAddress);
+ header.setSource(10); // randomly picked
+ header.setAck_required(false);
+ header.setRes_required(false);
+ header.setSequence(0);
+ header.setType(102);
+ byte[] headerBytes = header.getHeaderBytes();
+
+ for (int i = 0; i < 36; i++) {
+ packetBytes[i] = headerBytes[i];
+ }
+
+ // 1 reserved packet
+ packetBytes[37] = (byte)(bulbColor.getHue() & 0xFF);
+ packetBytes[38] = (byte)((bulbColor.getHue() >> 8) & 0xFF);
+
+ packetBytes[39] = (byte)(bulbColor.getSaturation() & 0xFF);
+ packetBytes[40] = (byte)((bulbColor.getSaturation() >> 8) & 0xFF);
+
+ packetBytes[41] = (byte)(bulbColor.getBrightness() & 0xFF);
+ packetBytes[42] = (byte)((bulbColor.getBrightness() >> 8) & 0xFF);
+
+ packetBytes[43] = (byte)(bulbColor.getKelvin() & 0xFF);
+ packetBytes[44] = (byte)((bulbColor.getKelvin() >> 8) & 0xFF);
+
+ packetBytes[45] = (byte)((duration >> 0) & 0xFF);
+ packetBytes[46] = (byte)((duration >> 8) & 0xFF);
+ packetBytes[47] = (byte)((duration >> 16) & 0xFF);
+ packetBytes[48] = (byte)((duration >> 24) & 0xFF);
+
+ sendPacket(packetBytes);
+ }
+
+ private void sendGetLightPowerPacket() {
+ LifxHeader header = new LifxHeader();
+ header.setSize(36);
+ header.setTagged(false);
+ header.setMacAddress(bulbMacAddress);
+ header.setSource(10); // randomly picked
+ header.setAck_required(false);
+ header.setRes_required(false);
+ header.setSequence(0);
+ header.setType(116);
+
+ byte[] dataBytes = header.getHeaderBytes();
+ sendPacket(dataBytes);
+ }
+
+ private void sendSetLightPowerPacket(int level, long duration) {
+
+ if ((level > 65535) || (duration > 4294967295l)
+ || (level < 0) || (duration < 0)) {
+ throw new InvalidParameterException("Invalid parameter values");
+ }
+
+ byte[] packetBytes = new byte[42];
+
+
+ LifxHeader header = new LifxHeader();
+ header.setSize(42);
+ header.setTagged(false);
+ header.setMacAddress(bulbMacAddress);
+ header.setSource(10); // randomly picked
+ header.setAck_required(false);
+ header.setRes_required(false);
+ header.setSequence(0);
+ header.setType(117);
+ byte[] headerBytes = header.getHeaderBytes();
+
+ for (int i = 0; i < 36; i++) {
+ packetBytes[i] = headerBytes[i];
+ }
+
+ packetBytes[36] = (byte)(level & 0xFF);
+ packetBytes[37] = (byte)((level >> 8) & 0xFF);
+
+ packetBytes[38] = (byte)((duration >> 0) & 0xFF);
+ packetBytes[39] = (byte)((duration >> 8) & 0xFF);
+ packetBytes[40] = (byte)((duration >> 16) & 0xFF);
+ packetBytes[41] = (byte)((duration >> 24) & 0xFF);
+
+ sendPacket(packetBytes);
+ }
+
+ private void sendEchoRequestPacket(byte[] data) {
+ // Currently only 0 and 65535 are supported
+ // This is a fix for now
+ if (data.length != 64) {
+ throw new InvalidParameterException("Invalid parameter values, must have 64 bytes");
+ }
+
+ byte[] packetBytes = new byte[100];
+
+ LifxHeader header = new LifxHeader();
+ header.setSize(100);
+ header.setTagged(false);
+ header.setMacAddress(bulbMacAddress);
+ header.setSource(10); // randomly picked
+ header.setAck_required(false);
+ header.setRes_required(false);
+ header.setSequence(0);
+ header.setType(58);
+ byte[] headerBytes = header.getHeaderBytes();
+
+ for (int i = 0; i < 36; i++) {
+ packetBytes[i] = headerBytes[i];
+ }
+
+ for (int i = 0; i < 64; i++) {
+ packetBytes[i + 36] = data[i];
+ }
+
+ sendPacket(packetBytes);
+ }
+
+
+ /*******************************************************************************************************************************************
+ ** Receiving
+ ** Device Messages
+ **
+ *******************************************************************************************************************************************/
+ private DeviceStateService parseDeviceStateServiceMessage(LifxHeader header, byte[] payloadData) {
+ int service = payloadData[0];
+ long port = ((payloadData[3] & 0xFF) << 24);
+ port |= ((payloadData[2] & 0xFF) << 16);
+ port |= ((payloadData[1] & 0xFF) << 8);
+ port |= (payloadData[0] & 0xFF);
+
+ return new DeviceStateService(service, port);
+ }
+
+ private DeviceStateHostInfo parseDeviceStateHostInfoMessage(LifxHeader header, byte[] payloadData) {
+ long signal = ((payloadData[3] & 0xFF) << 24);
+ signal |= ((payloadData[2] & 0xFF) << 16);
+ signal |= ((payloadData[1] & 0xFF) << 8);
+ signal |= (payloadData[0] & 0xFF);
+
+ long tx = ((payloadData[7] & 0xFF) << 24);
+ tx |= ((payloadData[6] & 0xFF) << 16);
+ tx |= ((payloadData[5] & 0xFF) << 8);
+ tx |= (payloadData[4] & 0xFF);
+
+ long rx = ((payloadData[11] & 0xFF) << 24);
+ rx |= ((payloadData[10] & 0xFF) << 16);
+ rx |= ((payloadData[9] & 0xFF) << 8);
+ rx |= (payloadData[8] & 0xFF);
+
+ return new DeviceStateHostInfo(signal, tx, rx);
+ }
+
+ private DeviceStateHostFirmware parseDeviceStateHostFirmwareMessage(LifxHeader header, byte[] payloadData) {
+ long build = 0;
+ for (int i = 0; i < 8; i++) {
+ build += ((long) payloadData[i] & 0xffL) << (8 * i);
+ }
+
+ // 8 reserved bytes
+
+ long version = ((payloadData[19] & 0xFF) << 24);
+ version |= ((payloadData[18] & 0xFF) << 16);
+ version |= ((payloadData[17] & 0xFF) << 8);
+ version |= (payloadData[16] & 0xFF);
+
+ return new DeviceStateHostFirmware(build, version);
+ }
+
+ private DeviceStateWifiInfo parseDeviceStateWifiInfoMessage(LifxHeader header, byte[] payloadData) {
+ long signal = ((payloadData[3] & 0xFF) << 24);
+ signal |= ((payloadData[2] & 0xFF) << 16);
+ signal |= ((payloadData[1] & 0xFF) << 8);
+ signal |= (payloadData[0] & 0xFF);
+
+ long tx = ((payloadData[7] & 0xFF) << 24);
+ tx |= ((payloadData[6] & 0xFF) << 16);
+ tx |= ((payloadData[5] & 0xFF) << 8);
+ tx |= (payloadData[4] & 0xFF);
+
+ long rx = ((payloadData[11] & 0xFF) << 24);
+ rx |= ((payloadData[10] & 0xFF) << 16);
+ rx |= ((payloadData[9] & 0xFF) << 8);
+ rx |= (payloadData[8] & 0xFF);
+
+ return new DeviceStateWifiInfo(signal, tx, rx);
+ }
+
+ private DeviceStateWifiFirmware parseDeviceStateWifiFirmwareMessage(LifxHeader header, byte[] payloadData) {
+ long build = 0;
+ for (int i = 0; i < 8; i++) {
+ build += ((long) payloadData[i] & 0xffL) << (8 * i);
+ }
+
+ // 8 reserved bytes
+
+ long version = ((payloadData[19] & 0xFF) << 24);
+ version |= ((payloadData[18] & 0xFF) << 16);
+ version |= ((payloadData[17] & 0xFF) << 8);
+ version |= (payloadData[16] & 0xFF);
+
+ return new DeviceStateWifiFirmware(build, version);
+ }
+
+ private int parseStatePowerMessage(LifxHeader header, byte[] payloadData) {
+ int level = ((payloadData[1] & 0xFF) << 8);
+ level |= (payloadData[0] & 0xFF);
+ return level;
+ }
+
+ private String parseStateLabelMessage(LifxHeader header, byte[] payloadData) {
+ return new String(payloadData);
+ }
+
+
+ private DeviceStateVersion parseDeviceStateVersionMessage(LifxHeader header, byte[] payloadData) {
+ long vender = ((payloadData[3] & 0xFF) << 24);
+ vender |= ((payloadData[2] & 0xFF) << 16);
+ vender |= ((payloadData[1] & 0xFF) << 8);
+ vender |= (payloadData[0] & 0xFF);
+
+ long product = ((payloadData[7] & 0xFF) << 24);
+ product |= ((payloadData[6] & 0xFF) << 16);
+ product |= ((payloadData[5] & 0xFF) << 8);
+ product |= (payloadData[4] & 0xFF);
+
+ long version = ((payloadData[11] & 0xFF) << 24);
+ version |= ((payloadData[10] & 0xFF) << 16);
+ version |= ((payloadData[9] & 0xFF) << 8);
+ version |= (payloadData[8] & 0xFF);
+
+ return new DeviceStateVersion(vender, product, version);
+ }
+
+ private DeviceStateInfo parseDeviceStateInfoMessage(LifxHeader header, byte[] payloadData) {
+ long time = 0;
+ long upTime = 0;
+ long downTime = 0;
+ for (int i = 0; i < 8; i++) {
+ time += ((long) payloadData[i] & 0xffL) << (8 * i);
+ upTime += ((long) payloadData[i + 8] & 0xffL) << (8 * i);
+ downTime += ((long) payloadData[i + 16] & 0xffL) << (8 * i);
+ }
+
+ return new DeviceStateInfo(time, upTime, downTime);
+ }
+
+ private DeviceStateLocation parseDeviceStateLocationMessage(LifxHeader header, byte[] payloadData) {
+ byte[] location = new byte[16];
+ for (int i = 0; i < 16; i++) {
+ location[i] = payloadData[i];
+ }
+
+ byte[] labelBytes = new byte[32];
+ for (int i = 0; i < 32; i++) {
+ labelBytes[i] = payloadData[i + 16];
+ }
+
+ long updatedAt = 0;
+ for (int i = 0; i < 8; i++) {
+ updatedAt += ((long) payloadData[48] & 0xffL) << (8 * i);
+ }
+
+ return new DeviceStateLocation(location, new String(labelBytes), updatedAt);
+ }
+
+ private DeviceStateGroup parseDeviceStateGroupMessage(LifxHeader header, byte[] payloadData) {
+ byte[] group = new byte[16];
+ for (int i = 0; i < 16; i++) {
+ group[i] = payloadData[i];
+ }
+
+ byte[] labelBytes = new byte[32];
+ for (int i = 0; i < 32; i++) {
+ labelBytes[i] = payloadData[i + 16];
+ }
+
+ long updatedAt = 0;
+ for (int i = 0; i < 8; i++) {
+ updatedAt += ((long) payloadData[48] & 0xffL) << (8 * i);
+ }
+
+ return new DeviceStateGroup(group, new String(labelBytes), updatedAt);
+ }
+
+ private byte[] parseDeviceEchoResponseMessage(LifxHeader header, byte[] payloadData) {
+ return payloadData;
+ }
+
+ /*******************************************************************************************************************************************
+ ** Receiving
+ ** Light Messages
+ **
+ *******************************************************************************************************************************************/
+ private LightState parseLightStateMessage(LifxHeader header, byte[] payloadData) {
+
+ byte[] colorData = new byte[8];
+ for (int i = 0; i < 8; i++) {
+ colorData[i] = payloadData[i];
+ }
+ BulbColor color = new BulbColor(colorData);
+
+ int power = ((payloadData[11] & 0xFF) << 8);
+ power |= (payloadData[10] & 0xFF);
+
+ String label = new String(payloadData);
+
+ byte[] labelArray = new byte[32];
+ for (int i = 0; i < 32; i++) {
+ labelArray[i] = payloadData[12 + i];
+ }
+
+ return new LightState(color, power, label);
+ }
+
+ private int parseLightStatePowerMessage(LifxHeader header, byte[] payloadData) {
+ int level = ((payloadData[1] & 0xFF) << 8);
+ level |= (payloadData[0] & 0xFF);
+ return level;
+ }
+
+
+ /*******************************************************************************************************************************************
+ **
+ ** Private Handlers
+ **
+ *******************************************************************************************************************************************/
+ private void handleStateVersionMessageRecieved(LifxHeader header, byte[] payloadData) {
+
+ DeviceStateVersion deviceState = parseDeviceStateVersionMessage(header, payloadData);
+ int productNumber = (int)deviceState.getProduct();
+
+ boolean isColor = false;
+
+ if (productNumber == 1) { // Original 1000
+ isColor = true;
+ } else if (productNumber == 3) { //Color 650
+ isColor = true;
+ } else if (productNumber == 10) { // White 800 (Low Voltage)
+ isColor = false;
+ } else if (productNumber == 11) { // White 800 (High Voltage)
+ isColor = false;
+ } else if (productNumber == 18) { // White 900 BR30 (Low Voltage)
+ isColor = false;
+ } else if (productNumber == 20) { // Color 1000 BR30
+ isColor = true;
+ } else if (productNumber == 22) { // Color 1000
+ isColor = true;
+ }
+
+ if (isColor) {
+ hueLowerBound = 0;
+ hueUpperBound = 65535;
+ saturationLowerBound = 0;
+ saturationUpperBound = 65535;
+ brightnessLowerBound = 0;
+ brightnessUpperBound = 65535;
+ temperatureLowerBound = 2500;
+ temperatureUpperBound = 9000;
+ } else {
+ hueLowerBound = 0;
+ hueUpperBound = 0;
+ saturationLowerBound = 0;
+ saturationUpperBound = 0;
+ brightnessLowerBound = 0;
+ brightnessUpperBound = 65535; // still can dim bulb
+ temperatureLowerBound = 2500;
+ temperatureUpperBound = 9000;
+ }
+
+ didGetBulbVersion.set(true);
+
+ }
+
+ private void handleLightStateMessageRecieved(LifxHeader header, byte[] payloadData) {
+ LightState lightState = parseLightStateMessage(header, payloadData);
+
+ BulbColor color = lightState.getColor();
+ int power = lightState.getPower();
+
+ boolean bulbWrongColor = false;
+ bulbWrongColor = bulbWrongColor || (color.getHue() != currentHue);
+ bulbWrongColor = bulbWrongColor || (color.getSaturation() != currentSaturation);
+ bulbWrongColor = bulbWrongColor || (color.getBrightness() != currentBrightness);
+ bulbWrongColor = bulbWrongColor || (color.getKelvin() != currentTemperature);
+
+
+ // gets set to true if any of the below if statements are taken
+ stateDidChange = false;
+
+ if (bulbWrongColor) {
+ BulbColor newColor = new BulbColor(currentHue, currentSaturation, currentBrightness, currentTemperature);
+ sendSetLightColorPacket(newColor, 250);
+ // System.out.println("Failed Check 1");
+ }
+
+ try {
+ bulbStateMutex.acquire();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ boolean bulbIsOnTmp = bulbIsOn;
+ bulbStateMutex.release();
+
+ if ((!bulbIsOnTmp) && (power != 0)) {
+ turnOff();
+ // System.out.println("Failed Check 2: " + Integer.toString(power));
+
+ }
+
+ if (bulbIsOnTmp && (power < 65530)) {
+ turnOn();
+ // System.out.println("Failed Check 3: " + Integer.toString(power));
+
+ }
+ }
+
+ /*******************************************************************************************************************************************
+ **
+ ** Light Bulb Interface Methods
+ **
+ *******************************************************************************************************************************************/
+ public double getHue() {
+ double tmp = 0;
+ try {
+ settingBulbColorMutex.acquire();
+ tmp = ((double)currentHue / 65535.0) * 360.0;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ settingBulbColorMutex.release();
+
+
+ return tmp;
+ }
+
+ public double getSaturation() {
+ double tmp = 0;
+ try {
+ settingBulbColorMutex.acquire();
+ tmp = ((double)currentSaturation / 65535.0) * 360.0;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ settingBulbColorMutex.release();
+
+
+ return tmp;
+ }
+
+ public double getBrightness() {
+ double tmp = 0;
+ try {
+ settingBulbColorMutex.acquire();
+ tmp = ((double)currentBrightness / 65535.0) * 360.0;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ settingBulbColorMutex.release();
+
+ return tmp;
+ }
+
+ public int getTemperature() {
+
+ int tmp = 0;
+ try {
+ settingBulbTempuraturerMutex.acquire();
+ tmp = currentTemperature;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ settingBulbTempuraturerMutex.release();
+
+ return tmp;
+ }
+
+ public double getHueRangeLowerBound() {
+ if (!didGetBulbVersion.get()) {
+ return -1;
+ }
+ return ((double)hueLowerBound / 65535.0) * 360.0;
+ }
+
+ public double getHueRangeUpperBound() {
+ if (!didGetBulbVersion.get()) {
+ return -1;
+ }
+ return ((double)hueUpperBound / 65535.0) * 360.0;
+ }
+
+ public double getSaturationRangeLowerBound() {
+ if (!didGetBulbVersion.get()) {
+ return -1;
+ }
+ return ((double)saturationLowerBound / 65535.0) * 100.0;
+ }
+
+ public double getSaturationRangeUpperBound() {
+ if (!didGetBulbVersion.get()) {
+ return -1;
+ }
+ return ((double)saturationUpperBound / 65535.0) * 100.0;
+ }
+
+ public double getBrightnessRangeLowerBound() {
+ if (!didGetBulbVersion.get()) {
+ return -1;
+ }
+ return ((double)brightnessLowerBound / 65535.0) * 100.0;
+ }
+
+ public double getBrightnessRangeUpperBound() {
+ if (!didGetBulbVersion.get()) {
+ return -1;
+ }
+ return ((double)brightnessUpperBound / 65535.0) * 100.0;
+ }
+
+ public int getTemperatureRangeLowerBound() {
+ if (!didGetBulbVersion.get()) {
+ return -1;
+ }
+ return temperatureLowerBound;
+ }
+
+ public int getTemperatureRangeUpperBound() {
+ if (!didGetBulbVersion.get()) {
+ return -1;
+ }
+ return temperatureUpperBound;
+ }
+
+ public void setTemperature(int _temperature) {
+
+ try {
+ settingBulbTempuraturerMutex.acquire();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ BulbColor newColor = new BulbColor(currentHue, currentSaturation, currentBrightness, _temperature);
+ sendSetLightColorPacket(newColor, 250);
+
+ currentTemperature = _temperature;
+ stateDidChange = true;
+
+ settingBulbTempuraturerMutex.release();
+ }
+
+ public void setColor(double _hue, double _saturation, double _brightness) {
+
+ try {
+ settingBulbColorMutex.acquire();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+
+ _hue /= 360.0;
+ _saturation /= 100.0;
+ _brightness /= 100.0;
+
+
+ int newHue = (int)(_hue * 65535.0);
+ int newSaturation = (int)(_saturation * 65535.0);
+ int newBrightness = (int)(_brightness * 65535.0);
+
+ BulbColor newColor = new BulbColor(newHue, newSaturation, newBrightness, currentTemperature);
+ sendSetLightColorPacket(newColor, 250);
+
+ currentHue = newHue;
+ currentSaturation = newSaturation;
+ currentBrightness = newBrightness;
+ stateDidChange = true;
+
+ settingBulbColorMutex.release();
+ }
+
+
+ public void turnOff() {
+
+ try {
+ bulbStateMutex.acquire();
+ bulbIsOn = false;
+ sendSetLightPowerPacket(0, 0);
+ stateDidChange = true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ bulbStateMutex.release();
+ }
+
+ public void turnOn() {
+ try {
+ bulbStateMutex.acquire();
+ bulbIsOn = true;
+ sendSetLightPowerPacket(65535, 0);
+ stateDidChange = true;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+
+ bulbStateMutex.release();
+ }
+
+ public boolean getState() {
+
+ boolean tmp = false;
+ try {
+ bulbStateMutex.acquire();
+ tmp = bulbIsOn;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ bulbStateMutex.release();
+
+ return tmp;
+ }
+
+
+ /*******************************************************************************************************************************************
+ **
+ ** Communication Helpers
+ **
+ *******************************************************************************************************************************************/
+ private void recievedPacket(byte[] packetData) {
+
+ byte[] headerBytes = new byte[36];
+ for (int i = 0; i < 36; i++) {
+ headerBytes[i] = packetData[i];
+ }
+
+ LifxHeader recHeader = new LifxHeader();
+ recHeader.setFromBytes(headerBytes);
+
+ // load the payload bytes (strip away the header)
+ byte[] payloadBytes = new byte[recHeader.getSize()];
+ for (int i = 36; i < recHeader.getSize(); i++) {
+ payloadBytes[i - 36] = packetData[i];
+ }
+
+ System.out.println("Received: " + Integer.toString(recHeader.getType()));
+
+ switch (recHeader.getType()) {
+ case 3:
+ DeviceStateService dat = parseDeviceStateServiceMessage(recHeader, payloadBytes);
+ // System.out.println("Service: " + Integer.toString(dat.getService()));
+ // System.out.println("Port : " + Long.toString(dat.getPort()));
+ break;
+
+
+ case 33:
+ handleStateVersionMessageRecieved(recHeader, payloadBytes);
+ break;
+
+ case 35:
+ parseDeviceStateInfoMessage(recHeader, payloadBytes);
+ break;
+
+
+ case 107:
+ handleLightStateMessageRecieved(recHeader, payloadBytes);
+ break;
+
+ default:
+ // System.out.println("unknown packet Type");
+ }
+
+ }
+
+ private void sendPacket(byte[] packetData) {
+ // System.out.println("About to send");
+ sendSocketFlag = true;
+
+ try {
+ socketMutex.acquire();
+ } catch (InterruptedException e) {
+ System.out.println("mutex Error");
+ }
+
+ try {
+ communicationSockect.sendData(packetData);
+
+ } catch (IOException e) {
+ System.out.println("Socket Send Error");
+ }
+
+ sendSocketFlag = false;
+ socketMutex.release();
+ }
+
+
+ /**
+ * Worker function which runs the while loop for receiving data from the bulb.
+ * Is blocking
+ */
+ private void workerFunction() {
+ LifxHeader h = new LifxHeader();
+
+ try {
+ // Need timeout on receives since we are not sure if a packet will be available
+ // for processing so don't block waiting
+ communicationSockect.setSoTimeout(50);
+ } catch (IOException e) {
+ }
+
+ // Start the bulb in the off state
+ turnOff();
+
+
+ while (true) {
+
+ // Check if we got the bulb version yet
+ // could have requested it but message could have gotten lost (UDP)
+ if (!didGetBulbVersion.get()) {
+ long currentTime = (new Date().getTime()) / 1000;
+ if ((currentTime - lastSentGetBulbVersionRequest) > GET_BULB_VERSION_RESEND_WAIT_SECONDS) {
+ // Get the bulb version so we know what type of bulb this is.
+ sendGetVersionPacket();
+ lastSentGetBulbVersionRequest = currentTime;
+ }
+ }
+
+ // Communication resource is busy so try again later
+ if (sendSocketFlag) {
+ continue;
+ }
+
+ try {
+ socketMutex.acquire();
+ } catch (InterruptedException e) {
+ }
+
+ byte[] dat = null;
+ try {
+ dat = communicationSockect.recieveData(1024);
+ } catch (java.net.SocketTimeoutException e) {
+ // Timeout occurred
+
+ } catch (IOException e) {
+ // Problem but might be able to recover??
+ e.printStackTrace();
+
+ }
+
+ // Never forget to release!
+ socketMutex.release();
+
+ // A packed arrived
+ if (dat != null) {
+ recievedPacket(dat);
+ }
+
+ // If a state change occurred then request the bulb state to ensure that the
+ // bulb did indeed change its state to the correct state
+ if (stateDidChange) {
+ sendGetLightStatePacket();
+ }
+
+ // Wait a bit as to not tie up system resources
+ try {
+ Thread.sleep(100);
+ } catch (Exception e) {
+
+ }
+
+
+ }
+ }
+
+
+ public void init() {
+
+ if (didAlreadyInit.compareAndSet(false, true) == false) {
+ return; // already init
+ }
+
+ try {
+ // Get the bulb address from the IoTSet
+ Iterator itr = lb_addresses.iterator();
+ IoTDeviceAddress deviceAddress = (IoTDeviceAddress)itr.next();
+
+ System.out.println("Address: " + deviceAddress.getCompleteAddress());
+
+ // Create the communication channel
+ communicationSockect = new IoTUDP(deviceAddress);
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ // Launch the worker function in a separate thread.
+ workerThread = new Thread(new Runnable() {
+ public void run() {
+ workerFunction();
+ }
+ });
+ workerThread.start();
+
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/** Class LightBulb interface for the light bulb devices.
+ *
+ * @author Ali Younis <ayounis @ uci.edu>
+ * @version 1.0
+ * @since 2016-01-27
+ */
+
+
+public interface LightBulb {
+
+ /** Method to turn the light bulb on (Physically illuminate the area).
+ *
+ * @param None.
+ *
+ * @return [void] None.
+ */
+
+ public void turnOff();
+
+ /** Method to turn the light bulb off.
+ *
+ * @return [void] None.
+ */
+ public void turnOn();
+
+
+ /** Method to get the current on/off state of the light bulb.
+ *
+ * @return [boolean] True means bulb on.
+ */
+ public boolean getState();
+
+
+ /** Method to set the light bulb color using Standard Hue, Saturation and Brightness
+ * conventions. See "http://www.tydac.ch/color/" for reference.
+ *
+ * @param _hue [double]: Hue value (in degrees).
+ * @param _saturation [double]: Saturation value (percentage).
+ * @param _brightness [double]: Brightness value (percentage).
+ *
+ * @return [void] None.
+ */
+ public void setColor(double _hue, double _saturation, double _brightness);
+
+
+ /** Method to set the color temperature.
+ *
+ * @param _temperature [int]: Color temperature in degrees kelvin.
+ *
+ * @return [void] None.
+ */
+ public void setTemperature(int _temperature);
+
+
+ /** Method to get the current hue value of the bulb.
+ *
+ * @return [double] Current hue value of the bulb in degrees.
+ */
+ public double getHue();
+
+
+ /** Method to get the current saturation value of the bulb.
+ *
+ * @return [double] Current saturation value of the bulb as a percentage.
+ */
+ public double getSaturation();
+
+
+ /** Method to get the current brightness value of the bulb.
+ *
+ * @return [double] Current brightness value of the bulb as a percentage.
+ */
+ public double getBrightness();
+
+
+ /** Method to get the current color temperature value of the bulb.
+ *
+ * @return [double] Current color temperature value of the bulb in kelvin.
+ */
+ public int getTemperature();
+
+
+ /** Method to get the hue range lower bound supported by the bulb.
+ *
+ * @return [double] Hue lower bound in degrees.
+ */
+ public double getHueRangeLowerBound();
+
+
+ /** Method to get the hue range upper bound supported by the bulb.
+ *
+ * @return [double] Hue upper bound in degrees.
+ */
+ public double getHueRangeUpperBound();
+
+
+ /** Method to get the saturation range lower bound supported by the bulb.
+ *
+ * @return [double] Saturation lower bound as a percentage.
+ */
+ public double getSaturationRangeLowerBound();
+
+
+ /** Method to get the saturation range upper bound supported by the bulb.
+ *
+ * @return [double] Saturation upper bound as a percentage.
+ */
+ public double getSaturationRangeUpperBound();
+
+
+ /** Method to get the brightness range lower bound supported by the bulb.
+ *
+ * @return [double] Brightness lower bound as a percentage.
+ */
+ public double getBrightnessRangeLowerBound();
+
+
+ /** Method to get the brightness range upper bound supported by the bulb.
+ *
+ * @return [double] Brightness upper bound as a percentage.
+ */
+ public double getBrightnessRangeUpperBound();
+
+
+ /** Method to get the temperature range lower bound supported by the bulb.
+ *
+ * @return [int] Temperature lower bound as a percentage.
+ */
+ public int getTemperatureRangeLowerBound();
+
+
+ /** Method to get the temperature range upper bound supported by the bulb.
+ *
+ * @return [int] Temperature upper bound as a percentage.
+ */
+ public int getTemperatureRangeUpperBound();
+
+
+ /** Method to initialize the bulb, if the bulb needs to be initialized.
+ *
+ * @return [void] None.
+ */
+ public void init();
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+
+
+public class LightState {
+ private final BulbColor color;
+ private final int power;
+ private final String label;
+
+ public LightState(BulbColor _color, int _power, String _label) {
+ color = _color;
+ power = _power;
+ label = _label;
+ }
+
+ public BulbColor getColor() {
+ return color;
+ }
+
+ public int getPower() {
+ return power;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+}
--- /dev/null
+import iotcloud.*;
+import java.util.*;
+
+class LightsController {
+
+ public static void main(String[] args) throws Exception {
+
+ Table t1 = new Table("http://dc-6.calit2.uci.edu/test.iotcloud/", "reallysecret", 321, -1);
+ t1.rebuild();
+
+ // Bulb 1
+ byte[] bulbMacAdd1 = new byte[8];
+ bulbMacAdd1[0] = (byte)0xD0;
+ bulbMacAdd1[1] = (byte)0x73;
+ bulbMacAdd1[2] = (byte)0xD5;
+ bulbMacAdd1[3] = (byte)0x11;
+ bulbMacAdd1[4] = (byte)0x42;
+ bulbMacAdd1[5] = (byte)0xE5;
+ bulbMacAdd1[6] = (byte)0x00;
+ bulbMacAdd1[7] = (byte)0x00;
+
+ IoTDeviceAddress devAddr1 = new IoTDeviceAddress("192.168.1.4", 56700, 56700, false, false);
+ IoTUDP udp1 = new IoTUDP(devAddr1);
+ LightBulb bulb1 = new LifxLightBulb(udp1, bulbMacAdd1);
+
+
+
+ byte[] bulbMacAdd2 = new byte[8];
+ bulbMacAdd2[0] = (byte)0xD0;
+ bulbMacAdd2[1] = (byte)0x73;
+ bulbMacAdd2[2] = (byte)0xD5;
+ bulbMacAdd2[3] = (byte)0x12;
+ bulbMacAdd2[4] = (byte)0x8E;
+ bulbMacAdd2[5] = (byte)0x30;
+ bulbMacAdd2[6] = (byte)0x00;
+ bulbMacAdd2[7] = (byte)0x00;
+
+ IoTDeviceAddress devAddr2 = new IoTDeviceAddress("192.168.1.32", 56701, 56700, false, false);
+ IoTUDP udp2 = new IoTUDP(devAddr2);
+ LightBulb bulb2 = new LifxLightBulb(udp2, bulbMacAdd2);
+
+
+
+ byte[] bulbMacAdd3 = new byte[8];
+ bulbMacAdd3[0] = (byte)0xD0;
+ bulbMacAdd3[1] = (byte)0x73;
+ bulbMacAdd3[2] = (byte)0xD5;
+ bulbMacAdd3[3] = (byte)0x02;
+ bulbMacAdd3[4] = (byte)0x41;
+ bulbMacAdd3[5] = (byte)0xDA;
+ bulbMacAdd3[6] = (byte)0x00;
+ bulbMacAdd3[7] = (byte)0x00;
+
+ IoTDeviceAddress devAddr3 = new IoTDeviceAddress("192.168.1.33", 56702, 56700, false, false);
+ IoTUDP udp3 = new IoTUDP(devAddr3);
+ LightBulb bulb3 = new LifxLightBulb(udp3, bulbMacAdd3);
+
+
+ List<LightBulb> bulbs = new ArrayList<LightBulb>();
+ bulbs.add(bulb1);
+ bulbs.add(bulb2);
+ bulbs.add(bulb3);
+
+
+ String a1 = "bulb1";
+ String a2 = "bulb2";
+ String a3 = "bulb3";
+
+ IoTString ia1 = new IoTString(a1);
+ IoTString ia2 = new IoTString(a2);
+ IoTString ia3 = new IoTString(a3);
+
+
+ List<IoTString> keys = new ArrayList<IoTString>();
+ keys.add(ia1);
+ keys.add(ia2);
+ keys.add(ia3);
+
+
+ String valueA = "on";
+ IoTString iValueA = new IoTString(valueA);
+
+
+ String pingTimerKey = "bulbController";
+ IoTString ipingTimerKey = new IoTString(pingTimerKey);
+
+
+
+ System.out.println("Starting System");
+ int counter = 0;
+
+ while (true) {
+
+ try {
+
+ counter++;
+ if (counter == 10) {
+ counter = 0;
+
+ String pingTimer = Long.toString(System.currentTimeMillis());
+ IoTString ipingTimer = new IoTString(pingTimer);
+
+ t1.update();
+ t1.startTransaction();
+ t1.addKV(ipingTimerKey, ipingTimer);
+ t1.commitTransaction();
+ }
+
+
+ t1.update();
+ Thread.sleep(1000);
+
+ for (int i = 0; i < 3; i++) {
+ IoTString testValA1 = t1.getCommitted(keys.get(i));
+ if ((testValA1 != null) && (testValA1.equals(iValueA) == true)) {
+ bulbs.get(i).turnOn();
+ } else {
+ bulbs.get(i).turnOff();
+ }
+ }
+
+ } catch (Error e) {
+
+ for (int i = 0; i < 3; i++) {
+ bulbs.get(i).setColor(0, 100, 100);
+ }
+
+
+
+ while (true) {
+ for (int i = 0; i < 3; i++) {
+ bulbs.get(i).turnOff();
+ }
+ Thread.sleep(1000);
+
+ for (int i = 0; i < 3; i++) {
+ bulbs.get(i).turnOn();
+ }
+ Thread.sleep(1000);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+First build using:
+ ./build.bash
+
+To run this example run:
+
+ # Starts the light bulb controller
+ ./run1.bash
+
+ # Starts the fan controller
+ ./run3.bash
+
+
+ # For each switch you need to run (can launch as many of these as desired as long as input number is different)
+ ./run2.bash <a unique integer not equal to 321 or 351>
+
+
+Dont forget to clear the cloud server directory
+
+
+
+
+https://javatutorial.net/raspberry-pi-java-tutorial
\ No newline at end of file
--- /dev/null
+import iotcloud.*;
+import java.util.*;
+
+class Setup {
+
+ public static void main(String[] args) throws Exception {
+
+ Table t1 = new Table("http://dc-6.calit2.uci.edu/test.iotcloud/", "reallysecret", 300, -1);
+ t1.initTable();
+
+
+ String a1 = "bulb1";
+ String a2 = "bulb2";
+ String a3 = "bulb3";
+ IoTString ia1 = new IoTString(a1);
+ IoTString ia2 = new IoTString(a2);
+ IoTString ia3 = new IoTString(a3);
+
+
+
+ String b1 = "wemo1";
+ String b2 = "wemo2";
+ IoTString ib1 = new IoTString(b1);
+ IoTString ib2 = new IoTString(b2);
+
+
+ String pingTimerKey = "bulbController";
+ IoTString ipingTimerKey = new IoTString(pingTimerKey);
+
+
+ String pingTimerKey2 = "wemoController";
+ IoTString ipingTimerKey2 = new IoTString(pingTimerKey);
+
+
+ t1.createNewKey(ia1, 321);
+ t1.createNewKey(ia2, 321);
+ t1.createNewKey(ia3, 321);
+ t1.createNewKey(ipingTimerKey, 321);
+
+ t1.createNewKey(ib1, 351);
+ t1.createNewKey(ib2, 351);
+ t1.createNewKey(ipingTimerKey2, 351);
+
+ t1.update();
+ }
+}
\ No newline at end of file
--- /dev/null
+// IoT Packages
+
+//import iotcode.annotation.*;
+
+// Native Java Packages
+import java.util.Iterator;
+import javax.xml.parsers.*;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import org.w3c.dom.*;
+import org.xml.sax.SAXException;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.Semaphore;
+import java.util.List;
+import java.util.ArrayList;
+
+public class Wemo {
+
+ private IoTDeviceAddress deviceAddress = null;
+
+ public Wemo(IoTDeviceAddress _deviceAddress) {
+ deviceAddress = _deviceAddress;
+
+ }
+
+ public void turnOff() throws IOException {
+ IoTHTTP httpConnection = null;
+ try {
+ httpConnection = new IoTHTTP(deviceAddress);
+ httpConnection.setURL("/upnp/control/basicevent1");
+
+ httpConnection.openConnection();
+ httpConnection.setDoOutput(true);
+ httpConnection.setRequestMethod("POST");
+ httpConnection.setRequestProperty("Connection", "close");
+ httpConnection.setRequestProperty("Content-type", "text/xml; charset=\"utf-8\"");
+ httpConnection.setRequestProperty("SOAPACTION", "\"urn:Belkin:service:basicevent:1#SetBinaryState\"");
+
+ httpConnection.setRequestProperty("User-Agent", "Java/1.8.0");
+ httpConnection.setRequestProperty("Host", "\"192.168.1.5:49153");
+ httpConnection.setRequestProperty("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2");
+
+ String reqXML = "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:SetBinaryState xmlns:u=\"urn:Belkin:service:basicevent:1\"><BinaryState>0</BinaryState></u:SetBinaryState></s:Body></s:Envelope>\n";
+
+ OutputStream reqStream = httpConnection.getOutputStream();
+ reqStream.write(reqXML.getBytes());
+
+ InputStream resStream = httpConnection.getInputStream();
+ byte[] byteBuf = new byte[10240];
+ int len = resStream.read(byteBuf);
+
+ reqStream.close();
+ resStream.close();
+
+
+ } finally {
+ if (httpConnection != null) {
+ try {
+ httpConnection.disconnect();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ }
+ }
+ }
+
+ }
+
+ public void turnOn() throws IOException {
+ IoTHTTP httpConnection = null;
+ try {
+ httpConnection = new IoTHTTP(deviceAddress);
+ httpConnection.setURL("/upnp/control/basicevent1");
+
+ httpConnection.openConnection();
+ httpConnection.setDoOutput(true);
+ httpConnection.setRequestMethod("POST");
+ httpConnection.setRequestProperty("Content-type", "text/xml; charset=\"utf-8\"");
+ httpConnection.setRequestProperty("SOAPACTION", "\"urn:Belkin:service:basicevent:1#SetBinaryState\"");
+ httpConnection.setRequestProperty("Accept", "");
+
+ String reqXML = "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:SetBinaryState xmlns:u=\"urn:Belkin:service:basicevent:1\"><BinaryState>1</BinaryState></u:SetBinaryState></s:Body></s:Envelope>\n";
+
+ OutputStream reqStream = httpConnection.getOutputStream();
+ reqStream.write(reqXML.getBytes());
+
+ InputStream resStream = httpConnection.getInputStream();
+ byte[] byteBuf = new byte[10240];
+ int len = resStream.read(byteBuf);
+
+ reqStream.close();
+ resStream.close();
+
+ } finally {
+ if (httpConnection != null) {
+ try {
+ httpConnection.disconnect();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+import iotcloud.*;
+import java.util.*;
+
+
+class WemoController {
+ public static void main(String[] args) throws Exception {
+
+ Table t1 = new Table("http://dc-6.calit2.uci.edu/test.iotcloud/", "reallysecret", 351, -1);
+ t1.rebuild();
+
+
+ String a = "fan";
+ IoTString ia = new IoTString(a);
+ t1.createNewKey(ia, 351);
+
+
+ String a1 = "wemo1";
+ String a2 = "wemo2";
+
+ IoTString ia1 = new IoTString(a1);
+ IoTString ia2 = new IoTString(a2);
+
+
+ List<IoTString> keys = new ArrayList<IoTString>();
+ keys.add(ia1);
+ keys.add(ia2);
+
+
+ IoTDeviceAddress devAddr1 = new IoTDeviceAddress("192.168.1.16", 49153, 49153, false, false);
+ Wemo wemo1 = new Wemo(devAddr1);
+
+ IoTDeviceAddress devAddr2 = new IoTDeviceAddress("192.168.1.34", 49154, 49153, false, false);
+ Wemo wemo2 = new Wemo(devAddr2);
+
+ List<Wemo> wemos = new ArrayList<Wemo>();
+ wemos.add(wemo1);
+ wemos.add(wemo2);
+
+
+ String pingTimerKey = "wemoController";
+ IoTString ipingTimerKey = new IoTString(pingTimerKey);
+
+
+ String valueA = "on";
+ IoTString iValueA = new IoTString(valueA);
+
+ System.out.println("Starting System");
+ int counter = 0;
+
+
+ while (true) {
+ try {
+ counter++;
+ if (counter == 10) {
+ counter = 0;
+
+ String pingTimer = Long.toString(System.currentTimeMillis());
+ IoTString ipingTimer = new IoTString(pingTimer);
+
+ t1.update();
+ t1.startTransaction();
+ t1.addKV(ipingTimerKey, ipingTimer);
+ t1.commitTransaction();
+ }
+
+
+ t1.update();
+ Thread.sleep(1000);
+
+ for (int i = 0; i < 2; i++) {
+ IoTString testValA1 = t1.getCommitted(keys.get(i));
+ if ((testValA1 != null) && (testValA1.equals(iValueA) == true)) {
+ wemos.get(i).turnOn();
+ } else {
+ wemos.get(i).turnOff();
+ }
+ }
+
+ } catch (Error e) {
+
+ Runtime runTime = Runtime.getRuntime();
+ runTime.exec("gpio mode 4 out");
+
+
+ while (true) {
+ runTime.exec("gpio write 4 1");
+ Thread.sleep(500);
+ runTime.exec("gpio write 4 0");
+ Thread.sleep(500);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+#!/bin/sh
+
+# javac -cp .:/Users/Ali/Desktop/iotcloud/version2/src/java/iotcloud/bin *.java
+
+javac -cp .:../iotcloud/bin *.java
\ No newline at end of file
--- /dev/null
+#!/bin/sh
+
+java -cp .:../iotcloud/bin LightsController
\ No newline at end of file
--- /dev/null
+#!/bin/sh
+
+java -cp .:../iotcloud/bin WemoController
\ No newline at end of file
--- /dev/null
+#!/bin/sh
+
+java -cp .:../iotcloud/bin WemoController
\ No newline at end of file
--- /dev/null
+#!/bin/sh
+
+java -cp .:../iotcloud/bin Setup
\ No newline at end of file