Python Scripting to Viz Engine

Shotski2

New member
Has anyone used python scripting to connect to a Viz Engine to feed data? I saw an example but cant figure out how it works.
 
Shotski2 Hello, yes it is possible, I did it as a test, and I was able to change text for specific containers, I was parsing an xml file, extracting info from the xml and setting text or images depending on what the xml info was.

I hope this is of some help, good luck


Code:
def talkToViz():
    #This is a variable I used in another part of the code
    global currentSponsorImage

    ## Create a TCP/IP socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    # Connect the socket to the port where the server is listening
    
    # this is the artist machine, where I was testing
    server_address = ('192.168.5.25', 6100)
    
    # this is the ticker engine, this is to confirm I could talk to other engines
    #server_address = ('192.168.5.12', 6100)
    
    #print >>sys.stderr, 'connecting to %s port %s' % server_address
    sock.connect(server_address)
    
    #Commands I was sending to the different engines
    #sock.send('0 RENDERER*FUNCTION*DataPool*Data SET tickerSponsorImage=' + str(currentHouseNumber) + '\0')
    #sock.send('0 MAIN_SCENE*TREE*$tickerSponsor*IMAGE SET IMAGE*KFMB_VER01/MASTER_CONTROL/TICKER_SPONSORS/' + 'name of the image' + '\0')
    
    # Next line is used to send a command to the engine, preffix and suffix were
    # declared at the top, this are just variable with viz commands, see the above line that starts, #soc.send...
    sock.send( vizCommandPreffix + currentSponsorImage + vizCommandSuffix)
    test to make sure the engine is reading what I'm sending
    print vizCommandPreffix, ' ', currentSponsorImage, ' ', vizCommandSuffix
    sock.close()

main()
 
Shotski2 sorry I have not been able to respond, I was using python 2.X to run this, I am now running python 3.X and the script I send you doesn't work any longer, I have been trying to make it work but haven't been able to.

The script when it worked I ran out of Textwrangler on a mac, I would just feed it some text via a variable and run the script which would connect to the artist engine, which was on air mode, and i was able to change the text on a container, or I could parse an xml and get the info I needed and then i would send it to the engine

as per the scene, there was nothing special about it, the one thing you have to pay attention to is the hierarchy on your tree, which in the script would be the command you send to the engine for example
#sock.send('0 MAIN_SCENE*TREE*$tickerSponsor*IMAGE SET IMAGE*KFMB_VER01/MASTER_CONTROL/TICKER_SPONSORS/' + 'name of the image' + '\0') in this case I am changing the image on a container from ('0 MAIN_SCENE*TREE*$tickerSponsor*IMAGE SET this is part of the command this IMAGE*KFMB_VER01/MASTER_CONTROL/TICKER_SPONSORS/ is the path to the image in my gfx hub

name of the image, this is a variable

and '\0') terminates the command

With python 3.X and engine 3.8.1 I get the following error message

TypeError: a bytes-like object is required, not 'str'

but if I change the info I am sending to byte-object I get the following error

TypeError: must be str, not bytes

I don't know why it does not want to take either of the types I am sending

if you find out why this thing is not working please post it
 
I am trying to get the script to run through Notepad++ but it is not connecting to Viz. I don't get any errors but it is not connecting either. I'm at a loss.
In the script below, i am just trying to connect to Viz artist in on-air mode but i get nothing. Any Ideas?

def talkToViz():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('10.55.14.104', 50007)
sock.connect(server_address)
sock.send('Hello, world')
data = sock.recv(1024)
sock.close()
print ('Received', repr(data))
 
So apparently in python 3 the way the data is received is as a binary code. I guess that changed from python 2 to python 3 for whatever reason. So i put a "b" for binary in from of the string 'Hello World'. The script below gets close but i get error in Viz once it connects. " ERROR: cannot read command from socket, code 10054". Almost there, just need to figure out this part. Any Ideas?

import socket

HOST = '10.55.14.104' # The remote host
PORT = 6100 # The same port as used by the server
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.connect((HOST, PORT))
socket.send(b'Hello, world')
data = socket.recv(1024)
socket.close()
print ('Received'), repr(data)
 
I got it to work with this code:

import socket

HOST = '10.55.14.104' # The remote host
PORT = 6100 # The same port as used by the server

socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

socket.connect((HOST, PORT))

socket.send(b'0 MAIN_SCENE*TREE*$IMG*IMAGE SET IMAGE*DESIGNER_LIBRARY/Robert/berlin3')

socket.close()
#print ('Received'), repr(data)
print ('Received')
 
Hello All,

Still having some issues with this script. I can get the information to populate from the xml and i can see it in python but i cant get the syntax to fill the containers. I get a socket error.

here is the script below. If anyone is a python/viz expert.

#Weather update from URL with Pyton
# Import necessary libraries
from xml.dom import minidom
import socket
import sys
import datetime
import time
from datetime import datetime
#'import urllib2
import urllib.request

#Var declaration
dayCounter = 1
highTempCounter = 1
weekReport = ()
dayReport = ()
dayCommandPreffix = '0 MAIN_SCENE*TREE*$day0'
highTempCommandPreffix = '0 MAIN_SCENE*TREE*$high_temp0'
vizCommandPreffix2 = '*GEOM*TEXT SET '
vizCommandSuffix = '\0'


def main():
readFeed()
printDays()
printHighTemps()

def readFeed():
global weekReport
global dayReport


readXMLfromURL = urllib.request.urlopen("http://xml.customweather.com/xml?product=current_extended&latitude=27.964157&longitude=-82.452606&client=vizrt_test&client_password=t3mp")

wxMiguelXML = minidom.parse(readXMLfromURL)
weekReport = wxMiguelXML.getElementsByTagName("report")[0]
dayReport = weekReport.getElementsByTagName("forecast")


def printDays():
for i in dayReport:
myDays = i.attributes["weekday"]
dayNames = myDays.value
daytalkToViz(dayNames)
#print (dayCommandPreffix)
print (dayNames)

def printHighTemps():
for j in dayReport:
myHighs = j.attributes["high_temp"]
dayHighTemps = myHighs.value
highTemptalkToViz(dayHighTemps)
print (dayHighTemps)


def daytalkToViz(inputFromXML):
global dayCounter
dayCounter = dayCounter + 1


#---------------------------------------------------------------------------------------------------------------------
HOST = '10.55.14.104' # The remote host
PORT = 6100 # The same port as used by the server

socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

socket.connect((HOST, PORT))
#--------------------


def highTemptalkToViz(inputFromXML):
global highTempCounter
highTempCounter = highTempCounter + 1

#socket.send(b'0 print (highTempCommandPreffix) + str(highTempCounter) + vizCommandPreffix2 + inputFromXML + vizCommandSuffix')
socket.send(b'0 MAIN_SCENE*TREE*$high_temp01*FUNCTION*ControlText*input SET 43345' )


socket.close()

main()
 
Hello All,

I still can't get this to work. I can see the correct information coming from the python script but cant seem to get the right format to feed to Viz.

The information below is what the python script is putting out but i cant get the right syntax in the python script to feed to Viz. Any Ideas???

0 MAIN_SCENE*TREE*$day01*GEOM*TEXT SET Wednesday
0 MAIN_SCENE*TREE*$day02*GEOM*TEXT SET Thursday
0 MAIN_SCENE*TREE*$day03*GEOM*TEXT SET Friday
 
To me it looks like you are missing '\0' (command delimiter) at the end of the Viz command string in the socket.send -function... You have that defined as vizCommandSuffix but never used.
 
I have that line commented out because python would give me an error saying values are not defined when they are.

#socket.send(b'0 print (highTempCommandPreffix) + str(highTempCounter) + vizCommandPreffix2 + inputFromXML + vizCommandSuffix')

When i use the print command in python with the information above it shows this:
0 MAIN_SCENE*TREE*$day01*GEOM*TEXT SET Wednesday

which is perfect for what viz would need to read but when i use the socket.send command it does not work.
 
Shotski2

Hello, I had gotten to the point were I got errors regarding sending bytes instead of strings, but anyways here is a script that works

ON the artist machine I created a simple scene, a parent container and a child container with a font, the name of the child container is myText, put the artist machine on air, then just run the script

I hope this is of some help

Code:
#!/usr/bin/env python

# Import necessary libraries

import socket
import sys


# Variable delacration
vizCommandPreffix = '0 MAIN_SCENE*TREE*$myText*GEOM*TEXT SET '
vizCommandSuffix = '\0'

newValue = "Obregon"

# This will call each function in turn
def main():
    talkToViz()


def talkToViz():
    ## Create a TCP/IP socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    # Connect the socket to the port where the server is listening
    
    # this is my artist machine
    server_address = ('10.40.12.29', 6100)
    
    
    #connect to the engine in my case I am using the artist machine
    sock.connect(server_address)
    print("Connected")

    #The following two commands will work, pay close attention to the way they are written, one of them is commented while I tested the other one
     
    #sock.send(b'0 MAIN_SCENE*TREE*$myText*GEOM*TEXT SET TEGNA \0;')
    sock.send(vizCommandPreffix.encode() + newValue.encode() + vizCommandSuffix.encode())

    sock.close()

main()
 
Hi Matzunaga,

The script you sent works for a value that is defined as a string or equals a string. The problem i am having is that the values that are coming from the function need a certain format to be treated as a string instead of an integer/float. I am using the script you made that worked in python 2.0. I reworked it a bit to work with python 3. The only problem left is the values for the days and temperature to be converted to a string. I have tried every combination i can think of to convert the value to a string.

It always returns the error of "NameError: name 'inputFromXML' is not defined. I tried the encode function you suggested but it give another error. Is there a way to convert the values from the xml to a string?

Here is the script: The last socket send line at the bottom is where i am so far.

#Weather update from URL with Pyton
# Import necessary libraries
from xml.dom import minidom
import socket
import sys
import datetime
import time
from datetime import datetime
#'import urllib2
import urllib.request

#Var declaration
dayCounter = 0
highTempCounter = 0
weekReport = ()
dayReport = ()
dayCommandPreffix = '0 MAIN_SCENE*TREE*$day0'
#highTempCommandPreffix = '0 MAIN_SCENE*TREE*$high_temp0'
highTempCommandPreffix = '0 MAIN_SCENE*TREE*$'
Temp1 = "high_temp01"
Temp2 = "high_temp02"
vizCommandPreffix2 = '*GEOM*TEXT SET '
vizCommandSuffix = '\0'

def main():
readFeed()
printDays()
printHighTemps()

def readFeed():
global weekReport
global dayReport


readXMLfromURL = urllib.request.urlopen("http://xml.customweather.com/xml?product=current_extended&latitude=27.964157&longitude=-82.452606&client=vizrt_test&client_password=t3mp")

wxMiguelXML = minidom.parse(readXMLfromURL)
weekReport = wxMiguelXML.getElementsByTagName("report")[0]
dayReport = weekReport.getElementsByTagName("forecast")


def printDays():
for i in dayReport:
myDays = i.attributes["weekday"]
dayNames = myDays.value
daytalkToViz(dayNames)
#print (dayCommandPreffix)
#print (dayNames)
#print (f'MAIN_SCENE*TREE*$day01*FUNCTION*ControlText*input SET {dayNames}')

def printHighTemps():
for j in dayReport:
myHighs = j.attributes["high_temp"]
dayHighTemps = myHighs.value
highTemptalkToViz(dayHighTemps)
#print (dayHighTemps)
#print (f'MAIN_SCENE*TREE*$high_temp01*FUNCTION*ControlText*input SET {dayHighTemps}')


def daytalkToViz(inputFromXML):
global dayCounter
dayCounter = dayCounter + 1

#x = print (dayCommandPreffix + str(dayCounter) + vizCommandPreffix2 + inputFromXML + vizCommandSuffix)
x = dayCommandPreffix + str(dayCounter) + vizCommandPreffix2 + inputFromXML + vizCommandSuffix
print(x)
#---------------------------------------------------------------------------------------------------------------------
HOST = '10.55.14.104' # The remote host
PORT = 6100 # The same port as used by the server

socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

socket.connect((HOST, PORT))
#--------------------


def highTemptalkToViz(inputFromXML):
global highTempCounter
highTempCounter = highTempCounter + 1
#x = print (highTempCommandPreffix + str(highTempCounter) + vizCommandPreffix2 + inputFromXML + vizCommandSuffix)
y = highTempCommandPreffix + str(highTempCounter) + vizCommandPreffix2 + inputFromXML + vizCommandSuffix
print(y)

#socket.send(highTempCommandPreffix + str(highTempCounter) + vizCommandPreffix2 + inputFromXML + vizCommandSuffix)
##socket.send(b'0 MAIN_SCENE*TREE*$high_temp01*FUNCTION*ControlText*input SET 44' )
##socket.send(b'0 MAIN_SCENE*TREE*$day01*GEOM*TEXT SET Wednesday')
#socket.send(highTempCommandPreffix.encode() + bytes(highTempCounter) + vizCommandPreffix2.encode() + vizCommandSuffix.encode())
#socket.send(highTempCommandPreffix.encode() + Temp1.encode() + vizCommandPreffix2.encode() + Temp1.encode() + vizCommandSuffix.encode())
socket.send(highTempCommandPreffix.encode() + Temp2.encode() + vizCommandPreffix2.encode() + Temp2.encode() + str(highTemptalkToViz(inputFromXML)) + vizCommandSuffix.encode())

socket.close()

main()
 
Shotski2 , here is a script that works with the scene you uploaded, in the script change the ip so that it point to your artist machine/engine, remember that the engine needs to be on air mode, I hope this helps


Code:
#Weather update from URL with Pyton
# Import necessary libraries
from xml.dom import minidom
import socket
import sys
import datetime
import time
from datetime import datetime
#'import urllib2
import urllib.request

#Var declaration
dayCounter = 0
dayCounter2 = 0
weekReport = ()
dayReport = ()


#---------------------------------------------------------------------------------------------------------------------
HOST = '10.55.14.104' # The remote host
PORT = 6100 # The same port as used by the server
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.connect((HOST, PORT))
#--------------------

def main():
     readFeed()
     printDays()
     printHighTemps()
     print('DONE')
    
def readFeed():
    global weekReport, dayReport
    readXMLfromURL = urllib.request.urlopen("http://xml.customweather.com/xml?product=current_extended&latitude=27.964157&longitude=-82.452606&client=vizrt_test&client_password=t3mp") 
    wxMiguelXML = minidom.parse(readXMLfromURL)
    weekReport = wxMiguelXML.getElementsByTagName("report")[0]
    dayReport = weekReport.getElementsByTagName("forecast")    
    
def printDays():
    global dayCounter
    for i in dayReport: 
        juanCounter = 0
        dayNamesArray = []
        juanPreffix = '0 MAIN_SCENE*TREE*$day0' + str(dayCounter+1) + '*GEOM*TEXT SET '
        juanSuffix = '\0'
        myDays = i.attributes["weekday"]
        dayNames = myDays.value
        dayNamesArray.append(dayNames)    
        socket.send(juanPreffix.encode() + dayNamesArray[juanCounter].encode() +  juanSuffix.encode())
        juanCounter = juanCounter + 1
        dayCounter = dayCounter + 1

def printHighTemps():
    global dayCounter2
    for j in dayReport: 
        juanCounter2 = 0
        highTempsArray = []
        juanPreffix2 = '0 MAIN_SCENE*TREE*$high_temp0' + str(dayCounter2+1) + '*GEOM*TEXT SET '
        juanSuffix = '\0'
        myHighs = j.attributes["high_temp"]
        myHighTemps = myHighs.value
        highTempsArray.append(myHighTemps)        
        socket.send(juanPreffix2.encode() + highTempsArray[juanCounter2].encode() +  juanSuffix.encode())
        juanCounter2 = juanCounter2 + 1
        dayCounter2 = dayCounter2 + 1
    
    socket.close()

main()
 
Hi matzunaga
Do you happen to know why I can't get a response from VIZRT over UDP? I'm using this script.

Python:
import socket
import time

msgFromClient = "0 VERSION   \0"
bytesToSend = str.encode(msgFromClient)
serverAddressPort = ("192.168.0.185", 6100)

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(bytesToSend, serverAddressPort)
data, address = sock.recvfrom(1024)

print(f"Received data: {data.decode()} from {address}")

VIZ terminal returns the following response to it:
error: could not send answer <0 Version 4.3.60028>


Similar functionality works without any issues over TCP. What could be the problem with the UDP connection?"
 
Back
Top