Everloop
Python Example
Device Compatibility
Overview
The Everloop driver allows for:
- Reading amount of LEDs your MATRIX device has.
- Setting the RGBW colors for each individual LED.
Available ZeroMQ Ports
Base port
: 20021Keep-alive port
: 20022Error port
: 20023Data update port
: 20024
Code Example
The following sections show how to implement a connection to each of the Everloop driver's ports. You can download this example here.
Initial Variables
Before we go into connecting to each port, the variables defined below are needed in order to access the ZeroMQ and MATRIX Protocol Buffer libraries for Python. We also define a few helpful variables for easy references.
import os # Miscellaneous operating system interface import zmq # Asynchronous messaging framework import time # Time access and conversions from random import randint # Random numbers import sys # System-specific parameters and functions from matrix_io.proto.malos.v1 import driver_pb2 # MATRIX Protocol Buffer driver library from matrix_io.proto.malos.v1 import io_pb2 # MATRIX Protocol Buffer sensor library from multiprocessing import Process, Manager, Value # Allow for multiple processes at once from zmq.eventloop import ioloop, zmqstream# Asynchronous events through ZMQ matrix_ip = '127.0.0.1' # Local device ip everloop_port = 20021 # Driver Base port led_count = 0 # Amount of LEDs on MATRIX device # Handy function for connecting to the Error port from utils import register_error_callback
Base Port
Here is where the configuration for our Everloop example goes. Once we connect to the Base Port, we will pass a configuration to the Everloop driver. With this we can set the LED configuration. The while True
loop is used to show how you can rapidly push different LED colors.
def config_socket(ledCount): # Define zmq socket context = zmq.Context() # Create a Pusher socket socket = context.socket(zmq.PUSH) # Connect Pusher to configuration socket socket.connect('tcp://{0}:{1}'.format(matrix_ip, everloop_port)) # Loop forever while True: # Create a new driver config driver_config_proto = driver_pb2.DriverConfig() # Create an empty Everloop image image = [] # For each device LED for led in range(ledCount): # Set individual LED value ledValue = io_pb2.LedValue() ledValue.blue = randint(0, 50) ledValue.red = randint(0, 200) ledValue.green = randint(0, 255) ledValue.white = 0 image.append(ledValue) # Store the Everloop image in driver configuration driver_config_proto.image.led.extend(image) # Send driver configuration through ZMQ socket socket.send(driver_config_proto.SerializeToString()) # Wait before restarting loop time.sleep(0.05)
Keep-alive Port
The next step is to connect and send a message to the Keep-alive Port. That message will grant us a response from the Data Update Port for the current LED count of your MATRIX device. The code below will give only send one ping because LED count will not change.
def ping_socket(): # Define zmq socket context = zmq.Context() # Create a Pusher socket ping_socket = context.socket(zmq.PUSH) # Connect to the socket ping_socket.connect('tcp://{0}:{1}'.format(matrix_ip, everloop_port+1)) # Send one ping ping_socket.send_string('')
Error Port
The Error Port connection is taken care of by the utils import
. Below we define a function to be called and given any error messages that occur within MATRIX CORE.
def everloop_error_callback(error): # Log error print('{0}'.format(error))
Data Update Port
A connection to the Data Update Port will allow us to receive the current LED count on your MATRIX device. Once we connect to the port, the updateLedCount
function will pass the LED count to a global variable and then close the connection the Data-update Port.
def update_socket(): # Define zmq socket context = zmq.Context() # Create a Subscriber socket socket = context.socket(zmq.SUB) # Connect to the Data Update port socket.connect('tcp://{0}:{1}'.format(matrix_ip, everloop_port+3)) # Connect Subscriber to Error port socket.setsockopt(zmq.SUBSCRIBE, b'') # Create the stream to listen to data from port stream = zmqstream.ZMQStream(socket) # Function to update LED count and close connection to the Data Update Port def updateLedCount(data): # Extract data and pass into led_count global variable global led_count led_count = io_pb2.LedValue().FromString(data[0]).green # Log LEDs print('{0} LEDs counted'.format(led_count)) # If LED count obtained if led_count > 0: # Close Data Update Port connection ioloop.IOLoop.instance().stop() print('LED count obtained. Disconnecting from data publisher {0}'.format(everloop_port+3)) # Call updateLedCount() once data is received stream.on_recv(updateLedCount) # Log and begin event loop for ZMQ connection to Data Update Port print('Connected to data publisher with port {0}'.format(everloop_port+3)) ioloop.IOLoop.instance().start()
Data Output
The Python object below is an example output you'll receive from the Data Update Port.The output name will be changed in a following update
green: 18
Start Processes
This is where we begin the asynchronous events for each of the driver ports and where we define the functions we want to use for each port. This example is only using the Error Port connection asynchronously because the Keep-alive Port and Data-update Port are only used once.
if __name__ == '__main__': # Initiate asynchronous events ioloop.install() # Start Error Port connection Process(target=register_error_callback, args=(everloop_error_callback, matrix_ip, everloop_port)).start() # Ping the Keep-alive Port once ping_socket() # Start Data Update Port connection & close after response update_socket() # Send Base Port configuration try: config_socket(led_count) # Avoid logging Everloop errors on user quiting except KeyboardInterrupt: print(' quit')