Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

96 lines
2.4KB

  1. // Licensed under the MIT license, see LICENSE file.
  2. // Author: Per Malmberg (https://github.com/PerMalmberg)
  3. module.exports = function(RED) {
  4. function BooleanLogic(config) {
  5. RED.nodes.createNode(this,config);
  6. this.config = config;
  7. this.state = {};
  8. var node = this;
  9. var NodeHelper = require('./NodeHelper.js');
  10. var h = new NodeHelper( node );
  11. this.on('input', function(msg) {
  12. var topic = msg.topic;
  13. var payload = msg.payload;
  14. if( topic !== undefined && payload !== undefined ) {
  15. var value = h.ToBoolean( payload );
  16. var state = node.state;
  17. state[topic] = value;
  18. // Do we have as many inputs as we expect?
  19. var keyCount = Object.keys(state).length;
  20. if( keyCount == node.config.inputCount ) {
  21. var res = CalculateResult();
  22. h.SetResult( res, node.config.topic );
  23. }
  24. else if(keyCount > node.config.inputCount ) {
  25. node.warn(
  26. (node.config.name !== undefined && node.config.name.length > 0
  27. ? node.config.name : "BooleanLogic")
  28. + " [" + node.config.operation + "]: More than the specified "
  29. + node.config.inputCount + " topics received, resetting. Will not output new value until " + node.config.inputCount + " new topics have been received.");
  30. node.state = {};
  31. h.DisplayUnkownStatus();
  32. }
  33. }
  34. });
  35. function CalculateResult() {
  36. var res;
  37. if( node.config.operation == "XOR") {
  38. res = PerformXOR();
  39. }
  40. else {
  41. // We need a starting value to perform AND and OR operations.
  42. var keys = Object.keys(node.state);
  43. res = node.state[keys[0]];
  44. for( var i = 1; i < keys.length; ++i ) {
  45. var key = keys[i];
  46. res = PerformSimpleOperation( node.config.operation, res, node.state[key] );
  47. }
  48. }
  49. return res;
  50. }
  51. function PerformXOR()
  52. {
  53. // XOR = exclusively one input is true. As such, we just count the number of true values and compare to 1.
  54. var trueCount = 0;
  55. for( var key in node.state ) {
  56. if( node.state[key] ) {
  57. trueCount++;
  58. }
  59. }
  60. return trueCount == 1;
  61. }
  62. function PerformSimpleOperation( operation, val1, val2 ) {
  63. var res;
  64. if( operation === "AND" ) {
  65. res = val1 && val2;
  66. }
  67. else if( operation === "OR" ) {
  68. res = val1 || val2;
  69. }
  70. else {
  71. node.error( "Unknown operation: " + operation );
  72. }
  73. return res;
  74. }
  75. h.DisplayUnkownStatus();
  76. }
  77. RED.nodes.registerType("BooleanLogic",BooleanLogic);
  78. }