Subversion Repositories HomeAutomation

Rev

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