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 iotcode.annotation.*;
11 import iotruntime.slave.*;
12 import iotcode.interfaces.*;
13 import iotruntime.zigbee.*;
15 /** Class Smartthings sensor driver for Smartthings sensor devices.
17 * @author Changwoo Lee, Rahmadi Trimananda <rtrimana @ uci.edu>
21 public class DoorlockSensor implements IoTZigbeeCallback, SmartthingsSensor {
23 private final int TIMEOUT_FOR_RESEND_MSEC = 900;
25 private IoTZigbee zigConnection = null;
26 private boolean didClose; // make sure that the clean up was done correctly
27 private boolean detectStatus = false;
29 private int detectedValue = 0;
30 private Date timestampOfLastDetecting = null;
32 private AtomicBoolean didAlreadyClose = new AtomicBoolean(true);
33 private AtomicBoolean didAlreadyInit = new AtomicBoolean(false);
34 private AtomicBoolean didWriteAttrb = new AtomicBoolean(false);
35 private AtomicBoolean didMatchDscr = new AtomicBoolean(false);
36 private AtomicBoolean didBind = new AtomicBoolean(false);
37 private AtomicBoolean didDoorLockConfigureReporting = new AtomicBoolean(false); // made by Jiawei
38 static Semaphore gettingLatestDataMutex = new Semaphore(1);
40 private List < SmartthingsSensorSmartCallback > callbackList = new CopyOnWriteArrayList < SmartthingsSensorSmartCallback > ();
42 private int sensorId = 0;
44 @config private IoTSet<IoTDeviceAddress> DoorlockSensorUdpAddress;
45 @config private IoTSet<IoTZigbeeAddress> DoorlockSensorZigbeeAddress;
47 public DoorlockSensor(IoTSet<IoTDeviceAddress> dSet, IoTSet<IoTZigbeeAddress> zigSet) {
48 DoorlockSensorUdpAddress = dSet;
49 DoorlockSensorZigbeeAddress = zigSet;
52 public DoorlockSensor() {
57 if (didAlreadyInit.compareAndSet(false, true) == false) {
58 return; // already init
61 didAlreadyClose.set(false);
64 Iterator itrUdp = DoorlockSensorUdpAddress.iterator();
65 Iterator itrZig = DoorlockSensorZigbeeAddress.iterator();
67 zigConnection = new IoTZigbee((IoTDeviceAddress)itrUdp.next(), (IoTZigbeeAddress)itrZig.next());
70 System.out.println("DEBUG: Allocate iterators to print out addresses!");
71 Iterator itrDebugUdp = DoorlockSensorUdpAddress.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());
77 Iterator itrDebugZig = DoorlockSensorZigbeeAddress.iterator();
78 IoTZigbeeAddress iotzbaddDebug = (IoTZigbeeAddress)itrDebugZig.next();
79 System.out.println("Zigbee address: " + iotzbaddDebug.getAddress());
81 zigConnection.registerCallback(this);
82 System.out.println("Register callback!");
84 System.out.println("Initialized!");
91 System.out.println("Sending Management Permit Joining Request");
92 // TODO: Might/might not need to send this 3 times
93 // for(int z=0; z<3; z++){
94 zigConnection.sendManagementPermitJoiningRequest(0x0002, 0x0036, 0x00);
99 while(!didBind.get()){
100 System.out.println("Sending Bind Request");
101 zigConnection.sendBindRequest(0x0003, 0x0101, 0x02);
105 while(!didDoorLockConfigureReporting.get()){
106 System.out.println("Sending Door Lock: Configure Reporting");
107 zigConnection.sendConfigureReportingCommand(0x0004, 0x0101, 0x0104, 0x01, 0x02, 0x0000, 0x30, 0x0000, 0x100E, null);
112 Scanner in = new Scanner(System.in);
113 System.out.println("\nUnlock door: 0");
114 System.out.println("Lock door: 1");
115 System.out.println("Read status: 2 (or anything else)");
116 String str = in.next();
117 if(str.equals("1")) {
118 System.out.println("the doorlock sensor is locking");
119 zigConnection.sendLockOrUnlockDoorRequest(0x0005, 0x0101, 0x0104, 0x02, 0);
121 }else if(str.equals("0")){
122 System.out.println("the doorlock sensor is unlocking");
123 zigConnection.sendLockOrUnlockDoorRequest(0x0005, 0x0101, 0x0104, 0x02, 1);
126 System.out.println("Let's see the doorlock sensor's status currently");
127 zigConnection.sendReadDoorStatusRequest(0x0005, 0x0101, 0x0104, 0x02, 0x10, 0x00, 0x0000);
133 } catch (Exception e) {
139 private void sleep(int multipleTime){
144 Thread.sleep(TIMEOUT_FOR_RESEND_MSEC*multipleTime);
145 } catch(Exception e){
151 public int getValue() {
155 gettingLatestDataMutex.acquire();
158 } catch (Exception e) {
161 gettingLatestDataMutex.release();
166 public boolean isActiveValue() {
168 int tmp = getValue();
170 detectStatus = true; // Door is locked
172 detectStatus = false; // Door is not locked/not fully locked
176 public void close() {
178 if (didAlreadyClose.compareAndSet(false, true) == false) {
179 return; // already init
182 didAlreadyInit.set(false);
186 zigConnection.close();
187 } catch (Exception e) {
192 public void Finalize() {
198 public void setId(int id) {
211 public long getTimestampOfLastReading() {
215 gettingLatestDataMutex.acquire();
216 tmp = (Date)timestampOfLastDetecting.clone();
218 } catch (Exception e) {
221 gettingLatestDataMutex.release();
222 long retLong = tmp.getTime();
227 public void newMessageAvailable(IoTZigbeeMessage _zm) {
230 if (_zm instanceof IoTZigbeeMessageZdoBindResponse) {
231 IoTZigbeeMessageZdoBindResponse message = (IoTZigbeeMessageZdoBindResponse)_zm;
232 if (message.getSucceeded()) {
236 else if (_zm instanceof IoTZigbeeMessageZclConfigureReportingResponse){
237 IoTZigbeeMessageZclConfigureReportingResponse message = (IoTZigbeeMessageZclConfigureReportingResponse)_zm;
238 if (message.getAllSuccess()) {
239 didDoorLockConfigureReporting.set(true);
242 else if (_zm instanceof IoTZigbeeMessageZclReadAttributesResponse) {
243 IoTZigbeeMessageZclReadAttributesResponse message = (IoTZigbeeMessageZclReadAttributesResponse)_zm;
244 List <IoTZigbeeMessageZclReadAttributesResponse.Attribute> attrList = message.getAttributes();
246 if (attrList.size() == 1) {
247 if(attrList.get(0).getAttributeId() == 0) {
248 byte[] data = attrList.get(0).getData();
252 gettingLatestDataMutex.acquire();
253 detectedValue = value;
254 timestampOfLastDetecting = new Date();
255 } catch (Exception e) {
258 gettingLatestDataMutex.release();
261 for (SmartthingsSensorSmartCallback cb : callbackList) {
262 cb.newReadingAvailable(this.getId(), this.getValue(), this.isActiveValue());
264 } catch (Exception e) {
272 public void registerCallback(SmartthingsSensorSmartCallback _callbackTo) {
273 callbackList.add(_callbackTo);