Your Universal Remote Control Center
RemoteCentral.com
Philips Pronto Professional Forum - View Post
Up level
Up level
The following page was printed from RemoteCentral.com:

Login:
Pass:
 
 

Original thread:
Post 3 made on Friday June 10, 2022 at 10:26
randman
Long Time Member
Joined:
Posts:
June 2003
423
Within a for loop, I call:
GUI.updateScreen();
System.delay(1000);

So in order to wait 20 seconds, GUI.updateScreen() and System.delay(1000) are called 20 times. But even if I did System.delay(20000) (which I don't), the getHTTP() call to control lights is called before System.delay, so I would think that getHTTP still would have issued the command to the server before System.delay is called.

Anyway, below is some of the code that I use.

// createWaitPopup() function
// This function creates a popup dialog box that goes over the existing
// window. This function is used in conjunction with the updateWaitPopup()
// and deleteWaitPopup() functions.
// The caller of this function must call deleteWaitPopup() later.
function createWaitPopup()
{
   waitWidgets[0] = GUI.addPanel();
   waitWidgets[0].setImage(CF.widget("PLEASE_WAIT_BACK", "Please Wait Widgets", "Resources").getImage());
   waitWidgets[0].width = 240;
   waitWidgets[0].height = 284;
   waitWidgets[0].top = 36;
   waitWidgets[0].left = 0;
   waitWidgets[0].visible = true;

   waitWidgets[1] = GUI.addPanel();
   waitWidgets[1].setImage(CF.widget("PLEASE_WAIT", "Please Wait Widgets", "Resources").getImage());
   waitWidgets[1].width = 157;
   waitWidgets[1].height = 105;
   waitWidgets[1].top = 110;
   waitWidgets[1].left = 43;
   waitWidgets[1].color = 255;
   waitWidgets[1].font = "ProntoMaestro";
   waitWidgets[1].fontSize = 16;
   waitWidgets[1].visible = true;
} // createWaitPopup



/////////////////////////////////////////////////////////////////////////////
// updateWaitPopup() function
// This function updates the popup window created by the createWaitPopup()
// function defined earlier. The window will display % complete based on
// the input parameters.
// Input parameters:
//    waitDuration: duration in seconds for the wait
//    minPcnt: starting percentage to display
//    maxPcnt: Ending percentage to display
//    message: Optional message to display
// Assumption: if this function is called more than once, the
// minPcnt of a call should be >= maxPcnt of previous call.
// Example use:
// createWaitPopup();
// // Send some remote commands to turn on some components
// updateWaitPopup(50, 0, 25, "Doing job #1");
// // Send more remote commands to turn on other components
// updateWaitPopup(150, 26, 100, "Doing job #2");
// deleteWaitPopup();
// Note: trace() below just calls System.print() if the given trace level is
// below a globally defined trace threshold.
// 10/2019: made changes to ensure that input parameters are treated
// as integers. Otherwise, an exception might be thrown.
function updateWaitPopup(waitDuration_, minPcnt_, maxPcnt_, optionalMessage)
{
   var deltaPcnt, displayPcnt, labelMessage, waitDuration;
   var waitDuration, minPcnt, maxPcnt;
   waitDuration = Math.round(waitDuration_);
   minPcnt = Math.round(minPcnt_);
   // 10/22/19: Account for potential rounding issues:
   if ( (maxPcnt_ > 100.0) && (maxPcnt_ < 101.0) ) {
      maxPcnt = 100;
   } else {
      maxPcnt = Math.round(maxPcnt_);
   }
   trace("minPcnt = " + minPcnt + " maxPcnt = " + maxPcnt + ".", 3);
   if ( (maxPcnt > 100) || (minPcnt < 0) || (maxPcnt <= minPcnt) |
   (waitDuration <= 0) ) {
      throw new Error("updateWaitPopup: ERROR. invalid input parameter.");
   }
   deltaPcnt = (maxPcnt - minPcnt) / waitDuration;
   displayPcnt = minPcnt;
   for (i = 1; i <= waitDuration; i++)
   {
      displayPcnt += deltaPcnt;
      if (optionalMessage.length > 0) {
         labelMessage = "\n\n" + optionalMessage + "\n";
         waitWidgets[1] .fontSize = 14;
      }
      else {
         labelMessage = "\n\n";
         waitWidgets[1] .fontSize = 16;
      }
      waitWidgets[1].label = labelMessage + Math.round(displayPcnt) + "% Done";
      GUI.updateScreen();
      System.delay(1000);
   }
   return;
} // updateWaitPopup

/////////////////////////////////////////////////////////////////////////////
// deleteWaitPopup() function
// This function is used to delete the widgets created by deleteWaitPopup().
function deleteWaitPopup()
{
   var len = waitWidgets.length;
   for (var i = 0; i < len; i++) {
      var w = waitWidgets[i];
      if (w) {
         w.remove();
      }
      waitWidgets[i] = null;
   }
}

/////////////////////////////////////////////////////////////////////////////
// doWaitPopup() function
// Convenience function.
function doWaitPopup(waitDuration, optionalMessage) {
   createWaitPopup();
   updateWaitPopup(waitDuration, 0, 100, optionalMessage);
   deleteWaitPopup();
}


Below is the function that I use to control (turn on or off) lights. The server
that getHTTP() talks to is a HomeSeer server that can turn on or off the lights (aside: HomeSeer talks to Homebridge, which talks to HomeKit to control the lights).

/////////////////////////////////////////////////////////////////////////////
// controlDeviceByLabel(ref, label)
// controlEviceByLabel() is a public function for controlling a device.
// ref is the HomeSeer reference number.
// label is the command to send, typically "On" or "Off".
// When HomeSeer replies, the processResponse2 function is called
// asynchronously.
/////////////////////////////////////////////////////////////////////////////
function controlDeviceByLabel(ref, label)
{
   var msg = "", msgSuffix = "";

   if ( (!ref) || (ref.length == 0) ) {
      com.randman.utils.trace("controlDeviceByLabel: ERROR: empty ref passed in.", 0);
      return false;
   }

   if ( (!label) || (label.length == 0) ) {
      com.randman.utils.trace("controlDeviceByLabel: ERROR: empty label passed in.", 0);
      return false;
   }

   // Sample URL to send to HomeSeer:
   // [Link: ]
   // Use encodeURI in case label has spaces:
   msgSuffix = "controldevicebylabel&ref=" + ref + "&label=" + encodeURI(label);
   msg = HomeSeer.msgPrefix + msgSuffix;
   com.randman.utils.trace("controlDeviceByLabel: msgSuffix = " + msgSuffix + ".", 5);
   HomeSeer.lastMessageSent = msgSuffix;
   com.philips.HttpLibrary.getHTTP(msg, processResponse2);
} // controlDeviceByLabel



////////////////////////////////////////////////////////////////////////////
// processResponse2(rcvd)
// This function is the callback which is called when HomeSeer responds to
// an HTTP request from the controlDeviceByLabel function.
////////////////////////////////////////////////////////////////////////////
function processResponse2(rcvd)
{
   com.randman.utils.trace("processResponse2: response was: " + rcvd + ". Length = " + rcvd.length + ".", 3);
   // For controlDeviceByLabel response, if event was run successfully,
   // HomeSeer returns a JSON formatted status of the device (same
   // return as "getstatus").

   // If an error occurred (for example, an invalid ref or label value was
   // given), HomeSeer will return:
   //
   // { "Response":"Error, controlling device" }
   //
   if (rcvd.length > 22) {
      // Remove "\r\n" at the end of the string
      HomeSeer.lastResponseReceived = rcvd.substr(14, 5);
   }
   else {
      com.randman.utils.trace("Warning: length of string received from HomeSeer <= 22. Length = " + rcvd.length, 0);
      HomeSeer.lastResponseReceived = rcvd;
   }

   if (HomeSeer.lastResponseReceived == "Error") {
      com.randman.utils.trace("Error: " + HomeSeer.lastMessageSent + " failed. Response: " + rcvd, 0);
   }
   else {
      com.randman.utils.trace("Command succeeded: " + HomeSeer.lastMessageSent + ".", 3);
   }
} // processResponse2

/////////////////////////////////////////////////////////////////////////////
// runEvent(groupName, eventName)
// runEvent() is a public function for running a HomeSeer event.
/////////////////////////////////////////////////////////////////////////////
function runEvent(groupName, eventName)
{
   var msg = "", msgSuffix = "";

   if ( (!groupName) || (groupName.length == 0) ) {
      com.randman.utils.trace("runEvent: ERROR: empty groupName passed in.", 0);
      return false;
   }

   if ( (!eventName) || (eventName.length == 0) ) {
      com.randman.utils.trace("runEvent: ERROR: empty eventName passed in.", 0);
      return false;
   }

   // Use encodeURI in case groupName or eventName have spaces:
   msgSuffix = "runevent&group=" + encodeURI(groupName) + "&name=" + encodeURI(eventName);
   msg = HomeSeer.msgPrefix + msgSuffix;
   com.randman.utils.trace("runEvent: msgSuffix = " + msgSuffix + ".", 5);
   HomeSeer.lastMessageSent = msgSuffix;
   com.philips.HttpLibrary.getHTTP(msg, processResponse);
} // runEvent

////////////////////////////////////////////////////////////////////////////
// processResponse(rcvd)
// This function is the callback which is called when HomeSeer responds to
// an HTTP request from the runEvent function.
////////////////////////////////////////////////////////////////////////////
function processResponse(rcvd)
{
   com.randman.utils.trace("processResponse: response was: " + rcvd + ". Length = " + rcvd.length + ".", 3);
   // For runEvent response, if event was run successfully, HomeSeer
   // returns "ok". Otherwise, HomeSeer will return "error" (for example,
   // if an invalid group or event name was given.
   // Sometime after 3/20/2015, HomeSeer
   // changed response from ok to { "Response":"ok" }
   if (rcvd.length >= 16) {
      HomeSeer.lastResponseReceived = rcvd.substr(14, 2);
   }
   else if (rcvd.length > 2) {
      // Remove "\r\n" at the end of the string
      HomeSeer.lastResponseReceived = rcvd.substr(0, rcvd.length - 2);
   }
   else {
      com.randman.utils.trace("Warning: length of string received from HomeSeer <= 2. Length = " + rcvd.length, 0);
      HomeSeer.lastResponseReceived = rcvd;
   }

   if (HomeSeer.lastResponseReceived == "ok") {
      com.randman.utils.trace("Command " + HomeSeer.lastMessageSent + " completed successfully.", 3);
   }
   else {
      com.randman.utils.trace("ERROR. Command failed: " + HomeSeer.lastMessageSent + ".", 0);
   }

} // processResponse



Below is code that I use whenever an activity (Apple TV, Shield, DVD Player), etc. is selected by the user. It checks if the processor and projector need to be turned on. If so, it turns them on and waits a certain amount of time for them to power on before proceeding. The projector takes a minute to turn on, so during this minute, I'd like to do a light show (turn off ceiling lights, turn on ambiance lights, turn off ambiance lights, etc.).

The interesting part of the function is in this if block:

if (HTProjectorState != "On") {
... turn on projector
... while waiting for projector to turn on, do a light show (using getHTTP
... commands while telling the user to please wait.
}

In this function below, none of the HomeSeer runEvent (used to call HomeSeer events via getHTTP()) and controlDeviceByLabel calls (used to tell HomeSeer to turn on or off lights using getHTTP()) in this function turn on and off the lights until AT THE END OR COMPLETION of this function. The behavior is as if all the runEvent and controlDeviceByLabel function calls are done one right after the other but only after this function completes. I don't know why they don't actually turn on or off the lights run at the time they are called. The lights only turn on and off after the minute it takes the projector to turn on. It seems that
Pronto queues up the getHTTP requiests and doesn't run them until the function completes. There is also no delay between when all the lights turn on and off, which seems to show that all getHTTP commands are running one right after the next. The lights don't start turning on and off until after the function finishes.

   function HTSystemOn(activity) {
         var HTPreampState, HTProjectorState, rc = 2, message;
         com.randman.utils.createWaitPopup();
         // getPreampState() and getHTProjectorState() uses RS232
         // and RFX9600 to get the current states of the processor
         // and projector.
         HTPreampState = com.randman.marantz_preamp.getPreampState();
         HTProjectorState = com.randman.jvc_projector.getHTProjectorState();
       
         // The wait* variables below are how long the function waits
         // using the updateWaitPopup() function.
         // waitAmbianceLights and waitSpeakerLights is how
         // long the ambiance and speaker lights should be ON while the
         // projector is starting, respectively.
         // NOTE: waitAmbianceLights + waitSpeakerLights must be <= waitProjectorOn.
         var waitPreampOn = 4, waitPreampHDMIOutput = 18, waitProjectorOn = 55, waitSwitchInput = 6, waitAmbianceLights = 40, waitSpeakerLights = 10, waitProjectorOnRemaining, waitTotal = 0, minPcnt = 0, maxPcnt = 0;
         // Calculate total wait time so we can correctly show
         // the user the % done in the wait dialog box.
         if (HTPreampState == "Off") {
            waitTotal += waitPreampOn;
            if (HTProjectorState == "On") {
               waitTotal += waitPreampHDMIOutput;
            }
         }

         if (HTProjectorState != "On") {
            waitTotal += waitProjectorOn;
         }

         if (HTPreampState == "Off") {
            // Need to turn on the Marantz processor
            rc = 1;
            try {
               minPcnt = maxPcnt + 1;
               maxPcnt = maxPcnt + 100 * waitPreampOn/waitTotal;
               com.randman.utils.updateWaitPopup(waitPreampOn, minPcnt, maxPcnt, "Powering Preamp");
            }
            catch(e2) {
               com.randman.utils.deleteWaitPopup();
               com.randman.utils.trace(e2, 0);
               message = "Could not turn on preamp.\nTry again.";
               com.randman.utils.createPopup(message);
               return 0;
            }
            // Switch the preamp's input based on activity:
            if (HTSwitchInput(1, activity) == 0) {
               com.randman.utils.deleteWaitPopup();
               message = "Could not switch input to\n" + activity + ". Try again.";
               com.randman.utils.createPopup(message);
               return 0;
            }
            try {
               // Processor can send output to projector or monitor/TV (or both).
               // Tell processor to send output to projector only:
               com.randman.utils.trace("Changing preamp HDMI output to projector.", 1);
               CF.widget("Preamp Output - Projector", "HT", "PS_MACROS").executeActions();

            }
            catch(e) {
               com.randman.utils.deleteWaitPopup();
               com.randman.utils.trace(e, 0);
               message = "Could not set preamp output to\nprojector. Try again.";
               com.randman.utils.createPopup(message);
               return 0;
            }
            if (HTProjectorState == "On") {
               // Only do this wait if projector is already on.
               minPcnt = maxPcnt + 1;
               maxPcnt = maxPcnt + 100 * waitPreampHDMIOutput/waitTotal;
               com.randman.utils.updateWaitPopup(waitPreampHDMIOutput, minPcnt, maxPcnt, "HDMI Out->projector" + activity);
            }
         }
         else {
            // Preamp already on
            var HTSIRC;
            HTSIRC = HTSwitchInput(2, activity);
            if (HTSIRC == 0) {
               com.randman.utils.deleteWaitPopup();
               message = "Unable to switch input to\n" + activity + ". Try again.";
               com.randman.utils.createPopup(message);
               return 0;
            }
            // Need to tell user to wait since it takes a while for
            // the JVC projector to show a video when input resolution changes.
            // However, we do not want to bring up dialog box if we
            // are already on the correct input to begin with.
            if ( (HTSIRC == 1) && (HTProjectorState == "On") ) {
               // Given this condition, this is the only time where we
               // need to tell the user to wait.
               com.randman.utils.updateWaitPopup(waitSwitchInput, 1, 100,
                  "Prepping " + activity);
            }
            // If the Home Theater was being used with the TV (and the
            // preamp was on), and the user selects an activity for the
            // projector, the preamp's HDMI Monitor output would be
            // for the TV and not the projector. Need to change to projector.
            if (HTProjectorState == "Off") {
               try {
                  com.randman.utils.trace("2. Changing preamp HDMI output to projector.", 1);
                  CF.widget("Preamp Output - Projector", "HT", "PS_MACROS").executeActions();
               }
               catch(e) {
                  com.randman.utils.deleteWaitPopup();
                  com.randman.utils.trace(e, 0);
                  message = "2. Could not set preamp output to\nprojector. Try again.";
                  com.randman.utils.createPopup(message);
                  return 0;
               }
            }
         }

         // If JVC projector is still powering up, getHTProjectorState()
         // returns "". In addition, shortly after
         // "Cooling down", the projector might return "" before it starts returning Off.
         if (HTProjectorState == "") {
            com.randman.utils.deleteWaitPopup();
            message = "Cannot determine projector state.\nIt may be powering on.\nTry again.";
            com.randman.utils.createPopup(message);
            return 0;
         }

         if (HTProjectorState == "Cooling down") {
            com.randman.utils.deleteWaitPopup();
            message = "Projector cooling down.\nPlease wait for the projector's\nfan to turn off before trying to\nuse the home theater again.";
            com.randman.utils.createPopup(message);
            return 0;
         }

         if (HTProjectorState == "Emergency") {
            com.randman.utils.deleteWaitPopup();
            message = "Projector has state Emergency.\nPlease diagnose the issue.";
            com.randman.utils.createPopup(message);
            return 0;
         }

         if (HTProjectorState != "On") {
            rc = 1;
            try {
               // HT System On reusable macro turns on the projector via an RS-232 command:
               com.randman.utils.trace("Turning on projector.", 1);
               CF.widget("System On", "HT", "PS_MACROS").executeActions();
            }
            catch(e) {
               com.randman.utils.deleteWaitPopup();
               com.randman.utils.trace(e, 0);
               message = "Could not turn on projector.\nTry again.";
               com.randman.utils.createPopup(message);
               return 0;
            }
            // Turn off all non-ambiance lights:
            com.randman.homeseer.runEvent("Pronto", "Pronto - Home Theater Non-Ambiance Lights - Off");

            // Turn on ambiance lights:
            com.randman.homeseer.controlDeviceByLabel(992,"On"); // 992: Step Lights
            com.randman.homeseer.controlDeviceByLabel(989,"On"); // 989: Lightstrips

            minPcnt = maxPcnt + 1;
            maxPcnt = maxPcnt + 100 * waitAmbianceLights/waitTotal;
            com.randman.utils.updateWaitPopup(waitAmbianceLights, minPcnt, maxPcnt, "Powering projector.");

            // Turn off ambiance lights and turn on speaker lights (for "IMAX" speaker effect):
            com.randman.homeseer.controlDeviceByLabel(989,"Off"); // 989: Lighstrips
            com.randman.homeseer.controlDeviceByLabel(1007,"Off"); // 1007: Sconces
            com.randman.homeseer.controlDeviceByLabel(991,"On");  // 991: Speaker lights

            minPcnt = maxPcnt + 1;
            maxPcnt = maxPcnt + 100 * waitSpeakerLights/waitTotal;
            com.randman.utils.updateWaitPopup(waitSpeakerLights, minPcnt, maxPcnt, "Powering projector..");
            com.randman.homeseer.controlDeviceByLabel(991,"Off");  // 991: Speaker lights

            // Since the projector was turned on before the logic to control
            // the lights, reduce the projector on wait time by the amount of time
            // the "light show" was being done:
            waitProjectorOnRemaining = waitProjectorOn - waitAmbianceLights - waitSpeakerLights;

            minPcnt = maxPcnt + 1;
            maxPcnt = maxPcnt + 100 * waitProjectorOnRemaining/waitTotal;
            com.randman.utils.updateWaitPopup(waitProjectorOnRemaining, minPcnt, maxPcnt, "Powering projector...");

            com.randman.homeseer.controlDeviceByLabel(992, "Off"); // 992: Step Lights

            if (com.randman.jvc_projector.switchProjectorInput("HDMI 1") == false) {
               com.randman.utils.deleteWaitPopup();
               message = "Error. Could not change\nprojector input to HDMI1.\nRetry.";
               com.randman.utils.createPopup(message);
               return 0;
            }
         } // if (HTProjectorState != "On")
         com.randman.utils.deleteWaitPopup();
         return rc;
   } // HTSystemOn()


Hosting Services by ipHouse