nes-proj/examples/jn516x/tsch/simple-sensor-network/script/Output-Visualisation.py
2015-12-17 13:29:42 +01:00

149 lines
5.9 KiB
Python

#
# Copyright (c) 2015 NXP B.V.
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of NXP B.V. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY NXP B.V. AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL NXP B.V. OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# This file is part of the Contiki operating system.
#
# Author: Theo van Daele <theo.van.daele@nxp.com>
#
#
import sys
import time
import socket
import thread
import numpy as np
import Gnuplot
# Plot buffer length for each node buffer
SIZE_NODE_DATA = 600
# Repeat time for connect watchdog and ping
TICK = 5
# Connect watchdog. Unit: [TICK]
CONNECT_WATCHDOG = 30/TICK
TX_PORT = 8185
RX_PORT = 8186
last_sample_value = 0
x_range = np.arange(SIZE_NODE_DATA)
dummy_data = np.zeros(SIZE_NODE_DATA, dtype=np.int)
plot = Gnuplot.Data(x_range,dummy_data)
g = Gnuplot.Gnuplot()
# Attention: Skip leading zero's in IPv6 address list, otherwise address comparison with received UDP packet address goes wrong
NODE_ALIAS = 0 # node name in plot
NODE_DATA = 1 # Time line with data to plot
NODE_CONNECTED = 2 # If 0, not connected, else connect_watchdog value
NODE_LAST_DATA = 3 # Storage for received sample
NODE_PLOT = 4 # Plot instance
node_data = {"bbbb::215:8d00:36:180" : ["NODE-001", np.zeros(SIZE_NODE_DATA, dtype=np.int), 0, last_sample_value, plot],
"bbbb::215:8d00:36:892" : ["NODE-196", np.zeros(SIZE_NODE_DATA, dtype=np.int), 0, last_sample_value, plot],
"bbbb::215:8d00:36:8b1" : ["NODE-193", np.zeros(SIZE_NODE_DATA, dtype=np.int), 0, last_sample_value, plot],
"bbbb::215:8d00:36:8b3" : ["NODE-198", np.zeros(SIZE_NODE_DATA, dtype=np.int), 0, last_sample_value, plot]}
# List of all nodes derived from node_data list
node_list = node_data.keys()
def initPlots():
for node in range(len(node_list)):
node_data_key = node_data[node_list[node]]
g.title('Sensor Network Output')
g.ylabel('Value')
g.xlabel('Time-Span[s]')
g("set yrange [-150:150]")
g("set xrange [0:"+str(SIZE_NODE_DATA)+"]")
node_data_key[NODE_PLOT] = Gnuplot.Data(x_range,node_data_key[NODE_DATA], title=node_data_key[NODE_ALIAS] , with_='lines lw 2')
nodes = [ node_data[node_list[i]][NODE_PLOT] for i in xrange(len(node_list)) ]
g.plot(*nodes)
def udpReceive():
"""RUNS ON SEPARATE THREAD """
while True:
data, addr = s_rx.recvfrom(128)
data = data.replace("\"","").strip("\0") # strip termination byte and possible
node_data_key = node_data[addr[0]]
# Indicate node is connected
node_data_key[NODE_CONNECTED] = CONNECT_WATCHDOG
print addr[0] + ' (' + node_data_key[NODE_ALIAS] + ') : ' + data
# Write new data at index in data buffer. Data buffer is view of plot
data_lock.acquire()
node_data_key[NODE_LAST_DATA] = int(data)
data_lock.release()
def plotGraphs():
while True:
data_lock.acquire()
for node in range(len(node_list)):
node_data_key = node_data[node_list[node]]
for k in range(1,SIZE_NODE_DATA,1):
node_data_key[NODE_DATA][k-1] = node_data_key[NODE_DATA][k]
node_data_key[NODE_DATA][SIZE_NODE_DATA-1] = node_data_key[NODE_LAST_DATA]
if node_data_key[NODE_CONNECTED] == 0:
node_data_key[NODE_PLOT] = Gnuplot.Data(x_range,node_data_key[NODE_DATA], title=node_data_key[NODE_ALIAS], with_='dots')
else:
node_data_key[NODE_PLOT] = Gnuplot.Data(x_range,node_data_key[NODE_DATA], title=node_data_key[NODE_ALIAS], with_='lines lw 2')
nodes = [ node_data[node_list[i]][NODE_PLOT] for i in xrange(len(node_list)) ]
g.plot(*nodes)
data_lock.release()
time.sleep(1)
##### MAIN #####
s_tx = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
s_rx = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
s_rx.bind(('', RX_PORT))
initPlots()
data_lock = thread.allocate_lock()
thread.start_new_thread(udpReceive, ())
thread.start_new_thread(plotGraphs, ())
ping_node_index = 0
ping_msg = "ping"
while True:
# Every 5 secs, one node of the list in pinged
if (ping_node_index >=len(node_list)):
ping_node_index = 0;
try:
print "ping " + node_data[node_list[ping_node_index]][NODE_ALIAS]
s_tx.sendto(ping_msg, (node_list[ping_node_index], TX_PORT))
except:
print 'Failed to send to ' + node_list[ping_node_index]
ping_node_index += 1
# Update connect watchdog
for node in range(len(node_list)):
node_data_key = node_data[node_list[node]]
if (node_data_key[NODE_CONNECTED] > 0):
node_data_key[NODE_CONNECTED] -= 1
time.sleep(TICK)