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