Adjustments to ZigbeeTest and Python files to use just 1 port for shooting Zigbee...
[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         @config private IoTSet<IoTDeviceAddress> devUdpAddress;
42         @config private IoTSet<IoTZigbeeAddress> devZigbeeAddress;
43
44         public MotionSensor(IoTSet<IoTDeviceAddress> dSet, IoTSet<IoTZigbeeAddress> zigSet) {
45                 devUdpAddress = dSet;
46                 devZigbeeAddress = zigSet;
47         }
48
49         public void init() {
50
51                 if (didAlreadyInit.compareAndSet(false, true) == false) {
52                         return; // already init
53                 }
54
55                 didAlreadyClose.set(false);
56
57                 try {
58                         Iterator itrUdp = devUdpAddress.iterator();
59                         Iterator itrZig = devZigbeeAddress.iterator();
60
61                         zigConnection = new IoTZigbee((IoTDeviceAddress)itrUdp.next(), (IoTZigbeeAddress)itrZig.next());
62
63                         // DEBUG
64                         System.out.println("DEBUG: Allocate iterators to print out addresses!");
65                         Iterator itrDebugUdp = devUdpAddress.iterator();
66                         IoTDeviceAddress iotaddDebug = (IoTDeviceAddress)itrDebugUdp.next();
67                         System.out.println("IP address: " + iotaddDebug.getCompleteAddress());
68                         System.out.println("Source port: " + iotaddDebug.getSourcePortNumber());
69                         System.out.println("Destination port: " + iotaddDebug.getDestinationPortNumber());
70
71                         Iterator itrDebugZig = devZigbeeAddress.iterator();
72                         IoTZigbeeAddress iotzbaddDebug = (IoTZigbeeAddress)itrDebugZig.next();
73                         System.out.println("Zigbee address: " + iotzbaddDebug.getAddress());
74
75                         zigConnection.registerCallback(this);
76                         System.out.println("Register callback!");
77                         zigConnection.init();
78                         System.out.println("Initialized!");
79
80                         //made by changwoo
81                         sleep(10);
82
83                         System.out.println("Sending Management Permit Joining Request");
84                         for(int z=0; z<3; z++){
85                                 zigConnection.sendManagementPermitJoiningRequest(0x0001, 0x0036, 0x00);
86                                 sleep(0);
87                         }
88                         
89                         //made by changwoo
90                         while (!didWriteAttrb.get()) {
91                                 System.out.println("Sending Write Attribute Request");
92                                 zigConnection.sendWriteAttributesCommand(0x0002, 0x0500, 0x0104, 0x01);
93                                 sleep(0);
94                         }
95
96                         //made by changwoo
97                         System.out.println("Sending Enrollment Reponse");
98                         zigConnection.sendEnrollmentResponse(0x0003, 0x0500, 0x0104, 0x01);
99                         sleep(0);
100
101                 } catch (Exception e) {
102                         e.printStackTrace();
103                 }
104         }
105
106         //made by changwoo
107         private void sleep(int multipleTime){
108                 if(multipleTime<=0){
109                         multipleTime=1;
110                 }
111                 try{
112                         Thread.sleep(TIMEOUT_FOR_RESEND_MSEC*multipleTime);
113                 } catch(Exception e){
114                         e.printStackTrace();
115                 }
116         }
117
118         public void close() {
119
120                 if (didAlreadyClose.compareAndSet(false, true) == false) {
121                         return; // already init
122                 }
123
124                 didAlreadyInit.set(false);
125
126
127                 try {
128                         zigConnection.close();
129                 } catch (Exception e) {
130                         e.printStackTrace();
131                 }
132         }
133
134
135         public void Finalize() {
136                 if (!didClose) {
137                         close();
138                 }
139         }
140
141         public int getValue() {
142
143                 int tmp = 0;
144                 try {
145                         gettingLatestDataMutex.acquire();
146                         tmp = detectedValue;
147
148                 } catch (Exception e) {
149                         e.printStackTrace();
150                 }
151                 gettingLatestDataMutex.release();
152
153                 return tmp;
154         }
155
156         // MotionSensor: 
157         // - 24 = no motion = false
158         // - 26 = motion = true
159         // After getting 26, if there is no motion for ~12 seconds then we get back 24
160         public boolean isActiveValue() {
161
162                 int tmp = getValue();
163                 if (tmp == 26)
164                         detectStatus = true;
165                 else // Getting 24 here
166                         detectStatus = false;
167
168                 return detectStatus;
169         }
170
171         public long getTimestampOfLastReading() {
172
173                 Date tmp = null;
174                 try {
175                         gettingLatestDataMutex.acquire();
176                         tmp = (Date)timestampOfLastDetecting.clone();
177
178                 } catch (Exception e) {
179                         e.printStackTrace();
180                 }
181                 gettingLatestDataMutex.release();
182                 long retLong = tmp.getTime();
183
184                 return retLong;
185         }
186
187         public void newMessageAvailable(IoTZigbeeMessage _zm) {
188
189                 //made by changwoo
190                 if(_zm instanceof IoTZigbeeMessageZclZoneStatusChangeNotification){
191                         IoTZigbeeMessageZclZoneStatusChangeNotification message = (IoTZigbeeMessageZclZoneStatusChangeNotification)_zm;
192                         if(message.getSuccessOrFail()){
193                                 //do something!
194
195                                 try {
196                                         gettingLatestDataMutex.acquire();
197                                         detectedValue = message.getStatus();
198                                         timestampOfLastDetecting = new Date();
199                                 } catch (Exception e) {
200                                         e.printStackTrace();
201                                 }
202                                 gettingLatestDataMutex.release();
203                                 try {
204                                         for (SmartthingsSensorCallback cb : callbackList) {
205                                                 cb.newReadingAvailable(this.getValue(), this.isActiveValue());
206                                         }
207                                 } catch (Exception e) {
208                                         e.printStackTrace();
209                                 }
210                         }//if
211                 
212                 //made by changwoo
213                 } else if (_zm instanceof IoTZigbeeMessageZclWriteAttributesResponse) {
214                         IoTZigbeeMessageZclWriteAttributesResponse message = (IoTZigbeeMessageZclWriteAttributesResponse)_zm;
215                         if (message.getSuccessOrFail()) {
216                                 didWriteAttrb.set(true);
217                         }
218                 }
219         }
220
221         public void registerCallback(SmartthingsSensorCallback _callbackTo) {
222                 callbackList.add(_callbackTo);
223         }
224 }