Escolar Documentos
Profissional Documentos
Cultura Documentos
WORKSHOP
CONTENT:
In
this
workshop,
were
going
to
use
Node-RED
as
a
development
tool
for
JavaScript.
Building
on
functionality
available
for
generic
programming
challenges,
were
going
to
use
the
communication
standard
TCP
(Transmission
Control
Protocol)
to
interact
with
the
Minecraft
API
(Application
Programming
Interface).
-1-
CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript
Technical
background:
For
this
workshop,
you
will
find
a
Raspberry
Pi
with
Node-RED
already
installed.
While
the
installation
of
Node-RED
software
is
relatively
easy,
it
would
be
difficult
to
include
this
step
within
the
time
constraints
of
the
exercise.
On
a
fresh
and
up-to-date
Raspian
installation
we
added:
node.js,
npm
and
Node-RED
as
per:
http://nodered.org/docs/hardware/raspberrypi.html
Note: On your own system, to leverage the power of Node-RED, consider installing the node for GPIO access as well.
1)
Exercise:
Starting
Node-RED
as
Raspberry
Pi
user
Node-RED
can
be
installed
as
a
service
on
the
Raspberry
Pi,
i.e.
as
a
program
thats
always
executed
when
your
Pi
is
running.
However,
this
is
only
useful
if
you
want
to
commit
your
Pi
for
this
particular
use
as
it
can
consume
considerable
resources.
For
everyone
else,
its
recommended
to
start
Node-RED
only
when
needed:
1. Open
the
LXTerminal
to
see
a
console
that
allows
you
to
enter
Linux
commands.
2. Start
Node-RED
by
issuing
node-red.
You
should
now
see
Node-RED
starting
up
that
may
take
a
few
seconds:
Congratulations.
Youre
now
ready
for
the
exercises.
Node-RED
represents
a
server
on
the
basis
of
node.js
and
interacts
with
the
user
through
a
graphical
user
interface.
It
can
be
reached
on
port
1880.
To
use
Node-RED,
open
a
web
browser
and
direct
it
to
http://localhost:1880
Its
useful
to
remember
that
Node-RED
acts
as
a
server
in
your
entire
network.
That
is,
if
your
Raspberry
Pis
internal
IP
address
is
something
like
192.x.x.x,
every
computer
in
your
network
can
open
the
Node-RED
GUI
through
http://192.x.x.x:1880.
You
can
make
your
system
more
restricted/secure
by
following
the
configuration
advice
on
http://nodered.org/docs/security.html.
2)
Exercise:
Your
first
flow
this
is
a
recap
for
those
who
attended
the
last
course(s)
The
best
way
to
explain
a
flow
is
by
creating
one.
In
this
mini
flow,
were
going
to
inject
a
value
into
our
debug
window
(refer
to
page
1
for
what
the
GUI
elements
are
called).
1. Open the Epiphany Web Browser. (It supports JavaScript better than Midori).
2. In the address line, enter localhost:1880. You will then see the Node-RED GUI.
-2-
CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript
3. Drag
and
drop
an
inject
node
from
the
nodes
library
into
the
flow
editor
(once
youve
chosen
the
inject
node,
you
should
see
some
general
explanation
about
its
functionality
in
the
info
pane
no
need
to
read
that
now).
4. Drag
and
drop
a
debug
node
from
the
nodes
library
into
the
flow
editor.
5. Create
a
pipe
between
the
inject
and
debug
nodes
by
drawing
a
connection
between
their
small
grey
rounded
rectangles.
6. Change
from
the
info
pane
to
the
debug
pane
(upper
right).
7. Deploy
(=start)
your
flow.
8. Once
deployed,
press
the
left
blue
rectangle
thats
attached
to
the
inject
node.
Check
whats
happening
in
the
debug
pane.
(Yes,
thats
a
Unix
time
stamp).
3)
Exercise:
Finding
the
Minecraft
API
and
understanding
the
protocol
1. Open
another
LXTerminal
and
change
to
your
Minecraft
installation
by
issuing
cd
/opt/minecraft-pi.
2. In
the
API
directory
(cd
api),
get
a
list
of
available
files
and
directories
(ls).
Those
with
previous
programming
experience
may
recognise
the
python
sub-directory.
Inside
you
would
find
the
files
that
expose
the
Minecraft
functionality
of
the
mcpi
package
to
Python.
Its
important
to
note
that
the
Application
Programmers
Interface
(API)
be
it
for
a
locally
installed
application
like
Minecraft
or
a
web
server
that
listens
to
your
commands
over
the
Internet
is
just
a
convention
on
which
interface
(local
socket
or
IP
address,
port)
an
application
is
listening
to
other
programs
(like
yours),
which
commands
are
available
and
what
parameters
in
which
formats
are
expected.
The
mcpi
package
encapsulates
these
concepts
(connection,
commands)
in
easy-to-use
Python
commands.
Sometimes
the
underlying
specification
is
not
communicated
and
as
a
programmer
youre
stuck
with
the
functions
available
in
the
higher-level
library.
However,
the
Minecraft
API
is
rather
transparent
and
if
you
3. Change
into
the
spec
directory
(cd
spec),
you
are
going
to
find
mcpi_protocol_spec.txt
a
humble
text
file
with
the
information
that
you
require.
4. Open
the
file
in
an
editor
(nano
mcpi_protocol_spec.txt)
and
have
a
look
around.
Most
modern
web
services
(including
Twitter
or
the
BBC)
provide
APIs
for
programmatic
retrieval
of
information.
If
youre
interested
how
to
use
APIs
over
the
Internet
in
Node-RED,
Ive
put
up
a
guide
on
accessing
IoT
platforms
that
can
serve
as
an
entry
point:
http://www.slideshare.net/BorisAdryan/node-red-iotplatformtest
The
specification
states
that
the
Minecraft
binary
listens
to
incoming
messages
at
TCP
port
4711
and
expects
character
strings
that
are
terminated
with
a
\n
(Unix
linefeed).
A
following
schematic
of
the
Open
Systems
Interconnection
(OSI)
Model
helps
to
digest
this:
In
a
nutshell,
once
a
physical
connection
is
established
between
two
devices
(Level
1)
and
they
can
exchange
signals
(Levels
2+3),
Level
4
in
the
OSI
Model
takes
care
of
housekeeping
jobs:
Is
there
an
error
in
the
communication?
Can
we
recover
from
small
errors?
Do
-3-
CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript
information
packages
arrive
in
the
right
order?
While
some
protocols
like
UDP
optimise
for
high
throughput
(little
error
checking,
little
redundancy),
others
are
slower
but
more
secure
in
terms
of
data
integrity
(like
TCP).
http://programmerhelp404.blogspot.co.uk/2014/01/iso-osi-layer-model-tcpip-model.html
Its
important
to
understand
that
these
communication
routes
exist
on
the
Internet,
but
at
the
same
time
localhost
(IP:
127.0.0.1)
offers
the
same
functionalities
on
your
local
computer.
One
can
imagine
the
communication
via
the
Internet
Protocol
(IP,
Level
3)
like
a
motorway,
but
there
are
65536
(216)
different
lanes,
commonly
referred
to
as
port.
1. Double-click
your
input
node,
and
once
the
associated
dialog
opens,
change
the
Payload
to
type
string
and
write
Hello
World
in
the
empty
text
field
below.
-4-
CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript
2. Drag-and-drop
in
a
function
node.
This
is
the
node
type
that
allows
you
to
directly
interact
with
Node-RED
messages
(by
default
having
a
payload
and
a
topic)
in
JavaScript.
3. In
your
function
node,
write
msg.payload
=
"chat.post("+msg.payload+")\n";
before
return
msg;
This
line
is
going
to
take
the
incoming
msg.payload
(Hello
World),
and
assigns
new
content
chat.post(Hello
World)\n
to
the
variable.
chat.post
is
a
command
weve
learned
from
the
mcpi_protocol_spec.txt,
and
Minecraft
is
going
to
assert
it
as
such
when
its
followed
by
a
line
break
(Unix
definition:
\n).
4. Drag-and-drop
a
TCP
node
from
the
output
panel.
Set
it
up
with
the
following
parameters:
5. Connect
the
nodes
like
this:
6. Deploy.
Test
your
flow
by
triggering
the
inject
node.
Do
you
see
what
you
expected?
5)
Exercise:
Move
Steve
around
-
and
build
stuff
Youve
been
there
before,
but
probably
in
Python.
Now
try
it
with
raw
ASCII
strings.
1. Have
a
look
around
the
protocol
specification
and
look
for
the
command
that
sets
the
player
to
a
new
coordinate.
2. Set
a
wooden
block
directly
in
front
of
you.
(Hint:
blockTypeID
for
wood
is
17;
and
hard-code
the
coordinate
for
now).
-5-
CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript
6)
Exercise:
Retrieving
values
from
Minecraft
So
far
our
interaction
with
Minecraft
was
rather
one-directional.
We
just
sent
command
strings
that
had
an
effect
on
the
Minecraft
world.
Now
were
going
to
modify
our
flow
so
we
can
query
values
like
our
own
position
via
the
API.
The
overall
anatomy
of
our
flow
is
going
to
look
like
this:
1. Use
an
inject
node
(here
named
trigger)
to
start
the
flow.
Just
as
we
indicated
the
end
of
our
message
to
the
server
with
a
\n
character,
Minecraft
terminates
its
return
messages
with
the
same
character.
4. By
default
the
TCP
request
node
returns
a
buffer,
and
we
need
to
convert
the
information
from
Node-RED
using
msg.payload
=
msg.payload.toString();
in
a
function
node.
5. The
flow
concludes
with
a
debug
node.
If
youre
having
trouble
with
the
flow,
consider
sending
output
to
debug
panel
and
console.
6. Deploy.
Have
a
walk
around
Minecraft
and
trigger
your
flow.
Do
you
see
what
you
expected?
7)
Exercise:
Event-driven
programming
and
loops
By
now
you
may
have
realised
that
our
Node-RED
flows
were
linear
series
of
commands.
Once
triggered,
we
sent
a
command,
retrieved
information
and
displayed
it.
But,
for
example,
how
can
we
iterate
over
a
set
of
coordinates
and
execute
world.getBlock(x,y,z)
for
Steves
immediate
neighbourhood?
-6-
CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript
For
this,
were
going
to
extend
our
flow
a
little
bit.
First,
look
at
the
overall
anatomy
of
our
flow.
Its
a
bit
of
a
mouth
full:
First,
we
translate
Steves
position
into
a
series
of
(x/y/z)
coordinates,
more
specifically,
a
cube
that
this
directly
underneath
Steves
feet.
Then,
were
going
to
query
each
block
in
the
Minecraft
world
for
its
content.
Next,
we
tabulate
the
elements
weve
found
and
provide
a
summary
in
the
debug
panel.
The
tutorial
is
going
to
guide
you
through
the
necessary
changes
bit
by
bit.
1. Change
the
.toString()
function
node.
Ive
renamed
it
to
position
to
()
string
to
better
reflect
its
new
functionality:
-7-
CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript
Optional
reading:
The
.trim
function
removes
the
invisible
trailing
\n
from
the
players
position,
and
with
.split(,)
we
separate
out
the
x,
y
and
z
component
of
the
coordinate
into
an
array
called
pos.
Due
to
the
way
Minecraft
considers
player
positions
as
floating
point
numbers,
but
places
elements
in
discrete
blocks,
we
need
to
round
our
position
with
the
Math.round
function.
JavaScript
can
occasionally
act
a
bit
funny,
so
to
about
any
problems,
we
specifically
tell
it
to
interpret
the
character
strings
in
the
pos
array
as
floating
point
numbers
with
parseFloat.
Ultimately,
we
are
going
to
define
an
array
called
coordinates,
and
each
element
inside
coordinates
is
a
payload
with
a
string
in
parenthesis,
featuring
a
coordinate
of
the
cube
below
Steve.
Obligatory
reading:
By
returning
[coordinates]
at
the
end
of
the
function
(line
30,
note
the
[
]),
were
going
to
tell
Node-RED
to
trigger
the
next
node
for
reach
element
in
the
array.
2. Add
a
function
node
and
add
msg.payload
=
"world.getBlock"+msg.payload+"\n";
-
this
simply
makes
the
overall
code
more
readable.
It
complements
each
(x,y,z)
triplet
with
the
world.getBlock
command,
followed
by
\n;
3. Add
another
TCP
request
node
and
configure
it
exactly
like
the
one
before.
4. The
material
.toString()
function
node
adds
exactly
this
functionality:
msg.payload
=
msg.payload.toString();
add
a
debug
node
if
you
want
to
check
your
results.
A
table
with
common
elements
is
shown
in
the
figure,
from
http://minecraft.gamepedia.com/Data_values_(Pocket_Edition)
5. The
function
node
tabulation
counts
how
many
times
each
element
of
the
Minecraft
world
was
seen
in
the
5x5x5
=
125
blocks
underneath
Steves
feet.
Because
tabulation
is
invoked
every
time
a
new
element
is
detected,
we
need
to
make
use
of
a
Node-RED
trick:
The
context
variable
remembers
its
state
between
iterations.
-8-
CamJam! Workshop: Node-RED and controlling Minecraft with JavaScript
To
prevent
summing
up
of
elements
of
different
trigger
events,
we
modify
the
inject
node
with
a
topic
called
trigger.
If
the
tabulation
node
is
invoked
from
the
inject
button
(note
the
new
connection!),
we
delete
the
variable
by
assigning
it
the
value
undefined.
However,
if
we
invoke
the
function
from
the
material
.toString()
node,
we
make
sure
we
interpret
the
code
as
String.
If
our
table
is
still
undefined,
we
create
it
as
array,
otherwise
we
use
the
existing
one
(line
8).
If
the
ID
has
been
seen
before,
we
take
its
current
count,
otherwise
we
assign
0
(line
9).
Then
we
increase
the
count
for
this
observation
(this
event
only)
of
seeing
the
ID
(line
10).
Ultimately,
we
return
our
table
as
message.
6. To
prevent
the
printing
of
our
table
while
it
is
still
being
generated
(remember,
the
tabulation
method
gets
invoked
125
times!),
we
make
use
of
the
trigger
node.
Configure
it
with
the
following
settings:
The
node
remembers
the
first
time
it
was
triggered,
and
only
if
it
hasnt
received
any
new
messages
for
250
milliseconds,
passes
the
information
on
to
the
final
debug
node.
7. Deploy
and
take
Steve
for
a
walk.
Trigger
the
inject
node.
Wait
patiently.
Check
the
console
and/or
debug
panel
for
output.
Does
the
output
make
sense
to
you?
Conclusions
Node-RED
is
an
incredibly
powerful
framework
that
allows
you
to
do
things
in
very
little
time.
The
official
directory
of
flows
donated
to
the
community
is
here
http://flows.nodered.org
and
they
can
easily
be
imported
by
copying
&
pasting
the
JSON-formatted
code.
Given
the
availability
of
a
convenient
input
node,
try
to
display
tweets
with
a
particular
hashtag
in
Minecraft.
Youre
going
to
be
surprised
how
simple
it
is!
-9-