Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

139 lines
3.7KB

  1. module.exports = function(RED) {
  2. function BooleanLogicUltimate(config) {
  3. RED.nodes.createNode(this,config);
  4. this.config = config;
  5. this.state = {};
  6. var node = this;
  7. var NodeHelper = require('./NodeHelper.js');
  8. var fs = require('fs');
  9. var h = new NodeHelper(node);
  10. // Delete persistent states on change/deploy
  11. DeletePersistFile();
  12. // Populate the state array with the persisten file
  13. if (this.config.persist == true) {
  14. try {
  15. var contents = fs.readFileSync(node.id.toString()).toString();
  16. if (typeof contents !== 'undefined') {
  17. node.state = JSON.parse(contents);
  18. node.status({fill: "blue",shape: "ring",text: "Loaded persistent states (" + Object.keys(this.state).length + " total)."});
  19. }
  20. } catch (error) {
  21. node.status({fill: "grey",shape: "ring",text: "No persistent states"});
  22. }
  23. } else {
  24. node.status({fill: "yellow",shape: "dot",text: "Waiting for input states"});
  25. }
  26. this.on('input', function (msg) {
  27. var topic = msg.topic;
  28. var payload = msg.payload;
  29. if (topic !== undefined && payload !== undefined) {
  30. var value = h.ToBoolean( payload );
  31. var state = node.state;
  32. state[topic] = value;
  33. // Sabe the state array to a perisistent file
  34. if (this.config.persist == true) {
  35. fs.writeFileSync(this.id.toString(),JSON.stringify(state));
  36. }
  37. // Do we have as many inputs as we expect?
  38. var keyCount = Object.keys(state).length;
  39. if( keyCount == node.config.inputCount ) {
  40. var resAND = CalculateResult("AND");
  41. var resOR = CalculateResult("OR");
  42. var resXOR = CalculateResult("XOR");
  43. if (this.config.filtertrue == "onlytrue") {
  44. if (!resAND) { resAND = null };
  45. if (!resOR) { resOR = null };
  46. if (!resXOR) { resXOR = null };
  47. }
  48. h.SetResult(resAND,resOR,resXOR, node.config.topic);
  49. }
  50. else if(keyCount > node.config.inputCount ) {
  51. node.warn(
  52. (node.config.name !== undefined && node.config.name.length > 0
  53. ? node.config.name : "BooleanLogicUltimate")
  54. + " [Logic]: More than the specified "
  55. + node.config.inputCount + " topics received, resetting. Will not output new value until " + node.config.inputCount + " new topics have been received.");
  56. node.state = {};
  57. h.DisplayUnkownStatus();
  58. }
  59. }
  60. });
  61. function DeletePersistFile (){
  62. // Detele the persist file
  63. try {
  64. fs.unlinkSync(node.id.toString());
  65. node.status({fill: "red",shape: "ring",text: "Persistent states deleted."});
  66. } catch (error) {
  67. node.status({fill: "red",shape: "ring",text: "Error deleting persistent file: " + error.toString()});
  68. }
  69. }
  70. function CalculateResult(_operation) {
  71. var res;
  72. if( _operation == "XOR") {
  73. res = PerformXOR();
  74. }
  75. else {
  76. // We need a starting value to perform AND and OR operations.
  77. var keys = Object.keys(node.state);
  78. res = node.state[keys[0]];
  79. for( var i = 1; i < keys.length; ++i ) {
  80. var key = keys[i];
  81. res = PerformSimpleOperation( _operation, res, node.state[key] );
  82. }
  83. }
  84. return res;
  85. }
  86. function PerformXOR()
  87. {
  88. // XOR = exclusively one input is true. As such, we just count the number of true values and compare to 1.
  89. var trueCount = 0;
  90. for( var key in node.state ) {
  91. if( node.state[key] ) {
  92. trueCount++;
  93. }
  94. }
  95. return trueCount == 1;
  96. }
  97. function PerformSimpleOperation( operation, val1, val2 ) {
  98. var res;
  99. if( operation === "AND" ) {
  100. res = val1 && val2;
  101. }
  102. else if( operation === "OR" ) {
  103. res = val1 || val2;
  104. }
  105. else {
  106. node.error( "Unknown operation: " + operation );
  107. }
  108. return res;
  109. }
  110. }
  111. RED.nodes.registerType("BooleanLogicUltimate",BooleanLogicUltimate);
  112. }