1 package iotcode.DoorlockSensor;
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 DoorlockSensor implements IoTZigbeeCallback, SmartthingsSensor {
26 private final int TIMEOUT_FOR_RESEND_MSEC = 900;
28 private IoTZigbee zigConnection = null;
29 private boolean didClose; // make sure that the clean up was done correctly
30 private boolean detectStatus = false;
32 private int detectedValue = 0;
33 private Date timestampOfLastDetecting = null;
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 private AtomicBoolean didBind = new AtomicBoolean(false);
40 private AtomicBoolean didDoorLockConfigureReporting = new AtomicBoolean(false); //made by Jiawei
41 static Semaphore gettingLatestDataMutex = new Semaphore(1);
43 private List < SmartthingsSensorSmartCallback > callbackList = new CopyOnWriteArrayList < SmartthingsSensorSmartCallback > ();
45 private int sensorId = 0;
47 @config private IoTSet<IoTDeviceAddress> DoorlockSensorUdpAddress;
48 @config private IoTSet<IoTZigbeeAddress> DoorlockSensorZigbeeAddress;
50 public DoorlockSensor(IoTSet<IoTDeviceAddress> dSet, IoTSet<IoTZigbeeAddress> zigSet) {
51 DoorlockSensorUdpAddress = dSet;
52 DoorlockSensorZigbeeAddress = zigSet;
55 public DoorlockSensor() {
60 if (didAlreadyInit.compareAndSet(false, true) == false) {
61 return; // already init
64 didAlreadyClose.set(false);
67 Iterator itrUdp = DoorlockSensorUdpAddress.iterator();
68 Iterator itrZig = DoorlockSensorZigbeeAddress.iterator();
70 zigConnection = new IoTZigbee((IoTDeviceAddress)itrUdp.next(), (IoTZigbeeAddress)itrZig.next());
73 System.out.println("DEBUG: Allocate iterators to print out addresses!");
74 Iterator itrDebugUdp = DoorlockSensorUdpAddress.iterator();
75 IoTDeviceAddress iotaddDebug = (IoTDeviceAddress)itrDebugUdp.next();
76 System.out.println("IP address: " + iotaddDebug.getCompleteAddress());
77 System.out.println("Source port: " + iotaddDebug.getSourcePortNumber());
78 System.out.println("Destination port: " + iotaddDebug.getDestinationPortNumber());
80 Iterator itrDebugZig = DoorlockSensorZigbeeAddress.iterator();
81 IoTZigbeeAddress iotzbaddDebug = (IoTZigbeeAddress)itrDebugZig.next();
82 System.out.println("Zigbee address: " + iotzbaddDebug.getAddress());
84 zigConnection.registerCallback(this);
85 System.out.println("Register callback!");
87 System.out.println("Initialized!");
94 // System.out.println("BroadcastingRouteRecordRequest ");
95 // zigConnection.sendBroadcastingRouteRecordRequest(0x0001);
98 System.out.println("Sending Management Permit Joining Request");
99 // for(int z=0; z<3; z++){
100 zigConnection.sendManagementPermitJoiningRequest(0x0002, 0x0036, 0x00);
105 while(!didBind.get()){
106 System.out.println("Sending Bind Request");
107 zigConnection.sendBindRequest(0x0003, 0x0101, 0x02);
111 while(!didDoorLockConfigureReporting.get()){
112 System.out.println("Sending Door Lock: Configure Reporting");
113 zigConnection.sendConfigureReportingCommand(0x0004, 0x0101, 0x0104, 0x01, 0x02, 0x0000, 0x30, 0x0000, 0x100E, null);
118 Scanner in = new Scanner(System.in);
119 System.out.println("\nUnlock door: 0");
120 System.out.println("Lock door: 1");
121 System.out.println("Read status: 2 (or anything else)");
122 String str = in.next();
123 if(str.equals("1")) {
124 System.out.println("the doorlock sensor is locking");
125 zigConnection.sendLockOrUnlockDoorRequest(0x0005, 0x0101, 0x0104, 0x02, 0);
127 }else if(str.equals("0")){
128 System.out.println("the doorlock sensor is unlocking");
129 zigConnection.sendLockOrUnlockDoorRequest(0x0005, 0x0101, 0x0104, 0x02, 1);
132 System.out.println("Let's see the doorlock sensor's status currently");
133 zigConnection.sendReadDoorStatusRequest(0x0005, 0x0101, 0x0104, 0x02, 0x10, 0x00, 0x0000);
139 } catch (Exception e) {
145 private void sleep(int multipleTime){
150 Thread.sleep(TIMEOUT_FOR_RESEND_MSEC*multipleTime);
151 } catch(Exception e){
157 //public int getStatus() {
158 public int getValue() {
162 gettingLatestDataMutex.acquire();
165 } catch (Exception e) {
168 gettingLatestDataMutex.release();
173 public boolean isActiveValue() {
175 int tmp = getValue();
177 detectStatus = true; // Door is locked
179 detectStatus = false; // Door is not locked/not fully locked
183 public void close() {
185 if (didAlreadyClose.compareAndSet(false, true) == false) {
186 return; // already init
189 didAlreadyInit.set(false);
193 zigConnection.close();
194 } catch (Exception e) {
199 public void Finalize() {
205 public void setId(int id) {
218 public long getTimestampOfLastReading() {
222 gettingLatestDataMutex.acquire();
223 tmp = (Date)timestampOfLastDetecting.clone();
225 } catch (Exception e) {
228 gettingLatestDataMutex.release();
229 long retLong = tmp.getTime();
234 public void newMessageAvailable(IoTZigbeeMessage _zm) {
237 if (_zm instanceof IoTZigbeeMessageZdoBindResponse) {
238 IoTZigbeeMessageZdoBindResponse message = (IoTZigbeeMessageZdoBindResponse)_zm;
239 if (message.getSucceeded()) {
243 else if (_zm instanceof IoTZigbeeMessageZclConfigureReportingResponse){
244 IoTZigbeeMessageZclConfigureReportingResponse message = (IoTZigbeeMessageZclConfigureReportingResponse)_zm;
245 if (message.getAllSuccess()) {
246 didDoorLockConfigureReporting.set(true);
249 else if (_zm instanceof IoTZigbeeMessageZclReadAttributesResponse) {
250 IoTZigbeeMessageZclReadAttributesResponse message = (IoTZigbeeMessageZclReadAttributesResponse)_zm;
251 List <IoTZigbeeMessageZclReadAttributesResponse.Attribute> attrList = message.getAttributes();
253 if (attrList.size() == 1) {
254 if(attrList.get(0).getAttributeId() == 0) {
255 byte[] data = attrList.get(0).getData();
259 gettingLatestDataMutex.acquire();
260 detectedValue = value;
261 timestampOfLastDetecting = new Date();
262 } catch (Exception e) {
265 gettingLatestDataMutex.release();
268 for (SmartthingsSensorSmartCallback cb : callbackList) {
269 cb.newReadingAvailable(this.getId(), this.getValue(), this.isActiveValue());
271 } catch (Exception e) {
279 public void registerCallback(SmartthingsSensorSmartCallback _callbackTo) {
280 callbackList.add(_callbackTo);