View Javadoc

1   package org.wcb.autohome;
2   /***
3    * Copyright (C) 1999  Walter Bogaardt
4    *
5    * This library is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU Lesser General Public
7    * License as published by the Free Software Foundation; either
8    * version 2 of the License, or (at your option) any later version.
9    *
10   * This library is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   * Lesser General Public License for more details.
14   *
15   * You should have received a copy of the GNU Lesser General Public
16   * License along with this library; if not, write to the Free Software
17   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
18   *
19   * Project: Alice X10 Home Automation
20   *
21   */
22  
23  import org.wcb.autohome.interfaces.X10DeviceConstants;
24  import org.wcb.autohome.interfaces.IHAGateway;
25  import org.wcb.autohome.interfaces.IX10Events;
26  import org.wcb.autohome.interfaces.IX10Module;
27  import org.wcb.autohome.exceptions.HomeException;
28  
29  import java.util.Vector;
30  import java.util.GregorianCalendar;
31  import java.util.Calendar;
32  import java.rmi.RemoteException;
33  
34  /***
35   * Filename:    $Id: EventsHandler.java,v 1.11 2004/02/25 21:38:32 wbogaardt Exp $
36   * 
37   * Abstract: The EventsHandler is a threaded daemon that runs in the background
38   * and parses through a vector and runs various events one at a time.
39   * until the stop run is called. The event runs if it meets conditions
40   * of date and time.
41   *
42   * $Log: EventsHandler.java,v $
43   * Revision 1.11  2004/02/25 21:38:32  wbogaardt
44   * added javadocs and fixed formating for checkstyle report
45   *
46   * Revision 1.10  2004/01/16 00:53:34  wbogaardt
47   * Fixed a very obscure bug with the Macro Panel that it didn't added new
48   * x10 devices to the drop down of available x10 device for the macro. Modified Macro triggers to change the events to
49   * integer verses strings cleaner this way.
50   *
51   * Revision 1.9  2003/12/22 20:51:29  wbogaardt
52   * refactored name assignments and formatted code for readability.
53   *
54   * Revision 1.8  2003/12/19 20:51:38  wbogaardt
55   * internationalization
56   *
57   * Revision 1.7  2003/12/13 05:36:50  wbogaardt
58   * fixed javadoc comments.
59   *
60   * Revision 1.6  2003/12/11 23:10:07  wbogaardt
61   * cleaned up exception handeling and logging of system.out messages
62   *
63   * Revision 1.5  2003/10/11 04:02:06  wbogaardt
64   * fixed event handler to work again
65   *
66   * Revision 1.4  2003/10/10 18:39:09  wbogaardt
67   * changed date time information from a string to a calendar object
68   *
69   *
70   *@author wbogaardt
71   *@version 1.0
72   */
73  public class EventsHandler implements Runnable, X10DeviceConstants {
74  
75      private Thread tTimerThread;
76      private Vector vCurrentEventsModel = null;
77      private IHAGateway gw;
78  
79      /***
80       * This creates an event handler and uses the passed in interface
81       * to know if the running events can be executed.
82       * @param gateway The Home automation gateway, which has status of serial port connection.
83       */
84      public EventsHandler(IHAGateway gateway) {
85          this.gw = gateway;
86      }
87  
88      /***
89       * This is a threaded object so it must implement
90       * start method calls.
91       */
92      public void start()
93      {
94          tTimerThread = new Thread(this);
95          tTimerThread.start();
96          run();
97      }
98  
99      /***
100      * This is the main run method for this thread.
101      */
102     public void run()
103     {
104         int delay = 30000;
105         while (Thread.currentThread() == tTimerThread)
106         {
107             try
108             {
109                 Thread.sleep(delay);
110             }
111             catch (InterruptedException ie)
112             {
113                 break;
114             }
115             parseEvents();
116         }
117     }
118 
119     /***
120      * This is used to stop the thread. When the
121      * user click on stop running.
122      */
123     public void stop()
124     {
125         tTimerThread = null;
126     }
127 
128     /***
129      *Sets the events into the daemon to run
130      *this vector gets parsed every minute to determin if certain elements
131      *in the vector meet the requirements if it meets the time requirements
132      *then the event is run appropriately.
133      *
134      *@param items - List of items/events to run.
135      */
136     public void setModel(Vector items)
137     {
138         vCurrentEventsModel = items;
139     }
140 
141     /***
142      *Gets the events that the daemon is running
143      *this vector gets parsed every minute to determin if certain elements
144      *in the vector meet the requirements if it meets the time requirements
145      *then the event is run appropriately.
146      *
147      *@return Vector - List of items/events that are running.
148      */
149     public Vector getModel()
150     {
151         if (vCurrentEventsModel.size() < 1)
152         {
153             return null;
154         }
155         return vCurrentEventsModel;
156     }
157 
158     /***
159      * Parse the entire table model and find the rows
160      * that the system needs to execute.
161      */
162     private void parseEvents()
163     {
164         GregorianCalendar currDate = new GregorianCalendar();
165         int currHour = currDate.get(Calendar.HOUR_OF_DAY);
166         int currMin = currDate.get(Calendar.MINUTE);
167         IX10Events row;
168         Calendar timestamp;
169         String status;
170         IX10Module module;
171 
172         for (int i = 0; i < vCurrentEventsModel.size(); i++)
173         {
174             /* check if day of week is ok */
175             row = (IX10Events) vCurrentEventsModel.elementAt(i);
176             module = row.getModule();
177             if (checkDayOfWeek(row))
178             {
179                 timestamp = row.getTime();
180                 status = row.getAction();
181                 /* check if start hour and minutes are equal to current time */
182                 if (currHour == timestamp.get(Calendar.HOUR_OF_DAY) && currMin == timestamp.get(Calendar.MINUTE))
183                 {
184                     if (module.getType() == LAMP_MODULE_ON && status.equalsIgnoreCase("off"))
185                     {
186                         sendLampCommand(module, 0, status);
187                     }
188                     if (module.getType() == LAMP_MODULE_ON && status.equalsIgnoreCase("on"))
189                     {
190                         sendLampCommand(module, 1, status);
191                     }
192                     if (module.getType() == LAMP_MODULE_ON && status.startsWith("-"))
193                     {
194                         sendLampCommand(module, 2, status);
195                     }
196                     if (module.getType() == LAMP_MODULE_ON && status.startsWith("+"))
197                     {
198                         sendLampCommand(module, 3, status);
199                     }
200                     if (module.getType() == APPLIANCE_MODULE_ON && status.equalsIgnoreCase("off"))
201                     {
202                         sendApplianceCommand(module, 0);
203                     }
204                     if (module.getType() == APPLIANCE_MODULE_ON && status.equalsIgnoreCase("on"))
205                     {
206                         sendApplianceCommand(module, 1);
207                     }
208                     if (status.startsWith("All Lights Off"))
209                     {
210                         sendAllCommand(module, 0);
211                     }
212                     if (status.startsWith("All Lights ON"))
213                     {
214                         sendAllCommand(module, 1);
215                     }
216                     if (status.startsWith("All Off"))
217                     {
218                         sendAllCommand(module, 2);
219                     }
220                 }
221             }
222         }
223     }
224 
225     /***
226      *  This is a prepatory command to parse the Light modules information
227      *  into information that can be assimilated by the CM11A or CM17A X10 API Java interface
228      *  We need to get the device broken down to house code and id and the starting
229      *  Lamp status(off/on) then we need to check if a dim command is associated with
230      *  the module to dim/brighten the lamp.
231      * @param deviceID x10Module to send command to
232      * @param status 0 turn off lamp; 1 turn on lamp; 2 dim lamp; 3 brighten lamp;
233      * @param dimCmds percentage to dim or brighten;
234      */
235     private void sendLampCommand(IX10Module deviceID, int status, String dimCmds)
236     {
237         int iPercentage = 0;
238         if (status > 1)
239         {
240             try
241             {
242                 String sPercentage = dimCmds.substring(1, dimCmds.length());
243                 iPercentage = Integer.parseInt(sPercentage);
244             }
245             catch (NumberFormatException nfe)
246             {
247                 printMessage("Not a valid number:" + nfe);
248             }
249         }
250         switch (status)
251         {
252             case 0:
253                 printMessage("Turn off lamp " + deviceID.getDescription());
254                 try
255                 {
256                     gw.deviceCommands(deviceID, 0);
257                 }
258                 catch (RemoteException re)
259                 {
260                     printMessage("Unable to connect to gateway." + re);
261                 }
262                 catch (HomeException he)
263                 {
264                     printMessage("Invalid Command");
265                 }
266                 break;
267             case 1:
268                 printMessage("Turn on lamp " + deviceID.getDescription());
269                 try
270                 {
271                     gw.deviceCommands(deviceID, 1);
272                 }
273                 catch (RemoteException re)
274                 {
275                     printMessage("Unable to connect to gateway." + re);
276                 }
277                 catch (HomeException he)
278                 {
279                     printMessage("Invalid Command");
280                 }
281                 break;
282             case 2:
283                 this.printMessage("Dimming " + deviceID.getDescription() + " to " + iPercentage + " percent.");
284                 try
285                 {
286                     gw.lampIntensity(deviceID, 0, iPercentage);
287                 }
288                 catch (RemoteException re)
289                 {
290                     printMessage("Unable to connect to gateway." + re);
291                 }
292                 catch (HomeException he)
293                 {
294                     printMessage("Invalid Command");
295                 }
296                 break;
297             case 3:
298                 this.printMessage("Brightening " + deviceID.getDescription() + " to " + iPercentage + " percent.");
299                 try
300                 {
301                     gw.lampIntensity(deviceID, 1, iPercentage);
302                 }
303                 catch (RemoteException re)
304                 {
305                     printMessage("Unable to connect to gateway.:" + re);
306                 }
307                 catch (HomeException he)
308                 {
309                     printMessage("Invalid Command");
310                 }
311                 break;
312         }
313     }
314 
315     /***
316      * Breaks down the device id into houseCode and moduleID and then
317      * sends the appropriate on or off command to the
318      * AutoHomeAdminSession controller.
319      * @param deviceID X10 module to send command to.
320      * @param iCmnd 0 turn off appliance; 1 - turn on appliance
321      */
322     private void sendApplianceCommand(IX10Module deviceID, int iCmnd)
323     {
324         switch(iCmnd)
325         {
326             case 0:
327                 printMessage("Turn off appliance " + deviceID.getDescription());
328                 try
329                 {
330                     gw.deviceCommands(deviceID, 0);
331                 }
332                 catch (RemoteException re)
333                 {
334                     printMessage("Unable to connect to gateway. " + re);
335                 }
336                 catch (HomeException he)
337                 {
338                     printMessage("Invalid Command");
339                 }
340                 break;
341             case 1:
342                 printMessage("Turn on appliance " + deviceID.getDescription());
343                 try
344                 {
345                     gw.deviceCommands(deviceID, 1);
346                 }
347                 catch (RemoteException re)
348                 {
349                     printMessage("Unable to connect to gateway. " + re);
350                 }
351                 catch (HomeException he)
352                 {
353                     printMessage("Invalid Command");
354                 }
355                 break;
356         }
357     }
358 
359     /***
360      * Breaks down the device id into houseCode and moduleID and then
361      * sends the appropriate on or off command to the entire house
362      * codes A - P.
363      * @param deviceID The x10 module section to send command to.
364      * @param cmnd 0 - All lights off; 1 - All lights on; 2 - all devices off
365      */
366     private void sendAllCommand(IX10Module deviceID, int cmnd)
367     {
368         char house = deviceID.getHouseCode();
369         try
370         {
371             gw.allCommandToSection(house, cmnd);
372         }
373         catch (RemoteException re)
374         {
375             printMessage("Unable to connect to gateway. " + re);
376         }
377         catch (HomeException he)
378         {
379             printMessage("Invalid command sent.");
380         }
381     }
382 
383     /***
384      * Checks if the string value has same date to return true
385      * @param evt Alice X10Events object
386      * @return True if the current system date and the event are the same.
387      */
388     private boolean checkDayOfWeek(IX10Events evt)
389     {
390         GregorianCalendar currDay = new GregorianCalendar();
391         if (currDay.get(Calendar.DAY_OF_WEEK) == 1 && evt.getSunday())
392         {
393             return true;
394         }
395         if (evt.getMonday() && currDay.get(Calendar.DAY_OF_WEEK) == 2)
396         {
397             return true;
398         }
399         if (evt.getTuesday() && currDay.get(Calendar.DAY_OF_WEEK) == 3)
400         {
401             return true;
402         }
403         if (evt.getWednesday() && currDay.get(Calendar.DAY_OF_WEEK) == 4)
404         {
405             return true;
406         }
407         if (evt.getThursday() && currDay.get(Calendar.DAY_OF_WEEK) == 5)
408         {
409             return true;
410         }
411         if (evt.getFriday() && currDay.get(Calendar.DAY_OF_WEEK) == 6)
412         {
413             return true;
414         }
415         if (evt.getSaturday() && currDay.get(Calendar.DAY_OF_WEEK) == 7)
416         {
417             return true;
418         }
419         return false;
420     }
421 
422     /***
423      * Prints the message to the console or speaks it.
424      * @param message
425      */
426     private void printMessage(String message)
427     {
428         AutoHomeAdminSession.getInstance().printMessage(message);
429     }
430 }
431 
432 
433 
434 
435 
436 
437 
438 
439 
440 
441 
442