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