1 //package iotcode.OutletSensor;
3 // Standard Java Packages
5 import java.util.concurrent.atomic.AtomicBoolean;
6 import java.util.concurrent.CopyOnWriteArrayList;
7 import java.util.concurrent.Semaphore;
10 //import iotchecker.qual.*;
11 import iotcode.annotation.*;
14 import iotruntime.slave.*;
15 import iotcode.interfaces.*;
16 import iotruntime.zigbee.*;
18 /** Class Smartthings sensor driver for Smartthings sensor devices.
20 * @author Changwoo Lee, Rahmadi Trimananda <rtrimana @ uci.edu>
24 public class OutletSensor implements IoTZigbeeCallback, SmartthingsSensor {
26 private final int TIMEOUT_FOR_RESEND_MSEC = 900;
28 private IoTZigbee zigConnection = null;
30 private float Watts = 0;
31 private boolean didClose; // make sure that the clean up was done correctly
32 //private boolean detectStatus = false;
34 //private int detectedValue = 0;
35 private Date timestampOfLastDetecting = null;
37 private AtomicBoolean didAlreadyClose = new AtomicBoolean(true);
38 private AtomicBoolean didAlreadyInit = new AtomicBoolean(false);
39 private AtomicBoolean didWriteAttrb = new AtomicBoolean(false);
40 //private AtomicBoolean didMatchDscr = new AtomicBoolean(false);
41 private AtomicBoolean didBind = new AtomicBoolean(false);/////////yuting
42 private AtomicBoolean didConfigureReporting = new AtomicBoolean(false);/////////////yuting
43 static Semaphore gettingLatestDataMutex = new Semaphore(1);
45 private List < SmartthingsSensorCallback > callbackList = new CopyOnWriteArrayList < SmartthingsSensorCallback > ();
47 private int sensorId = 0;
49 @config private IoTSet<IoTDeviceAddress> OutletSensorUdpAddress; //
50 @config private IoTSet<IoTZigbeeAddress> OutletSensorZigbeeAddress;//
52 public OutletSensor(IoTSet<IoTDeviceAddress> dSet, IoTSet<IoTZigbeeAddress> zigSet) {
53 OutletSensorUdpAddress = dSet;
54 OutletSensorZigbeeAddress = zigSet;
57 public OutletSensor() {
62 if (didAlreadyInit.compareAndSet(false, true) == false) {
63 return; // already init
66 didAlreadyClose.set(false);
69 Iterator itrUdp = OutletSensorUdpAddress.iterator();
70 Iterator itrZig = OutletSensorZigbeeAddress.iterator();
72 zigConnection = new IoTZigbee((IoTDeviceAddress)itrUdp.next(), (IoTZigbeeAddress)itrZig.next());
75 System.out.println("DEBUG: Allocate iterators to print out addresses!");
76 Iterator itrDebugUdp = OutletSensorUdpAddress.iterator();
77 IoTDeviceAddress iotaddDebug = (IoTDeviceAddress)itrDebugUdp.next();
78 System.out.println("IP address: " + iotaddDebug.getCompleteAddress());
79 System.out.println("Source port: " + iotaddDebug.getSourcePortNumber());
80 System.out.println("Destination port: " + iotaddDebug.getDestinationPortNumber());
82 Iterator itrDebugZig = OutletSensorZigbeeAddress.iterator();
83 IoTZigbeeAddress iotzbaddDebug = (IoTZigbeeAddress)itrDebugZig.next();
84 System.out.println("Zigbee address: " + iotzbaddDebug.getAddress());
86 zigConnection.registerCallback(this);
87 System.out.println("Register callback!");
89 System.out.println("Initialized!");
95 //System.out.println("Sending BroadcastingRouteRecordRequest");
96 //zigConnection.sendBroadcastingRouteRecordRequest(0x0001);
99 System.out.println("Sending Management Permit Joining Request");
100 for(int z=0; z<3; z++){
101 zigConnection.sendManagementPermitJoiningRequest(0x0002, 0x0036, 0x00);
106 while(!didBind.get()){
107 System.out.println("Sending Bind Request");
108 zigConnection.sendBindRequest(0x0003,0x0B04, 0x01);// 0x0021, 0x00);// 0x0B04, 0x01);
114 while(!didConfigureReporting.get()){
115 System.out.println("Sending Configure Reporting");
116 byte [] reportableChange= {0x0005};
117 zigConnection.sendConfigureReportingCommand(0x0004, 0x0B04, 0x0104, 0x01, 0x050b, 0x29, 0x0001, 0x0500, reportableChange);
123 } catch (Exception e) {
129 private void sleep(int multipleTime){
134 Thread.sleep(TIMEOUT_FOR_RESEND_MSEC*multipleTime);
135 } catch(Exception e){
140 public float getWatts() {
144 gettingLatestDataMutex.acquire();
147 } catch (Exception e) {
150 gettingLatestDataMutex.release();
155 public void TurnOn(){
157 System.out.println("the outlet sensor is turning on");
158 zigConnection.sendChangeSwtichRequest(0x0005, 0x0006, 0x0104, 1, 0x01);
159 } catch(Exception e){
164 public void TurnOff(){
166 System.out.println("the outlet sensor is turning off");
167 zigConnection.sendChangeSwtichRequest(0x0005, 0x0006, 0x0104, 0, 0x01);
168 } catch(Exception e){
173 public void close() {
175 if (didAlreadyClose.compareAndSet(false, true) == false) {
176 return; // already init
179 didAlreadyInit.set(false);
183 zigConnection.close();
184 } catch (Exception e) {
189 public void Finalize() {
195 public void setId(int id) {
208 public long getTimestampOfLastReading() {
212 gettingLatestDataMutex.acquire();
213 tmp = (Date)timestampOfLastDetecting.clone();
215 } catch (Exception e) {
218 gettingLatestDataMutex.release();
219 long retLong = tmp.getTime();
224 public void newMessageAvailable(IoTZigbeeMessage _zm) {
227 if (_zm instanceof IoTZigbeeMessageZdoBindResponse) {
228 IoTZigbeeMessageZdoBindResponse message = (IoTZigbeeMessageZdoBindResponse)_zm;
229 if (message.getSucceeded()) {
234 else if (_zm instanceof IoTZigbeeMessageZclConfigureReportingResponse){
235 IoTZigbeeMessageZclConfigureReportingResponse message = (IoTZigbeeMessageZclConfigureReportingResponse)_zm;
236 if (message.getAllSuccess()) {
237 didConfigureReporting.set(true);
241 else if (_zm instanceof IoTZigbeeMessageZclChangeSwitchResponse){
242 IoTZigbeeMessageZclChangeSwitchResponse message = (IoTZigbeeMessageZclChangeSwitchResponse)_zm;
243 if (message.getSuccessOrFail()) {
244 if (message.getStatus()==1){
245 System.out.println("change on/off response: turned on");
246 //System.out.println(message.getStatus());
248 else if(message.getStatus()==0){
249 System.out.println("change on/off response: turned off");
254 else if (_zm instanceof IoTZigbeeMessageZclReportAttributes) {
255 IoTZigbeeMessageZclReportAttributes message = (IoTZigbeeMessageZclReportAttributes)_zm;
256 List <IoTZigbeeMessageZclReportAttributes.Attribute> attrList = message.getAttributes();
258 if (attrList.size() == 1) {
259 if(attrList.get(0).getAttributeId() == 2821) {
260 byte[] data = attrList.get(0).getData();
261 int value = (data[0] * 256) + data[1];
264 gettingLatestDataMutex.acquire();
265 Watts = (float)value;
266 timestampOfLastDetecting = new Date();
267 } catch (Exception e) {
270 gettingLatestDataMutex.release();
273 for (SmartthingsSensorCallback cb : callbackList) {
274 cb.newReadingAvailable(this);
276 } catch (Exception e) {
284 //public void registerCallback(SmartthingsSensorSmartCallback _callbackTo) {
285 public void registerCallback(SmartthingsSensorCallback _callbackTo) {
286 callbackList.add(_callbackTo);