Skip to content

Complete examples

Reaction to events

Change value in variable

Detect when the input 9 changes (Variable I9) of the deviceIO. When the input is activated (value 1), activate output 0 (variable O0).

events.addListener({ eventName: 'VariableChange', deviceCode: 'IO', variableCode: 'I9' }, ev => {
  if (ev.newValue === 1) {
    logger.info('Enable variable O0');
    devices.write('IO', 'O0', 1);
  } else {
    logger.info('Disable output O0');
    devices.write('IO', 'O0', 0);
  }
});

Timer Events

We have configured on the Virtual Device Memory a variable actual_hour and actual_min that send your updates to screens and other external systems. We have created a one timer to shoot each minute (exact, second 00) with the name minuter:

Event configured to shoot with the minute change

// For ease to update the device code, We place it in a constant:
const virtualDevCode = 'memory';
events.addListener({
  eventName: 'Timer',
  timerName: 'Minuter'
},
// We can ignore the Event parameter, since we do not use its values 
// for that we create the handler that does not receive any parameter
() => {
  const date = new Date(); // We keep the current date and time and time
  // And we update both fields
  devices.write(virtualDevCode, 'actual_hour', date.getHours());
  devices.write(virtualDevCode, 'actual_min', date.getMinutes());
});

Use of GlobalData.

The variable of the GlobalData context allows you to share data between scripts. When all the scripts that have read or written on a field within GlobalData that field is eliminated; That is why it is important to use the GlobalData.RegisterVariable (Variable:String) function at the beginning of a script that may take to access the field.

In this installation the "zone" concept is handled to link variables within the same passenger compartment. It is a concept that the installer has decided, alien to adquio, but thanks to the flexibility of the scripts, it is allowed to handle them easily.

// In this script we are going to make common initializations. 
 // By simplifying the example we will only show the map that links the zones 
 // And the air units that climate each area.
globalData.UEByZone = {
  Principal: ['UE_01', 'UE_02'],
  Admin: ['UE_03', 'UE_04'],
  Salon1: ['UE_05'],
  Salon2: ['UE_06', 'UE_07'],
  Reception: ['UE_08']
};
//We started the variable Onzones if it has no value, which will save the zones with climate on. 
// In this case we will use an JavaScript set, a set is a special list  that it does not do
// anything if you try to add the same value twice.
globalData.onZones = globalData.onZones || new Set();

events.addListener((ev) => ev.eventName === 'Timer' && (ev.timerName.startsWith('On') || ev.timerName.startsWith('Off')), (ev) => {
  // We detect if the event is on or off
  const isOn = ev.timerName.startsWith('On');
  // In this case, the zone goes in the name of the event
  // After the words "on" or "off"
  const zone = ev.timerName.replace('Off', '').replace('On', '');
  // We add or eliminate the area of the Set
  if(isOn) globalData.onZones.add(zone);
  else globalData.onZones.delete(zone);
});

In the following script we will use the Data of Onzones to react depending on whether the area is active or not active:

// Link this script to Onzones and UeByZone, so that the variable does not disappear
// By making changes in previous scripts
globalData.registerVariableUse('onZones');
globalData.registerVariableUse('UEByZone');

// We can define a Arrow function, so that it is more readable to check onzones
const isZoneOn = zone => globalData.onZones.has(zone);

events.addListener({
  eventName: 'VariableChange',
  deviceCode: virtualDevCode
}, (ev) => {
  if (ev.variableCode.startsWith('TempSet')) {
    // We know that the variable begins with tempset (length 7) and follows the 
    // Name of the zone. So we can stay only with the name of the area:
    const zoneName = ev.variableCode.substring(7);

    // We are only interested in doing this writing if the area is on
    if(isZoneOn(zoneName)) {
      try {
        //we go through all the air units of the area with the new value
        globalData.UEByZone[zoneName].forEach(ueCode => {
          devices.write(ueCode, 'SET_TSET', ev.newValue);
        });
      } catch (err) {
        // We handle the possible error. You have to keep in mind that this makes 
        // Stop writing with the first error, we could put the TRY {} around 
        // of each scripture so that the following yes are carried out
        logger.error('Problem in TempSet handler', zoneName, err);
      }
    }
  }
}

Postpone a reaction or action

Act before a change of variable, but postpone it 10 seconds and only execute it once for every 10 seconds:

let timer;
events.addListener({eventName: 'NewVariablesHistoric'}, () => {
  // If there is an active timer, we deactivate it and erase the variable
  if(timer) {
    clearTimeout(timer);
    timer = null;
  }
  timer = setTimeout(() => {
    //Code that we want to execute with the event
  }, 10 * 1000 /* Settimeout specifies the time in thousandths of a second */);
});

Error handling

Read outdoor temperature variable, if reading fails to use another method consisting of reading an equivalent variable of the specified machine.

const getExternalTemp = machine => {
  let externalTemp;
  try {
    externalTemp = devices.read('Recuperator', 'Exterior_Temperature');
  } catch (err) {
    logger.error('externalTemp: Could not be read ', err, machine);
  }
  // If the variable has not been read or has not returned the reading value
  if(externalTemp === undefined) {
    try {
    externalTemp = devices.read(machine, 'EXT_TEMP');
    } catch (err) {
      logger.error('Alternative reading also failed', err);
    }
  }
  return externalTemp;
}