Subversion Repositories HomeAutomation

Rev

Rev 1234 | Rev 1238 | 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.  
  17. /* format: dat objects, just use the time */
  18. Display.prototype.bookFromTime = null;
  19. Display.prototype.bookToTime = null;
  20.  
  21. /* the shortname for this exchangeobject */
  22. Display.prototype.shortName = null;
  23.  
  24. /* the name for this display (shown on first screen) */
  25. Display.prototype.niceName = null;
  26.  
  27. /* The display should regulary update and store the calendar */
  28. Display.prototype.exchangeData = null;
  29.  
  30. Display.prototype.myLCDService = null;
  31. Display.prototype.myRotaryService = null;
  32. Display.prototype.mySoftPwmService = null;
  33. Display.prototype.myInterval = null;
  34.  
  35. /*  */
  36. Display.prototype.exchangeCalendar = null;
  37. /*  */
  38. Display.prototype.exchangeCalendarFirstMenuItem = null;
  39. Display.prototype.exchangeCalendarLastMenuItem = null;
  40. Display.prototype.statusMenuItem = null;
  41. Display.prototype.bookMenuItem = null;
  42. Display.prototype.bookResultMenuItem = null;
  43.  
  44.  
  45. /* The currently displayed menuitem */
  46. Display.prototype.currentMenuItem = null;
  47.  
  48. /* counter for calling exchange update */
  49. Display.prototype.exchangeUpdateCnt = null;
  50.  
  51. /* counter for going to screensaver */
  52. Display.prototype.screenSaverCnt = null;
  53.  
  54. /* counter for going to main screen */
  55. Display.prototype.mainScreenCnt = null;
  56.  
  57. const exchangeUpdateTimeout = 50;
  58. const mainScreenTimeout = 40;
  59. const screenSaverTimeout = 120;
  60.  
  61. const bookingIncrease = 15;
  62.  
  63. /* This function must always be declared, this is where all the startup code
  64.    should be placed. Gets called with arguments like what ids to use etc. */
  65. Display.prototype.initialize = function(initialArguments)
  66. {
  67.     /* We must always call the parent initialize */
  68.     this.Service.prototype.initialize.call(this, initialArguments);
  69.  
  70.     /* This is used for function declarations like the callbacks below */
  71.     var self = this;
  72.  
  73.     if (!this.myInitialArguments["HD44789"])
  74.     {
  75.         log(this.myName + ":" + this.myId + "> Failed to initialize, HD44789-config missing from config.\n");
  76.         return;
  77.     }
  78.    
  79.     if (!this.myInitialArguments["Rotary"])
  80.     {
  81.         log(this.myName + ":" + this.myId + "> Failed to initialize, Rotary-config missing from config.\n");
  82.         return;
  83.     }
  84.    
  85.     if (!this.myInitialArguments["softPWM"])
  86.     {
  87.         log(this.myName + ":" + this.myId + "> Failed to initialize, softPWM-config missing from config.\n");
  88.         return;
  89.     }
  90.    
  91.     if (!this.myInitialArguments["Name"])
  92.     {
  93.         log(this.myName + ":" + this.myId + "> Failed to initialize, Name-config missing from config.\n");
  94.         return;
  95.     }
  96.     this.niceName = this.myInitialArguments["Name"];
  97.  
  98.     if (!this.myInitialArguments["ShortName"])
  99.     {
  100.         log(this.myName + ":" + this.myId + "> Failed to initialize, Name-config missing from config.\n");
  101.         return;
  102.     }
  103.     this.shortName = this.myInitialArguments["ShortName"];
  104.    
  105.     this.screenSaverCnt = 0;
  106.     this.mainScreenCnt = 0;
  107.     this.exchangeUpdateCnt = exchangeUpdateTimeout-10;
  108.    
  109.     /* Get the LCD service that we want from the ServiceManager, it takes type, service name, service id */
  110.     this.myLCDService = ServiceManager.getService("Can", "HD44789", this.myInitialArguments["HD44789"]["Id"]);
  111.     /* Add a callback for when the service goes online */
  112.     this.myLCDService.registerEventCallback("online", function(args) { self.lcdOnline(); });
  113.     /* If the service is already online we should call the handler here */
  114.     this.lcdOnline();
  115.     /* Add a callback for when the service goes offline */
  116.     this.myLCDService.registerEventCallback("offline", function(args) { self.lcdOffline(); });
  117.    
  118.     /* Get the Rotary service that we want from the ServiceManager, it takes type, service name, service id */
  119.     this.myRotaryService = ServiceManager.getService("Can", "Rotary", this.myInitialArguments["Rotary"]["Id"]);
  120.     /* Add a callback for when the encoder reports a new position */
  121.     this.myRotaryService.registerEventCallback("newPosition", function(args) { self.rotaryPosUpdate(args); });
  122.     /* Add a callback for when the encoder reports a new button status */
  123.     this.myRotaryService.registerEventCallback("newBtnStatus", function(args) { self.rotaryBtnUpdate(args); });
  124.     /* Add a callback for when the service goes online */
  125.     this.myRotaryService.registerEventCallback("online", function(args) { self.rotaryOnline(); });
  126.     /* If the service is already online we should call the handler here */
  127.     this.rotaryOnline();
  128.    
  129.     /* Get the softPWM service that we want from the ServiceManager, it takes type, service name, service id */
  130.     this.mySoftPwmService = ServiceManager.getService("Can", "softPWM", this.myInitialArguments["softPWM"]["Id"]);
  131.     /* Add a callback for when the service goes online */
  132.     this.mySoftPwmService.registerEventCallback("online", function(args) { self.softPwmOnline(); });
  133.     /* If the service is already online we should call the handler here */
  134.     this.softPwmOnline();
  135.    
  136.     this.exchangeCalendar = new ExchangeCalendar(function(shortname, data) { self.exchangeCalendarLookupCallback(shortname, data); });
  137.     this.exchangeCalendarBook = new ExchangeCalendar(function(shortname, data) { self.exchangeCalendarBookCallback(shortname, data); });
  138.    
  139.     /* create the first menu item */
  140.     this.statusMenuItem = new MenuItem(this);
  141.     this.statusMenuItem.displayData[0] = this.lcdCenterText(this.niceName);
  142.     this.statusMenuItem.doUpdate = function(args) { self.updateStatusMenuItem(); };
  143.     this.currentMenuItem = this.statusMenuItem;
  144.    
  145.     /* create the menuitem where you can choose to enter the booking sub-menu */
  146.     this.bookMenuItem = new MenuItem(this);
  147.     this.bookMenuItem.displayData[0] = this.lcdCenterText("Book room");
  148.     this.bookMenuItem.displayData[1] = this.lcdCenterText("(Push button)");
  149.     this.bookMenuItem.doUpdate = function(args) { self.updateBookMenuItem(); };
  150.  
  151.     /* connect the items as a linked list */
  152.     this.statusMenuItem.setNextItem(this.bookMenuItem);
  153.     this.statusMenuItem.setPrevItem(this.bookMenuItem);
  154.     /* set the function that shall be executed when knob is turned */
  155.     this.statusMenuItem.doRight = function(args) { self.changeToNext(); };
  156.     this.statusMenuItem.doLeft = function(args) { self.changeToPrev(); };
  157.    
  158.     /* connect the items as a linked list */
  159.     this.bookMenuItem.setNextItem(this.statusMenuItem);
  160.     this.bookMenuItem.setPrevItem(this.statusMenuItem);
  161.     /* set the function that shall be executed when knob is turned */
  162.     this.bookMenuItem.doRight = function(args) { self.changeToNext(); };
  163.     this.bookMenuItem.doLeft = function(args) { self.changeToPrev(); };
  164.    
  165.     /* create the menuitem where you can choose the to-time */
  166.     var menuChooseTo = new MenuItem(this);
  167.     menuChooseTo.displayData[1] = this.lcdCenterText(" Ok     Cancel ");
  168.     menuChooseTo.doUpdate = function(args) { self.chooseBookTimeTo(); };
  169.    
  170.     this.bookMenuItem.doPress = function(args) { self.prepareBookingMenu(); };
  171.     this.bookMenuItem.setDescItem(menuChooseTo);
  172.    
  173.     /* create the menuitem where you can choose to book the room with OK */
  174.     var menuChooseOk = new MenuItem(this);
  175.     menuChooseOk.displayData[1] = this.lcdCenterText("<Ok>    Cancel ");
  176.     menuChooseOk.doUpdate = function(args) { self.setBookTime(); };
  177.  
  178.     /* create the menuitem where you can choose to cancel the booking */
  179.     var menuChooseCancel = new MenuItem(this);
  180.     menuChooseCancel.displayData[1] = this.lcdCenterText(" Ok    <Cancel>");
  181.     menuChooseCancel.doUpdate = function(args) { self.setBookTime(); };
  182.  
  183.     /* create the menuitem where you can choose the from-time */
  184.     var menuChooseFrom = new MenuItem(this);
  185.     menuChooseFrom.displayData[1] = this.lcdCenterText(" Ok     Cancel ");
  186.     menuChooseFrom.doUpdate = function(args) { self.chooseBookTimeFrom(); };
  187.  
  188.     /* create the menuitem where you see the result of a booking */
  189.     this.bookResultMenuItem = new MenuItem(this);
  190.     this.bookResultMenuItem.displayData[0] = this.lcdCenterText("Booking...");
  191.     this.bookResultMenuItem.displayData[1] = this.lcdCenterText("(Push to return)");
  192.     this.bookResultMenuItem.setDescItem(this.bookMenuItem);
  193.     this.bookResultMenuItem.doPress = function(args) { self.changeToDesc(); };
  194.  
  195.     /* connect the items as a linked list */
  196.     menuChooseTo.setNextItem(menuChooseOk);
  197.     menuChooseTo.setPrevItem(menuChooseFrom);
  198.     /* set the function that shall be executed when knob is turned */
  199.     menuChooseTo.doRight = function(args) { self.changeToNext(); };
  200.     menuChooseTo.doLeft = function(args) { self.changeToPrev(); };
  201.     menuChooseTo.doPress = function(args) { self.changeToDesc(); };
  202.  
  203.     /* connect the items as a linked list */
  204.     menuChooseOk.setNextItem(menuChooseCancel);
  205.     menuChooseOk.setPrevItem(menuChooseTo);
  206.     menuChooseOk.setDescItem(this.bookResultMenuItem);
  207.     /* set the function that shall be executed when knob is turned */
  208.     menuChooseOk.doRight = function(args) { self.changeToNext(); };
  209.     menuChooseOk.doLeft = function(args) { self.changeToPrev(); };
  210.     menuChooseOk.doPress = function(args) { self.doBooking(); };
  211.  
  212.     /* connect the items as a linked list */
  213.     menuChooseCancel.setNextItem(menuChooseFrom);
  214.     menuChooseCancel.setPrevItem(menuChooseOk);
  215.     menuChooseCancel.setDescItem(this.bookMenuItem);
  216.     /* set the function that shall be executed when knob is turned */
  217.     menuChooseCancel.doRight = function(args) { self.changeToNext(); };
  218.     menuChooseCancel.doLeft = function(args) { self.changeToPrev(); };
  219.     menuChooseCancel.doPress = function(args) { self.changeToDesc(); };
  220.  
  221.     /* connect the items as a linked list */
  222.     menuChooseFrom.setNextItem(menuChooseTo);
  223.     menuChooseFrom.setPrevItem(menuChooseCancel);
  224.     /* set the function that shall be executed when knob is turned */
  225.     menuChooseFrom.doRight = function(args) { self.changeToNext(); };
  226.     menuChooseFrom.doLeft = function(args) { self.changeToPrev(); };
  227.     menuChooseFrom.doPress = function(args) { self.changeToDesc(); };
  228.  
  229.     /* create the menuitem where you can modify the to-time */
  230.     var menuSetTo = new MenuItem(this);
  231.     menuSetTo.doUpdate = function(args) { self.setBookTimeTo(); };
  232.     menuSetTo.displayData[0] = this.lcdCenterText("Set end time");
  233.     menuSetTo.doRight = function(args) { self.incBookTimeTo(); };
  234.     menuSetTo.doLeft = function(args) { self.decBookTimeTo(); };
  235.     menuSetTo.doPress = function(args) { self.changeToDesc(); };
  236.     menuSetTo.setDescItem(menuChooseTo);
  237.     menuChooseTo.setDescItem(menuSetTo);
  238.  
  239.     /* create the menuitem where you can modify the from-time */
  240.     var menuSetFrom = new MenuItem(this);
  241.     menuSetFrom.doUpdate = function(args) { self.setBookTimeFrom(); };
  242.     menuSetFrom.displayData[0] = this.lcdCenterText("Set start time");
  243.     menuSetFrom.doRight = function(args) { self.incBookTimeFrom(); };
  244.     menuSetFrom.doLeft = function(args) { self.decBookTimeFrom(); };
  245.     menuSetFrom.doPress = function(args) { self.changeToDesc(); };
  246.     menuSetFrom.setDescItem(menuChooseFrom);
  247.     menuChooseFrom.setDescItem(menuSetFrom);
  248.  
  249. }
  250.  
  251. Display.prototype.exchangeCalendarBookCallback = function(shortname, data)
  252. {
  253.     if (shortname == this.shortName)
  254.     {
  255.         //FIXME check if data contains error tag and error message, print to log and keep previous data?
  256.         if (data.result)
  257.         {
  258.             if (data.error)
  259.             {
  260.                 this.bookResultMenuItem.displayData[0] = this.lcdCenterText("Booking failed");
  261.                 log("Display: got this error from exchange server: " + data.error + "\n");
  262.             }
  263.             else
  264.             {
  265.                 this.bookResultMenuItem.displayData[0] = this.lcdCenterText("Booking succeeded");
  266.                 log("Display: Successfully booked room\n");
  267.                
  268.                 /* do an exchange lookup */
  269.                 this.exchangeCalendar.lookup(this.shortName);
  270.             }
  271.            
  272.         }
  273.         else if (data.error)
  274.         {
  275.             this.bookResultMenuItem.displayData[0] = this.lcdCenterText("Booking failed");
  276.             log("Display: got this error from exchange.php: " + data.error + "\n");
  277.         }
  278.         this.updateDisplay();
  279.     }
  280. }
  281.  
  282. Display.prototype.doBooking = function()
  283. {
  284.     this.bookResultMenuItem.displayData[0] = this.lcdCenterText("Booking...");
  285.     if (this.currentMenuItem.descItem)
  286.     {
  287.         this.currentMenuItem = this.currentMenuItem.descItem;
  288.     }
  289.     //this.changeToDesc();
  290.  
  291.     var bookFrom = this.bookFromTime.getTimeShortFormated();
  292.     var bookTo = this.bookToTime.getTimeShortFormated();
  293.     this.exchangeCalendarBook.book(this.shortName, bookFrom, bookTo);
  294.    
  295.     //bookFromTime bookToTime
  296. }
  297.  
  298. Display.prototype.prepareBookingMenu = function()
  299. {
  300.     this.bookFromTime = new Date();
  301.     this.bookToTime = new Date();
  302.     //this.bookFromTime.setHours(8);
  303.     //this.bookToTime.setHours(8);
  304.     if (this.bookFromTime.getMinutes() < 30)
  305.     {
  306.         this.bookFromTime.setMinutes(0);
  307.         this.bookToTime.setMinutes(30);
  308.     }
  309.     else
  310.     {
  311.         this.bookFromTime.setMinutes(30);
  312.         this.bookToTime.setHours(this.bookToTime.getHours()+1);
  313.         this.bookToTime.setMinutes(0);
  314.     }
  315.  
  316.     this.currentMenuItem = this.currentMenuItem.descItem;
  317. }
  318.  
  319. Display.prototype.changeToDesc = function()
  320. {
  321.     if (this.currentMenuItem.descItem)
  322.     {
  323.         this.currentMenuItem = this.currentMenuItem.descItem;
  324.     }
  325. }
  326.  
  327. Display.prototype.changeToNext = function()
  328. {
  329.     if (this.currentMenuItem.nextItem)
  330.     {
  331.         this.currentMenuItem = this.currentMenuItem.nextItem;
  332.     }
  333. }
  334.  
  335. Display.prototype.changeToPrev = function()
  336. {
  337.     if (this.currentMenuItem.prevItem)
  338.     {
  339.         this.currentMenuItem = this.currentMenuItem.prevItem;
  340.     }
  341. }
  342.  
  343. Display.prototype.incBookTimeTo = function()
  344. {
  345.     //FIXME: constraints?
  346.     if (this.bookToTime.getHours() < 23)
  347.     {
  348.         this.bookToTime.setMinutes(this.bookToTime.getMinutes() + bookingIncrease);
  349.     }
  350. }
  351.  
  352. Display.prototype.decBookTimeTo = function()
  353. {
  354.     //FIXME: constraints?
  355.     var now = new Date();
  356.     if (this.bookToTime.getHours() >= now.getHours())
  357.     {
  358.         this.bookToTime.setMinutes(this.bookToTime.getMinutes() - bookingIncrease);
  359.     }
  360. }
  361.  
  362. Display.prototype.incBookTimeFrom = function()
  363. {
  364.     //FIXME: constraints?
  365.     if (this.bookFromTime.getHours() < 23)
  366.     {
  367.         this.bookFromTime.setMinutes(this.bookFromTime.getMinutes() + bookingIncrease);
  368.     }
  369. }
  370.  
  371. Display.prototype.decBookTimeFrom = function()
  372. {
  373.     //FIXME: constraints?
  374.     var now = new Date();
  375.     if (this.bookFromTime.getHours() >= now.getHours())
  376.     {
  377.         this.bookFromTime.setMinutes(this.bookFromTime.getMinutes() - bookingIncrease);
  378.     }
  379. }
  380.  
  381. Display.prototype.setBookTimeFrom = function()
  382. {
  383.     this.currentMenuItem.displayData[1] = "      <"+this.bookFromTime.getTimeShortFormated()+">       ";
  384. }
  385.  
  386. Display.prototype.setBookTimeTo = function()
  387. {
  388.     this.currentMenuItem.displayData[1] = "      <"+this.bookToTime.getTimeShortFormated()+">       ";
  389. }
  390.  
  391. Display.prototype.chooseBookTimeTo = function()
  392. {
  393.     this.currentMenuItem.displayData[0] = "  "+this.bookFromTime.getTimeShortFormated()+"  - <"
  394.                                 +this.bookToTime.getTimeShortFormated()+">  ";
  395. }
  396.  
  397. Display.prototype.chooseBookTimeFrom = function()
  398. {
  399.     this.currentMenuItem.displayData[0] = " <"+this.bookFromTime.getTimeShortFormated()+"> -  "
  400.                                 +this.bookToTime.getTimeShortFormated()+"   ";
  401. }
  402.  
  403. Display.prototype.setBookTime = function()
  404. {
  405.     this.currentMenuItem.displayData[0] = "  "+this.bookFromTime.getTimeShortFormated()+"  -  "
  406.                                 +this.bookToTime.getTimeShortFormated()+"   ";
  407. }
  408.  
  409. Display.prototype.updateStatusMenuItem = function()
  410. {
  411.     var date = new Date();
  412.     var dateAndTime = "" + date.getTimeShortFormated();
  413.     this.statusMenuItem.displayData[1] = this.lcdCenterText(dateAndTime);
  414. }
  415.  
  416. Display.prototype.updateBookMenuItem = function()
  417. {
  418.     if (this.exchangeCalendarFirstMenuItem && this.exchangeCalendarLastMenuItem)
  419.     {
  420.         this.statusMenuItem.setNextItem(this.exchangeCalendarFirstMenuItem);
  421.         this.bookMenuItem.setPrevItem(this.exchangeCalendarLastMenuItem);
  422.     }
  423.     else
  424.     {
  425.         this.statusMenuItem.setNextItem(this.bookMenuItem);
  426.         this.bookMenuItem.setPrevItem(this.statusMenuItem);
  427.     }
  428. }
  429.  
  430. Display.prototype.exchangeCalendarLookupCallback = function(shortname, data)
  431. {
  432. //log("callback: "+shortname+" \n");
  433.     if (shortname == this.shortName)
  434.     {
  435.         //FIXME check if data contains error tag and error message, print to log and keep previous data?
  436.         if (data.error)
  437.         {
  438.             log("Display: got this error from exchange.php: " + data.error + "\n");
  439.         }
  440.         else
  441.         {
  442.             this.exchangeData = data;
  443.             this.createCalendarMenu();
  444.         }
  445.     }
  446. }
  447.  
  448. /* this function parses calendar data from exchange-script and creates a menu */
  449. Display.prototype.createCalendarMenu = function()
  450. {
  451.     /* This is used for function declarations like the callbacks below */
  452.     var self = this;
  453.  
  454.     this.exchangeCalendarLastMenuItem = null;
  455.     this.exchangeCalendarFirstMenuItem = null;
  456.    
  457. //log("createCalendar \n");
  458.     if (this.exchangeData)
  459.     {
  460. //log("have data \n");
  461.         var lastMenuItem;
  462.         for (var i = 0; i < this.exchangeData.meetings.length; i++)
  463.         {
  464. //log("looping \n");
  465.             /* create the menuitem for a calendar meeting */
  466.             var menu = new MenuItem(this);
  467.             menu.displayData[0] = this.lcdCenterText(this.replaceAumlauts(this.exchangeData.meetings[i].subject));
  468.             menu.displayData[1] = this.lcdCenterText(this.exchangeData.meetings[i].start.replace(":",".") + " - "
  469.                                         + this.exchangeData.meetings[i].end.replace(":","."));
  470.             menu.doRight = function(args) { self.changeToNext(); };
  471.             menu.doLeft = function(args) { self.changeToPrev(); };
  472.            
  473.             if (i == 0)
  474.             {
  475.                 this.exchangeCalendarFirstMenuItem = menu;
  476.             }
  477.             else
  478.             {
  479.                 menu.setPrevItem(lastMenuItem);
  480.                 lastMenuItem.setNextItem(menu);
  481.             }
  482.            
  483.             lastMenuItem = menu;
  484.         }
  485.         if (lastMenuItem)
  486.         {
  487.             this.exchangeCalendarLastMenuItem = lastMenuItem;
  488.             this.exchangeCalendarLastMenuItem.setNextItem(this.bookMenuItem);
  489.             this.exchangeCalendarFirstMenuItem.setPrevItem(this.statusMenuItem);
  490.        
  491.         }
  492.         /* to link in the newly created menuitems with exchangeinformation the display must be showing
  493.            either the statusmenu or the bookingmenu */
  494.         if (this.currentMenuItem == this.statusMenuItem || this.currentMenuItem == this.bookMenuItem || this.currentMenuItem == this.bookResultMenuItem)
  495.         {
  496.             /* if there is one or more exchangemenuitems */
  497.             if (this.exchangeCalendarFirstMenuItem && this.exchangeCalendarLastMenuItem)
  498.             {
  499.                 this.statusMenuItem.setNextItem(this.exchangeCalendarFirstMenuItem);
  500.                 this.bookMenuItem.setPrevItem(this.exchangeCalendarLastMenuItem);
  501.             }
  502.             /* if not then link statusmenu to bookingmenu */
  503.             else
  504.             {
  505.                 this.statusMenuItem.setNextItem(this.bookMenuItem);
  506.                 this.bookMenuItem.setPrevItem(this.statusMenuItem);
  507.             }
  508.         }
  509.     }
  510. }
  511.  
  512. Display.prototype.replaceAumlauts = function(intext)
  513. {
  514.     intext = intext.replace(/Å/, String.fromCharCode(1));
  515.     intext = intext.replace(/å/, String.fromCharCode(0));
  516.     intext = intext.replace(/Ä/, String.fromCharCode(2));
  517.     intext = intext.replace(/ä/, String.fromCharCode(225));
  518.     intext = intext.replace(/Ö/, String.fromCharCode(3));
  519.     intext = intext.replace(/ö/, String.fromCharCode(239));
  520.     //intext = intext.replace(/:/, ";");
  521.     //intext = intext.replace(/,/, ".");
  522.     return intext;
  523. }
  524.  
  525. Display.prototype.softPwmOnline = function()
  526. {
  527. }
  528.  
  529. Display.prototype.rotaryOnline = function()
  530. {
  531. }
  532.  
  533. Display.prototype.rotaryPosUpdate = function(SwitchId)
  534. {
  535.     this.screenSaverCnt = 0;
  536.     this.mainScreenCnt = 0;
  537.     for (var i = 0; i < this.myRotaryService.getSteps(SwitchId); i++)
  538.     {
  539.         if (this.myRotaryService.getDirection(SwitchId) == "Clockwise")
  540.         {
  541.             if (this.currentMenuItem.doRight)
  542.             {
  543.                 this.currentMenuItem.doRight();
  544.             }
  545.         }
  546.         else
  547.         {
  548.             if (this.currentMenuItem.doLeft)
  549.             {
  550.                 this.currentMenuItem.doLeft();
  551.             }
  552.         }
  553.     }
  554.    
  555.     this.updateDisplay();
  556. }
  557.  
  558. Display.prototype.rotaryBtnUpdate = function(SwitchId)
  559. {
  560.     this.screenSaverCnt = 0;
  561.     this.mainScreenCnt = 0;
  562.     if (this.myRotaryService.getButtonStatus(SwitchId) == "Released")
  563.     {
  564.         if (this.currentMenuItem.doPress)
  565.         {
  566.             this.currentMenuItem.doPress();
  567.         }
  568.         this.updateDisplay();
  569.     }
  570. }
  571.  
  572. Display.prototype.updateDisplay = function()
  573. {
  574.     /* see if the current menuitem wants to update itself */
  575.     if (this.currentMenuItem.doUpdate)
  576.     {
  577.         this.currentMenuItem.doUpdate();
  578.     }
  579.  
  580.     /* Clear the LCD screen */
  581.     //this.myLCDService.clearScreen();
  582.    
  583.     /* send the data for the current menuitem to display */
  584.     for (var i = 0; i < this.currentMenuItem.displayData.length; i++)
  585.     {
  586.         this.myLCDService.printText(0, i, this.currentMenuItem.displayData[i]);
  587.     }
  588.    
  589. }
  590.  
  591. Display.prototype.lcdCenterText = function(text)
  592. {
  593.     returnText = text;
  594.     var displayWidth = 20;  //this.myLCDService.getWidth();
  595.     /* pad on both sides with spaces to displayWidth */
  596.     returnText = text.pad(displayWidth, " ", 2);
  597.    
  598.     return returnText;
  599. }
  600.  
  601. Display.prototype.lcdOffline = function()
  602. {
  603.     /* If we have no interval timer running do nothing */
  604.     if (this.myInterval != null)
  605.     {
  606.         /* Stop the interval */
  607.         this.myInterval.stop();
  608.     }
  609. }
  610.  
  611. Display.prototype.lcdOnline = function()
  612. {
  613.     /* If service is not online do nothing */
  614.     if (this.myLCDService.isOnline())
  615.     {
  616.         /* Clear the LCD screen */
  617.         this.myLCDService.clearScreen();
  618.         /* Set backlight to max */
  619.         this.myLCDService.setBacklight(255);
  620.  
  621.         /* If we have no interval timer running start it */
  622.         if (this.myInterval == null)
  623.         {
  624.             var self = this;
  625.        
  626.             /* Start interval timer for our printout. Arguments are the callback function and time in milliseconds */
  627.             this.myInterval = new Interval(function() { self.timerUpdate() }, 5000);
  628.         }
  629.        
  630.         this.myInterval.start();
  631.        
  632.         this.timerUpdate();
  633.     }
  634. }
  635.  
  636. Display.prototype.setLED = function(red, green, blue)
  637. {
  638.    
  639. }
  640.  
  641. Display.prototype.timerUpdate = function()
  642. {
  643.     /* If LCD service is not online do nothing */
  644.     if (this.myLCDService.isOnline())
  645.     {
  646.         this.screenSaverCnt++;
  647.         this.mainScreenCnt++;
  648.         this.exchangeUpdateCnt++;
  649.  
  650.         if (this.mainScreenCnt > mainScreenTimeout/5)
  651.         {
  652.             /* Go to main screen (time) */
  653.             this.currentMenuItem = this.statusMenuItem;
  654.  
  655.             /* update the info on display */
  656.             this.updateDisplay();
  657.  
  658.             this.mainScreenCnt = 0;
  659.         }
  660.        
  661.         if (this.screenSaverCnt > screenSaverTimeout/5)
  662.         {
  663.            
  664.             this.screenSaverCnt = 0;
  665.         }
  666.  
  667.         if (this.exchangeUpdateCnt > exchangeUpdateTimeout/5)
  668.         {
  669.             /* update the info on display */
  670.             this.updateDisplay();
  671.            
  672.             /* do an exchange lookup */
  673.             this.exchangeCalendar.lookup(this.shortName);
  674.            
  675.             this.exchangeUpdateCnt = 0;
  676.         }
  677.        
  678.     }
  679.    
  680.     /*if (this.mySoftPwmService.isOnline())
  681.     {
  682.         this.mySoftPwmService.setPWMValue(0, 0);
  683.         this.mySoftPwmService.setPWMValue(11, 1);
  684.         this.mySoftPwmService.setPWMValue(11, 2);
  685.     }*/
  686. }
  687.  
  688.