| 
				
			 | 
			
			 | 
			@@ -4,20 +4,24 @@ module.exports = function(RED) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					this.config = config; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        this.state = {}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					var node = this; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					var NodeHelper = require('./NodeHelper.js'); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					var fs = require('fs'); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					var h = new NodeHelper(node); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					var decimal = /^\s*[+-]{0,1}\s*([\d]+(\.[\d]*)*)\s*$/ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					// Delete persistent states on change/deploy | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					DeletePersistFile(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					// Helper for the config html, to be able to delete the peristent states file | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					RED.httpAdmin.get("/stateoperation_delete", RED.auth.needsPermission('BooleanLogicUltimate.read'), function (req, res) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						//node.send({ req: req }); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						DeletePersistFile(req.query.nodeid); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						res.json({ status: 220 }); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					}); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					// Populate the state array with the persisten file | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (this.config.persist == true) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (node.config.persist == true) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						try { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							var contents = fs.readFileSync(node.id.toString()).toString(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							var contents = fs.readFileSync("states/" + node.id.toString()).toString(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							if (typeof contents !== 'undefined') { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								node.state = JSON.parse(contents); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								node.status({fill: "blue",shape: "ring",text: "Loaded persistent states (" + Object.keys(this.state).length + " total)."}); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								node.status({fill: "blue",shape: "ring",text: "Loaded persistent states (" + Object.keys(node.state).length + " total)."}); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} catch (error) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							node.status({fill: "grey",shape: "ring",text: "No persistent states"}); | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -34,14 +38,15 @@ module.exports = function(RED) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if (topic !== undefined && payload !== undefined) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							var value = h.ToBoolean( payload ); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							var value = ToBoolean( payload ); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							var state = node.state; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							state[topic] = value; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							// Sabe the state array to a perisistent file | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							if (this.config.persist == true) {  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								fs.writeFileSync(this.id.toString(),JSON.stringify(state)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								if (!fs.existsSync("states")) fs.mkdirSync("states"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								fs.writeFileSync("states/" + node.id.toString(),JSON.stringify(state)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
											 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							// Do we have as many inputs as we expect? | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -53,12 +58,12 @@ module.exports = function(RED) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								var resOR = CalculateResult("OR"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								var resXOR = CalculateResult("XOR"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								if (this.config.filtertrue == "onlytrue") { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								if (node.config.filtertrue == "onlytrue") { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
									if (!resAND) { resAND = null }; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
									if (!resOR) { resOR = null }; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
									if (!resXOR) { resXOR = null }; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								h.SetResult(resAND,resOR,resXOR, node.config.topic); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								SetResult(resAND,resOR,resXOR, node.config.topic); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							else if(keyCount > node.config.inputCount ) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								node.warn(  | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -67,18 +72,30 @@ module.exports = function(RED) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
										+ " [Logic]: More than the specified "  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
										+ node.config.inputCount + " topics received, resetting. Will not output new value until " + node.config.inputCount + " new topics have been received."); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								node.state = {}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								h.DisplayUnkownStatus(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								DisplayUnkownStatus(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        }); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					}); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					function DeletePersistFile (){ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					this.on('close', function(removed, done) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if (removed) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							// This node has been deleted | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							// Delete persistent states on change/deploy | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							DeletePersistFile(node.id); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							// This node is being restarted | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						done(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					}); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					function DeletePersistFile (_nodeid){ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						// Detele the persist file | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						var _node = RED.nodes.getNode(_nodeid); // Gets node object from nodeit, because when called from the config html, the node object is not defined | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						try { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							fs.unlinkSync(node.id.toString()); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							node.status({fill: "red",shape: "ring",text: "Persistent states deleted."}); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							fs.unlinkSync("states/" + _nodeid.toString()); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							_node.status({fill: "red",shape: "ring",text: "Persistent states deleted ("+_nodeid.toString()+")."}); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} catch (error) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							node.status({fill: "red",shape: "ring",text: "Error deleting persistent file: " + error.toString()}); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							_node.status({fill: "red",shape: "ring",text: "Error deleting persistent file: " + error.toString()}); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
	
		
			
			| 
				
			 | 
			
			 | 
			@@ -132,7 +149,71 @@ module.exports = function(RED) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						return res; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					function ToBoolean( value ) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						var res = false; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if (typeof value === 'boolean') { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							res = value; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						}  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						else if( typeof value === 'number' || typeof value === 'string' ) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							// Is it formated as a decimal number? | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							if( decimal.test( value ) ) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								var v = parseFloat( value ); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								res = v != 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								res = value.toLowerCase() === "true"; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						return res; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					function DisplayStatus ( value ) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						node.status(  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							{  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								fill: value ? "green" : "red",  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								shape: value ? "dot" : "ring",  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								text: value ? "true" : "false"  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					function DisplayUnkownStatus () { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						node.status(  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							{  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								fill: "gray",  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								shape: "dot",  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								text: "Unknown"  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							}); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					function SetResult( _valueAND, _valueOR, _valueXOR, optionalTopic ) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						DisplayStatus( "AND:" + _valueAND + " OR:" +_valueOR + " XOR:" +_valueXOR); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if (_valueAND!=null){ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							var msgAND = {  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								topic: optionalTopic === undefined ? "result" : optionalTopic, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								operation:"AND", | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								payload: _valueAND | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if (_valueOR!=null){ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							var msgOR = {  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								topic: optionalTopic === undefined ? "result" : optionalTopic, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								operation:"OR", | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								payload: _valueOR | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if (_valueXOR!=null){ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							var msgXOR = {  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								topic: optionalTopic === undefined ? "result" : optionalTopic, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								operation:"XOR", | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								payload: _valueXOR | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						node.send([msgAND,msgOR,msgXOR]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					}; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    }	 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    RED.nodes.registerType("BooleanLogicUltimate",BooleanLogicUltimate); |