Subversion Repositories HomeAutomation

Rev

Rev 1185 | Rev 1190 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1.  
  2. loadScript("Logic/MenuItem.js");
  3.  
  4. function Display(type, name, id)
  5. {
  6.     /* We must always call the parent constructor, initialization
  7.        of variables could be done here, but initialize is a better place */
  8.     this.Service(type, name, id);
  9. }
  10.  
  11. /* We inherit from Service with this call, it must always be next
  12.    after the constructor */
  13. extend(Display, Service);
  14.  
  15. /* Declaration of instance variables, for static variables remove prototype */
  16. /* The currently displayed menuitem */
  17. Display.prototype.currentMenuItem = null;
  18.  
  19. Display.prototype.statusMenuItem = null;
  20. Display.prototype.bookMenuItem = null;
  21.  
  22. /* format: minutes since 00:00 (480/60 = 8:00) */
  23. Display.prototype.bookFromTime = null;
  24. Display.prototype.bookToTime = null;
  25.  
  26. /* the shortname for this exchangeobject */
  27. Display.prototype.shortName = null;
  28.  
  29. /* the name for this display (shown on first screen) */
  30. Display.prototype.niceName = null;
  31.  
  32. /* The display should regulary update and store the calendar */
  33. Display.prototype.exchangeData = null;
  34.  
  35. Display.prototype.myLCDService = null;
  36. Display.prototype.myRotaryService = null;
  37. Display.prototype.mySoftPwmService = null;
  38. Display.prototype.myInterval = null;
  39.  
  40. Display.prototype.exchangeCalendar = null;
  41. Display.prototype.exchangeCalendarFirstMenuItem = null;
  42. Display.prototype.exchangeCalendarLastMenuItem = null;
  43.  
  44.  
  45. /* This function must always be declared, this is where all the startup code
  46.    should be placed. Gets called with arguments like what ids to use etc. */
  47. Display.prototype.initialize = function(initialArguments)
  48. {
  49.     /* We must always call the parent initialize */
  50.     this.Service.prototype.initialize.call(this, initialArguments);
  51.  
  52.     /* This is used for function declarations like the callbacks below */
  53.     var self = this;
  54.  
  55.     if (!this.myInitialArguments["HD44789"])
  56.     {
  57.         log(this.myName + ":" + this.myId + "> Failed to initialize, HD44789-config missing from config.\n");
  58.         return;
  59.     }
  60.    
  61.     if (!this.myInitialArguments["Rotary"])
  62.     {
  63.         log(this.myName + ":" + this.myId + "> Failed to initialize, Rotary-config missing from config.\n");
  64.         return;
  65.     }
  66.    
  67.     if (!this.myInitialArguments["softPWM"])
  68.     {
  69.         log(this.myName + ":" + this.myId + "> Failed to initialize, softPWM-config missing from config.\n");
  70.         return;
  71.     }
  72.    
  73.     if (!this.myInitialArguments["Name"])
  74.     {
  75.         log(this.myName + ":" + this.myId + "> Failed to initialize, Name-config missing from config.\n");
  76.         return;
  77.     }
  78.     this.niceName = this.myInitialArguments["Name"];
  79.  
  80.     if (!this.myInitialArguments["ShortName"])
  81.     {
  82.         log(this.myName + ":" + this.myId + "> Failed to initialize, Name-config missing from config.\n");
  83.         return;
  84.     }
  85.     this.shortName = this.myInitialArguments["ShortName"];
  86.    
  87.     /* Get the LCD service that we want from the ServiceManager, it takes type, service name, service id */
  88.     this.myLCDService = ServiceManager.getService("Can", "HD44789", this.myInitialArguments["HD44789"]["Id"]);
  89.     /* Add a callback for when the service goes online */
  90.     this.myLCDService.registerEventCallback("online", function(args) { self.lcdOnline(); });
  91.     /* If the service is already online we should call the handler here */
  92.     this.lcdOnline();
  93.     /* Add a callback for when the service goes offline */
  94.     this.myLCDService.registerEventCallback("offline", function(args) { self.lcdOffline(); });
  95.    
  96.     /* Get the Rotary service that we want from the ServiceManager, it takes type, service name, service id */
  97.     this.myRotaryService = ServiceManager.getService("Can", "Rotary", this.myInitialArguments["Rotary"]["Id"]);
  98.     /* Add a callback for when the encoder reports a new position */
  99.     this.myRotaryService.registerEventCallback("newPosition", function(args) { self.rotaryPosUpdate(args); });
  100.     /* Add a callback for when the encoder reports a new button status */
  101.     this.myRotaryService.registerEventCallback("newBtnStatus", function(args) { self.rotaryBtnUpdate(args); });
  102.     /* Add a callback for when the service goes online */
  103.     this.myRotaryService.registerEventCallback("online", function(args) { self.rotaryOnline(); });
  104.     /* If the service is already online we should call the handler here */
  105.     this.rotaryOnline();
  106.    
  107.     /* Get the softPWM service that we want from the ServiceManager, it takes type, service name, service id */
  108.     this.mySoftPwmService = ServiceManager.getService("Can", "softPWM", this.myInitialArguments["softPWM"]["Id"]);
  109.     /* Add a callback for when the service goes online */
  110.     this.mySoftPwmService.registerEventCallback("online", function(args) { self.softPwmOnline(); });
  111.     /* If the service is already online we should call the handler here */
  112.     this.softPwmOnline();
  113.    
  114.     this.exchangeCalendar = new ExchangeCalendar(function(shortname, data) { self.exchangeCalendarLookupCallback(shortname, data); });
  115.    
  116.     this.bookFromTime = new Date();
  117.     this.bookFromTime.setHours(8);
  118.     this.bookFromTime.setMinutes(0);
  119.     this.bookToTime = new Date();
  120.     this.bookToTime.setHours(8);
  121.     this.bookToTime.setMinutes(30);
  122.    
  123.    
  124.     /* create the first menu item */
  125.     this.statusMenuItem = new MenuItem(this);
  126.     this.statusMenuItem.displayData[0] = "       " + this.niceName + "       ";
  127.     this.statusMenuItem.doUpdate = this.updateStatusMenuItem;
  128.     this.currentMenuItem = this.statusMenuItem;
  129.    
  130.     /* create the menuitem where you can choose to enter the booking sub-menu */
  131.     this.bookMenuItem = new MenuItem(this);
  132.     this.bookMenuItem.displayData[0] = "     Book room      ";
  133.     this.bookMenuItem.displayData[1] = "                    ";
  134.     this.bookMenuItem.doUpdate = this.updateBookMenuItem;
  135.  
  136.     /* connect the items as a linked list */
  137.     this.statusMenuItem.setNextItem(this.bookMenuItem);
  138.     this.statusMenuItem.setPrevItem(this.bookMenuItem);
  139.     /* set the function that shall be executed when knob is turned */
  140.     this.statusMenuItem.doRight = this.changeToNext;
  141.     this.statusMenuItem.doLeft = this.changeToPrev;
  142.    
  143.     /* connect the items as a linked list */
  144.     this.bookMenuItem.setNextItem(this.statusMenuItem);
  145.     this.bookMenuItem.setPrevItem(this.statusMenuItem);
  146.     /* set the function that shall be executed when knob is turned */
  147.     this.bookMenuItem.doRight = this.changeToNext;
  148.     this.bookMenuItem.doLeft = this.changeToPrev;
  149.    
  150.     /* create the menuitem where you can choose the to-time */
  151.     var menuChooseTo = new MenuItem(this);
  152.     menuChooseTo.displayData[1] = "    Ok     Cancel   ";
  153.     menuChooseTo.doUpdate = this.chooseBookTimeTo;
  154.    
  155.     this.bookMenuItem.doPress = this.changeToDesc;
  156.     this.bookMenuItem.setDescItem(menuChooseTo);
  157.    
  158.     /* create the menuitem where you can choose to book the room with OK */
  159.     var menuChooseOk = new MenuItem(this);
  160.     menuChooseOk.displayData[1] = "   <Ok>    Cancel   ";
  161.     menuChooseOk.doUpdate = this.setBookTime;
  162.  
  163.     /* create the menuitem where you can choose to cancel the booking */
  164.     var menuChooseCancel = new MenuItem(this);
  165.     menuChooseCancel.displayData[1] = "    Ok    <Cancel>  ";
  166.     menuChooseCancel.doUpdate = this.setBookTime;
  167.  
  168.     /* create the menuitem where you can choose the from-time */
  169.     var menuChooseFrom = new MenuItem(this);
  170.     menuChooseFrom.displayData[1] = "    Ok     Cancel   ";
  171.     menuChooseFrom.doUpdate = this.chooseBookTimeFrom;
  172.  
  173.     /* connect the items as a linked list */
  174.     menuChooseTo.setNextItem(menuChooseOk);
  175.     menuChooseTo.setPrevItem(menuChooseFrom);
  176.     /* set the function that shall be executed when knob is turned */
  177.     menuChooseTo.doRight = this.changeToNext;
  178.     menuChooseTo.doLeft = this.changeToPrev;
  179.     menuChooseTo.doPress = this.changeToDesc;
  180.  
  181.     /* connect the items as a linked list */
  182.     menuChooseOk.setNextItem(menuChooseCancel);
  183.     menuChooseOk.setPrevItem(menuChooseTo);
  184.     /* set the function that shall be executed when knob is turned */
  185.     menuChooseOk.doRight = this.changeToNext;
  186.     menuChooseOk.doLeft = this.changeToPrev;
  187.  
  188.     /* connect the items as a linked list */
  189.     menuChooseCancel.setNextItem(menuChooseFrom);
  190.     menuChooseCancel.setPrevItem(menuChooseOk);
  191.     menuChooseCancel.setDescItem(this.bookMenuItem);
  192.     /* set the function that shall be executed when knob is turned */
  193.     menuChooseCancel.doRight = this.changeToNext;
  194.     menuChooseCancel.doLeft = this.changeToPrev;
  195.     menuChooseCancel.doPress = this.changeToDesc;
  196.  
  197.     /* connect the items as a linked list */
  198.     menuChooseFrom.setNextItem(menuChooseTo);
  199.     menuChooseFrom.setPrevItem(menuChooseCancel);
  200.     /* set the function that shall be executed when knob is turned */
  201.     menuChooseFrom.doRight = this.changeToNext;
  202.     menuChooseFrom.doLeft = this.changeToPrev;
  203.     menuChooseFrom.doPress = this.changeToDesc;
  204.  
  205.     /* create the menuitem where you can modify the to-time */
  206.     var menuSetTo = new MenuItem(this);
  207.     menuSetTo.doUpdate = this.setBookTimeTo;
  208.     menuSetTo.displayData[0] = "    Set end time    ";
  209.     menuSetTo.doRight = this.incBookTimeTo;
  210.     menuSetTo.doLeft = this.decBookTimeTo;
  211.     menuSetTo.doPress = this.changeToDesc;
  212.     menuSetTo.setDescItem(menuChooseTo);
  213.     menuChooseTo.setDescItem(menuSetTo);
  214.  
  215.     /* create the menuitem where you can modify the from-time */
  216.     var menuSetFrom = new MenuItem(this);
  217.     menuSetFrom.doUpdate = this.setBookTimeFrom;
  218.     menuSetFrom.displayData[0] = "   Set start time   ";
  219.     menuSetFrom.doRight = this.incBookTimeFrom;
  220.     menuSetFrom.doLeft = this.decBookTimeFrom;
  221.     menuSetFrom.doPress = this.changeToDesc;
  222.     menuSetFrom.setDescItem(menuChooseFrom);
  223.     menuChooseFrom.setDescItem(menuSetFrom);
  224.  
  225. }
  226.  
  227. Display.prototype.changeToDesc = function()
  228. {
  229.     if (this.descItem)
  230.     {
  231.         this.parentDisplay.currentMenuItem = this.descItem;
  232.     }
  233. }
  234.  
  235. Display.prototype.changeToNext = function()
  236. {
  237.     if (this.nextItem)
  238.     {
  239.         this.parentDisplay.currentMenuItem = this.nextItem;
  240.     }
  241. }
  242.  
  243. Display.prototype.changeToPrev = function()
  244. {
  245.     if (this.prevItem)
  246.     {
  247.         this.parentDisplay.currentMenuItem = this.prevItem;
  248.     }
  249. }
  250.  
  251. Display.prototype.incBookTimeTo = function()
  252. {
  253.     //FIXME: constraints?
  254.     this.parentDisplay.bookToTime.setMinutes(this.parentDisplay.bookToTime.getMinutes() + 30);
  255. }
  256.  
  257. Display.prototype.decBookTimeTo = function()
  258. {
  259.     //FIXME: constraints?
  260.     this.parentDisplay.bookToTime.setMinutes(this.parentDisplay.bookToTime.getMinutes() - 30);
  261. }
  262.  
  263. Display.prototype.incBookTimeFrom = function()
  264. {
  265.     //FIXME: constraints?
  266.     this.parentDisplay.bookFromTime.setMinutes(this.parentDisplay.bookFromTime.getMinutes() + 30);
  267. }
  268.  
  269. Display.prototype.decBookTimeFrom = function()
  270. {
  271.     //FIXME: constraints?
  272.         this.parentDisplay.bookFromTime.setMinutes(this.parentDisplay.bookFromTime.getMinutes() - 30);
  273. }
  274.  
  275. Display.prototype.setBookTimeFrom = function()
  276. {
  277.     this.displayData[1] = "      <"+this.parentDisplay.bookFromTime.getTimeShortFormated()+">       ";
  278. }
  279.  
  280. Display.prototype.setBookTimeTo = function()
  281. {
  282.     this.displayData[1] = "      <"+this.parentDisplay.bookToTime.getTimeShortFormated()+">       ";
  283. }
  284.  
  285. Display.prototype.chooseBookTimeTo = function()
  286. {
  287.     this.displayData[0] = "  "+this.parentDisplay.bookFromTime.getTimeShortFormated()+"  - <"
  288.                                 +this.parentDisplay.bookToTime.getTimeShortFormated()+">  ";
  289. }
  290.  
  291. Display.prototype.chooseBookTimeFrom = function()
  292. {
  293.     this.displayData[0] = " <"+this.parentDisplay.bookFromTime.getTimeShortFormated()+"> -  "
  294.                                 +this.parentDisplay.bookToTime.getTimeShortFormated()+"   ";
  295. }
  296.  
  297. Display.prototype.setBookTime = function()
  298. {
  299.     this.displayData[0] = "  "+this.parentDisplay.bookFromTime.getTimeShortFormated()+"  -  "
  300.                                 +this.parentDisplay.bookToTime.getTimeShortFormated()+"   ";
  301. }
  302.  
  303. Display.prototype.updateStatusMenuItem = function()
  304. {
  305.     var date = new Date();
  306.     var dateAndTime = "" + date.getTimeShortFormated();
  307.     this.displayData[1] = "       " + dateAndTime + "        ";
  308.    
  309.     if (this.parentDisplay.exchangeCalendarFirstMenuItem && this.parentDisplay.exchangeCalendarLastMenuItem)
  310.     {
  311.         this.parentDisplay.statusMenuItem.setNextItem(this.parentDisplay.exchangeCalendarFirstMenuItem);
  312.         this.parentDisplay.bookMenuItem.setPrevItem(this.parentDisplay.exchangeCalendarLastMenuItem);
  313.     }
  314. }
  315.  
  316. Display.prototype.updateBookMenuItem = function()
  317. {
  318.     if (this.parentDisplay.exchangeCalendarFirstMenuItem && this.parentDisplay.exchangeCalendarLastMenuItem)
  319.     {
  320.         this.parentDisplay.statusMenuItem.setNextItem(this.parentDisplay.exchangeCalendarFirstMenuItem);
  321.         this.parentDisplay.bookMenuItem.setPrevItem(this.parentDisplay.exchangeCalendarLastMenuItem);
  322.     }
  323. }
  324.  
  325. Display.prototype.exchangeCalendarLookupCallback = function(shortname, data)
  326. {
  327. log("callback: "+shortname+" \n");
  328.     if (shortname == this.shortName)
  329.     {
  330.         //FIXME check if data contains error tag and error message, print to log and keep previous data?
  331.         this.exchangeData = data;
  332.        
  333.         this.createCalendarMenu();
  334.     }
  335. }
  336.  
  337. Display.prototype.createCalendarMenu = function()
  338. {
  339. log("createCalendar \n");
  340.     if (this.exchangeData)
  341.     {
  342. log("have data \n");
  343.         var lastMenuItem;
  344.         for (var i = 0; i < this.exchangeData.meetings.length; i++)
  345.         {
  346. log("looping \n");
  347.             /* create the menuitem for a calendar meeting */
  348.             var menu = new MenuItem(this);
  349.             menu.displayData[0] = this.exchangeData.meetings[i].organizer;
  350.             menu.displayData[1] = "   "+this.exchangeData.meetings[i].start.replace(":",".") + " - "
  351.                                         + this.exchangeData.meetings[i].end.replace(":",".")+"    ";
  352.             menu.doRight = this.changeToNext;
  353.             menu.doLeft = this.changeToPrev;
  354.            
  355.             if (i == 0)
  356.             {
  357.                 this.exchangeCalendarFirstMenuItem = menu;
  358.             }
  359.             else
  360.             {
  361.                 menu.setPrevItem(lastMenuItem);
  362.                 lastMenuItem.setNextItem(menu);
  363.             }
  364.            
  365.             lastMenuItem = menu;
  366.         }
  367.         this.exchangeCalendarLastMenuItem = lastMenuItem;
  368.         this.exchangeCalendarLastMenuItem.setNextItem(this.bookMenuItem);
  369.         this.exchangeCalendarFirstMenuItem.setPrevItem(this.statusMenuItem);
  370.     }
  371. }
  372.  
  373. Display.prototype.softPwmOnline = function()
  374. {
  375. }
  376.  
  377. Display.prototype.rotaryOnline = function()
  378. {
  379. }
  380.  
  381. Display.prototype.rotaryPosUpdate = function(SwitchId)
  382. {
  383.     for (var i = 0; i < this.myRotaryService.getSteps(SwitchId); i++)
  384.     {
  385.         if (this.myRotaryService.getDirection(SwitchId) == "Clockwise")
  386.         {
  387.             if (this.currentMenuItem.doRight)
  388.             {
  389.                 this.currentMenuItem.doRight();
  390.             }
  391.         }
  392.         else
  393.         {
  394.             if (this.currentMenuItem.doLeft)
  395.             {
  396.                 this.currentMenuItem.doLeft();
  397.             }
  398.         }
  399.     }
  400.    
  401.     this.updateDisplay();
  402. }
  403.  
  404. Display.prototype.rotaryBtnUpdate = function(SwitchId)
  405. {
  406.     if (this.myRotaryService.getButtonStatus(SwitchId) == "Released")
  407.     {
  408.         if (this.currentMenuItem.doPress)
  409.         {
  410.             this.currentMenuItem.doPress();
  411.         }
  412.     }
  413.     this.updateDisplay();
  414. }
  415.  
  416. Display.prototype.updateDisplay = function()
  417. {
  418.     /* see if the current menuitem wants to update itself */
  419.     if (this.currentMenuItem.doUpdate)
  420.     {
  421.         this.currentMenuItem.doUpdate();
  422.     }
  423.  
  424.     /* Clear the LCD screen */
  425.     //this.myLCDService.clearScreen();
  426.    
  427.     /* send the data for the current menuitem to display */
  428.     for (var i = 0; i < this.currentMenuItem.displayData.length; i++)
  429.     {
  430.         this.myLCDService.printText(0, i, this.currentMenuItem.displayData[i]);
  431.     }
  432.    
  433. }
  434.  
  435. Display.prototype.lcdOffline = function()
  436. {
  437.     /* If we have no interval timer running do nothing */
  438.     if (this.myInterval != null)
  439.     {
  440.         /* Stop the interval */
  441.         this.myInterval.stop();
  442.     }
  443. }
  444.  
  445. Display.prototype.lcdOnline = function()
  446. {
  447.     /* If service is not online do nothing */
  448.     if (this.myLCDService.isOnline())
  449.     {
  450.         /* Clear the LCD screen */
  451.         this.myLCDService.clearScreen();
  452.         /* Set backlight to max */
  453.         this.myLCDService.setBacklight(255);
  454.  
  455.         /* If we have no interval timer running start it */
  456.         if (this.myInterval == null)
  457.         {
  458.             var self = this;
  459.        
  460.             /* Start interval timer for our printout. Arguments are the callback function and time in milliseconds */
  461.             this.myInterval = new Interval(function() { self.timerUpdate() }, 10000);
  462.         }
  463.        
  464.         this.myInterval.start();
  465.        
  466.         this.timerUpdate();
  467.     }
  468. }
  469.  
  470. Display.prototype.timerUpdate = function()
  471. {
  472.     /* If LCD service is not online do nothing */
  473.     if (this.myLCDService.isOnline())
  474.     {
  475.         this.exchangeCalendar.lookup(this.shortName);
  476.        
  477.         /* update the info on display */
  478.         this.updateDisplay();
  479.        
  480.         //var date = new Date();
  481.         /* Get the current date time on the format YYYY-mm-dd HH.ii.ss */
  482.         //var dateAndTime = date.getDateTimeFormated();
  483.         /* Print the text to the LCD */
  484.         //this.myLCDService.printText(0, 1, dateAndTime);
  485.         /* Print out what we are doing to the console */
  486.         //log(this.myName + ":" + this.myId + "> Trying to print " + dateAndTime + " to LCD\n");
  487.     }
  488. }
  489.  
  490.