mirror of
https://github.com/node-red/node-red-nodes.git
synced 2023-10-10 13:36:58 +02:00
Add out node
This commit is contained in:
parent
20f14a698c
commit
0cc33db58f
@ -28,7 +28,8 @@ Run the following command in your Node-RED user directory (typically `~/.node-re
|
||||
|
||||
### Input Node
|
||||
|
||||
This node sends readings from the various sensors on the Sense HAT, grouped into three sets; motion events, environment events and joystick events.
|
||||
This node sends readings from the various sensors on the Sense HAT, grouped into
|
||||
three sets; motion events, environment events and joystick events.
|
||||
|
||||
#### Motion events
|
||||
|
||||
@ -38,9 +39,9 @@ per second. The `topic` is set to `motion` and the `payload` is an object with t
|
||||
following values:
|
||||
|
||||
- `acceleration.x/y/z` : the acceleration intensity in Gs
|
||||
- `gyroscope.x/y/z` : the rotational intensity in radians/s
|
||||
- `orientation.roll/pitch/yaw` : the angle of the axis in degrees
|
||||
- `compass` : the direction of North in degrees
|
||||
-`gyroscope.x/y/z` : the rotational intensity in radians/s
|
||||
-`orientation.roll/pitch/yaw` : the angle of the axis in degrees
|
||||
-`compass` : the direction of North in degrees
|
||||
|
||||
#### Environment events
|
||||
|
||||
@ -49,17 +50,69 @@ sensors. They are sent at a rate of approximately 1 per second. The `topic`
|
||||
is set to `environment` and the `payload` is an object
|
||||
with the following values:
|
||||
|
||||
- `temperature` : degrees Celsius
|
||||
- `humidity` : percentage of relative humidity
|
||||
- `pressure` : Millibars
|
||||
-`temperature` : degrees Celsius
|
||||
-`humidity` : percentage of relative humidity
|
||||
-`pressure` : Millibars
|
||||
|
||||
#### Joystick events
|
||||
|
||||
Joystick events are sent when the Sense HAT joystick is interacted with. The
|
||||
`topic` is set to `joystick` and the `payload` is an object with the following values:
|
||||
|
||||
- `key` : one of `UP`, `DOWN`, `LEFT`, `RIGHT`, `ENTER`
|
||||
- `state` : the state of the key:
|
||||
- `0` : the key has been released
|
||||
- `1` : the key has been pressed
|
||||
- `2` : the key is being held down
|
||||
-`key` : one of `UP`, `DOWN`, `LEFT`, `RIGHT`, `ENTER`
|
||||
-`state` : the state of the key:
|
||||
-`0` : the key has been released
|
||||
-`1` : the key has been pressed
|
||||
-`2` : the key is being held down
|
||||
|
||||
|
||||
### Output Node
|
||||
|
||||
This node sends commands to the 8x8 LED display on the Sense HAT.
|
||||
|
||||
Commands are sent to the node in `msg.payload`. Multiple commands can
|
||||
be sent in a single message by separating them with newline (\n) characters.
|
||||
|
||||
#### Set the colour of individual pixels
|
||||
|
||||
Format: `<x>,<y>,<colour>`
|
||||
|
||||
`x` and `y` must either be a value in the range 0-7, or `*` to indicate the entire row or column.
|
||||
|
||||
`colour` must be one of:
|
||||
|
||||
- the well-known <a href="https://en.wikipedia.org/wiki/Web_colors" target="_new">HTML colour names</a>
|
||||
- eg `red` or `aquamarine`,
|
||||
- the <a href="http://cheerlights.com/cheerlights-api/">CheerLights colour names</a>,
|
||||
- a HEX colour value - eg `#aa9900`
|
||||
- an RGB triple - `190,255,0`
|
||||
- or simply `off`
|
||||
|
||||
To set the entire screen to red: `*,*,red`
|
||||
|
||||
To set the four corners of the display to red, green (#00ff00), yellow and blue (0,0,255):
|
||||
|
||||
`0,0,red,0,7,#00ff00,7,7,yellow,7,0,0,0,255`
|
||||
|
||||
#### Rotate the screen
|
||||
|
||||
Format: `R<angle>`
|
||||
|
||||
`angle` must be 0, 90, 180 or 270.
|
||||
|
||||
#### Flip the screen
|
||||
|
||||
Format: `R<axis>`
|
||||
|
||||
`axis` must be either `H` or `V` to flip on the horizontal or vertical axis respectively.
|
||||
|
||||
#### Scroll a message
|
||||
|
||||
If `msg.payload` is not recognised as any of the above commands, it is treated
|
||||
as a text message to be scrolled across the screen.
|
||||
|
||||
The following message properties can be used to customise the appearance:
|
||||
|
||||
- `msg.colour` - the colour of the text, default: `white`
|
||||
- `msg.background` - the colour of the background, default: `off`
|
||||
- `msg.speed` - the scroll speed. A value in the range 1 (slower) to 5 (faster), default: `3`
|
||||
|
220
hardware/sensehat/colours.js
Normal file
220
hardware/sensehat/colours.js
Normal file
@ -0,0 +1,220 @@
|
||||
/**
|
||||
* Copyright 2016 IBM Corp.
|
||||
*
|
||||
* 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 colours = {
|
||||
'aqua':'#00FFFF',
|
||||
'aliceblue':'#F0F8FF',
|
||||
'antiquewhite':'#FAEBD7',
|
||||
'black':'#000000',
|
||||
'off':'#000000',
|
||||
'blue':'#0000FF',
|
||||
'cyan':'#00FFFF',
|
||||
'darkblue':'#00008B',
|
||||
'darkcyan':'#008B8B',
|
||||
'darkgreen':'#006400',
|
||||
'darkturquoise':'#00CED1',
|
||||
'deepskyblue':'#00BFFF',
|
||||
'green':'#008000',
|
||||
'lime':'#00FF00',
|
||||
'mediumblue':'#0000CD',
|
||||
'mediumspringgreen':'#00FA9A',
|
||||
'navy':'#000080',
|
||||
'springgreen':'#00FF7F',
|
||||
'teal':'#008080',
|
||||
'midnightblue':'#191970',
|
||||
'dodgerblue':'#1E90FF',
|
||||
'lightseagreen':'#20B2AA',
|
||||
'forestgreen':'#228B22',
|
||||
'seagreen':'#2E8B57',
|
||||
'darkslategray':'#2F4F4F',
|
||||
'darkslategrey':'#2F4F4F',
|
||||
'limegreen':'#32CD32',
|
||||
'mediumseagreen':'#3CB371',
|
||||
'turquoise':'#40E0D0',
|
||||
'royalblue':'#4169E1',
|
||||
'steelblue':'#4682B4',
|
||||
'darkslateblue':'#483D8B',
|
||||
'mediumturquoise':'#48D1CC',
|
||||
'indigo':'#4B0082',
|
||||
'darkolivegreen':'#556B2F',
|
||||
'cadetblue':'#5F9EA0',
|
||||
'cornflowerblue':'#6495ED',
|
||||
'mediumaquamarine':'#66CDAA',
|
||||
'dimgray':'#696969',
|
||||
'dimgrey':'#696969',
|
||||
'slateblue':'#6A5ACD',
|
||||
'olivedrab':'#6B8E23',
|
||||
'slategray':'#708090',
|
||||
'slategrey':'#708090',
|
||||
'lightslategray':'#778899',
|
||||
'lightslategrey':'#778899',
|
||||
'mediumslateblue':'#7B68EE',
|
||||
'lawngreen':'#7CFC00',
|
||||
'aquamarine':'#7FFFD4',
|
||||
'chartreuse':'#7FFF00',
|
||||
'gray':'#808080',
|
||||
'grey':'#808080',
|
||||
'maroon':'#800000',
|
||||
'olive':'#808000',
|
||||
'purple':'#800080',
|
||||
'lightskyblue':'#87CEFA',
|
||||
'skyblue':'#87CEEB',
|
||||
'blueviolet':'#8A2BE2',
|
||||
'darkmagenta':'#8B008B',
|
||||
'darkred':'#8B0000',
|
||||
'saddlebrown':'#8B4513',
|
||||
'darkseagreen':'#8FBC8F',
|
||||
'lightgreen':'#90EE90',
|
||||
'mediumpurple':'#9370DB',
|
||||
'darkviolet':'#9400D3',
|
||||
'palegreen':'#98FB98',
|
||||
'darkorchid':'#9932CC',
|
||||
'yellowgreen':'#9ACD32',
|
||||
'sienna':'#A0522D',
|
||||
'brown':'#A52A2A',
|
||||
'darkgray':'#A9A9A9',
|
||||
'darkgrey':'#A9A9A9',
|
||||
'greenyellow':'#ADFF2F',
|
||||
'lightblue':'#ADD8E6',
|
||||
'paleturquoise':'#AFEEEE',
|
||||
'lightsteelblue':'#B0C4DE',
|
||||
'powderblue':'#B0E0E6',
|
||||
'firebrick':'#B22222',
|
||||
'darkgoldenrod':'#B8860B',
|
||||
'mediumorchid':'#BA55D3',
|
||||
'rosybrown':'#BC8F8F',
|
||||
'darkkhaki':'#BDB76B',
|
||||
'silver':'#C0C0C0',
|
||||
'mediumvioletred':'#C71585',
|
||||
'indianred':'#CD5C5C',
|
||||
'peru':'#CD853F',
|
||||
'chocolate':'#D2691E',
|
||||
'tan':'#D2B48C',
|
||||
'lightgray':'#D3D3D3',
|
||||
'lightgrey':'#D3D3D3',
|
||||
'thistle':'#D8BFD8',
|
||||
'goldenrod':'#DAA520',
|
||||
'orchid':'#DA70D6',
|
||||
'palevioletred':'#DB7093',
|
||||
'crimson':'#DC143C',
|
||||
'gainsboro':'#DCDCDC',
|
||||
'plum':'#DDA0DD',
|
||||
'burlywood':'#DEB887',
|
||||
'lightcyan':'#E0FFFF',
|
||||
'lavender':'#E6E6FA',
|
||||
'darksalmon':'#E9967A',
|
||||
'palegoldenrod':'#EEE8AA',
|
||||
'violet':'#EE82EE',
|
||||
'azure':'#F0FFFF',
|
||||
'honeydew':'#F0FFF0',
|
||||
'khaki':'#F0E68C',
|
||||
'lightcoral':'#F08080',
|
||||
'sandybrown':'#F4A460',
|
||||
'beige':'#F5F5DC',
|
||||
'mintcream':'#F5FFFA',
|
||||
'wheat':'#F5DEB3',
|
||||
'whitesmoke':'#F5F5F5',
|
||||
'ghostwhite':'#F8F8FF',
|
||||
'lightgoldenrodyellow':'#FAFAD2',
|
||||
'linen':'#FAF0E6',
|
||||
'salmon':'#FA8072',
|
||||
'oldlace':'#FDF5E6',
|
||||
'warmwhite':'#FDF5E6',
|
||||
'bisque':'#FFE4C4',
|
||||
'blanchedalmond':'#FFEBCD',
|
||||
'coral':'#FF7F50',
|
||||
'cornsilk':'#FFF8DC',
|
||||
'darkorange':'#FF8C00',
|
||||
'deeppink':'#FF1493',
|
||||
'floralwhite':'#FFFAF0',
|
||||
'fuchsia':'#FF00FF',
|
||||
'gold':'#FFD700',
|
||||
'hotpink':'#FF69B4',
|
||||
'ivory':'#FFFFF0',
|
||||
'lavenderblush':'#FFF0F5',
|
||||
'lemonchiffon':'#FFFACD',
|
||||
'lightpink':'#FFB6C1',
|
||||
'lightsalmon':'#FFA07A',
|
||||
'lightyellow':'#FFFFE0',
|
||||
'magenta':'#FF00FF',
|
||||
'mistyrose':'#FFE4E1',
|
||||
'moccasin':'#FFE4B5',
|
||||
'navajowhite':'#FFDEAD',
|
||||
'orange':'#FFA500',
|
||||
'orangered':'#FF4500',
|
||||
'papayawhip':'#FFEFD5',
|
||||
'peachpuff':'#FFDAB9',
|
||||
'pink':'#FFC0CB',
|
||||
'red':'#FF0000',
|
||||
'seashell':'#FFF5EE',
|
||||
'snow':'#FFFAFA',
|
||||
'tomato':'#FF6347',
|
||||
'white':'#FFFFFF',
|
||||
'yellow':'#FFFF00',
|
||||
'amber':'#FFD200'
|
||||
};
|
||||
|
||||
var hexColour = /^#([0-9A-F][0-9A-F][0-9A-F]){1,2}$/i;
|
||||
|
||||
module.exports.getRGB = function(col,rgb) {
|
||||
if (!col) {
|
||||
return null;
|
||||
}
|
||||
if (/^\d{1,3},\d{1,3},\d{1,3}$/.test(col)) {
|
||||
return col;
|
||||
}
|
||||
col = col.toString().toLowerCase();
|
||||
if (col in colours) {
|
||||
col = colours[col];
|
||||
}
|
||||
if (hexColour.test(col)) {
|
||||
if (col.length === 4) {
|
||||
col = "#"+col[1]+col[1]+col[2]+col[2]+col[3]+col[3];
|
||||
}
|
||||
if (rgb === "grb") {
|
||||
g = parseInt(col.slice(1,3),16);
|
||||
r = parseInt(col.slice(3,5),16);
|
||||
b = parseInt(col.slice(5),16);
|
||||
}
|
||||
else {
|
||||
r = parseInt(col.slice(1,3),16);
|
||||
g = parseInt(col.slice(3,5),16);
|
||||
b = parseInt(col.slice(5),16);
|
||||
}
|
||||
return r+","+g+","+b;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.getHex = function(col) {
|
||||
col = col.toString().toLowerCase();
|
||||
if (col in colours) {
|
||||
return colours[col];
|
||||
}
|
||||
else { return null; }
|
||||
}
|
||||
|
||||
module.exports.HexRGB = function(hex) {
|
||||
try {
|
||||
r = parseInt(hex.slice(1,3),16);
|
||||
g = parseInt(hex.slice(3,5),16);
|
||||
b = parseInt(hex.slice(5),16);
|
||||
return r+","+g+","+b;
|
||||
}
|
||||
catch(e) { return null; }
|
||||
}
|
@ -36,6 +36,13 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-template-name="rpi-sensehat out">
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
||||
<input type="text" id="node-input-name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="rpi-sensehat in">
|
||||
<p>Raspberry Pi Sense HAT input node.</p>
|
||||
<p>This node sends readings from the various sensors on the Sense HAT,
|
||||
@ -75,10 +82,53 @@ is an object with the following values:</p>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="rpi-sensehat out">
|
||||
<p>Raspberry Pi Sense HAT output node.</p>
|
||||
<p>This node sends commands to the 8x8 LED display on the Sense HAT.</p>
|
||||
<p>Commands are sent to the node in <code>msg.payload</code>. Multiple commands can
|
||||
be sent in a single message by separating them with newline (\n) characters.<p>
|
||||
|
||||
<p><b>Set the colour of individual pixels</b></p>
|
||||
<p>Format: <code><x>,<y>,<colour></code>
|
||||
<p><code>x</code> and <code>y</code> must either be a value in the range 0-7, or
|
||||
<code>*</code> to indicate the entire row or column.</p>
|
||||
<p><code>colour</code> must be one of:
|
||||
<ul>
|
||||
<li>the well-known <a href="https://en.wikipedia.org/wiki/Web_colors" target="_new">HTML colour names</a>
|
||||
- eg <code>red</code> or <code>aquamarine</code>,</li>
|
||||
<li>the <a href="http://cheerlights.com/cheerlights-api/">CheerLights colour names</a>,</li>
|
||||
<li>a HEX colour value - eg <code>#aa9900</code></li>
|
||||
<li>an RGB triple - <code>190,255,0</code></li>
|
||||
<li>or simply <code>off</code></li>
|
||||
</ul>
|
||||
|
||||
<p><i>Examples</i></p>
|
||||
<p>To set the entire screen to red:</p>
|
||||
<p><code>*,*,red</code></p>
|
||||
<p>To set the four corners of the display to red, green (#00ff00), yellow and blue (0,0,255):</p>
|
||||
<p><code>0,0,red,0,7,#00ff00,7,7,yellow,7,0,0,0,255</code></p>
|
||||
|
||||
<p><b>Rotate the screen</b></p>
|
||||
<p>Format: <code>R<angle></code></p>
|
||||
<p><code>angle</code> must be 0, 90, 180 or 270.</p>
|
||||
|
||||
<p><b>Flip the screen</b></p>
|
||||
<p>Format: <code>R<axis></code></p>
|
||||
<p><code>axis</code> must be either <code>H</code> or <code>V</code> to flip on
|
||||
the horizontal or vertical axis respectively.</p>
|
||||
|
||||
<p><b>Scroll a message</b></p>
|
||||
<p>If <code>msg.payload</code> is not recognised as any of the above commands,
|
||||
it is treated as a text message to be scrolled across the screen.</p>
|
||||
<p>The following message properties can be used to customise the appearance:</p>
|
||||
<ul>
|
||||
<li><code>msg.colour</code> - the colour of the text, default: <code>white</code></li>
|
||||
<li><code>msg.background</code> - the colour of the background, default: <code>off</code></li>
|
||||
<li><code>msg.speed</code> - the scroll speed. A value in the range 1 (slower) to 5 (faster), default: <code>3</code></li>
|
||||
</ul>
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('rpi-sensehat in',{
|
||||
category: 'Raspberry Pi',
|
||||
@ -100,4 +150,23 @@ is an object with the following values:</p>
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
|
||||
RED.nodes.registerType('rpi-sensehat out',{
|
||||
category: 'Raspberry Pi',
|
||||
paletteLabel: "Sense HAT",
|
||||
color:"#c6dbef",
|
||||
defaults: {
|
||||
name: { value:"" },
|
||||
},
|
||||
inputs:1,
|
||||
outputs:0,
|
||||
icon: "rpi.png",
|
||||
align: "right",
|
||||
label: function() {
|
||||
return this.name||"Sense HAT";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -18,6 +18,7 @@ module.exports = function(RED) {
|
||||
"use strict";
|
||||
var fs = require('fs');
|
||||
var spawn = require('child_process').spawn;
|
||||
var colours = require('./colours');
|
||||
|
||||
var hatCommand = __dirname+'/sensehat';
|
||||
|
||||
@ -198,10 +199,16 @@ module.exports = function(RED) {
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
},
|
||||
send: function(msg) {
|
||||
if (hat) {
|
||||
hat.stdin.write(msg+'\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
function SenseHatInNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.motion = n.motion;
|
||||
@ -215,4 +222,115 @@ module.exports = function(RED) {
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("rpi-sensehat in",SenseHatInNode);
|
||||
|
||||
function SenseHatOutNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
var node = this;
|
||||
HAT.open(this);
|
||||
|
||||
node.on("close", function(done) {
|
||||
HAT.close(this,done);
|
||||
});
|
||||
|
||||
node.on("input",function(msg) {
|
||||
var command;
|
||||
var parts;
|
||||
var col;
|
||||
if (typeof msg.payload === 'string') {
|
||||
var lines = msg.payload.split("\n");
|
||||
lines.forEach(function(line) {
|
||||
command = null;
|
||||
col = colours.getRGB(line);
|
||||
if ( /^(([0-7]|\*),([0-7]|\*),(\d{1,3},\d{1,3},\d{1,3}|#[a-f0-9]{3,6}|[a-z]+))(,([0-7]|\*),([0-7]|\*),(\d{1,3},\d{1,3},\d{1,3}|#[a-f0-9]{3,6}|[a-z]+))*$/i.test(line)) {
|
||||
parts = line.split(",");
|
||||
var expanded = [];
|
||||
var i=0;
|
||||
var j=0;
|
||||
while (i<parts.length) {
|
||||
var x = parts[i++];
|
||||
var y = parts[i++];
|
||||
col = parts[i++];
|
||||
if (/#[a-f0-9]{3,6}|[a-z]/i.test(col)) {
|
||||
col = colours.getRGB(col);
|
||||
if (col === null) {
|
||||
// invalid colour, go no further
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
col += ","+parts[i++]+","+parts[i++];
|
||||
}
|
||||
if (x!=='*' && y!=='*') {
|
||||
expanded.push([x,y,col]);
|
||||
} else if (x == '*' && y == '*') {
|
||||
for (j=0;j<8;j++) {
|
||||
for (var k=0;k<8;k++) {
|
||||
expanded.push([j,k,col]);
|
||||
}
|
||||
}
|
||||
} else if (x == '*') {
|
||||
for (j=0;j<8;j++) {
|
||||
expanded.push([j,y,col]);
|
||||
}
|
||||
} else if (y == '*') {
|
||||
for (j=0;j<8;j++) {
|
||||
expanded.push([x,j,col]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (expanded.length > 0) {
|
||||
var pixels = {};
|
||||
var rules = [];
|
||||
for (i=expanded.length-1;i>=0;i--) {
|
||||
var rule = expanded[i];
|
||||
if (!pixels[rule[0]+","+rule[1]]) {
|
||||
rules.unshift(rule.join(","));
|
||||
pixels[rule[0]+","+rule[1]] = true;
|
||||
}
|
||||
}
|
||||
if (rules.length > 0) {
|
||||
command = "P"+rules.join(",");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!command) {
|
||||
if (/^R(0|90|180|270)$/i.test(line)) {
|
||||
command = line.toUpperCase();
|
||||
} else if (/^F(H|V)$/i.test(line)) {
|
||||
command = line.toUpperCase();
|
||||
} else {
|
||||
var textCol = colours.getRGB(msg.color);
|
||||
var backCol = colours.getRGB(msg.background);
|
||||
var speed = null;
|
||||
if (!isNaN(msg.speed)) {
|
||||
speed = msg.speed;
|
||||
}
|
||||
command = "T";
|
||||
if (textCol) {
|
||||
command += textCol;
|
||||
if (backCol) {
|
||||
command += ","+backCol;
|
||||
}
|
||||
}
|
||||
if (speed) {
|
||||
var s = parseInt(speed);
|
||||
if (s >= 1 && s <= 5) {
|
||||
s = 0.1 + (3-s)*0.03;
|
||||
}
|
||||
command = command + ((command.length === 1)?"":",") + s;
|
||||
}
|
||||
command += ":" + line;
|
||||
}
|
||||
}
|
||||
if (command) {
|
||||
//console.log(command);
|
||||
HAT.send(command);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("rpi-sensehat out",SenseHatOutNode);
|
||||
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
# C[R,G,B] - clear to colour (or off if no RGB provided)
|
||||
# R[rot] - rotate by rot (0,90,180,270)
|
||||
# P[x,y,R,G,B]+ - set individual pixel(s) to a colour
|
||||
# T[R,G,B:]Message - scroll a message (nb: if message contains ':' it must be prefixed with ':')
|
||||
# T[R,G,B[,R,G,B][,S]:]Message - scroll a message (nb: if message contains ':' it must be prefixed with ':')
|
||||
# F[H|V] - flip horizontal|vertical
|
||||
# X[0|1] - high frequency reporting (accel/gyro/orientation/compass) off|on
|
||||
# Y[0|1] - low frequency reporting (temperature/humidity/pressure) off|on
|
||||
@ -32,8 +32,11 @@ import sys
|
||||
import glob
|
||||
import time
|
||||
import errno
|
||||
import ctypes
|
||||
import select
|
||||
import struct
|
||||
import inspect
|
||||
import threading
|
||||
|
||||
from sense_hat import SenseHat
|
||||
|
||||
@ -69,40 +72,48 @@ lf_interval = 1
|
||||
hf_enabled = False
|
||||
lf_enabled = False
|
||||
|
||||
scroll = None
|
||||
|
||||
class ScrollThread(threading.Thread):
|
||||
def __init__(self,fcol,bcol,speed,message):
|
||||
threading.Thread.__init__(self)
|
||||
self.fcol = fcol
|
||||
self.bcol = bcol
|
||||
self.message = message
|
||||
self.speed = speed
|
||||
|
||||
def run(self):
|
||||
global SH
|
||||
old_rotation = SH.rotation
|
||||
|
||||
try:
|
||||
SH.show_message(self.message,text_colour=self.fcol,back_colour=self.bcol,scroll_speed=self.speed)
|
||||
except:
|
||||
SH.set_rotation(old_rotation,False)
|
||||
SH.clear(self.bcol);
|
||||
pass
|
||||
|
||||
def interrupt(self):
|
||||
if not self.isAlive():
|
||||
raise threading.ThreadError()
|
||||
for thread_id, thread_object in threading._active.items():
|
||||
if thread_object == self:
|
||||
r = ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id,ctypes.py_object(StandardError))
|
||||
if r == 1:
|
||||
pass
|
||||
else:
|
||||
if r > 1:
|
||||
ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, 0)
|
||||
raise SystemError()
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
def process_command(data):
|
||||
global hf_enabled, lf_enabled
|
||||
if data[0] == "R":
|
||||
SH.set_rotation(float(data[1:]))
|
||||
elif data[0] == "C":
|
||||
data = data[1:].strip()
|
||||
if len(data) > 0:
|
||||
s = data.split(",")
|
||||
col = (int(s[0]),int(s[1]),int(s[2]))
|
||||
else:
|
||||
col = (0,0,0)
|
||||
SH.clear(col)
|
||||
elif data[0] == "P":
|
||||
data = data[1:].strip()
|
||||
s = data.split(',')
|
||||
for p in range(0,len(s),5):
|
||||
SH.set_pixel(int(s[p]),int(s[p+1]),int(s[p+2]),int(s[p+3]),int(s[p+4]))
|
||||
elif data[0] == "T":
|
||||
data = data[1:].strip()
|
||||
col = (255,255,255)
|
||||
s = data.split(':',1)
|
||||
if len(s) == 2:
|
||||
data = s[1]
|
||||
if len(s[0]) > 0:
|
||||
c = s[0].split(",")
|
||||
col = (int(c[0]),int(c[1]),int(c[2]))
|
||||
SH.show_message(data,text_colour=col)
|
||||
elif data[0] == "F":
|
||||
if data[1] == "H":
|
||||
SH.flip_h()
|
||||
elif data[1] == "V":
|
||||
SH.flip_v()
|
||||
elif data[0] == "X":
|
||||
global hf_enabled, lf_enabled,scroll
|
||||
|
||||
if data[0] == "X":
|
||||
if data[1] == '0':
|
||||
hf_enabled = False
|
||||
else:
|
||||
@ -112,6 +123,61 @@ def process_command(data):
|
||||
lf_enabled = False
|
||||
else:
|
||||
lf_enabled = True
|
||||
else:
|
||||
if threading.activeCount() == 2:
|
||||
scroll.interrupt()
|
||||
while scroll.isAlive():
|
||||
time.sleep(0.01)
|
||||
try:
|
||||
scroll.interrupt()
|
||||
except:
|
||||
pass
|
||||
if data[0] == "R":
|
||||
SH.set_rotation(float(data[1:]))
|
||||
elif data[0] == "C":
|
||||
data = data[1:].strip()
|
||||
if len(data) > 0:
|
||||
s = data.split(",")
|
||||
col = (int(s[0]),int(s[1]),int(s[2]))
|
||||
else:
|
||||
col = (0,0,0)
|
||||
SH.clear(col)
|
||||
elif data[0] == "P":
|
||||
data = data[1:].strip()
|
||||
s = data.split(',')
|
||||
for p in range(0,len(s),5):
|
||||
SH.set_pixel(int(s[p]),int(s[p+1]),int(s[p+2]),int(s[p+3]),int(s[p+4]))
|
||||
elif data[0] == "T":
|
||||
data = data[1:].strip()
|
||||
tcol = (255,255,255)
|
||||
bcol = (0,0,0)
|
||||
speed = 0.1
|
||||
s = data.split(':',1)
|
||||
if len(s) == 2:
|
||||
data = s[1]
|
||||
if len(s[0]) > 0:
|
||||
c = s[0].split(",")
|
||||
if len(c) == 1:
|
||||
speed = float(c[0])
|
||||
elif len(c) == 3:
|
||||
tcol = (int(c[0]),int(c[1]),int(c[2]))
|
||||
if len(c) == 4:
|
||||
tcol = (int(c[0]),int(c[1]),int(c[2]))
|
||||
speed = float(c[3])
|
||||
elif len(c) == 6:
|
||||
tcol = (int(c[0]),int(c[1]),int(c[2]))
|
||||
bcol = (int(c[3]),int(c[4]),int(c[5]))
|
||||
elif len(c) == 7:
|
||||
tcol = (int(c[0]),int(c[1]),int(c[2]))
|
||||
bcol = (int(c[3]),int(c[4]),int(c[5]))
|
||||
speed = float(c[6])
|
||||
scroll = ScrollThread(tcol,bcol,speed,data);
|
||||
scroll.start()
|
||||
elif data[0] == "F":
|
||||
if data[1] == "H":
|
||||
SH.flip_h()
|
||||
elif data[1] == "V":
|
||||
SH.flip_v()
|
||||
|
||||
def idle_work():
|
||||
global last_hf_time, last_lf_time
|
||||
|
Loading…
Reference in New Issue
Block a user