Update machine settings at various moments over time period I have the actions and the times in an instructions.js file:

module.exports = {
  temperature : {
    "00:00" : 100,
    "01:00" : 110,
    "02:00" : 120,
    "03:00" : 130
  },
  ventilation : {
    "00:00" : 0,
    "00:30" : 25,
    "01:30" : 75,
    "02:30" : 100
  },
  end : "03:30"
}


Then after importing the instructions,

function adjustMachineParams() {
  if (instructions.temperature[machineTime()]) {
    var temp = instructions.temperature[machineTime()];
    machine.setTemperature(temp);
  }
  if (instructions. ventilation[machineTime()]) {
    var vent = instructions.ventilation[machineTime()];
    machine.setVentilation(vent);
  }
  if (machineTime() == instructions.end) {
    machine.stop();
  }
}

function machineTime() {
  var date = new Date(null);
  date.setSeconds(machineTimer/10); // machineTimer is in deciseconds
  return date.toISOString().substr(14, 5);
}


And finally, the machine loop...

var machineLoop = setInterval(function() {
    adjustMachineParams()
    machineTimer += 10;
  }
}, 1000)


Looking for feedback on the way that I have set up the instructions and also the general strategy and elegance (or lack of it) of the code.
To be honest: Not a very elegant approach.

Let's have a look at a different hypothetical sample data to see where it breaks:

module.exports = {
  temperature : {
    "00:00" : 100,
    "01:05" : 110,
  },
  ventilation : {
    "00:00" : 0,
    "00:30" : 25,
  },
  end : "01:35"
}


And the machine did not stop. Why?

Because you are only handling multiples of 10 seconds, and everything in between is never matched by your string comparisons.



Specifying the times as strings for readability in the config module is reasonable, so let's keep this as a requirement for now.

This leaves us with either increasing the sample rate on the timer, or with refactoring the logic which handles the state at any given point in time. Since the sample rate can't be increased arbitrarily, let's go with refactoring the logic.



Tracking the machines state is the key here. Right now, your state only contains machineTimer. However, it should also contain some information which allows to decide which instructions have been executed yet, and which don't.

For simplicity, let's just call that one machineLastUpdate, and assume that everything up to the time stamp recorded in that variable has already run.

With that, simply reverse the logic. Instead of converting machineTimer to string, instead convert the times from the configuration into seconds. For every converted time stamp, execute the correlating command exactly when timestamp &gt; machineLastUpdate &amp;&amp; timestamp &lt;= machineTimer.

This approach ensures that all defined commands are executed exactly once - regardless of whether your timer can provide that resolution.




  // machineTimer is in deciseconds


This is somewhat pointless in Javascript, it's a double precision float anyway.

Unless you have a good reason to specifically use deciseconds, just stick with the established standard of using seconds as the unit for all time stamps.



machineTimer += 10;


Beware that setInterval can have a drift, or may even skip invocations when missing the time window. If you need accuracy for longer runs, instead better sample the system time at every invocation instead to determine the real time offset since the machine was started.