/**
 * Copyright 2017 M. I. Bell
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 **/
module.exports = function(RED) {
    function GateNode(config) {
        RED.nodes.createNode(this,config);
        const openStatus = {fill:"green",shape:"dot",text:"open"};
        const closedStatus = {fill:'red',shape:'ring',text:'closed'};
        var status;
        // Copy configuration items
        this.controlTopic = config.controlTopic.toLowerCase();
        this.openCmd = config.openCmd.toLowerCase();
        this.closeCmd = config.closeCmd.toLowerCase();
        this.toggleCmd = config.toggleCmd.toLowerCase();
        this.defaultCmd = config.defaultCmd.toLowerCase();
        this.defaultState = config.defaultState.toLowerCase();
        this.persist = config.persist;
        // Save "this" object
        var node = this
        var context = node.context();
        var persist = node.persist;
        var state = context.get('state'); //debug
        if (!persist || typeof state === 'undefined') {
            state = node.defaultState;
        }
        context.set('state',state);
        // Show status
        status = (state === 'open') ? openStatus:closedStatus;
        node.status(status);
        // Process inputs
        node.on('input', function(msg) {
            state = context.get('state');
           // Change state
            if (msg.topic !== undefined && msg.topic.toLowerCase() === node.controlTopic) {
                switch (msg.payload.toLowerCase()) {
                    case node.openCmd:
                        state = 'open';
                        break;
                    case node.closeCmd:
                        state = 'closed';
                        break;
                    case node.toggleCmd:
                        if (state === 'open') {
                            state = 'closed';
                        } else {
                            state = 'open';
                        }
                        break;
                    case node.defaultCmd:
                        state = node.defaultState;
                        break;
                    default:
                        node.error('Invalid command');
                        break;
                }
                // Save state
                context.set('state',state);
                // Show status
                status = (state === 'open') ? openStatus:closedStatus;
                node.status(status);
                node.send(null);
            }
            // Transmit message
            else if (state === 'open') {
                    node.send(msg);
                } else {
                    node.send(null);
            }
        });
    }
    RED.nodes.registerType("gate",GateNode);
}

@@ -1933,24 +1933,170 @@
 rolTopic) %7B%0A
+                if (typeof msg.payload != 'string')%7B%0A                    node.error('Command must be a string');%0A                    %7D else %7B%0A    
             
@@ -2148,32 +2148,36 @@
                 
+    
 case node.openCm
@@ -2195,32 +2195,36 @@
                 
+ 
+   
 state = 'open';%0A
@@ -2239,32 +2239,36 @@
                 
+    
 break;%0A         
@@ -2270,32 +2270,36 @@
                 
+  
+  
 case node.closeC
@@ -2318,32 +2318,36 @@
                 
+    
 state = 'closed'
@@ -2364,39 +2364,47 @@
                 
+  
+  
 break;%0A
+    
                 
@@ -2448,24 +2448,28 @@
             
+   
+ 
 if (state ==
@@ -2500,32 +2500,36 @@
                 
+    
 state = 'closed'
@@ -2546,32 +2546,36 @@
                 
+   
+ 
 %7D else %7B%0A       
@@ -2559,32 +2559,36 @@
        %7D else %7B%0A
+    
                 
@@ -2631,34 +2631,42 @@
                 
-%7D%0A
+    %7D%0A    
                 
@@ -2692,32 +2692,36 @@
                 
+   
+ 
 case node.defaul
@@ -2722,24 +2722,28 @@
 defaultCmd:%0A
+    
             
@@ -2797,39 +2797,47 @@
                 
+    
 break;%0A
+    
                 
@@ -2849,16 +2849,20 @@
 efault:%0A
+    
         
@@ -2924,32 +2924,36 @@
                 
+    
 break;%0A         
@@ -2951,32 +2951,36 @@
                 
+    
 %7D%0A              
@@ -2973,32 +2973,36 @@
                 
+ 
+   
 // Save state%0A  
@@ -2991,32 +2991,36 @@
   // Save state%0A
+    
                 
@@ -3055,32 +3055,36 @@
                 
+ 
+   
 // Show status%0A 
@@ -3074,32 +3074,36 @@
  // Show status%0A
+    
                 
@@ -3165,32 +3165,36 @@
                 
+    
 node.status(stat
@@ -3206,32 +3206,36 @@
                 
+    
 node.send(null);
@@ -3227,32 +3227,50 @@
 ode.send(null);%0A
+                %7D%0A
             %7D%0A  

test for invalid control inputs