1 package iotcode.DoorlockActuator;
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 DoorlockActuator implements IoTZigbeeCallback, SmartthingsActuator {
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 < SmartthingsActuatorSmartCallback > callbackList = new CopyOnWriteArrayList < SmartthingsActuatorSmartCallback > ();
45 private int sensorId = 0;
47 @config private IoTSet<IoTDeviceAddress> doorlockActuatorUdpAddress;
48 @config private IoTSet<IoTZigbeeAddress> doorlockActuatorZigbeeAddress;
50 public DoorlockActuator(IoTSet<IoTDeviceAddress> dSet, IoTSet<IoTZigbeeAddress> zigSet) {
51 doorlockActuatorUdpAddress = dSet;
52 doorlockActuatorZigbeeAddress = zigSet;
55 public DoorlockActuator() {
60 if (didAlreadyInit.compareAndSet(false, true) == false) {
61 return; // already init
64 didAlreadyClose.set(false);
67 Iterator itrUdp = doorlockActuatorUdpAddress.iterator();
68 Iterator itrZig = doorlockActuatorZigbeeAddress.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 = doorlockActuatorUdpAddress.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 = doorlockActuatorZigbeeAddress.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);
117 } catch (Exception e) {
125 * @param value Integer value for actuation
126 * @return boolean Status of sending actuate command
128 public boolean actuate(int value) {
132 System.out.println("Doorlock: Is locking!");
134 System.out.println("Doorlock: Is unlocking!");
135 else { // Failed to send command because of invalid value
136 throw new Error("Doorlock: Actuate value " + value + " is not recognized (only 0 or 1)! Please check your method call...");
139 zigConnection.sendLockOrUnlockDoorRequest(0x0005, 0x0101, 0x0104, 0x02, value);
141 } catch (Exception e) {
148 * requestStatus() method
152 public void requestStatus() {
153 System.out.println("Doorlock: Requesting status... Receiving answer through callback...");
155 zigConnection.sendReadDoorStatusRequest(0x0005, 0x0101, 0x0104, 0x02, 0x10, 0x00, 0x0000);
157 } catch (Exception e) {
163 private void sleep(int multipleTime){
168 Thread.sleep(TIMEOUT_FOR_RESEND_MSEC*multipleTime);
169 } catch(Exception e){
175 public int getStatus() {
180 gettingLatestDataMutex.acquire();
183 } catch (Exception e) {
186 gettingLatestDataMutex.release();
191 public boolean isActiveStatus() {
193 int tmp = getStatus();
195 detectStatus = true; // ACTIVE == Door is locked
197 detectStatus = false; // NOT ACTIVE == Door is not locked/not fully locked
201 public void close() {
203 if (didAlreadyClose.compareAndSet(false, true) == false) {
204 return; // already init
207 didAlreadyInit.set(false);
211 zigConnection.close();
212 } catch (Exception e) {
217 public void Finalize() {
223 public void setId(int id) {
236 public long getTimestampOfLastReading() {
240 gettingLatestDataMutex.acquire();
241 tmp = (Date)timestampOfLastDetecting.clone();
243 } catch (Exception e) {
246 gettingLatestDataMutex.release();
247 long retLong = tmp.getTime();
252 public void newMessageAvailable(IoTZigbeeMessage _zm) {
255 if (_zm instanceof IoTZigbeeMessageZdoBindResponse) {
256 IoTZigbeeMessageZdoBindResponse message = (IoTZigbeeMessageZdoBindResponse)_zm;
257 if (message.getSucceeded()) {
261 else if (_zm instanceof IoTZigbeeMessageZclConfigureReportingResponse){
262 IoTZigbeeMessageZclConfigureReportingResponse message = (IoTZigbeeMessageZclConfigureReportingResponse)_zm;
263 if (message.getAllSuccess()) {
264 didDoorLockConfigureReporting.set(true);
267 else if (_zm instanceof IoTZigbeeMessageZclReadAttributesResponse) {
268 IoTZigbeeMessageZclReadAttributesResponse message = (IoTZigbeeMessageZclReadAttributesResponse)_zm;
269 List <IoTZigbeeMessageZclReadAttributesResponse.Attribute> attrList = message.getAttributes();
271 if (attrList.size() == 1) {
272 if(attrList.get(0).getAttributeId() == 0) {
273 byte[] data = attrList.get(0).getData();
277 gettingLatestDataMutex.acquire();
278 detectedValue = value;
279 timestampOfLastDetecting = new Date();
280 } catch (Exception e) {
283 gettingLatestDataMutex.release();
286 for (SmartthingsActuatorSmartCallback cb : callbackList) {
287 cb.newActuatorReadingAvailable(this.getId(), this.getStatus(), this.isActiveStatus());
289 } catch (Exception e) {
297 public void registerCallback(SmartthingsActuatorSmartCallback _callbackTo) {
298 callbackList.add(_callbackTo);