announceNest : function (device, command, controllers, values, config) {
      var runCommand  = require(__dirname + '/../lib/runCommand'),
          translate   = require(__dirname + '/../lib/translate'),
          notify      = require(__dirname + '/../lib/notify'),
          message     = '',
          tempMessage = '',
          i           = 0,
          subDevice,
          deviceId,
          rawMacro,
          macro;

      if(values.protect) {
        for(subDevice in values.protect) {
          if(values.protect[subDevice].smoke !== 'ok') {
            tempMessage = translate.translate('{{i18n_SMOKE_DETECTED}}', 'nest', controllers.config.language).replace('{{LABEL}}', values.protect[subDevice].label);

            if(message) {
              message = message + ' ';
            }

            message = message + tempMessage;
          }

          if(values.protect[subDevice].co !== 'ok') {
            tempMessage = translate.translate('{{i18n_CO_DETECTED}}', 'nest', controllers.config.language).replace('{{LABEL}}', values.protect[subDevice].label);

            if(message) {
              message = message + ' ';
            }

            message = message + tempMessage;
          }
        }

        if(message) {
          notify.notify(message, controllers, device);

          // If you have a macro assigned to this specific Mode, we'll act upon
          // it.
          if(config.macro) {
            rawMacro = config.macro.split(';');

            for(macro in rawMacro) {
              runCommand.macroCommands(rawMacro[macro]);
            }
          }
        }
      }
    }
Example #2
0
    hallLightHome : function (deviceId, command, controllers, values, config) {
      var deviceState = require(__dirname + '/../lib/deviceState'),
          runCommand  = require(__dirname + '/../lib/runCommand'),
          now         = new Date().getTime(),
          delay       = (config.delay  || 15) * 1000,
          rawMacro    = (config.macros || '').split(';'),
          macro,
          currentDeviceState,
          currDevice,
          subdevice,
          state,
          isIn        = function (command, collection, prefix) {
            var found = false,
                current;

            for (current in collection) {
              if (command === prefix + collection[current] + '-on') {
                found = true;
                break;
              }
            }

            return found;
          };

      if (isIn(command, config.presence, 'subdevice-state-presence-')) {
        this.lastEvents.presence = now;
      }

      else if (isIn(command, config.contact, 'subdevice-state-contact-')) {
        this.lastEvents.open = now;
      }

      if ((now > delay + this.lastEvents.acted) && (now < delay + this.lastEvents.presence) && (now < delay + this.lastEvents.open)) {
        if (config.macros) {
          for (macro in rawMacro) {
            if (rawMacro.hasOwnProperty(macro)) {
              runCommand.macroCommands(rawMacro[macro]);
            }
          }
        }

        for (currDevice in controllers) {
          if (controllers.hasOwnProperty(currDevice)) {
            state = deviceState.getDeviceState(currDevice);

            if (controllers[currDevice].config) {
              switch (controllers[currDevice].config.typeClass) {
                case 'smartthings'     :
                case 'wemo'            :
                case 'raspberryRemote' :
                  currentDeviceState = deviceState.getDeviceState(currDevice);
                break;

                default :
                  currentDeviceState = null;
              }

              if ((currentDeviceState.value) && (currentDeviceState.value.devices)) {
                for (subdevice in currentDeviceState.value.devices) {
                  if (config.action.indexOf(currentDeviceState.value.devices[subdevice].label) !== -1) {
                    this.lastEvents.acted = now;

                    runCommand.runCommand(currDevice, 'subdevice-' + currentDeviceState.value.devices[subdevice].label + '-on', currDevice);
                  }
                }
              }
            }
          }
        }
      }
    }
Example #3
0
    setDevice : function (rawText, controllers, device, macros, language) {
      var translate      = require(__dirname + '/../../lib/translate'),
          runCommand     = require(__dirname + '/../../lib/runCommand'),
          gertyLanguage  = require(__dirname + '/language'),
          genericDevices = gertyLanguage.getGenericDevices(controllers),
          subDevices     = gertyLanguage.getSubDevices(controllers),
          genericTerms   = gertyLanguage.getGenericTerms(language),
          verbs          = gertyLanguage.getVerbs(language),
          inquiry        = gertyLanguage.getInquiry(language),
          implied        = translate.translate('{{i18n_AND}}', 'gerty', language),
          commands       = [{ action : null, implied : false }],
          questions      = [{ action : null, implied : false }],
          devices        = [{ device : null, typeClass : null, subDevice : null }],
          rawMacro       = [],
          macro          = '',
          text           = [],
          keyword        = '',
          acted          = false,
          i              = 0,
          j              = 0,
          k              = 0,
          x              = 0;

      text = rawText.split(' ');

      if (macros) {
        // Loop through all configured macros anywhere in the inputted text.
        for (keyword in macros) {
          if (rawText.indexOf(keyword.toUpperCase()) !== -1) {
            rawMacro = macros[keyword].split(';');

            for (macro in rawMacro) {
              if (rawMacro.hasOwnProperty(macro)) {
                runCommand.macroCommands(rawMacro[macro]);
              }
            }

            acted = true;
          }
        }
      }

      for (i = 0; i < text.length; i += 1) {
        // If you have a series of commands, you don't want to have to repeat
        // the same word.  So we'll use "AND" to assume the same action.
        if ((commands.length > 1) && (text[i] === implied.toUpperCase())) {
          commands[j].action  = commands[(j - 1)].action;
          commands[j].implied = true;
        }

        // Loop through looking for action words.  Once we have one, store it
        // so we can act on it once we find a suitable device.
        for (keyword in verbs) {
          if (verbs.hasOwnProperty(keyword)) {
            // Look ahead for "Channel Up" to not confuse with just "Up".
            if (text[i] + ' ' + text[(i + 1)] === verbs[keyword].toUpperCase()) {
              commands[j].action = verbs[keyword];

              i += 1;

              break;
            }

            else if (text[i] === verbs[keyword].toUpperCase()) {
              commands[j].action = verbs[keyword];

              break;
            }

            // When we have a pair of action + command, we can start looking for
            // our next command.
            if ((commands[j].action) && (devices[j].device)) {
              j += 1;

              commands[j] = { action : null, implied : false };
              devices[j]  = { device : null, typeClass : null, subDevice : null };
            }
          }
        }

        // Loop through looking for inquiry words.  Once we have one, store it
        // so we can act on it once we find a suitable device.
        for (keyword in inquiry) {
          if (inquiry.hasOwnProperty(keyword)) {
            if (text[i] === inquiry[keyword].toUpperCase()) {
              questions[x].action = inquiry[keyword];

              break;
            }

            // When we have a pair of action + command, we can start looking for
            // our next command.
            if ((questions[x].action) && (devices[j].device)) {
              x += 1;

              questions[x] = { action : null, implied : false };
              devices[j]   = { device : null, typeClass : null, subDevice : null };
            }
          }
        }

        for (keyword in genericTerms) {
          // Check for generic names "TV", "Stereo", "Playstation", etc.
          if (genericTerms[keyword].toUpperCase() === text[i]) {
            if (controllers[genericDevices[genericTerms[keyword].toUpperCase()]]) {
              devices[j].device    = genericDevices[genericTerms[keyword].toUpperCase()];
              devices[j].typeClass = controllers[genericDevices[genericTerms[keyword].toUpperCase()]].config.typeClass;

              // When we have a pair of action + command, we can start looking
              // for our next command.
              if ((commands[j].action) && (devices[j].device)) {
                j += 1;

                commands[j] = { action : null, implied : false };
                devices[j]  = { device : null, typeClass : null, subDevice : null };
              }
            }
          }
        }

        // Look through any registered subdevices that may need to be acted
        // upon.
        for (keyword in controllers) {
          if (keyword !== 'config') {
            if ((subDevices) && (subDevices[keyword]) && (subDevices[keyword].subDevices)) {
              for (k = 0; k < subDevices[keyword].subDevices.length; k += 1) {
                // Look ahead for device names that may be multiple words.
                if (text[i] + ' ' + text[(i + 1)] + ' ' + text[(i + 2)] === subDevices[keyword].subDevices[k].toUpperCase()) {
                  devices[j].device    = keyword;
                  devices[j].typeClass = controllers[keyword].config.typeClass;
                  devices[j].subDevice = subDevices[keyword].subDevices[k];

                  i += 2;

                  break;
                }

                else if (text[i] + ' ' + text[(i + 1)] === subDevices[keyword].subDevices[k].toUpperCase()) {
                  devices[j].device    = keyword;
                  devices[j].typeClass = controllers[keyword].config.typeClass;
                  devices[j].subDevice = subDevices[keyword].subDevices[k];

                  i += 1;

                  break;
                }

                else if (text[i] === subDevices[keyword].subDevices[k].toUpperCase()) {
                  devices[j].device = keyword;
                  devices[j].typeClass = controllers[keyword].config.typeClass;
                  devices[j].subDevice = subDevices[keyword].subDevices[k];
                }

                // When we have a pair of action + command, we can start looking for
                // our next command.
                if ((commands[j].action) && (devices[j].device)) {
                  j += 1;

                  commands[j] = { action : null, implied : false };
                  devices[j]  = { device : null, typeClass : null, subDevice : null };
                }
              }
            }
          }
        }

        // Look through each device and compare with the "title" used in the
        // navigation.
        for (keyword in controllers) {
          if (keyword !== 'config') {
            // Look ahead for device names that may be multiple words.
            if (text[i] + ' ' + text[(i + 1)] + ' ' + text[(i + 2)] === controllers[keyword].config.title.toUpperCase()) {
              commands[j].device    = keyword;
              commands[j].typeClass = controllers[keyword].config.typeClass;

              i += 2;

              break;
            }

            else if (text[i] + ' ' + text[(i + 1)] === controllers[keyword].config.title.toUpperCase()) {
              commands[j].device    = keyword;
              commands[j].typeClass = controllers[keyword].config.typeClass;

              i += 1;

              break;
            }

            else if (text[i] === controllers[keyword].config.title.toUpperCase()) {
              commands[j].device    = keyword;
              commands[j].typeClass = controllers[keyword].config.typeClass;
            }

            // When we have a pair of action + command, we can start looking for
            // our next command.
            if ((commands[j].action) && (commands[j].device)) {
              j += 1;

              commands[j] = { action : null, device : null, typeClass: null, subDevice : null };
            }
          }
        }
      }

      // If we have a question that's not related to any device.
      // "What time is it?"
      // "What is the date?"
      // "Do I need a coat?"
      // "How are you doing?"
      if ((!devices[0].device) && (!commands[0].action) && (questions[0].action)) {
// Register questions
      }

      else if ((devices[0].device) && ((commands[0].action) || (questions[0].action))) {

// Figure out how to coordinate "questions" with "commands"

        // If we have more commands than devices, there's probably some
        // ambiguity with a conjunction, such as:
        // "Turn off the hall light and office light"
        // Which "and" should imply that both devices be "off".  However, a
        // structure such as:
        // "Turn off the hall light and turn on the office light"
        // This would produce an extra element in the "commands" list, which is
        // what we'll try and filter here.
        if (commands.length > devices.length) {
          for (i = 0; i < commands.length; i += 1) {
            if (commands[i].implied === true) {
              commands.splice(i, 1);
            }
          }
        }

        // We should have a perfect matching between devices and commands.  If
        // we do not, then we clearly misunderstand part (or all) of a message,
        // so it's probably best to not act on it rather than act incorrectly
        // on it.
        if (commands.length === devices.length) {
          for (i = 0; i < commands.length; i += 1) {
            if ((devices[i].device) && (commands[i].action)) {
              // Only at this point should we assume a command will actually be
              // acted upon.
              acted = true;

              if (devices[i].subDevice) {
                if (devices[i].typeClass === 'nest') {
                  devices[i].subDevice = devices[i].subDevice + '-' + commands[i].action.toLowerCase();
                  commands[i].action   = 'mode';
                }

                commands[i].action = 'subdevice-' + commands[i].action.toLowerCase() + '-' + devices[i].subDevice;
              }

              switch (this.findDeviceType(devices[i].typeClass)) {
                case 'tv'            :
                case 'entertainment' :
                case 'stereo'        :
                  switch (commands[i].action.toUpperCase()) {
                    case 'OFF' :
                      commands[i].action = 'PowerOff';
                    break;

                    case 'ON' :
                      commands[i].action = 'PowerOn';
                    break;
                  }
                break;

                case 'security' :
                  switch (commands[i].action.toUpperCase()) {
                    case 'ARM' :
                      commands[i].action = 'Alarm_On';
                    break;

                    case 'DISARM' :
                      commands[i].action = 'Alarm_Off';
                    break;
                  }
                break;
              }

              runCommand.runCommand(devices[i].device, commands[i].action);
            }
          }
        }
      }

      return acted;
    },
Example #4
0
      setDevice = function(rawText, controllers, device, macros, language) {
        var genericDevices = getGenericDevices(controllers),
            subDevices     = getSubDevices(controllers),
            genericTerms   = getGenericTerms(language),
            verbs          = getVerbs(language),
            commands       = { 0 : {} },
            rawMacro       = [],
            macro          = '',
            text           = [],
            keyword        = '',
            acted          = false,
            i              = 0,
            j              = 0,
            k              = 0;

        text = rawText.split(' ');

        if(macros) {
          // Loop through all configured macros anywhere in the inputted text.
          for(keyword in macros) {
            if(rawText.indexOf(keyword.toUpperCase()) !== -1) {
              rawMacro = macros[keyword].split(';');

              for(macro in rawMacro) {
                runCommand.macroCommands(rawMacro[macro]);
              }

              acted = true;
            }
          }
        }

        for(i = 0; i < text.length; i += 1) {
          // Loop through looking for action words.  Once we have one, store it
          // so we can act on it once we find a suitable device.
          for(keyword in verbs) {
            // Look ahead for "Channel Up" to not confuse with just "Up".
            if(text[i] + ' ' + text[(i + 1)] === verbs[keyword].toUpperCase()) {
              commands[j].action = verbs[keyword];

              i += 1;

              break;
            }

            else if(text[i] === verbs[keyword].toUpperCase()) {
              commands[j].action = verbs[keyword];

              break;
            }

            // When we have a pair of action + command, we can start looking for
            // our next command.
            if((commands[j].action) && (commands[j].device)) {
              j += 1;

              commands[j] = { action : null, device : null, subdevice : null };
            }
          }

          for(keyword in genericTerms) {
            // Check for generic names "TV", "Stereo", "Playstation", etc.
            if(genericTerms[keyword] === text[i]) {
              commands[j].device = genericDevices[genericTerms[keyword]];

              // When we have a pair of action + command, we can start looking
              // for our next command.
              if((commands[j].action) && (commands[j].device)) {
                j += 1;

                commands[j] = { action : null, device : null, subdevice : null };
              }
            }
          }

          // Look through any registered subdevices that may need to be acted
          // upon.
          for(keyword in controllers) {
            if(keyword !== 'config') {
              if((subDevices) && (subDevices[keyword]) && (subDevices[keyword].subDevices)) {
                for(k = 0; k < subDevices[keyword].subDevices.length; k += 1) {
                  // Look ahead for device names that may be multiple words.
                  if(text[i] + ' ' + text[(i + 1)] + ' ' + text[(i + 2)] === subDevices[keyword].subDevices[k].toUpperCase()) {
                    commands[j].device    = keyword;
                    commands[j].subDevice = subDevices[keyword].subDevices[k];

                    i += 2;

                    break;
                  }

                  else if(text[i] + ' ' + text[(i + 1)] === subDevices[keyword].subDevices[k].toUpperCase()) {
                    commands[j].device = keyword;
                    commands[j].subDevice = subDevices[keyword].subDevices[k];

                    i += 1;

                    break;
                  }

                  else if(text[i] === subDevices[keyword].subDevices[k].toUpperCase()) {
                    commands[j].device = keyword;
                    commands[j].subDevice = subDevices[keyword].subDevices[k];
                  }

                  // When we have a pair of action + command, we can start looking for
                  // our next command.
                  if((commands[j].action) && (commands[j].device)) {
                    j += 1;

                    commands[j] = { action : null, device : null, subdevice : null };
                  }
                }
              }
            }
          }

          // Look through each device and compare with the "title" used in the
          // navigation.
          for(keyword in controllers) {
            if(keyword !== 'config') {
              // Look ahead for device names that may be multiple words.
              if(text[i] + ' ' + text[(i + 1)] + ' ' + text[(i + 2)] === controllers[keyword].config.title.toUpperCase()) {
                commands[j].device = keyword;

                i += 2;

                break;
              }

              else if(text[i] + ' ' + text[(i + 1)] === controllers[keyword].config.title.toUpperCase()) {
                commands[j].device = keyword;

                i += 1;

                break;
              }

              else if(text[i] === controllers[keyword].config.title.toUpperCase()) {
                commands[j].device = keyword;
              }

              // When we have a pair of action + command, we can start looking for
              // our next command.
              if((commands[j].action) && (commands[j].device)) {
                j += 1;

                commands[j] = { action : null, device : null, subdevice : null };
              }
            }
          }
        }

        if((commands[0].device) && (commands[0].action)) {
          acted = true;

          for(keyword in commands) {
            if((commands[keyword].device) && (commands[keyword].action)) {
              if(commands[keyword].subDevice) {
                commands[keyword].action = 'subdevice-' + commands[keyword].action.toLowerCase() + '-' + commands[keyword].subDevice;
              }

              runCommand.runCommand(commands[keyword].device, commands[keyword].action, 'single');
            }
          }
        }

        return acted;
      };