mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Merge branch 'dev' into pr_2229
This commit is contained in:
		| @@ -54,12 +54,9 @@ | ||||
|         "mqtt": "2.18.8", | ||||
|         "multer": "1.4.1", | ||||
|         "mustache": "3.0.1", | ||||
|         "node-red-node-email": "^1.6.2", | ||||
|         "node-red-node-feedparser": "^0.1.14", | ||||
|         "node-red-node-rbe": "^0.2.4", | ||||
|         "node-red-node-sentiment": "^0.1.3", | ||||
|         "node-red-node-tail": "^0.0.2", | ||||
|         "node-red-node-twitter": "^1.1.5", | ||||
|         "nopt": "4.0.1", | ||||
|         "oauth2orize": "1.11.0", | ||||
|         "on-headers": "1.0.2", | ||||
| @@ -112,7 +109,7 @@ | ||||
|         "wdio-mocha-framework": "^0.6.4", | ||||
|         "wdio-spec-reporter": "^0.1.5", | ||||
|         "webdriverio": "^4.14.1", | ||||
|         "node-red-node-test-helper": "^0.2.2", | ||||
|         "node-red-node-test-helper": "^0.2.3", | ||||
|         "jsdoc-nr-template": "node-red/jsdoc-nr-template" | ||||
|     }, | ||||
|     "engines": { | ||||
|   | ||||
| @@ -17,6 +17,8 @@ RED.nodes = (function() { | ||||
|  | ||||
|     var node_defs = {}; | ||||
|     var nodes = []; | ||||
|     var nodeTabMap = {}; | ||||
|  | ||||
|     var configNodes = {}; | ||||
|     var links = []; | ||||
|     var defaultWorkspace; | ||||
| @@ -213,6 +215,11 @@ RED.nodes = (function() { | ||||
|                 n.i = nextId+1; | ||||
|             } | ||||
|             nodes.push(n); | ||||
|             if (nodeTabMap[n.z]) { | ||||
|                 nodeTabMap[n.z][n.id] = n; | ||||
|             } else { | ||||
|                 console.warn("Node added to unknown tab/subflow:",n); | ||||
|             } | ||||
|         } | ||||
|         RED.events.emit('nodes:add',n); | ||||
|     } | ||||
| @@ -246,6 +253,9 @@ RED.nodes = (function() { | ||||
|             node = getNode(id); | ||||
|             if (node) { | ||||
|                 nodes.splice(nodes.indexOf(node),1); | ||||
|                 if (nodeTabMap[node.z]) { | ||||
|                     delete nodeTabMap[node.z][node.id]; | ||||
|                 } | ||||
|                 removedLinks = links.filter(function(l) { return (l.source === node) || (l.target === node); }); | ||||
|                 removedLinks.forEach(function(l) {links.splice(links.indexOf(l), 1); }); | ||||
|                 var updatedConfigNode = false; | ||||
| @@ -300,6 +310,8 @@ RED.nodes = (function() { | ||||
|  | ||||
|     function addWorkspace(ws,targetIndex) { | ||||
|         workspaces[ws.id] = ws; | ||||
|         nodeTabMap[ws.id] = {}; | ||||
|  | ||||
|         ws._def = RED.nodes.getType('tab'); | ||||
|         if (targetIndex === undefined) { | ||||
|             workspacesOrder.push(ws.id); | ||||
| @@ -312,6 +324,7 @@ RED.nodes = (function() { | ||||
|     } | ||||
|     function removeWorkspace(id) { | ||||
|         delete workspaces[id]; | ||||
|         delete nodeTabMap[ws.id]; | ||||
|         workspacesOrder.splice(workspacesOrder.indexOf(id),1); | ||||
|  | ||||
|         var removedNodes = []; | ||||
| @@ -357,6 +370,8 @@ RED.nodes = (function() { | ||||
|             sf.name = subflowName; | ||||
|         } | ||||
|         subflows[sf.id] = sf; | ||||
|         nodeTabMap[sf.id] = {}; | ||||
|  | ||||
|         RED.nodes.registerType("subflow:"+sf.id, { | ||||
|             defaults:{ | ||||
|                 name:{value:""}, | ||||
| @@ -393,6 +408,7 @@ RED.nodes = (function() { | ||||
|     } | ||||
|     function removeSubflow(sf) { | ||||
|         delete subflows[sf.id]; | ||||
|         delete nodeTabMap[sf.id]; | ||||
|         registry.removeNodeType("subflow:"+sf.id); | ||||
|     } | ||||
|  | ||||
| @@ -1266,12 +1282,13 @@ RED.nodes = (function() { | ||||
|     // TODO: supports filter.z|type | ||||
|     function filterNodes(filter) { | ||||
|         var result = []; | ||||
|         var searchSet = nodes; | ||||
|         if (filter.hasOwnProperty("z") && Object.hasOwnProperty("values") && nodeTabMap.hasOwnProperty(filter.z) ) { | ||||
|             searchSet = Object.values(nodeTabMap[filter.z]); | ||||
|         } | ||||
|  | ||||
|         for (var n=0;n<nodes.length;n++) { | ||||
|             var node = nodes[n]; | ||||
|             if (filter.hasOwnProperty("z") && node.z !== filter.z) { | ||||
|                 continue; | ||||
|             } | ||||
|         for (var n=0;n<searchSet.length;n++) { | ||||
|             var node = searchSet[n]; | ||||
|             if (filter.hasOwnProperty("type") && node.type !== filter.type) { | ||||
|                 continue; | ||||
|             } | ||||
| @@ -1339,6 +1356,7 @@ RED.nodes = (function() { | ||||
|     function clear() { | ||||
|         nodes = []; | ||||
|         links = []; | ||||
|         nodeTabMap = {}; | ||||
|         configNodes = {}; | ||||
|         workspacesOrder = []; | ||||
|         var subflowIds = Object.keys(subflows); | ||||
|   | ||||
| @@ -1,544 +0,0 @@ | ||||
| <style> | ||||
|     .rpi-gpio-pinTable { | ||||
|         width: 340px; | ||||
|         display: inline-table; | ||||
|         font-size: 13px; | ||||
|         height: 380px; | ||||
|         min-height: 380px; | ||||
|         max-height: 380px; | ||||
|     } | ||||
|     .rpi-gpio-pinTable input[type="radio"] { | ||||
|         width: auto; | ||||
|         margin: 2px 2px; | ||||
|     } | ||||
|     .rpi-gpio-pinTable label { | ||||
|         width: auto; | ||||
|         margin: 0; | ||||
|         display: block; | ||||
|     } | ||||
|     .rpi-gpio-pinTable .pinTableBody { | ||||
|         width: 340px; | ||||
|         display: table-row-group; | ||||
|         line-height: 12px; | ||||
|     } | ||||
|     .rpi-gpio-pinTable .pinTableRow { | ||||
|         width: 340px; | ||||
|         display: table-row; | ||||
|         height: 14px; | ||||
|     } | ||||
|     .rpi-gpio-pinTable .pinTableCellL { | ||||
|         width: 170px; | ||||
|         display: table-cell; | ||||
|         text-align: right; | ||||
|         padding-right: 4px; | ||||
|         vertical-align: top; | ||||
|         border: 1px solid #444; | ||||
|     } | ||||
|     .rpi-gpio-pinTable .pinTableCellR { | ||||
|         width: 170px; | ||||
|         display: table-cell; | ||||
|         text-align: left; | ||||
|         padding-left: 4px; | ||||
|         vertical-align: top; | ||||
|         border: 1px solid #000; | ||||
|     } | ||||
|     .rpi-gpio-pinTable .pinColorPower { | ||||
|         background-color:#FECBCE; | ||||
|     } | ||||
|     .rpi-gpio-pinTable .pinColorGround { | ||||
|         background-color:#DDDDDD; | ||||
|     } | ||||
|     .rpi-gpio-pinTable .pinColorGPIO { | ||||
|         background-color:#BFEBBF; | ||||
|     } | ||||
|     .rpi-gpio-pinTable .pinColorDual { | ||||
|         background-color:#D0E6F4; | ||||
|     } | ||||
|     .rpi-gpio-pinTable .pinColorSD { | ||||
|         background-color:#FFFDD0; | ||||
|     } | ||||
| </style> | ||||
| <script type="text/x-red" data-template-name="rpi-gpio in"> | ||||
|  | ||||
|     <div class="form-row" style="min-width: 540px"> | ||||
|         <label><i class="fa fa-circle"></i> <span data-i18n="rpi-gpio.pinname"></span></label> | ||||
|         <input type="text" id="node-input-pin" style="display:none;"> | ||||
|         <div class="rpi-gpio-pinTable"> | ||||
|             <div class="pinTableBody" id="pinform"> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorPower"><label>3.3V Power - 1 <input disabled type="radio" name="pins" value=""></label></div> | ||||
|                     <div class="pinTableCellR pinColorPower"><label><input disabled type="radio" name="pins" value=""> 2 - 5V Power</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorDual"><label for="pinTable-pin-3">SDA1 - GPIO02 - 3 <input id="pinTable-pin-3" type="radio" name="pins" value="3"></label></div> | ||||
|                     <div class="pinTableCellR pinColorPower"><label><input disabled type="radio" name="pins" value=""> 4 - 5V Power</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorDual"><label for="pinTable-pin-5">SCL1 - GPIO03 - 5 <input id="pinTable-pin-5" type="radio" name="pins" value="5"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 6 - Ground</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-7">GPIO04 - 7 <input id="pinTable-pin-7" type="radio" name="pins" value="7"></label></div> | ||||
|                     <div class="pinTableCellR pinColorDual"><label for="pinTable-pin-8"><input id="pinTable-pin-8" type="radio" name="pins" value="8"> 8 - GPIO14 - TxD</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGround"><label>Ground - 9 <input disabled type="radio" name="pins" value=""></label></div> | ||||
|                     <div class="pinTableCellR pinColorDual"><label for="pinTable-pin-10"><input id="pinTable-pin-10" type="radio" name="pins" value="10"> 10 - GPIO15 - RxD</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-11">GPIO17 - 11 <input id="pinTable-pin-11" type="radio" name="pins" value="11"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-12"><input id="pinTable-pin-12" type="radio" name="pins" value="12"> 12 - GPIO18</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-13">GPIO27 - 13 <input id="pinTable-pin-13" type="radio" name="pins" value="13"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 14 - Ground</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-15">GPIO22 - 15 <input id="pinTable-pin-15" type="radio" name="pins" value="15"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-16"><input id="pinTable-pin-16" type="radio" name="pins" value="16"> 16 - GPIO23</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorPower"><label>3.3V Power - 17 <input disabled type="radio" name="pins" value=""></label></div> | ||||
|                     <div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-18"><input id="pinTable-pin-18" type="radio" name="pins" value="18"> 18 - GPIO24</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorDual"><label for="pinTable-pin-19">MOSI - GPIO10 - 19 <input id="pinTable-pin-19" type="radio" name="pins" value="19"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 20 - Ground</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorDual"><label for="pinTable-pin-21">MISO - GPIO09 - 21 <input id="pinTable-pin-21" type="radio" name="pins" value="21"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-22"><input id="pinTable-pin-22" type="radio" name="pins" value="22"> 22 - GPIO25</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorDual"><label for="pinTable-pin-23">SCLK - GPIO11 - 23 <input id="pinTable-pin-23" type="radio" name="pins" value="23"></label></div> | ||||
|                     <div class="pinTableCellR pinColorDual"><label for="pinTable-pin-24"><input id="pinTable-pin-24" type="radio" name="pins" value="24"> 24 - GPIO8 - CE0</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGround"><label>Ground - 25 <input disabled type="radio" name="pins" value=""></label></div> | ||||
|                     <div class="pinTableCellR pinColorDual"><label for="pinTable-pin-26"><input id="pinTable-pin-26" type="radio" name="pins" value="26"> 26 - GPIO7 - CE1</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorSD"><label>SD - 27 <input disabled type="radio" name="pins" value=""></label></div> | ||||
|                     <div class="pinTableCellR pinColorSD"><label><input disabled type="radio" name="pins" value=""> 28 - SC</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-29">GPIO05 - 29 <input id="pinTable-pin-29" type="radio" name="pins" value="29"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 30 - Ground</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-31">GPIO06 - 31 <input id="pinTable-pin-31" type="radio" name="pins" value="31"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-32"><input id="pinTable-pin-32" type="radio" name="pins" value="32"> 32 - GPIO12</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-33">GPIO13 - 33 <input id="pinTable-pin-33" type="radio" name="pins" value="33"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 34 - Ground</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-35">GPIO19 - 35 <input id="pinTable-pin-35" type="radio" name="pins" value="35"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-36"><input id="pinTable-pin-36" type="radio" name="pins" value="36"> 36 - GPIO16</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-37">GPIO26 - 37 <input id="pinTable-pin-37" type="radio" name="pins" value="37"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-38"><input id="pinTable-pin-38" type="radio" name="pins" value="38"> 38 - GPIO20</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGround"><label>Ground - 39 <input disabled type="radio" name="pins" value=""></label></div> | ||||
|                     <div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-40"><input id="pinTable-pin-40" type="radio" name="pins" value="40"> 40 - GPIO21</label></div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="form-row"> | ||||
|         <label for="node-input-intype"><i class="fa fa-level-up"></i> <span data-i18n="rpi-gpio.label.resistor"></span></label> | ||||
|         <select type="text" id="node-input-intype" style="width:100px;"> | ||||
|         <option value="tri" data-i18n="rpi-gpio.resistor.none"></option> | ||||
|         <option value="up" data-i18n="rpi-gpio.resistor.pullup"></option> | ||||
|         <option value="down" data-i18n="rpi-gpio.resistor.pulldown"></option> | ||||
|         </select> | ||||
|              <span data-i18n="rpi-gpio.label.debounce"></span> | ||||
|         <input type="text" id="node-input-debounce" style="width:47px; text-align:right"/> mS | ||||
|     </div> | ||||
|     <div class="form-row"> | ||||
|         <label> </label> | ||||
|         <input type="checkbox" id="node-input-read" style="display: inline-block; width: auto; vertical-align: top;"> | ||||
|         <label for="node-input-read" style="width:70%;"><span data-i18n="rpi-gpio.label.readinitial"></span></label> | ||||
|     </div> | ||||
|     <div class="form-row"> | ||||
|         <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> | ||||
|         <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> | ||||
|     </div> | ||||
|     <div class="form-tips" id="pin-tip"><span data-i18n="[html]rpi-gpio.tip.pin"></span></div> | ||||
|     <div class="form-tips"><span data-i18n="[html]rpi-gpio.tip.in"></span></div> | ||||
| </script> | ||||
|  | ||||
| <script type="text/javascript"> | ||||
|     var bcm2pin = { | ||||
|         "2":"3", "3":"5", "4":"7", "14":"8", "15":"10", "17":"11", "18":"12", "27":"13", "22":"15", | ||||
|         "23":"16", "24":"18", "10":"19", "9":"21", "25":"22", "11":"23", "8":"24", "7":"26", | ||||
|         "5":"29", "6":"31", "12":"32", "13":"33", "19":"35", "16":"36", "26":"37", "20":"38", "21":"40" | ||||
|     }; | ||||
|     var pinsInUse = {}; | ||||
|     RED.nodes.registerType('rpi-gpio in',{ | ||||
|         category: 'Raspberry Pi', | ||||
|         color:"#c6dbef", | ||||
|         defaults: { | ||||
|             name: { value:"" }, | ||||
|             pin: { value:"tri",required:true,validate:RED.validators.number() }, | ||||
|             intype: { value:"tri" }, | ||||
|             debounce: { value:"25" }, | ||||
|             read: { value:false } | ||||
|         }, | ||||
|         inputs:0, | ||||
|         outputs:1, | ||||
|         icon: "rpi.png", | ||||
|         info: function() { | ||||
|             if ( Object.keys(pinsInUse).length !== 0 ) { | ||||
|                 return "**Pins in use** : "+Object.keys(pinsInUse); | ||||
|             } | ||||
|             else { return ""; } | ||||
|         }, | ||||
|         label: function() { | ||||
|             var suf = ""; | ||||
|             if (this.intype === "up") { suf = "↑ "} | ||||
|             if (this.intype === "down") { suf = "↓ "} | ||||
|             return this.name || "PIN: "+suf+this.pin ; | ||||
|         }, | ||||
|         labelStyle: function() { | ||||
|             return this.name?"node_label_italic":""; | ||||
|         }, | ||||
|         outputLabels: function() { return "GPIO"+this.pin; }, | ||||
|         oneditprepare: function() { | ||||
|             var pinnow = this.pin; | ||||
|             var pintip = this._("rpi-gpio.tip.pin"); | ||||
|             var pinname = this._("rpi-gpio.pinname"); | ||||
|             var alreadyuse = this._("rpi-gpio.alreadyuse"); | ||||
|             var alreadyset = this._("rpi-gpio.alreadyset"); | ||||
|  | ||||
|             $.getJSON('rpi-pins/'+this.id,function(data) { | ||||
|                 pinsInUse = data || {}; | ||||
|                 $('#pin-tip').html(pintip + Object.keys(data)); | ||||
|             }); | ||||
|             $("#node-input-pin").on("change", function() { | ||||
|                 if ($("#node-input-pin").val()) { | ||||
|                     $("#pinform input[value="+$("#node-input-pin").val()+"]").prop('checked', true); | ||||
|                 } | ||||
|                 var pinnew = $("#node-input-pin").val(); | ||||
|                 if ((pinnew) && (pinnew !== pinnow)) { | ||||
|                     if (pinsInUse.hasOwnProperty(pinnew)) { | ||||
|                         RED.notify(pinname+" "+pinnew+" "+alreadyuse,"warn"); | ||||
|                     } | ||||
|                     pinnow = pinnew; | ||||
|                 } | ||||
|             }); | ||||
|             $("#node-input-intype").on("change", function() { | ||||
|                 var newtype = $("#node-input-intype").val(); | ||||
|                 if ((pinsInUse.hasOwnProperty(pinnow)) && (pinsInUse[pinnow] !== newtype)) { | ||||
|                     RED.notify(pinname+" "+pinnow+" "+alreadyset+" "+pinsInUse[pinnow],"error"); | ||||
|                 } | ||||
|             }); | ||||
|             $('#pinform input').on('change', function() { | ||||
|                 this.pin = $("#pinform input[type='radio']:checked").val(); | ||||
|                 $("#node-input-pin").val(this.pin); | ||||
|             }); | ||||
|         } | ||||
|     }); | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-template-name="rpi-gpio out"> | ||||
|     <div class="form-row" style="min-width: 540px"> | ||||
|         <label><i class="fa fa-circle"></i> <span data-i18n="rpi-gpio.pinname"></span></label> | ||||
|         <input type="text" id="node-input-pin" style="display:none;"> | ||||
|         <div class="rpi-gpio-pinTable"> | ||||
|             <div class="pinTableBody" id="pinform"> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorPower"><label>3.3V Power - 1 <input disabled type="radio" name="pins" value=""></label></div> | ||||
|                     <div class="pinTableCellR pinColorPower"><label><input disabled type="radio" name="pins" value=""> 2 - 5V Power</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorDual"><label for="pinTable-pin-3">SDA1 - GPIO02 - 3 <input id="pinTable-pin-3" type="radio" name="pins" value="3"></label></div> | ||||
|                     <div class="pinTableCellR pinColorPower"><label><input disabled type="radio" name="pins" value=""> 4 - 5V Power</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorDual"><label for="pinTable-pin-5">SCL1 - GPIO03 - 5 <input id="pinTable-pin-5" type="radio" name="pins" value="5"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 6 - Ground</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-7">GPIO04 - 7 <input id="pinTable-pin-7" type="radio" name="pins" value="7"></label></div> | ||||
|                     <div class="pinTableCellR pinColorDual"><label for="pinTable-pin-8"><input id="pinTable-pin-8" type="radio" name="pins" value="8"> 8 - GPIO14 - TxD</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGround"><label>Ground - 9 <input disabled type="radio" name="pins" value=""></label></div> | ||||
|                     <div class="pinTableCellR pinColorDual"><label for="pinTable-pin-10"><input id="pinTable-pin-10" type="radio" name="pins" value="10"> 10 - GPIO15 - RxD</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-11">GPIO17 - 11 <input id="pinTable-pin-11" type="radio" name="pins" value="11"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-12"><input id="pinTable-pin-12" type="radio" name="pins" value="12"> 12 - GPIO18</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-13">GPIO27 - 13 <input id="pinTable-pin-13" type="radio" name="pins" value="13"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 14 - Ground</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-15">GPIO22 - 15 <input id="pinTable-pin-15" type="radio" name="pins" value="15"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-16"><input id="pinTable-pin-16" type="radio" name="pins" value="16"> 16 - GPIO23</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorPower"><label>3.3V Power - 17 <input disabled type="radio" name="pins" value=""></label></div> | ||||
|                     <div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-18"><input id="pinTable-pin-18" type="radio" name="pins" value="18"> 18 - GPIO24</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorDual"><label for="pinTable-pin-19">MOSI - GPIO10 - 19 <input id="pinTable-pin-19" type="radio" name="pins" value="19"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 20 - Ground</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorDual"><label for="pinTable-pin-21">MISO - GPIO09 - 21 <input id="pinTable-pin-21" type="radio" name="pins" value="21"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-22"><input id="pinTable-pin-22" type="radio" name="pins" value="22"> 22 - GPIO25</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorDual"><label for="pinTable-pin-23">SCLK - GPIO11 - 23 <input id="pinTable-pin-23" type="radio" name="pins" value="23"></label></div> | ||||
|                     <div class="pinTableCellR pinColorDual"><label for="pinTable-pin-24"><input id="pinTable-pin-24" type="radio" name="pins" value="24"> 24 - GPIO8 - CE0</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGround"><label>Ground - 25 <input disabled type="radio" name="pins" value=""></label></div> | ||||
|                     <div class="pinTableCellR pinColorDual"><label for="pinTable-pin-26"><input id="pinTable-pin-26" type="radio" name="pins" value="26"> 26 - GPIO7 - CE1</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorSD"><label>SD - 27 <input disabled type="radio" name="pins" value=""></label></div> | ||||
|                     <div class="pinTableCellR pinColorSD"><label><input disabled type="radio" name="pins" value=""> 28 - SC</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-29">GPIO05 - 29 <input id="pinTable-pin-29" type="radio" name="pins" value="29"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 30 - Ground</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-31">GPIO06 - 31 <input id="pinTable-pin-31" type="radio" name="pins" value="31"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-32"><input id="pinTable-pin-32" type="radio" name="pins" value="32"> 32 - GPIO12</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-33">GPIO13 - 33 <input id="pinTable-pin-33" type="radio" name="pins" value="33"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGround"><label><input disabled type="radio" name="pins" value=""> 34 - Ground</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-35">GPIO19 - 35 <input id="pinTable-pin-35" type="radio" name="pins" value="35"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-36"><input id="pinTable-pin-36" type="radio" name="pins" value="36"> 36 - GPIO16</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGPIO"><label for="pinTable-pin-37">GPIO26 - 37 <input id="pinTable-pin-37" type="radio" name="pins" value="37"></label></div> | ||||
|                     <div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-38"><input id="pinTable-pin-38" type="radio" name="pins" value="38"> 38 - GPIO20</label></div> | ||||
|                 </div> | ||||
|                 <div class="pinTableRow"> | ||||
|                     <div class="pinTableCellL pinColorGround"><label>Ground - 39 <input disabled type="radio" name="pins" value=""></label></div> | ||||
|                     <div class="pinTableCellR pinColorGPIO"><label for="pinTable-pin-40"><input id="pinTable-pin-40" type="radio" name="pins" value="40"> 40 - GPIO21</label></div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="form-row" id="node-set-pwm"> | ||||
|         <label>    <span data-i18n="rpi-gpio.label.type"></span></label> | ||||
|         <select id="node-input-out" style="width: 250px;"> | ||||
|             <option value="out" data-i18n="rpi-gpio.digout"></option> | ||||
|             <option value="pwm" data-i18n="rpi-gpio.pwmout"></option> | ||||
|         </select> | ||||
|     </div> | ||||
|     <div class="form-row" id="node-set-tick"> | ||||
|         <label> </label> | ||||
|         <input type="checkbox" id="node-input-set" style="display: inline-block; width: auto; vertical-align: top;"> | ||||
|         <label for="node-input-set" style="width: 70%;"><span data-i18n="rpi-gpio.label.initpin"></span></label> | ||||
|     </div> | ||||
|     <div class="form-row" id="node-set-state"> | ||||
|         <label for="node-input-level"> </label> | ||||
|         <select id="node-input-level" style="width: 250px;"> | ||||
|             <option value="0" data-i18n="rpi-gpio.initpin0"></option> | ||||
|             <option value="1" data-i18n="rpi-gpio.initpin1"></option> | ||||
|         </select> | ||||
|     </div> | ||||
|     <div class="form-row" id="node-set-freq"> | ||||
|         <label for="node-input-freq"> <span data-i18n="rpi-gpio.label.freq"></span></label> | ||||
|         <input type="text" id="node-input-freq" placeholder="100"> Hz | ||||
|     </div> | ||||
|     <div class="form-row"> | ||||
|         <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> | ||||
|         <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> | ||||
|     </div> | ||||
|     <div class="form-tips" id="pin-tip"><span data-i18n="[html]rpi-gpio.tip.pin"></span></div> | ||||
|     <div class="form-tips" id="dig-tip"><span data-i18n="[html]rpi-gpio.tip.dig"></span></div> | ||||
|     <div class="form-tips" id="pwm-tip"><span data-i18n="[html]rpi-gpio.tip.pwm"></span></div> | ||||
| </script> | ||||
|  | ||||
| <script type="text/javascript"> | ||||
|     var bcm2pin = { | ||||
|         "2":"3", "3":"5", "4":"7", "14":"8", "15":"10", "17":"11", "18":"12", "27":"13", "22":"15", | ||||
|         "23":"16", "24":"18", "10":"19", "9":"21", "25":"22", "11":"23", "8":"24", "7":"26", | ||||
|         "5":"29", "6":"31", "12":"32", "13":"33", "19":"35", "16":"36", "26":"37", "20":"38", "21":"40" | ||||
|     }; | ||||
|     var pinsInUse = {}; | ||||
|     RED.nodes.registerType('rpi-gpio out',{ | ||||
|         category: 'Raspberry Pi', | ||||
|         color:"#c6dbef", | ||||
|         defaults: { | ||||
|             name: { value:"" }, | ||||
|             pin: { value:"",required:true,validate:RED.validators.number() }, | ||||
|             set: { value:"" }, | ||||
|             level: { value:"0" }, | ||||
|             freq: {value:""}, | ||||
|             out: { value:"out" } | ||||
|         }, | ||||
|         inputs:1, | ||||
|         outputs:0, | ||||
|         icon: "rpi.png", | ||||
|         info: function() { | ||||
|             if ( Object.keys(pinsInUse).length !== 0 ) { | ||||
|                 return "**Pins in use** : "+Object.keys(pinsInUse); | ||||
|             } | ||||
|             else { return ""; } | ||||
|         }, | ||||
|         align: "right", | ||||
|         label: function() { | ||||
|             if (this.out === "pwm") { return this.name || "PWM: "+this.pin; } | ||||
|             else if (this.out === "ser") { return this.name || "Servo: "+this.pin; } | ||||
|             else { | ||||
|                 var suf = ""; | ||||
|                 if (this.set == true) { suf = (this.level === "1") ? " ¹" : " ₀"; } | ||||
|                 return this.name||"PIN: "+ this.pin + suf ; | ||||
|             } | ||||
|         }, | ||||
|         labelStyle: function() { | ||||
|             return this.name?"node_label_italic":""; | ||||
|         }, | ||||
|         inputLabels: function() { return "GPIO"+this.pin; }, | ||||
|         oneditprepare: function() { | ||||
|             var pinnow = this.pin; | ||||
|             var pintip = this._("rpi-gpio.tip.pin"); | ||||
|             var pinname = this._("rpi-gpio.pinname"); | ||||
|             var alreadyuse = this._("rpi-gpio.alreadyuse"); | ||||
|             var alreadyset = this._("rpi-gpio.alreadyset"); | ||||
|             if (!$("#node-input-out").val()) { $("#node-input-out").val("out"); } | ||||
|  | ||||
|             $.getJSON('rpi-pins/'+this.id,function(data) { | ||||
|                 pinsInUse = data || {}; | ||||
|                 $('#pin-tip').html(pintip + Object.keys(data)); | ||||
|             }); | ||||
|  | ||||
|             $("#node-input-pin").on("change", function() { | ||||
|                 if ($("#node-input-pin").val()) { | ||||
|                     $("#pinform input[value="+$("#node-input-pin").val()+"]").prop('checked', true); | ||||
|                 } | ||||
|                 var pinnew = $("#node-input-pin").val(); | ||||
|                 if ((pinnew) && (pinnew !== pinnow)) { | ||||
|                     if (pinsInUse.hasOwnProperty(pinnew)) { | ||||
|                         RED.notify(pinname+" "+pinnew+" "+alreadyuse,"warn"); | ||||
|                     } | ||||
|                     pinnow = pinnew; | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             $("#node-input-out").on("change", function() { | ||||
|                 var newtype = $("#node-input-out").val(); | ||||
|                 if ((pinsInUse.hasOwnProperty(pinnow)) && (pinsInUse[pinnow] !== newtype)) { | ||||
|                     RED.notify(pinname+" "+pinnow+" "+alreadyset+" "+pinsInUse[pinnow],"error"); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             var hidestate = function () { | ||||
|                 if ($("#node-input-out").val() === "pwm") { | ||||
|                     $('#node-set-tick').hide(); | ||||
|                     $('#node-set-state').hide(); | ||||
|                     $('#node-input-set').prop('checked', false); | ||||
|                     $("#dig-tip").hide(); | ||||
|                     $("#pwm-tip").show(); | ||||
|                     $('#node-set-freq').show(); | ||||
|                 } | ||||
|                 else { | ||||
|                     $('#node-set-tick').show(); | ||||
|                     $("#dig-tip").show(); | ||||
|                     $("#pwm-tip").hide(); | ||||
|                     $('#node-set-freq').hide(); | ||||
|                 } | ||||
|             }; | ||||
|             $("#node-input-out").on("change", function () { hidestate(); }); | ||||
|             hidestate(); | ||||
|  | ||||
|             var setstate = function () { | ||||
|                 if ($('#node-input-set').is(":checked")) { | ||||
|                     $("#node-set-state").show(); | ||||
|                 } else { | ||||
|                     $("#node-set-state").hide(); | ||||
|                 } | ||||
|             }; | ||||
|             $("#node-input-set").on("change", function () { setstate(); }); | ||||
|             setstate(); | ||||
|  | ||||
|             $('#pinform input').on('change', function() { | ||||
|                 this.pin = $("#pinform input[type='radio']:checked").val(); | ||||
|                 $("#node-input-pin").val(this.pin); | ||||
|             }); | ||||
|         } | ||||
|     }); | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-template-name="rpi-mouse"> | ||||
|     <div class="form-row"> | ||||
|         <label for="node-input-butt"><i class="fa fa-circle"></i> <span data-i18n="rpi-gpio.label.button"></span></label> | ||||
|         <select type="text" id="node-input-butt" style="width: 250px;"> | ||||
|             <option value="1" data-i18n="rpi-gpio.left"></option> | ||||
|             <option value="2" data-i18n="rpi-gpio.right"></option> | ||||
|             <option value="4" data-i18n="rpi-gpio.middle"></option> | ||||
|             <option value="7" data-i18n="rpi-gpio.any"></option> | ||||
|          </select> | ||||
|     </div> | ||||
|     <br/> | ||||
|     <div class="form-row"> | ||||
|         <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> | ||||
|         <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> | ||||
|     </div> | ||||
| </script> | ||||
|  | ||||
| <script type="text/javascript"> | ||||
|     RED.nodes.registerType('rpi-mouse',{ | ||||
|         category: 'Raspberry Pi', | ||||
|         color:"#c6dbef", | ||||
|         defaults: { | ||||
|             name: { value:"" }, | ||||
|             butt: { value:"1",required:true } | ||||
|         }, | ||||
|         inputs:0, | ||||
|         outputs:1, | ||||
|         icon: "rpi.png", | ||||
|         label: function() { | ||||
|             var na = this._("rpi-gpio.label.pimouse"); | ||||
|             if (this.butt === "1") { na += " "+this._("rpi-gpio.label.left"); } | ||||
|             if (this.butt === "2") { na += " "+this._("rpi-gpio.label.right"); } | ||||
|             if (this.butt === "4") { na += " "+this._("rpi-gpio.label.middle"); } | ||||
|             return this.name||na; | ||||
|         }, | ||||
|         labelStyle: function() { | ||||
|             return this.name?"node_label_italic":""; | ||||
|         } | ||||
|     }); | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-template-name="rpi-keyboard"> | ||||
|     <div class="form-row"> | ||||
|         <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label> | ||||
|         <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"> | ||||
|     </div> | ||||
| </script> | ||||
|  | ||||
| <script type="text/javascript"> | ||||
|     RED.nodes.registerType('rpi-keyboard',{ | ||||
|         category: 'Raspberry Pi', | ||||
|         color:"#c6dbef", | ||||
|         defaults: { | ||||
|             name: { value:"" } | ||||
|         }, | ||||
|         inputs:0, | ||||
|         outputs:1, | ||||
|         icon: "rpi.png", | ||||
|         label: function() { | ||||
|             return this.name || this._("rpi-gpio.label.pikeyboard"); | ||||
|         }, | ||||
|         labelStyle: function() { | ||||
|             return this.name?"node_label_italic":""; | ||||
|         } | ||||
|     }); | ||||
| </script> | ||||
| @@ -1,371 +0,0 @@ | ||||
|  | ||||
| module.exports = function(RED) { | ||||
|     "use strict"; | ||||
|     var exec = require('child_process').exec; | ||||
|     var spawn = require('child_process').spawn; | ||||
|     var fs = require('fs'); | ||||
|  | ||||
|     var gpioCommand = __dirname+'/nrgpio'; | ||||
|     var allOK = true; | ||||
|  | ||||
|     try { | ||||
|         var cpuinfo = fs.readFileSync("/proc/cpuinfo").toString(); | ||||
|         if (cpuinfo.indexOf(": BCM") === -1) { | ||||
|             allOK = false; | ||||
|             RED.log.warn("rpi-gpio : "+RED._("rpi-gpio.errors.ignorenode")); | ||||
|         } | ||||
|         try { | ||||
|             fs.statSync("/usr/share/doc/python-rpi.gpio"); // test on Raspbian | ||||
|             // /usr/lib/python2.7/dist-packages/RPi/GPIO | ||||
|         } catch(err) { | ||||
|             try { | ||||
|                 fs.statSync("/usr/lib/python2.7/site-packages/RPi/GPIO"); // test on Arch | ||||
|             } catch(err) { | ||||
|                 try { | ||||
|                     fs.statSync("/usr/lib/python2.7/dist-packages/RPi/GPIO"); // test on Hypriot | ||||
|                 } catch(err) { | ||||
|                     try { | ||||
|                         fs.statSync("/usr/local/lib/python2.7/dist-packages/RPi/GPIO"); // installed with pip | ||||
|                     } catch(err) { | ||||
|                         RED.log.warn("rpi-gpio : "+RED._("rpi-gpio.errors.libnotfound")); | ||||
|                         allOK = false; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         if ( !(1 & parseInt((fs.statSync(gpioCommand).mode & parseInt("777", 8)).toString(8)[0]) )) { | ||||
|             RED.log.warn("rpi-gpio : "+RED._("rpi-gpio.errors.needtobeexecutable",{command:gpioCommand})); | ||||
|             allOK = false; | ||||
|         } | ||||
|     } catch(err) { | ||||
|         allOK = false; | ||||
|         RED.log.warn("rpi-gpio : "+RED._("rpi-gpio.errors.ignorenode")); | ||||
|     } | ||||
|  | ||||
|     // the magic to make python print stuff immediately | ||||
|     process.env.PYTHONUNBUFFERED = 1; | ||||
|  | ||||
|     var pinsInUse = {}; | ||||
|     var pinTypes = {"out":RED._("rpi-gpio.types.digout"), "tri":RED._("rpi-gpio.types.input"), "up":RED._("rpi-gpio.types.pullup"), "down":RED._("rpi-gpio.types.pulldown"), "pwm":RED._("rpi-gpio.types.pwmout")}; | ||||
|  | ||||
|     function GPIOInNode(n) { | ||||
|         RED.nodes.createNode(this,n); | ||||
|         this.buttonState = -1; | ||||
|         this.pin = n.pin; | ||||
|         this.intype = n.intype; | ||||
|         this.read = n.read || false; | ||||
|         this.debounce = Number(n.debounce || 25); | ||||
|         if (this.read) { this.buttonState = -2; } | ||||
|         var node = this; | ||||
|         if (!pinsInUse.hasOwnProperty(this.pin)) { | ||||
|             pinsInUse[this.pin] = this.intype; | ||||
|         } | ||||
|         else { | ||||
|             if ((pinsInUse[this.pin] !== this.intype)||(pinsInUse[this.pin] === "pwm")) { | ||||
|                 node.warn(RED._("rpi-gpio.errors.alreadyset",{pin:this.pin,type:pinTypes[pinsInUse[this.pin]]})); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (allOK === true) { | ||||
|             if (node.pin !== undefined) { | ||||
|                 node.child = spawn(gpioCommand, ["in",node.pin,node.intype,node.debounce]); | ||||
|                 node.running = true; | ||||
|                 node.status({fill:"green",shape:"dot",text:"common.status.ok"}); | ||||
|  | ||||
|                 node.child.stdout.on('data', function (data) { | ||||
|                     var d = data.toString().trim().split("\n"); | ||||
|                     for (var i = 0; i < d.length; i++) { | ||||
|                         if (d[i] === '') { return; } | ||||
|                         if (node.running && node.buttonState !== -1 && !isNaN(Number(d[i])) && node.buttonState !== d[i]) { | ||||
|                             node.send({ topic:"pi/"+node.pin, payload:Number(d[i]) }); | ||||
|                         } | ||||
|                         node.buttonState = d[i]; | ||||
|                         node.status({fill:"green",shape:"dot",text:d[i]}); | ||||
|                         if (RED.settings.verbose) { node.log("out: "+d[i]+" :"); } | ||||
|                     } | ||||
|                 }); | ||||
|  | ||||
|                 node.child.stderr.on('data', function (data) { | ||||
|                     if (RED.settings.verbose) { node.log("err: "+data+" :"); } | ||||
|                 }); | ||||
|  | ||||
|                 node.child.on('close', function (code) { | ||||
|                     node.running = false; | ||||
|                     node.child = null; | ||||
|                     if (RED.settings.verbose) { node.log(RED._("rpi-gpio.status.closed")); } | ||||
|                     if (node.done) { | ||||
|                         node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"}); | ||||
|                         node.done(); | ||||
|                     } | ||||
|                     else { node.status({fill:"red",shape:"ring",text:"rpi-gpio.status.stopped"}); } | ||||
|                 }); | ||||
|  | ||||
|                 node.child.on('error', function (err) { | ||||
|                     if (err.errno === "ENOENT") { node.error(RED._("rpi-gpio.errors.commandnotfound")); } | ||||
|                     else if (err.errno === "EACCES") { node.error(RED._("rpi-gpio.errors.commandnotexecutable")); } | ||||
|                     else { node.error(RED._("rpi-gpio.errors.error",{error:err.errno})) } | ||||
|                 }); | ||||
|  | ||||
|             } | ||||
|             else { | ||||
|                 node.warn(RED._("rpi-gpio.errors.invalidpin")+": "+node.pin); | ||||
|             } | ||||
|         } | ||||
|         else { | ||||
|             node.status({fill:"grey",shape:"dot",text:"node-red:rpi-gpio.status.not-available"}); | ||||
|             if (node.read === true) { | ||||
|                 var val; | ||||
|                 if (node.intype == "up") { val = 1; } | ||||
|                 if (node.intype == "down") { val = 0; } | ||||
|                 setTimeout(function(){ | ||||
|                     node.send({ topic:"pi/"+node.pin, payload:val }); | ||||
|                     node.status({fill:"grey",shape:"dot",text:RED._("rpi-gpio.status.na",{value:val})}); | ||||
|                 },250); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         node.on("close", function(done) { | ||||
|             node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"}); | ||||
|             delete pinsInUse[node.pin]; | ||||
|             if (node.child != null) { | ||||
|                 node.done = done; | ||||
|                 node.child.stdin.write("close "+node.pin); | ||||
|                 node.child.kill('SIGKILL'); | ||||
|             } | ||||
|             else { done(); } | ||||
|         }); | ||||
|     } | ||||
|     RED.nodes.registerType("rpi-gpio in",GPIOInNode); | ||||
|  | ||||
|     function GPIOOutNode(n) { | ||||
|         RED.nodes.createNode(this,n); | ||||
|         this.pin = n.pin; | ||||
|         this.set = n.set || false; | ||||
|         this.level = n.level || 0; | ||||
|         this.freq = n.freq || 100; | ||||
|         this.out = n.out || "out"; | ||||
|         var node = this; | ||||
|         if (!pinsInUse.hasOwnProperty(this.pin)) { | ||||
|             pinsInUse[this.pin] = this.out; | ||||
|         } | ||||
|         else { | ||||
|             if ((pinsInUse[this.pin] !== this.out)||(pinsInUse[this.pin] === "pwm")) { | ||||
|                 node.warn(RED._("rpi-gpio.errors.alreadyset",{pin:this.pin,type:pinTypes[pinsInUse[this.pin]]})); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         function inputlistener(msg) { | ||||
|             if (msg.payload === "true") { msg.payload = true; } | ||||
|             if (msg.payload === "false") { msg.payload = false; } | ||||
|             var out = Number(msg.payload); | ||||
|             var limit = 1; | ||||
|             if (node.out === "pwm") { limit = 100; } | ||||
|             if ((out >= 0) && (out <= limit)) { | ||||
|                 if (RED.settings.verbose) { node.log("out: "+out); } | ||||
|                 if (node.child !== null) { | ||||
|                     node.child.stdin.write(out+"\n"); | ||||
|                     node.status({fill:"green",shape:"dot",text:msg.payload.toString()}); | ||||
|                 } | ||||
|                 else { | ||||
|                     node.error(RED._("rpi-gpio.errors.pythoncommandnotfound"),msg); | ||||
|                     node.status({fill:"red",shape:"ring",text:"rpi-gpio.status.not-running"}); | ||||
|                 } | ||||
|             } | ||||
|             else { node.warn(RED._("rpi-gpio.errors.invalidinput")+": "+out); } | ||||
|         } | ||||
|  | ||||
|         if (allOK === true) { | ||||
|             if (node.pin !== undefined) { | ||||
|                 if (node.set && (node.out === "out")) { | ||||
|                     node.child = spawn(gpioCommand, [node.out,node.pin,node.level]); | ||||
|                     node.status({fill:"green",shape:"dot",text:node.level}); | ||||
|                 } else { | ||||
|                     node.child = spawn(gpioCommand, [node.out,node.pin,node.freq]); | ||||
|                     node.status({fill:"green",shape:"dot",text:"common.status.ok"}); | ||||
|                 } | ||||
|                 node.running = true; | ||||
|  | ||||
|                 node.on("input", inputlistener); | ||||
|  | ||||
|                 node.child.stdout.on('data', function (data) { | ||||
|                     if (RED.settings.verbose) { node.log("out: "+data+" :"); } | ||||
|                 }); | ||||
|  | ||||
|                 node.child.stderr.on('data', function (data) { | ||||
|                     if (RED.settings.verbose) { node.log("err: "+data+" :"); } | ||||
|                 }); | ||||
|  | ||||
|                 node.child.on('close', function (code) { | ||||
|                     node.child = null; | ||||
|                     node.running = false; | ||||
|                     if (RED.settings.verbose) { node.log(RED._("rpi-gpio.status.closed")); } | ||||
|                     if (node.done) { | ||||
|                         node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"}); | ||||
|                         node.done(); | ||||
|                     } | ||||
|                     else { node.status({fill:"red",shape:"ring",text:"rpi-gpio.status.stopped"}); } | ||||
|                 }); | ||||
|  | ||||
|                 node.child.on('error', function (err) { | ||||
|                     if (err.errno === "ENOENT") { node.error(RED._("rpi-gpio.errors.commandnotfound")); } | ||||
|                     else if (err.errno === "EACCES") { node.error(RED._("rpi-gpio.errors.commandnotexecutable")); } | ||||
|                     else { node.error(RED._("rpi-gpio.errors.error")+': ' + err.errno); } | ||||
|                 }); | ||||
|  | ||||
|             } | ||||
|             else { | ||||
|                 node.warn(RED._("rpi-gpio.errors.invalidpin")+": "+node.pin); | ||||
|             } | ||||
|         } | ||||
|         else { | ||||
|             node.status({fill:"grey",shape:"dot",text:"node-red:rpi-gpio.status.not-available"}); | ||||
|             node.on("input", function(msg){ | ||||
|                 node.status({fill:"grey",shape:"dot",text:RED._("rpi-gpio.status.na",{value:msg.payload.toString()})}); | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         node.on("close", function(done) { | ||||
|             node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"}); | ||||
|             delete pinsInUse[node.pin]; | ||||
|             if (node.child != null) { | ||||
|                 node.done = done; | ||||
|                 node.child.stdin.write("close "+node.pin); | ||||
|                 node.child.kill('SIGKILL'); | ||||
|             } | ||||
|             else { done(); } | ||||
|         }); | ||||
|  | ||||
|     } | ||||
|     RED.nodes.registerType("rpi-gpio out",GPIOOutNode); | ||||
|  | ||||
|     function PiMouseNode(n) { | ||||
|         RED.nodes.createNode(this,n); | ||||
|         this.butt = n.butt || 7; | ||||
|         var node = this; | ||||
|  | ||||
|         if (allOK === true) { | ||||
|             node.child = spawn(gpioCommand+".py", ["mouse",node.butt]); | ||||
|             node.status({fill:"green",shape:"dot",text:"common.status.ok"}); | ||||
|  | ||||
|             node.child.stdout.on('data', function (data) { | ||||
|                 data = Number(data); | ||||
|                 if (data !== 0) { node.send({ topic:"pi/mouse", button:data, payload:1 }); } | ||||
|                 else { node.send({ topic:"pi/mouse", button:data, payload:0 }); } | ||||
|             }); | ||||
|  | ||||
|             node.child.stderr.on('data', function (data) { | ||||
|                 if (RED.settings.verbose) { node.log("err: "+data+" :"); } | ||||
|             }); | ||||
|  | ||||
|             node.child.on('close', function (code) { | ||||
|                 node.child = null; | ||||
|                 node.running = false; | ||||
|                 if (RED.settings.verbose) { node.log(RED._("rpi-gpio.status.closed")); } | ||||
|                 if (node.done) { | ||||
|                     node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"}); | ||||
|                     node.done(); | ||||
|                 } | ||||
|                 else { node.status({fill:"red",shape:"ring",text:"rpi-gpio.status.stopped"}); } | ||||
|             }); | ||||
|  | ||||
|             node.child.on('error', function (err) { | ||||
|                 if (err.errno === "ENOENT") { node.error(RED._("rpi-gpio.errors.commandnotfound")); } | ||||
|                 else if (err.errno === "EACCES") { node.error(RED._("rpi-gpio.errors.commandnotexecutable")); } | ||||
|                 else { node.error(RED._("rpi-gpio.errors.error")+': ' + err.errno); } | ||||
|             }); | ||||
|  | ||||
|             node.on("close", function(done) { | ||||
|                 node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"}); | ||||
|                 if (node.child != null) { | ||||
|                     node.done = done; | ||||
|                     node.child.kill('SIGINT'); | ||||
|                     node.child = null; | ||||
|                 } | ||||
|                 else { done(); } | ||||
|             }); | ||||
|         } | ||||
|         else { | ||||
|             node.status({fill:"grey",shape:"dot",text:"node-red:rpi-gpio.status.not-available"}); | ||||
|         } | ||||
|     } | ||||
|     RED.nodes.registerType("rpi-mouse",PiMouseNode); | ||||
|  | ||||
|     function PiKeyboardNode(n) { | ||||
|         RED.nodes.createNode(this,n); | ||||
|         var node = this; | ||||
|  | ||||
|         if (allOK === true) { | ||||
|             node.child = spawn(gpioCommand+".py", ["kbd","0"]); | ||||
|             node.status({fill:"green",shape:"dot",text:"common.status.ok"}); | ||||
|  | ||||
|             node.child.stdout.on('data', function (data) { | ||||
|                 var b = data.toString().trim().split(","); | ||||
|                 var act = "up"; | ||||
|                 if (b[1] === "1") { act = "down"; } | ||||
|                 if (b[1] === "2") { act = "repeat"; } | ||||
|                 node.send({ topic:"pi/key", payload:Number(b[0]), action:act }); | ||||
|             }); | ||||
|  | ||||
|             node.child.stderr.on('data', function (data) { | ||||
|                 if (RED.settings.verbose) { node.log("err: "+data+" :"); } | ||||
|             }); | ||||
|  | ||||
|             node.child.on('close', function (code) { | ||||
|                 node.running = false; | ||||
|                 node.child = null; | ||||
|                 if (RED.settings.verbose) { node.log(RED._("rpi-gpio.status.closed")); } | ||||
|                 if (node.done) { | ||||
|                     node.status({fill:"grey",shape:"ring",text:"rpi-gpio.status.closed"}); | ||||
|                     node.done(); | ||||
|                 } | ||||
|                 else { node.status({fill:"red",shape:"ring",text:"rpi-gpio.status.stopped"}); } | ||||
|             }); | ||||
|  | ||||
|             node.child.on('error', function (err) { | ||||
|                 if (err.errno === "ENOENT") { node.error(RED._("rpi-gpio.errors.commandnotfound")); } | ||||
|                 else if (err.errno === "EACCES") { node.error(RED._("rpi-gpio.errors.commandnotexecutable")); } | ||||
|                 else { node.error(RED._("rpi-gpio.errors.error")+': ' + err.errno); } | ||||
|             }); | ||||
|  | ||||
|             node.on("close", function(done) { | ||||
|             node.status({}); | ||||
|             if (node.child != null) { | ||||
|                 node.done = done; | ||||
|                 node.child.kill('SIGINT'); | ||||
|                 node.child = null; | ||||
|             } | ||||
|             else { done(); } | ||||
|         }); | ||||
|         } | ||||
|         else { | ||||
|             node.status({fill:"grey",shape:"dot",text:"node-red:rpi-gpio.status.not-available"}); | ||||
|         } | ||||
|     } | ||||
|     RED.nodes.registerType("rpi-keyboard",PiKeyboardNode); | ||||
|  | ||||
|     var pitype = { type:"" }; | ||||
|     if (allOK === true) { | ||||
|         exec(gpioCommand+" info", function(err,stdout,stderr) { | ||||
|             if (err) { | ||||
|                 RED.log.info(RED._("rpi-gpio.errors.version")); | ||||
|             } | ||||
|             else { | ||||
|                 try { | ||||
|                     var info = JSON.parse( stdout.trim().replace(/\'/g,"\"") ); | ||||
|                     pitype.type = info["TYPE"]; | ||||
|                 } | ||||
|                 catch(e) { | ||||
|                     RED.log.info(RED._("rpi-gpio.errors.sawpitype"),stdout.trim()); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     RED.httpAdmin.get('/rpi-gpio/:id', RED.auth.needsPermission('rpi-gpio.read'), function(req,res) { | ||||
|         res.json(pitype); | ||||
|     }); | ||||
|  | ||||
|     RED.httpAdmin.get('/rpi-pins/:id', RED.auth.needsPermission('rpi-gpio.read'), function(req,res) { | ||||
|         res.json(pinsInUse); | ||||
|     }); | ||||
| } | ||||
| @@ -1,17 +0,0 @@ | ||||
| #!/bin/bash | ||||
| # | ||||
| # Copyright JS Foundation and other contributors, http://js.foundation | ||||
| # | ||||
| # 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. | ||||
| # | ||||
|  | ||||
| BASEDIR=$(dirname $0) | ||||
| python -u $BASEDIR/nrgpio.py $@ | ||||
| @@ -1,239 +0,0 @@ | ||||
| #!/usr/bin/python | ||||
| # | ||||
| # Copyright JS Foundation and other contributors, http://js.foundation | ||||
| # | ||||
| # 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. | ||||
| # | ||||
|  | ||||
| # Import library functions we need | ||||
| import RPi.GPIO as GPIO | ||||
| import struct | ||||
| import sys | ||||
| import os | ||||
| import subprocess | ||||
| from time import sleep | ||||
|  | ||||
| try: | ||||
|     raw_input          # Python 2 | ||||
| except NameError: | ||||
|     raw_input = input  # Python 3 | ||||
|  | ||||
| bounce = 25 | ||||
|  | ||||
| if len(sys.argv) > 2: | ||||
|     cmd = sys.argv[1].lower() | ||||
|     pin = int(sys.argv[2]) | ||||
|     GPIO.setmode(GPIO.BOARD) | ||||
|     GPIO.setwarnings(False) | ||||
|  | ||||
|     if cmd == "pwm": | ||||
|         #print("Initialised pin "+str(pin)+" to PWM") | ||||
|         try: | ||||
|             freq = int(sys.argv[3]) | ||||
|         except: | ||||
|             freq = 100 | ||||
|  | ||||
|         GPIO.setup(pin,GPIO.OUT) | ||||
|         p = GPIO.PWM(pin, freq) | ||||
|         p.start(0) | ||||
|  | ||||
|         while True: | ||||
|             try: | ||||
|                 data = raw_input() | ||||
|                 if 'close' in data: | ||||
|                     sys.exit(0) | ||||
|                 p.ChangeDutyCycle(float(data)) | ||||
|             except (EOFError, SystemExit):        # hopefully always caused by us sigint'ing the program | ||||
|                 GPIO.cleanup(pin) | ||||
|                 sys.exit(0) | ||||
|             except Exception as ex: | ||||
|                 print("bad data: "+data) | ||||
|  | ||||
|     elif cmd == "buzz": | ||||
|         #print("Initialised pin "+str(pin)+" to Buzz") | ||||
|         GPIO.setup(pin,GPIO.OUT) | ||||
|         p = GPIO.PWM(pin, 100) | ||||
|         p.stop() | ||||
|  | ||||
|         while True: | ||||
|             try: | ||||
|                 data = raw_input() | ||||
|                 if 'close' in data: | ||||
|                     sys.exit(0) | ||||
|                 elif float(data) == 0: | ||||
|                     p.stop() | ||||
|                 else: | ||||
|                     p.start(50) | ||||
|                     p.ChangeFrequency(float(data)) | ||||
|             except (EOFError, SystemExit):        # hopefully always caused by us sigint'ing the program | ||||
|                 GPIO.cleanup(pin) | ||||
|                 sys.exit(0) | ||||
|             except Exception as ex: | ||||
|                 print("bad data: "+data) | ||||
|  | ||||
|     elif cmd == "out": | ||||
|         #print("Initialised pin "+str(pin)+" to OUT") | ||||
|         GPIO.setup(pin,GPIO.OUT) | ||||
|         if len(sys.argv) == 4: | ||||
|             GPIO.output(pin,int(sys.argv[3])) | ||||
|  | ||||
|         while True: | ||||
|             try: | ||||
|                 data = raw_input() | ||||
|                 if 'close' in data: | ||||
|                     sys.exit(0) | ||||
|                 data = int(data) | ||||
|             except (EOFError, SystemExit):        # hopefully always caused by us sigint'ing the program | ||||
|                 GPIO.cleanup(pin) | ||||
|                 sys.exit(0) | ||||
|             except: | ||||
|                 if len(sys.argv) == 4: | ||||
|                    data = int(sys.argv[3]) | ||||
|                 else: | ||||
|                    data = 0 | ||||
|             if data != 0: | ||||
|                 data = 1 | ||||
|             GPIO.output(pin,data) | ||||
|  | ||||
|     elif cmd == "in": | ||||
|         #print("Initialised pin "+str(pin)+" to IN") | ||||
|         bounce = float(sys.argv[4]) | ||||
|         def handle_callback(chan): | ||||
|             sleep(bounce/1000.0) | ||||
|             print(GPIO.input(chan)) | ||||
|  | ||||
|         if sys.argv[3].lower() == "up": | ||||
|             GPIO.setup(pin,GPIO.IN,GPIO.PUD_UP) | ||||
|         elif sys.argv[3].lower() == "down": | ||||
|             GPIO.setup(pin,GPIO.IN,GPIO.PUD_DOWN) | ||||
|         else: | ||||
|             GPIO.setup(pin,GPIO.IN) | ||||
|  | ||||
|         print(GPIO.input(pin)) | ||||
|         GPIO.add_event_detect(pin, GPIO.BOTH, callback=handle_callback, bouncetime=int(bounce)) | ||||
|  | ||||
|         while True: | ||||
|             try: | ||||
|                 data = raw_input() | ||||
|                 if 'close' in data: | ||||
|                     sys.exit(0) | ||||
|             except (EOFError, SystemExit):        # hopefully always caused by us sigint'ing the program | ||||
|                 GPIO.cleanup(pin) | ||||
|                 sys.exit(0) | ||||
|  | ||||
|     elif cmd == "byte": | ||||
|         #print("Initialised BYTE mode - "+str(pin)+) | ||||
|         list = [7,11,13,12,15,16,18,22] | ||||
|         GPIO.setup(list,GPIO.OUT) | ||||
|  | ||||
|         while True: | ||||
|             try: | ||||
|                 data = raw_input() | ||||
|                 if 'close' in data: | ||||
|                     sys.exit(0) | ||||
|                 data = int(data) | ||||
|             except (EOFError, SystemExit):        # hopefully always caused by us sigint'ing the program | ||||
|                 GPIO.cleanup() | ||||
|                 sys.exit(0) | ||||
|             except: | ||||
|                 data = 0 | ||||
|             for bit in range(8): | ||||
|                 if pin == 1: | ||||
|                     mask = 1 << (7 - bit) | ||||
|                 else: | ||||
|                     mask = 1 << bit | ||||
|                 GPIO.output(list[bit], data & mask) | ||||
|  | ||||
|     elif cmd == "borg": | ||||
|         #print("Initialised BORG mode - "+str(pin)+) | ||||
|         GPIO.setup(11,GPIO.OUT) | ||||
|         GPIO.setup(13,GPIO.OUT) | ||||
|         GPIO.setup(15,GPIO.OUT) | ||||
|         r = GPIO.PWM(11, 100) | ||||
|         g = GPIO.PWM(13, 100) | ||||
|         b = GPIO.PWM(15, 100) | ||||
|         r.start(0) | ||||
|         g.start(0) | ||||
|         b.start(0) | ||||
|  | ||||
|         while True: | ||||
|             try: | ||||
|                 data = raw_input() | ||||
|                 if 'close' in data: | ||||
|                     sys.exit(0) | ||||
|                 c = data.split(",") | ||||
|                 r.ChangeDutyCycle(float(c[0])) | ||||
|                 g.ChangeDutyCycle(float(c[1])) | ||||
|                 b.ChangeDutyCycle(float(c[2])) | ||||
|             except (EOFError, SystemExit):        # hopefully always caused by us sigint'ing the program | ||||
|                 GPIO.cleanup() | ||||
|                 sys.exit(0) | ||||
|             except: | ||||
|                 data = 0 | ||||
|  | ||||
|     elif cmd == "mouse":  # catch mice button events | ||||
|         file = open( "/dev/input/mice", "rb" ) | ||||
|         oldbutt = 0 | ||||
|  | ||||
|         def getMouseEvent(): | ||||
|           global oldbutt | ||||
|           global pin | ||||
|           buf = file.read(3) | ||||
|           pin = pin & 0x07 | ||||
|           button = ord( buf[0] ) & pin # mask out just the required button(s) | ||||
|           if button != oldbutt:  # only send if changed | ||||
|               oldbutt = button | ||||
|               print(button) | ||||
|  | ||||
|         while True: | ||||
|             try: | ||||
|                 getMouseEvent() | ||||
|             except: | ||||
|                 file.close() | ||||
|                 sys.exit(0) | ||||
|  | ||||
|     elif cmd == "kbd":  # catch keyboard button events | ||||
|         try: | ||||
|             while not os.path.isdir("/dev/input/by-path"): | ||||
|                 sleep(10) | ||||
|             infile = subprocess.check_output("ls /dev/input/by-path/ | grep -m 1 'kbd'", shell=True).strip() | ||||
|             infile_path = "/dev/input/by-path/" + infile | ||||
|             EVENT_SIZE = struct.calcsize('llHHI') | ||||
|             file = open(infile_path, "rb") | ||||
|             event = file.read(EVENT_SIZE) | ||||
|             while event: | ||||
|                 (tv_sec, tv_usec, type, code, value) = struct.unpack('llHHI', event) | ||||
|                 #if type != 0 or code != 0 or value != 0: | ||||
|                 if type == 1: | ||||
|                     # type,code,value | ||||
|                     print("%u,%u" % (code, value)) | ||||
|                 event = file.read(EVENT_SIZE) | ||||
|             print("0,0") | ||||
|             file.close() | ||||
|             sys.exit(0) | ||||
|         except: | ||||
|             file.close() | ||||
|             sys.exit(0) | ||||
|  | ||||
| elif len(sys.argv) > 1: | ||||
|     cmd = sys.argv[1].lower() | ||||
|     if cmd == "rev": | ||||
|         print(GPIO.RPI_REVISION) | ||||
|     elif cmd == "ver": | ||||
|         print(GPIO.VERSION) | ||||
|     elif cmd == "info": | ||||
|         print(GPIO.RPI_INFO) | ||||
|     else: | ||||
|         print("Bad parameters - in|out|pwm|buzz|byte|borg|mouse|kbd|ver|info {pin} {value|up|down}") | ||||
|         print("  only ver (gpio version) and info (board information) accept no pin parameter.") | ||||
|  | ||||
| else: | ||||
|     print("Bad parameters - in|out|pwm|buzz|byte|borg|mouse|kbd|ver|info {pin} {value|up|down}") | ||||
| @@ -1,74 +0,0 @@ | ||||
| <!-- | ||||
|   Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  | ||||
|   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. | ||||
| --> | ||||
|  | ||||
| <script type="text/x-red" data-help-name="rpi-gpio in"> | ||||
|     <p> Raspberry Pi-Empfangs-Node. Generiert eine <code>msg.payload</code> mit einem Wert von | ||||
|         0 oder 1 in Abhängigkeit vom Status des Eingabepins. </p> | ||||
|         <h3> Ausgaben </h3> | ||||
|         <dl class="message-properties"> | ||||
|             <dt> payload  <span class="property-type"> Zahl </span> </dt> | ||||
|             <dd> Die Nutzdaten sind 1 oder 0. </dd> | ||||
|             <dt> topic  <span class="property-type"> Zeichenfolge </span> </dt> | ||||
|             <dd> Das Topic wird auf  <code>pi/ { the pin number }</code> gesetzt. </dd> | ||||
|         </dl> | ||||
|         <h3> Details </h3> | ||||
|         <p> Sie können auch den Eingangs-Pullup-Widerstand oder den Pulldown-Widerstand aktivieren. </p> | ||||
|         <p> Erfordert die Python-Bibliothek RPi.GPIO in der Version 0.5.10 (oder besser). </p> | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-help-name="rpi-gpio out"> | ||||
|     <p> Raspberry Pi-Ausgabe-Node. Kann im Digital- oder PWM-Modus verwendet werden. </p> | ||||
|     <h3> Eingaben </h3> | ||||
|     <dl class="message-properties"> | ||||
|         <dt> payload  <span class="property-type"> Zahl | Zeichen | Boolean </span> </dt> | ||||
|     </dl> | ||||
|     <h3> Details </h3> | ||||
|     <p> Der digitale Modus erwartet der Node eine <code>msg.payload</code>  von entweder 0 oder 1 (oder false oder true) | ||||
|     und schaltet den ausgewählten physischen Pin in Abhängigkeit von dem übergebenen Wert entweder auf LOW oder HIGH. </p> | ||||
|     <p> Der Anfangswert für den Pin kann bei der Implementierung auf 0 oder 1 gesetzt werden. </p> | ||||
|     <p> Im PWM-Modus erwartet der Node einen Eingabewert mit der Zahl 0-100. Es kann ein Gleitkommazahl sein. </p> | ||||
|     <p> Der PWM-Modus kann verwendet werden, um einen Servo unter Verwendung von Eingabewerten nur zwischen 10 und 20 zu steuern,  | ||||
|         akzeptiert aber auch Gleitkommawerte. Der GPIO2-Pin eignet sich am besten dafür, da er Hardware-PWM unterstützt. Für eine bessere Servounterstützung  | ||||
|         sollten Sie den alternativen Node <pre>Node-red-node-pi-gpiod</pre> berücksichtigen. </p> | ||||
|     <p> Erfordert die Python-Bibliothek RPi.GPIO in der Version 0.5.10 (oder besser). </p> | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-help-name="rpi-mouse"> | ||||
|     <p> Raspberry Pi-Maustasten-Node. Erfordert eine USB-Maus. </p> | ||||
|     <h3>Ausgaben </h3> | ||||
|     <dl class="message-properties"> | ||||
|         <dt> payload  <span class="property-type"> Zahl </span> </dt> | ||||
|         <dd> 1 oder 0, wenn die ausgewählte Maustaste gedrückt und losgelassen wird. </dd> | ||||
|         <dt> Schaltfläche  <span class="property-type"> Zahl </span> </dt> | ||||
|         <dd> 1, 2, 4 entsprechend der linken, der rechten und der mittleren Taste, so dass Sie herausfinden können,  | ||||
|             welche Schaltfläche oder Kombination gedrückt wurde. </dd> | ||||
|         <dt> topic  <span class="property-type"> Zeichenfolge </span> </dt> | ||||
|         <dd>wird auf: <code>pi/mouse</code> gesetzt</dd> | ||||
|     </dl> | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-help-name="rpi-keyboard"> | ||||
|     <p>Raspberry Pi Tastatur-Node. Benötigt eine USB Tastatur.</p> | ||||
|     <h3>Ausgaben</h3> | ||||
|     <dl class="message-properties"> | ||||
|         <dt>payload <span class="property-type">Zahl</span></dt> | ||||
|         <dd>enthält den Tastaturcode value</dd> | ||||
|         <dt>action <span class="property-type">Zeichenfolge</span></dt> | ||||
|         <dd>wird auf "up", "down", oder "repeat" gesetzt</dd> | ||||
|         <dt>topic <span class="property-type">Zeichenfolge</span></dt> | ||||
|         <dd>wird auf <code>pi/key</code> gesetzt</dd> | ||||
|     </dl> | ||||
| </script> | ||||
| @@ -729,78 +729,6 @@ | ||||
|       "xml_js" : "Dieser Node verarbeitet nur XML-Zeichenfolgen oder JS-Objekte." | ||||
|     } | ||||
|   }, | ||||
|   "rpi-gpio" : { | ||||
|     "label" : { | ||||
|       "gpiopin" : "GPIO", | ||||
|       "selectpin" : "Auswahlstift", | ||||
|       "resistor" : "Widerstand?", | ||||
|       "readinitial" : "Anfangsstatus des Pins bei Implementierung/Neustart lesen?", | ||||
|       "type" : "Typ", | ||||
|       "initpin" : "Pin-Status initialisieren?", | ||||
|       "debounce" : "Debounce", | ||||
|       "freq" : "Frequenz", | ||||
|       "button" : "Knopf", | ||||
|       "pimouse" : "Pi-Maus", | ||||
|       "pikeyboard" : "Pi-Tastatur", | ||||
|       "left" : "Links", | ||||
|       "right" : "Rechts", | ||||
|       "middle" : "Mitte" | ||||
|     }, | ||||
|     "resistor" : { | ||||
|       "none" : "keine", | ||||
|       "pullup" : "pullup", | ||||
|       "pulldown" : "Pulldown" | ||||
|     }, | ||||
|     "digout" : "Digitale Ausgabe", | ||||
|     "pwmout" : "PWM-Ausgabe", | ||||
|     "servo" : "Servo-Ausgabe", | ||||
|     "initpin0" : "Anfangsstand des Pin-Niedrig (0)", | ||||
|     "initpin1" : "Anfangsebene von Pin-High (1)", | ||||
|     "left" : "links", | ||||
|     "right" : "rechts", | ||||
|     "middle" : "Mitte", | ||||
|     "any" : "beliebig", | ||||
|     "pinname" : "Pin", | ||||
|     "alreadyuse" : "bereits im Gebrauch", | ||||
|     "alreadyset" : "bereits festgelegt als", | ||||
|     "tip" : { | ||||
|       "pin" : "<b> Verwender Pins </b>: ", | ||||
|       "in" : "Tipp: Es wird nur die digitale Eingabe unterstützt. Die Eingabe muss 0 oder 1 sein.", | ||||
|       "dig" : "Tipp: Für die digitale Ausgabe muss der Wert 0 oder 1 sein.", | ||||
|       "pwm" : "Tipp: Für die PWM-Ausgabe muss der Wert zwischen 0 und 100 liegen; die Einstellung der Hochfrequenz kann mehr CPU beanspruchen als erwartet.", | ||||
|       "ser" : "<b> Tipp </b>: Für die Servo-Ausgabe muss ein Wert zwischen 0 und 100 eingegeben werden. 50 ist das Zentrum." | ||||
|     }, | ||||
|     "types" : { | ||||
|       "digout" : "digitale Ausgabe", | ||||
|       "input" : "Eingabe", | ||||
|       "pullup" : "Eingabe mit Pull-up", | ||||
|       "pulldown" : "Eingabe mit Pull-down", | ||||
|       "pwmout" : "PWM-Ausgabe", | ||||
|       "servo" : "Servo-Ausgabe" | ||||
|     }, | ||||
|     "status" : { | ||||
|       "stopped" : "Gestoppt", | ||||
|       "closed" : "geschlossen", | ||||
|       "not-running" : "nicht aktiv", | ||||
|       "not-available" : "nicht verfügbar", | ||||
|       "na" : "N/A: __Wert__" | ||||
|     }, | ||||
|     "errors" : { | ||||
|       "ignorenode" : "Raspberry Pi-spezifische Nodes inaktiv", | ||||
|       "version" : "Abrufen der Version von Pi fehlgeschlagen", | ||||
|       "sawpitype" : "Saw-Pi-Typ", | ||||
|       "libnotfound" : "Pi RPi.GPIO-Python-Bibliothek nicht gefunden", | ||||
|       "alreadyset" : "GPIO-Stift __pin__ ist bereits als Typ festgelegt: __type__", | ||||
|       "invalidpin" : "Ungültiger GPIO-Pin", | ||||
|       "invalidinput" : "Ungültige Eingabe", | ||||
|       "needtobeexecutable" : "__command__ muss ausführbar sein", | ||||
|       "mustbeexecutable" : "nrgpio muss ausführbar sein", | ||||
|       "commandnotfound" : "Befehl 'nrgpio' nicht gefunden", | ||||
|       "commandnotexecutable" : "nrgpio-Befehl nicht ausführbar", | ||||
|       "error" : "Fehler: __error__", | ||||
|       "pythoncommandnotfound" : "Befehl 'nrpgio python' nicht aktiv" | ||||
|     } | ||||
|   }, | ||||
|   "tail" : { | ||||
|     "tail" : "Tail", | ||||
|     "label" : { | ||||
|   | ||||
| @@ -1,75 +0,0 @@ | ||||
| <!-- | ||||
|   Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  | ||||
|   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. | ||||
| --> | ||||
|  | ||||
| <script type="text/x-red" data-help-name="rpi-gpio in"> | ||||
|     <p>Raspberry Pi input node. Generates a <code>msg.payload</code> with either a | ||||
|     0 or 1 depending on the state of the input pin.</p> | ||||
|     <h3>Outputs</h3> | ||||
|     <dl class="message-properties"> | ||||
|         <dt>payload <span class="property-type">number</span></dt> | ||||
|         <dd>the payload will be a 1 or a 0.</dd> | ||||
|         <dt>topic <span class="property-type">string</span></dt> | ||||
|         <dd>the topic will be set to <code>pi/{the pin number}</code>.</dd> | ||||
|     </dl> | ||||
|     <h3>Details</h3> | ||||
|     <p>You may also enable the input pullup resistor or the pulldown resistor.</p> | ||||
|     <p>Requires the RPi.GPIO python library version 0.5.10 (or better) in order to work.</p> | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-help-name="rpi-gpio out"> | ||||
|     <p>Raspberry Pi output node. Can be used in Digital or PWM modes.</p> | ||||
|     <h3>Inputs</h3> | ||||
|     <dl class="message-properties"> | ||||
|         <dt>payload <span class="property-type">number | string | boolean</span></dt> | ||||
|     </dl> | ||||
|     <h3>Details</h3> | ||||
|     <p>Digital mode - expects a <code>msg.payload</code> with either a 0 or 1 (or true or false), | ||||
|     and will set the selected physical pin high or low depending on the value passed in.</p> | ||||
|     <p>The initial value of the pin at deploy time can also be set to 0 or 1.</p> | ||||
|     <p>PWM mode - expects an input value of a number 0 - 100. It can be floating point.</p> | ||||
|     <p>PWM mode can be used to drive a servo using input values between 10 and 20 only, | ||||
|     but will accept floating point values. | ||||
|     The GPIO2 pin is best for this as it uses hardware to do the PWM. For better servo support | ||||
|     consider the alternative node-red-node-pi-gpiod node.</p> | ||||
|     <p>Requires the RPi.GPIO python library version 0.5.10 (or better) in order to work.</p> | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-help-name="rpi-mouse"> | ||||
|     <p>Raspberry Pi mouse button node. Requires a USB mouse.</p> | ||||
|     <h3>Outputs</h3> | ||||
|     <dl class="message-properties"> | ||||
|         <dt>payload <span class="property-type">number</span></dt> | ||||
|         <dd>1 or 0 when the selected mouse button is pressed and released.</dd> | ||||
|         <dt>button <span class="property-type">number</span></dt> | ||||
|         <dd>1, 2, 4 corresponding to left, right and middle buttons, so you | ||||
|         can work out which button or combination was pressed.</dd> | ||||
|         <dt>topic <span class="property-type">string</span></dt> | ||||
|         <dd>set to <code>pi/mouse</code></dd> | ||||
|     </dl> | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-help-name="rpi-keyboard"> | ||||
|     <p>Raspberry Pi keyboard handling node. Requires a USB keyboard.</p> | ||||
|     <h3>Outputs</h3> | ||||
|     <dl class="message-properties"> | ||||
|         <dt>payload <span class="property-type">number</span></dt> | ||||
|         <dd>contains the keycode value</dd> | ||||
|         <dt>action <span class="property-type">string</span></dt> | ||||
|         <dd>set to "up", "down", or "repeat"</dd> | ||||
|         <dt>topic <span class="property-type">string</span></dt> | ||||
|         <dd>set to <code>pi/key</code></dd> | ||||
|     </dl> | ||||
| </script> | ||||
| @@ -774,78 +774,6 @@ | ||||
|             "xml_js": "This node only handles xml strings or js objects." | ||||
|         } | ||||
|     }, | ||||
|     "rpi-gpio": { | ||||
|         "label": { | ||||
|             "gpiopin": "GPIO", | ||||
|             "selectpin": "select pin", | ||||
|             "resistor": "Resistor?", | ||||
|             "readinitial": "Read initial state of pin on deploy/restart?", | ||||
|             "type": "Type", | ||||
|             "initpin": "Initialise pin state?", | ||||
|             "debounce": "Debounce", | ||||
|             "freq": "Frequency", | ||||
|             "button": "Button", | ||||
|             "pimouse": "Pi Mouse", | ||||
|             "pikeyboard": "Pi Keyboard", | ||||
|             "left": "Left", | ||||
|             "right": "Right", | ||||
|             "middle": "Middle" | ||||
|         }, | ||||
|         "resistor": { | ||||
|             "none": "none", | ||||
|             "pullup": "pullup", | ||||
|             "pulldown": "pulldown" | ||||
|         }, | ||||
|         "digout": "Digital output", | ||||
|         "pwmout": "PWM output", | ||||
|         "servo": "Servo output", | ||||
|         "initpin0": "initial level of pin - low (0)", | ||||
|         "initpin1": "initial level of pin - high (1)", | ||||
|         "left": "left", | ||||
|         "right": "right", | ||||
|         "middle": "middle", | ||||
|         "any": "any", | ||||
|         "pinname": "Pin", | ||||
|         "alreadyuse": "already in use", | ||||
|         "alreadyset": "already set as", | ||||
|         "tip": { | ||||
|             "pin": "<b>Pins in Use</b>: ", | ||||
|             "in": "Tip: Only Digital Input is supported - input must be 0 or 1.", | ||||
|             "dig": "Tip: For digital output - input must be 0 or 1.", | ||||
|             "pwm": "Tip: For PWM output - input must be between 0 to 100; setting high frequency might occupy more CPU than expected.", | ||||
|             "ser": "<b>Tip</b>: For Servo output - input must be between 0 to 100. 50 is centre." | ||||
|         }, | ||||
|         "types": { | ||||
|             "digout": "digital output", | ||||
|             "input": "input", | ||||
|             "pullup": "input with pull up", | ||||
|             "pulldown": "input with pull down", | ||||
|             "pwmout": "PWM output", | ||||
|             "servo": "Servo output" | ||||
|         }, | ||||
|         "status": { | ||||
|             "stopped": "stopped", | ||||
|             "closed": "closed", | ||||
|             "not-running": "not running", | ||||
|             "not-available": "not available", | ||||
|             "na": "N/A : __value__" | ||||
|         }, | ||||
|         "errors": { | ||||
|             "ignorenode": "Raspberry Pi specific node set inactive", | ||||
|             "version": "Failed to get version from Pi", | ||||
|             "sawpitype": "Saw Pi Type", | ||||
|             "libnotfound": "Cannot find Pi RPi.GPIO python library", | ||||
|             "alreadyset": "GPIO pin __pin__ already set as type: __type__", | ||||
|             "invalidpin": "Invalid GPIO pin", | ||||
|             "invalidinput": "Invalid input", | ||||
|             "needtobeexecutable": "__command__ needs to be executable", | ||||
|             "mustbeexecutable": "nrgpio must to be executable", | ||||
|             "commandnotfound": "nrgpio command not found", | ||||
|             "commandnotexecutable": "nrgpio command not executable", | ||||
|             "error": "error: __error__", | ||||
|             "pythoncommandnotfound": "nrpgio python command not running" | ||||
|         } | ||||
|     }, | ||||
|     "file": { | ||||
|         "label": { | ||||
|             "filename": "Filename", | ||||
|   | ||||
| @@ -1,71 +0,0 @@ | ||||
| <!-- | ||||
|   Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  | ||||
|   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. | ||||
| --> | ||||
|  | ||||
| <script type="text/x-red" data-help-name="rpi-gpio in"> | ||||
|     <p>Raspberry Piの入力ノード。入力ピンの状態に応じて、0 または 1 の値を持つ<code>msg.payload</code>を生成します。</p> | ||||
|     <h3>出力</h3> | ||||
|     <dl class="message-properties"> | ||||
|         <dt>payload <span class="property-type">数値</span></dt> | ||||
|         <dd>ペイロードには、0 または 1 が設定されます。</dd> | ||||
|         <dt>topic <span class="property-type">文字列</span></dt> | ||||
|         <dd>トピックには、<code>pi/{ピン番号}</code>が設定されます。</dd> | ||||
|     </dl> | ||||
|     <h3>詳細</h3> | ||||
|     <p>入力のプルアップ抵抗またはプルダウン抵抗を有効にすることもできます。</p> | ||||
|     <p>動作にはRPi.GPIO pythonライブラリのバージョン 0.5.10 (またはそれ以上)が必要です。</p> | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-help-name="rpi-gpio out"> | ||||
|     <p>Raspberry Piの出力ノード。デジタルモードまたはPWMモードで利用できます。</p> | ||||
|     <h3>入力</h3> | ||||
|     <dl class="message-properties"> | ||||
|         <dt>payload <span class="property-type">数値 | 文字列 | 真偽値</span></dt> | ||||
|     </dl> | ||||
|     <h3>詳細</h3> | ||||
|     <p>デジタルモード - <code>msg.payload</code>に 0 または 1 (あるいは true または false ) を指定すると、入力値に応じて選択された物理ピンにハイまたはローを設定します。</p> | ||||
|     <p>デプロイ時にピンの初期値として 0 または 1 を設定することもできます。</p> | ||||
|     <p>PWMモード - 入力値に 0 から 100 の数値を指定でき。小数値の指定も可能です。</p> | ||||
|     <p>サーボの制御にPWMモードが利用でき、入力に小数値も含む 10 から 20 の値が指定可能です。 | ||||
|     PWMを行うハードウェアを利用していることから、PWMモードの指定にはGPIO2ピンが最も適しています。 | ||||
|     より良くサーボの制御を行いたい場合は、node-red-node-pi-gpiod ノードの利用も検討してください。</p> | ||||
|     <p>動作にはRPi.GPIO pythonライブラリのバージョン 0.5.10 (またはそれ以上)が必要です。</p> | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-help-name="rpi-mouse"> | ||||
|     <p>Raspberry Pi のマウスボタンノード。USBマウスが必要です。</p> | ||||
|     <h3>出力</h3> | ||||
|     <dl class="message-properties"> | ||||
|         <dt>payload <span class="property-type">数値</span></dt> | ||||
|         <dd>選択されたマウスのボタンが押された、または離された場合に 1 または 0 が設定されます。</dd> | ||||
|         <dt>button <span class="property-type">数値</span></dt> | ||||
|         <dd>左、右、真ん中のボタンに応じて 1, 2, 4 が設定され、ボタンあるいはボタンの組み合わせに応じた処理ができます。</dd> | ||||
|         <dt>topic <span class="property-type">文字列</span></dt> | ||||
|         <dd><code>pi/mouse</code>が設定されます。</dd> | ||||
|     </dl> | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-help-name="rpi-keyboard"> | ||||
|     <p>Raspberry Pi のキーボードを制御するノード。USBキーボードが必要です。</p> | ||||
|     <h3>出力</h3> | ||||
|     <dl class="message-properties"> | ||||
|         <dt>payload <span class="property-type">数値</span></dt> | ||||
|         <dd>キーコードを含みます。</dd> | ||||
|         <dt>action <span class="property-type">文字列</span></dt> | ||||
|         <dd>"up", "down", または "repeat" が設定されます。</dd> | ||||
|         <dt>topic <span class="property-type">文字列</span></dt> | ||||
|         <dd><code>pi/key</code>が設定されます。</dd> | ||||
|     </dl> | ||||
| </script> | ||||
| @@ -768,78 +768,6 @@ | ||||
|             "xml_js": "本ノードは、XML形式の文字列またはJSONのみ処理します" | ||||
|         } | ||||
|     }, | ||||
|     "rpi-gpio": { | ||||
|         "label": { | ||||
|             "gpiopin": "GPIO", | ||||
|             "selectpin": "端子の選択", | ||||
|             "resistor": "抵抗", | ||||
|             "readinitial": "デプロイや再起動時に端子の初期状態を読み込む", | ||||
|             "type": "出力形式", | ||||
|             "initpin": "端子の状態を初期化", | ||||
|             "debounce": "デバウンス", | ||||
|             "freq": "頻度", | ||||
|             "button": "ボタン", | ||||
|             "pimouse": "Pi Mouse", | ||||
|             "pikeyboard": "Pi Keyboard", | ||||
|             "left": "Left", | ||||
|             "right": "Right", | ||||
|             "middle": "Middle" | ||||
|         }, | ||||
|         "resistor": { | ||||
|             "none": "なし", | ||||
|             "pullup": "プルアップ", | ||||
|             "pulldown": "プルダウン" | ||||
|         }, | ||||
|         "digout": "デジタル出力", | ||||
|         "pwmout": "PWM出力", | ||||
|         "servo": "サーボ出力", | ||||
|         "initpin0": "端子の初期レベル - Low (0)", | ||||
|         "initpin1": "端子の初期レベル - High (1)", | ||||
|         "left": "左", | ||||
|         "right": "右", | ||||
|         "middle": "中間", | ||||
|         "any": "全て", | ||||
|         "pinname": "端子", | ||||
|         "alreadyuse": "使用中", | ||||
|         "alreadyset": "設定済", | ||||
|         "tip": { | ||||
|             "pin": "<b>使用中の端子</b>: ", | ||||
|             "in": "注釈: 入力値は、0または1の数値のみ対応しています。", | ||||
|             "dig": "注釈: 「出力形式」として「デジタル出力」を用いる場合、入力値は0または1の数値である必要があります。", | ||||
|             "pwm": "注釈: 「出力形式」として「PWM出力」を用いる場合、入力値は0~100の数値である必要があります。", | ||||
|             "ser": "<b>注釈</b>: サーボ出力向け - 入力値は0~100の間である必要があります。50が中心値です。" | ||||
|         }, | ||||
|         "types": { | ||||
|             "digout": "デジタル出力", | ||||
|             "input": "入力", | ||||
|             "pullup": "プルアップの入力", | ||||
|             "pulldown": "プルダウンの入力", | ||||
|             "pwmout": "PWM出力", | ||||
|             "servo": "サーボ出力" | ||||
|         }, | ||||
|         "status": { | ||||
|             "stopped": "停止", | ||||
|             "closed": "切断", | ||||
|             "not-running": "停止中", | ||||
|             "not-available": "利用不可", | ||||
|             "na": "N/A : __value__" | ||||
|         }, | ||||
|         "errors": { | ||||
|             "ignorenode": "Raspberry Pi固有のノードを無視しました", | ||||
|             "version": "バージョンコマンドが失敗しました", | ||||
|             "sawpitype": "Saw Pi Type", | ||||
|             "libnotfound": "RPi.GPIO pythonライブラリを見つけられませんでした", | ||||
|             "alreadyset": "GPIO端子  __pin__ は既に出力形式が設定されています: __type__", | ||||
|             "invalidpin": "GPIO端子が不正です", | ||||
|             "invalidinput": "入力が不正です", | ||||
|             "needtobeexecutable": "__command__ は実行可能である必要があります", | ||||
|             "mustbeexecutable": "nrgpio は実行可能である必要があります", | ||||
|             "commandnotfound": "nrgpio コマンドが見つかりません", | ||||
|             "commandnotexecutable": "nrgpio コマンドが実行可能ではありません", | ||||
|             "error": "エラー: __error__", | ||||
|             "pythoncommandnotfound": "nrpgio python コマンドが実行されていません" | ||||
|         } | ||||
|     }, | ||||
|     "file": { | ||||
|         "label": { | ||||
|             "filename": "ファイル名", | ||||
|   | ||||
| @@ -1,71 +0,0 @@ | ||||
| <!-- | ||||
|   Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  | ||||
|   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. | ||||
| --> | ||||
|  | ||||
| <script type="text/x-red" data-help-name="rpi-gpio in"> | ||||
|     <p>Raspberry Pi의 입력노드. 입력 핀의 상태에 따라, 0 또는 1의 값을 갖는 <code>msg.payload</code>을 생성합니다.</p> | ||||
|     <h3>출력</h3> | ||||
|     <dl class="message-properties"> | ||||
|         <dt>payload <span class="property-type">수치</span></dt> | ||||
|         <dd>페이로드에는, 0 또는 1이 설정됩니다.</dd> | ||||
|         <dt>topic <span class="property-type">문자열</span></dt> | ||||
|         <dd>토픽에는, <code>pi/{핀 번호}</code>가 설정됩니다.</dd> | ||||
|     </dl> | ||||
|     <h3>상세</h3> | ||||
|     <p>입력의 풀 업 저항 또는, 풀 다운 저항을 유효화 할 수도 있습니다.</p> | ||||
|     <p>작동하려면 RPi.GPIO python라이브러리 버젼0.5.10 (또는 그 이상)이 필요합니다.</p> | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-help-name="rpi-gpio out"> | ||||
|     <p>Raspberry Pi의 출력노드. 디지털모드 또는 PWM모드에서 이용할 수 있습니다.</p> | ||||
|     <h3>입력</h3> | ||||
|     <dl class="message-properties"> | ||||
|         <dt>payload <span class="property-type">수치 | 문자열 | 진위값</span></dt> | ||||
|     </dl> | ||||
|     <h3>상세</h3> | ||||
|     <p>디지털모드 - <code>msg.payload</code>에 0 또는 1 (혹은 true 또는 false) 을 지정하면, 입력값에 따라 선택된 물리핀에 high 또는 low를 설정합니다.</p> | ||||
|     <p>배포시에 핀의 초기값으로 0 또는 1을 설정할 수도 있습니다.</p> | ||||
|     <p>PWM모드 - 입력값에 0에서 100의 수치를 지정할수 있고, 소수값도 지정할수 있습니다.</p> | ||||
|     <p>서보제어에 PWM모드를 이용할수 있으며, 입력에 소수값을 포함한 10에서 20의 값을 지정할 수 있습니다. | ||||
|     PWM를 실행하는 하드웨어를 이용하여, PWM모드의 지정에는 GPIO2핀이 가장 적합합니다. | ||||
|     보다 좋은 서보제어를 원하는 경우에는, node-red-node-pi-gpiod 노드를 이용할 것을 검토해 주십시오.</p> | ||||
|     <p>작동하려면 RPi.GPIO python라이브러리 버젼0.5.10 (또는 그 이상)이 필요합니다.</p> | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-help-name="rpi-mouse"> | ||||
|     <p>Raspberry Pi 의 마우스버튼노드. USB마우스가 필요합니다.</p> | ||||
|     <h3>출력</h3> | ||||
|     <dl class="message-properties"> | ||||
|         <dt>payload <span class="property-type">수치</span></dt> | ||||
|         <dd>선택된 마우스의 버튼이 눌려지거나 떨어졌을 경우에 1 또는 0이 설정됩니다.</dd> | ||||
|         <dt>button <span class="property-type">수치</span></dt> | ||||
|         <dd>좌, 우, 중앙 버튼에 따라 1, 2, 4 가 설정되어, 버튼 혹은 버튼의 조합에 따른 처리를 할 수 있습니다.</dd> | ||||
|         <dt>topic <span class="property-type">문자열</span></dt> | ||||
|         <dd><code>pi/mouse</code>이 설정됩니다.</dd> | ||||
|     </dl> | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-help-name="rpi-keyboard"> | ||||
|     <p>Raspberry Pi 의 키보드를 제어하는 노드. USB키보드가 필요합니다.</p> | ||||
|     <h3>출력</h3> | ||||
|     <dl class="message-properties"> | ||||
|         <dt>payload <span class="property-type">수치</span></dt> | ||||
|         <dd>키 코드를 포함합니다.</dd> | ||||
|         <dt>action <span class="property-type">문자열</span></dt> | ||||
|         <dd>"up", "down", 또는 "repeat" 이 설정됩니다.</dd> | ||||
|         <dt>topic <span class="property-type">문자열</span></dt> | ||||
|         <dd><code>pi/key</code>가 설정됩니다.</dd> | ||||
|     </dl> | ||||
| </script> | ||||
| @@ -774,78 +774,6 @@ | ||||
|             "xml_js": "이 노드는, XML형식의 문자열 혹은 JSON만 처리합니다" | ||||
|         } | ||||
|     }, | ||||
|     "rpi-gpio": { | ||||
|         "label": { | ||||
|             "gpiopin": "GPIO", | ||||
|             "selectpin": "단자의 선택", | ||||
|             "resistor": "저항", | ||||
|             "readinitial": "배포나 재시작시에 단자의 초기상태를 불러옴", | ||||
|             "type": "출력형식", | ||||
|             "initpin": "단자의 상태를 초기화", | ||||
|             "debounce": "디바운스", | ||||
|             "freq": "빈도", | ||||
|             "button": "버튼", | ||||
|             "pimouse": "Pi Mouse", | ||||
|             "pikeyboard": "Pi Keyboard", | ||||
|             "left": "Left", | ||||
|             "right": "Right", | ||||
|             "middle": "Middle" | ||||
|         }, | ||||
|         "resistor": { | ||||
|             "none": "없음", | ||||
|             "pullup": "풀 업", | ||||
|             "pulldown": "풀 다운" | ||||
|         }, | ||||
|         "digout": "디지털 출력", | ||||
|         "pwmout": "PWM 출력", | ||||
|         "servo": "서보 출력", | ||||
|         "initpin0": "단자의 초기레벨 - Low (0)", | ||||
|         "initpin1": "단자의 초기레벨 - High (1)", | ||||
|         "left": "좌", | ||||
|         "right": "우", | ||||
|         "middle": "중간", | ||||
|         "any": "모두", | ||||
|         "pinname": "단자", | ||||
|         "alreadyuse": "사용중", | ||||
|         "alreadyset": "설정됨", | ||||
|         "tip": { | ||||
|             "pin": "<b>사용중인 단자</b>: ", | ||||
|             "in": "주석: 입력값은, 0 혹은 1의 수치만 대응하고 있습니다.", | ||||
|             "dig": "주석: ’출력형식’으로 ’디지털출력’을 사용하는 경우, 입력값은 0 혹은 1의 수치일 필요가 있습니다.", | ||||
|             "pwm": "주석: ’출력형식’으로 ’PWM출력’을 사용하는 경우, 입력값은 0~100의 수치일 필요가 있습니다.", | ||||
|             "ser": "<b>주석</b>: 서보 출력용 - 입력값은 0~100 사이일 필요가 있습니다. 50이 중심값입니다." | ||||
|         }, | ||||
|         "types": { | ||||
|             "digout": "디지털 출력", | ||||
|             "input": "입력", | ||||
|             "pullup": "풀 업 입력", | ||||
|             "pulldown": "풀 다운 입력", | ||||
|             "pwmout": "PWM 출력", | ||||
|             "servo": "서보 출력" | ||||
|         }, | ||||
|         "status": { | ||||
|             "stopped": "정지", | ||||
|             "closed": "절단", | ||||
|             "not-running": "정지중", | ||||
|             "not-available": "이용불가", | ||||
|             "na": "N/A : __value__" | ||||
|         }, | ||||
|         "errors": { | ||||
|             "ignorenode": "Raspberry Pi고유의 노드를 무시했습니다", | ||||
|             "version": "버젼커맨드에 실패했습니다", | ||||
|             "sawpitype": "Saw Pi Type", | ||||
|             "libnotfound": "RPi.GPIO python라이브러리를 발견하지 못했습니다", | ||||
|             "alreadyset": "GPIO단자  __pin__ 은 이미 출력형식이 설정되어 있습니다: __type__", | ||||
|             "invalidpin": "GPIO단자가 올바르지 않습니다", | ||||
|             "invalidinput": "입력이 올바르지 않습니다", | ||||
|             "needtobeexecutable": "__command__ 은 실행가능상태일 필요가 있습니다 ", | ||||
|             "mustbeexecutable": "nrgpio 은 실행가능상태일 필요가 있습니다 ", | ||||
|             "commandnotfound": "nrgpio 커맨드를 찾을수 없습니다", | ||||
|             "commandnotexecutable": "nrgpio 커맨드가 실행가능상태가 아닙니다", | ||||
|             "error": "에러: __error__", | ||||
|             "pythoncommandnotfound": "nrpgio python 커맨드가 실행되지 않았습니다" | ||||
|         } | ||||
|     }, | ||||
|     "file": { | ||||
|         "label": { | ||||
|             "filename": "파일명", | ||||
|   | ||||
| @@ -702,76 +702,6 @@ | ||||
|             "xml_js": "此节点仅处理XML字符串或JS对象." | ||||
|         } | ||||
|     }, | ||||
|     "rpi-gpio": { | ||||
|         "label": { | ||||
|             "gpiopin": "GPIO", | ||||
|             "selectpin": "选择引脚", | ||||
|             "resistor": "电阻?", | ||||
|             "readinitial": "在部署/重启时读取引脚的初始状态?", | ||||
|             "type": "类型", | ||||
|             "initpin": "初始化引脚状态?", | ||||
|             "debounce": "去抖动", | ||||
|             "freq": "频率", | ||||
|             "button": "按钮", | ||||
|             "pimouse": "Pi鼠标", | ||||
|             "pikeyboard": "Pi键盘", | ||||
|             "left": "左", | ||||
|             "right": "右", | ||||
|             "middle": "中" | ||||
|         }, | ||||
|         "resistor": { | ||||
|             "none": "无", | ||||
|             "pullup": "上拉电阻", | ||||
|             "pulldown": "下拉电阻" | ||||
|         }, | ||||
|         "digout": "数字输出", | ||||
|         "pwmout": "PWM输出", | ||||
|         "servo": "伺服输出", | ||||
|         "initpin0": "初始引脚电平 - 低(0)", | ||||
|         "initpin1": "初始引脚电平 - 高(1)", | ||||
|         "left": "左", | ||||
|         "right": "右", | ||||
|         "middle": "中", | ||||
|         "any": "任何", | ||||
|         "pinname": "引脚", | ||||
|         "alreadyuse": "已被使用", | ||||
|         "alreadyset": "已被设为", | ||||
|         "tip": { | ||||
|             "pin": "<b>正在使用引脚</b>: ", | ||||
|             "in": "提示: 仅接受数字输入 - 输出必须为0或1.", | ||||
|             "dig": "提示: 如用数字输出 - 输入必须为0或1.", | ||||
|             "pwm": "提示: 如用PWM输出 - 输入必须为0至100之间; 如用高频率可能会比预期占用更多CPU资源.", | ||||
|             "ser": "<b>提示</b>: 如用伺服输出 - 输入必须为0至100之间. 50为中间值." | ||||
|         }, | ||||
|         "types": { | ||||
|             "digout": "数字输出", | ||||
|             "input": "输入", | ||||
|             "pullup": "含有上拉电阻的输入", | ||||
|             "pulldown": "含有下拉电阻的输入", | ||||
|             "pwmout": "PWM输出", | ||||
|             "servo": "伺服输出" | ||||
|         }, | ||||
|         "status": { | ||||
|             "stopped": "已停止", | ||||
|             "closed": "已关闭", | ||||
|             "not-running": "不运行" | ||||
|         }, | ||||
|         "errors": { | ||||
|             "ignorenode": "忽略树莓派的特定节点", | ||||
|             "version": "版本命令失败", | ||||
|             "sawpitype": "查看Pi类型", | ||||
|             "libnotfound": "找不到树莓派RPi.GPIO的python库", | ||||
|             "alreadyset": "GPIO引脚 __pin__ 已经被设定为类型: __type__", | ||||
|             "invalidpin": "无效GPIO引脚", | ||||
|             "invalidinput": "无效输入", | ||||
|             "needtobeexecutable": "__command__须为可运行命令", | ||||
|             "mustbeexecutable": "nrgpio须为可运行", | ||||
|             "commandnotfound": "nrgpio命令不存在", | ||||
|             "commandnotexecutable": "nrgpio命令不可运行", | ||||
|             "error": "错误: __error__", | ||||
|             "pythoncommandnotfound": "nrpgio python命令未处于运行状态" | ||||
|         } | ||||
|     }, | ||||
|     "file": { | ||||
|         "label": { | ||||
|             "filename": "文件名", | ||||
|   | ||||
| @@ -50,7 +50,12 @@ var nodes = { | ||||
|  | ||||
|     "sentiment": {module:"node-red-node-sentiment"}, | ||||
|  | ||||
|     "tail": {module:"node-red-node-tail"} | ||||
|     "tail": {module:"node-red-node-tail"}, | ||||
|  | ||||
|     "rpi-gpio in": {module:"node-red-node-pi-gpio"}, | ||||
|     "rpi-gpio out": {module:"node-red-node-pi-gpio"}, | ||||
|     "rpi-mouse": {module:"node-red-node-pi-gpio"}, | ||||
|     "rpi-keyboard": {module:"node-red-node-pi-gpio"} | ||||
| } | ||||
|  | ||||
| module.exports = { | ||||
|   | ||||
							
								
								
									
										3
									
								
								packages/node_modules/node-red/package.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								packages/node_modules/node-red/package.json
									
									
									
									
										vendored
									
									
								
							| @@ -39,12 +39,9 @@ | ||||
|         "bcryptjs": "2.4.3", | ||||
|         "express": "4.17.1", | ||||
|         "fs-extra": "8.1.0", | ||||
|         "node-red-node-email": "^1.6.2", | ||||
|         "node-red-node-feedparser": "^0.1.14", | ||||
|         "node-red-node-rbe": "^0.2.4", | ||||
|         "node-red-node-sentiment": "^0.1.3", | ||||
|         "node-red-node-tail": "^0.0.2", | ||||
|         "node-red-node-twitter": "^1.1.5", | ||||
|         "nopt": "4.0.1", | ||||
|         "semver": "6.2.0" | ||||
|     }, | ||||
|   | ||||
| @@ -1,154 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * 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. | ||||
|  **/ | ||||
|  | ||||
| var should = require("should"); | ||||
| var rpiNode = require("nr-test-utils").require("@node-red/nodes/core/hardware/36-rpi-gpio.js"); | ||||
| var statusNode = require("nr-test-utils").require("@node-red/nodes/core/core/25-status.js"); | ||||
| var helper = require("node-red-node-test-helper"); | ||||
| var fs = require("fs"); | ||||
|  | ||||
| describe('RPI GPIO Node', function() { | ||||
|  | ||||
|     before(function(done) { | ||||
|         helper.startServer(done); | ||||
|     }); | ||||
|  | ||||
|     after(function(done) { | ||||
|         helper.stopServer(done); | ||||
|     }); | ||||
|  | ||||
|     afterEach(function() { | ||||
|         helper.unload(); | ||||
|     }); | ||||
|  | ||||
|     var checkIgnore = function(done) { | ||||
|         setTimeout(function() { | ||||
|             try { | ||||
|                 var logEvents = helper.log().args.filter(function(evt) { | ||||
|                     return ((evt[0].level == 30) && (evt[0].msg.indexOf("rpi-gpio")===0)); | ||||
|                 }); | ||||
|                 logEvents[0][0].should.have.a.property('msg'); | ||||
|                 logEvents[0][0].msg.toString().should.startWith("rpi-gpio : rpi-gpio.errors.ignorenode"); | ||||
|                 done(); | ||||
|             } catch(err) { | ||||
|                 done(err); | ||||
|             } | ||||
|         },25); | ||||
|     } | ||||
|  | ||||
|     it('should load Input node', function(done) { | ||||
|         var flow = [{id:"n1", type:"rpi-gpio in", name:"rpi-gpio in" }]; | ||||
|         helper.load(rpiNode, flow, function() { | ||||
|             var n1 = helper.getNode("n1"); | ||||
|             n1.should.have.property('name', 'rpi-gpio in'); | ||||
|             try { | ||||
|                 var cpuinfo = fs.readFileSync("/proc/cpuinfo").toString(); | ||||
|                 if (cpuinfo.indexOf(": BCM") === 1) { | ||||
|                     done(); // It's ON a PI ... should really do more tests ! | ||||
|                 } else { | ||||
|                     checkIgnore(done); | ||||
|                 } | ||||
|             } | ||||
|             catch(e) { | ||||
|                 checkIgnore(done); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     it('should load Output node', function(done) { | ||||
|         var flow = [{id:"n1", type:"rpi-gpio out", name:"rpi-gpio out" }]; | ||||
|         helper.load(rpiNode, flow, function() { | ||||
|             var n1 = helper.getNode("n1"); | ||||
|             n1.should.have.property('name', 'rpi-gpio out'); | ||||
|             try { | ||||
|                 var cpuinfo = fs.readFileSync("/proc/cpuinfo").toString(); | ||||
|                 if (cpuinfo.indexOf(": BCM") === 1) { | ||||
|                     done(); // It's ON a PI ... should really do more tests ! | ||||
|                 } else { | ||||
|                     checkIgnore(done); | ||||
|                 } | ||||
|             } | ||||
|             catch(e) { | ||||
|                 checkIgnore(done); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|  | ||||
|     it('should read a dummy value high (not on Pi)', function(done) { | ||||
|         var flow = [{id:"n1", type:"rpi-gpio in", pin:"7", intype:"up", debounce:"25", read:true, wires:[["n2"]] }, | ||||
|         {id:"n2", type:"helper"}]; | ||||
|         helper.load(rpiNode, flow, function() { | ||||
|             var n1 = helper.getNode("n1"); | ||||
|             var n2 = helper.getNode("n2"); | ||||
|             n2.on("input", function(msg) { | ||||
|                 try { | ||||
|                     msg.should.have.property('topic', 'pi/7'); | ||||
|                     msg.should.have.property('payload', 1); | ||||
|                     done(); | ||||
|                 } catch(err) { | ||||
|                     done(err); | ||||
|                 } | ||||
|             }); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     it('should read a dummy value low (not on Pi)', function(done) { | ||||
|         var flow = [{id:"n1", type:"rpi-gpio in", pin:"11", intype:"down", debounce:"25", read:true, wires:[["n2"]] }, | ||||
|         {id:"n2", type:"helper"}]; | ||||
|         helper.load(rpiNode, flow, function() { | ||||
|             var n1 = helper.getNode("n1"); | ||||
|             var n2 = helper.getNode("n2"); | ||||
|             n2.on("input", function(msg) { | ||||
|                 try { | ||||
|                     msg.should.have.property('topic', 'pi/11'); | ||||
|                     msg.should.have.property('payload', 0); | ||||
|                     done(); | ||||
|                 } catch(err) { | ||||
|                     done(err); | ||||
|                 } | ||||
|             }); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     it('should be able preset out to a dummy value (not on Pi)', function(done) { | ||||
|         var flow = [{id:"n1", type:"rpi-gpio out", pin:"7", out:"out", level:"0", set:true, freq:"", wires:[], z:"1"}, | ||||
|         {id:"n2", type:"status", scope:null, wires:[["n3"]], z:"1"}, | ||||
|         {id:"n3", type:"helper", z:"1"}]; | ||||
|         helper.load([rpiNode,statusNode], flow, function() { | ||||
|             var n1 = helper.getNode("n1"); | ||||
|             var n2 = helper.getNode("n2"); | ||||
|             var n3 = helper.getNode("n3"); | ||||
|             var count = 0; | ||||
|             n3.on("input", function(msg) { | ||||
|                 // Only check the first status message received as it may get a | ||||
|                 // 'closed' status as the test is tidied up. | ||||
|                 if (count === 0) { | ||||
|                     count++; | ||||
|                     try { | ||||
|                         msg.should.have.property('status'); | ||||
|                         msg.status.should.have.property('text', "rpi-gpio.status.na"); | ||||
|                         done(); | ||||
|                     } catch(err) { | ||||
|                         done(err); | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|             n1.receive({payload:"1"}); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
| }); | ||||
		Reference in New Issue
	
	Block a user