68dfe29d9def4914971e7842d4257a9c4415a0e5
[iot2.git] / benchmarks / other / ZigbeeTest / MotionSensor.java
1 // Standard Java Packages
2 import java.util.*;
3 import java.util.concurrent.atomic.AtomicBoolean;
4 import java.util.concurrent.CopyOnWriteArrayList;
5 import java.util.concurrent.Semaphore;
6
7 // Checker annotations
8 //import iotchecker.qual.*;
9 //import iotcode.annotation.*;
10
11 // IoT Packages
12 import iotruntime.slave.*;
13 //import iotcode.interfaces.*;
14 import iotruntime.zigbee.*;
15
16 /** Class Smartthings sensor driver for Smartthings sensor devices.
17  *
18  * @author      Changwoo Lee, Rahmadi Trimananda <rtrimana @ uci.edu>
19  * @version     1.0
20  * @since       2016-12-01
21  */
22 public class MotionSensor implements IoTZigbeeCallback, SmartthingsSensor {
23
24         private final int TIMEOUT_FOR_RESEND_MSEC = 900;
25
26         private IoTZigbee zigConnection = null;
27         private boolean didClose; // make sure that the clean up was done correctly
28         private boolean detectStatus = false;
29
30         private int detectedValue = 0;
31         private Date timestampOfLastDetecting = null;
32
33         private AtomicBoolean didAlreadyClose = new AtomicBoolean(true);
34         private AtomicBoolean didAlreadyInit = new AtomicBoolean(false);
35         private AtomicBoolean didWriteAttrb = new AtomicBoolean(false);
36         private AtomicBoolean didMatchDscr = new AtomicBoolean(false);
37         static Semaphore gettingLatestDataMutex = new Semaphore(1);
38
39         private List < SmartthingsSensorCallback > callbackList = new CopyOnWriteArrayList < SmartthingsSensorCallback > ();
40
41         private int sensorId = 0;
42
43         @config private IoTSet<IoTDeviceAddress> devUdpAddress;
44         @config private IoTSet<IoTZigbeeAddress> devZigbeeAddress;
45
46         public MotionSensor(IoTSet<IoTDeviceAddress> dSet, IoTSet<IoTZigbeeAddress> zigSet) {
47                 devUdpAddress = dSet;
48                 devZigbeeAddress = zigSet;
49         }
50
51         public void init() {
52
53                 if (didAlreadyInit.compareAndSet(false, true) == false) {
54                         return; // already init
55                 }
56
57                 didAlreadyClose.set(false);
58
59                 try {
60                         Iterator itrUdp = devUdpAddress.iterator();
61                         Iterator itrZig = devZigbeeAddress.iterator();
62
63                         zigConnection = new IoTZigbee((IoTDeviceAddress)itrUdp.next(), (IoTZigbeeAddress)itrZig.next());
64
65                         // DEBUG
66                         System.out.println("DEBUG: Allocate iterators to print out addresses!");
67                         Iterator itrDebugUdp = devUdpAddress.iterator();
68                         IoTDeviceAddress iotaddDebug = (IoTDeviceAddress)itrDebugUdp.next();
69                         System.out.println("IP address: " + iotaddDebug.getCompleteAddress());
70                         System.out.println("Source port: " + iotaddDebug.getSourcePortNumber());
71                         System.out.println("Destination port: " + iotaddDebug.getDestinationPortNumber());
72
73                         Iterator itrDebugZig = devZigbeeAddress.iterator();
74                         IoTZigbeeAddress iotzbaddDebug = (IoTZigbeeAddress)itrDebugZig.next();
75                         System.out.println("Zigbee address: " + iotzbaddDebug.getAddress());
76
77                         zigConnection.registerCallback(this);
78                         System.out.println("Register callback!");
79                         zigConnection.init();
80                         System.out.println("Initialized!");
81
82                         //made by changwoo
83                         sleep(10);
84
85                         System.out.println("Sending Management Permit Joining Request");
86                         for(int z=0; z<3; z++){
87                                 zigConnection.sendManagementPermitJoiningRequest(0x0001, 0x0036, 0x00);
88                                 sleep(0);
89                         }
90                         
91                         //made by changwoo
92                         while (!didWriteAttrb.get()) {
93                                 System.out.println("Sending Write Attribute Request");
94                                 zigConnection.sendWriteAttributesCommand(0x0002, 0x0500, 0x0104, 0x01);
95                                 sleep(0);
96                         }
97
98                         //made by changwoo
99                         System.out.println("Sending Enrollment Reponse");
100                         zigConnection.sendEnrollmentResponse(0x0003, 0x0500, 0x0104, 0x01);
101                         sleep(0);
102
103                 } catch (Exception e) {
104                         e.printStackTrace();
105                 }
106         }
107
108         //made by changwoo
109         private void sleep(int multipleTime){
110                 if(multipleTime<=0){
111                         multipleTime=1;
112                 }
113                 try{
114                         Thread.sleep(TIMEOUT_FOR_RESEND_MSEC*multipleTime);
115                 } catch(Exception e){
116                         e.printStackTrace();
117                 }
118         }
119
120         public void close() {
121
122                 if (didAlreadyClose.compareAndSet(false, true) == false) {
123                         return; // already init
124                 }
125
126                 didAlreadyInit.set(false);
127
128
129                 try {
130                         zigConnection.close();
131                 } catch (Exception e) {
132                         e.printStackTrace();
133                 }
134         }
135
136
137         public void Finalize() {
138                 if (!didClose) {
139                         close();
140                 }
141         }
142
143         public void setId(int id) {
144
145                 sensorId = id;
146
147         }
148
149         public int getId() {
150
151                 return sensorId;
152
153         }
154
155         public int getValue() {
156
157                 int tmp = 0;
158                 try {
159                         gettingLatestDataMutex.acquire();
160                         tmp = detectedValue;
161
162                 } catch (Exception e) {
163                         e.printStackTrace();
164                 }
165                 gettingLatestDataMutex.release();
166
167                 return tmp;
168         }
169
170         // MotionSensor: 
171         // - 24 = no motion = false
172         // - 26 = motion = true
173         // After getting 26, if there is no motion for ~12 seconds then we get back 24
174         public boolean isActiveValue() {
175
176                 int tmp = getValue();
177                 if (tmp == 26)
178                         detectStatus = true;
179                 else // Getting 24 here
180                         detectStatus = false;
181
182                 return detectStatus;
183         }
184
185         public long getTimestampOfLastReading() {
186
187                 Date tmp = null;
188                 try {
189                         gettingLatestDataMutex.acquire();
190                         tmp = (Date)timestampOfLastDetecting.clone();
191
192                 } catch (Exception e) {
193                         e.printStackTrace();
194                 }
195                 gettingLatestDataMutex.release();
196                 long retLong = tmp.getTime();
197
198                 return retLong;
199         }
200
201         public void newMessageAvailable(IoTZigbeeMessage _zm) {
202
203                 //made by changwoo
204                 if(_zm instanceof IoTZigbeeMessageZclZoneStatusChangeNotification){
205                         IoTZigbeeMessageZclZoneStatusChangeNotification message = (IoTZigbeeMessageZclZoneStatusChangeNotification)_zm;
206                         if(message.getSuccessOrFail()){
207                                 //do something!
208
209                                 try {
210                                         gettingLatestDataMutex.acquire();
211                                         detectedValue = message.getStatus();
212                                         timestampOfLastDetecting = new Date();
213                                 } catch (Exception e) {
214                                         e.printStackTrace();
215                                 }
216                                 gettingLatestDataMutex.release();
217                                 try {
218                                         for (SmartthingsSensorCallback cb : callbackList) {
219                                                 cb.newReadingAvailable(this.getId(), this.getValue(), this.isActiveValue());
220                                         }
221                                 } catch (Exception e) {
222                                         e.printStackTrace();
223                                 }
224                         }//if
225                 
226                 //made by changwoo
227                 } else if (_zm instanceof IoTZigbeeMessageZclWriteAttributesResponse) {
228                         IoTZigbeeMessageZclWriteAttributesResponse message = (IoTZigbeeMessageZclWriteAttributesResponse)_zm;
229                         if (message.getSuccessOrFail()) {
230                                 didWriteAttrb.set(true);
231                         }
232                 }
233         }
234
235         public void registerCallback(SmartthingsSensorCallback _callbackTo) {
236                 callbackList.add(_callbackTo);
237         }
238 }