Example Python Telnet Program – React to Noise
Below is a script that uses the Oculus Telnet Interface, written in Python. This will log into the Oculus-Java server running on the robot, startup the microphone, and synth-voice complain whenever it hears a loud noise.
# onsound.py
import socket
import re
import time
host = "127.0.0.1"
username = "admin"
password = "KurwGDyd+oy+ZZ3S4qMn/wjeKOQ=" #encrypted password
port = 4444
#FUNCTIONS
def sendString(s):
oculusock.sendall(s+"\r\n")
print("> "+s)
def waitForReplySearch(p):
while True:
servermsg = (oculusfileIO.readline()).strip()
print(servermsg)
if re.search(p, servermsg):
break
return servermsg
#MAIN
#connect
oculusock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
oculusock.connect((host, port))
oculusfileIO = oculusock.makefile()
#login
waitForReplySearch("^<telnet> LOGIN")
sendString(username+":"+password)
sendString("publish mic")
time.sleep(2)
while True:
sendString("setstreamactivitythreshold 0 10")
waitForReplySearch("streamactivity: audio")
sendString("speech please be quiet")
time.sleep(5)
oculusfileIO.close()
oculusock.close()
Let’s walk through this program bit by bit to break down what it’s doing:
import socket
import re
import time
These import the Python modules we need: ‘socket’ to communicate via TCP/telnet protocol, ‘re’ for regular expression string parsing, and ‘time’ to measure time.
host = "127.0.0.1"
username = "admin"
password = "KurwGDyd+oy+ZZ3S4qMn/wjeKOQ=" #encrypted password
port = 4444
This declares variables we need to connect and login. In this case, ‘host’ is set to 127.0.0.1, for the program to be running on the robot’s laptop, but you could also run it remotely and change ‘host’ to the IP address of the robot. This script is using the encrypted version of the password, found next to ‘pass0’ in ‘Oculus/conf/oculus_settings.txt.’
def sendString(s):
oculusock.sendall(s+"\r\n")
print("> "+s)
This declares a function that sends text to the Oculus-Java server, followed by line-ending ‘\r\n
’ characters, so the server knows to process it as a single chunk of text.
def waitForReplySearch(p):
while True:
servermsg = (oculusfileIO.readline()).strip()
print(servermsg)
if re.search(p, servermsg):
break
return servermsg
This function reads a line of output from the robot and compares it to a regular expression. If it matches, it returns the whole line. If not, it keeps reading lines forever until it finds a match. The two above functions set the program up for 2-way ‘conversation’ with the server.
#connect
oculusock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
oculusock.connect((host, port))
oculusfileIO = oculusock.makefile()
This makes a TCP/socket connection with the server, and converts it into fileIO so it interprets single lines as individual chunks of text to be processed
#login
waitForReplySearch("^<telnet> LOGIN")
sendString(username+":"+password)
This waits for the server to output a login string, then sends login info.
sendString("publish mic")
time.sleep(2)
while True:
sendString("setstreamactivitythreshold 0 10")
waitForReplySearch("streamactivity: audio")
sendString("speech please be quiet")
time.sleep(5)
And finally, this is the ‘main loop’ of the program that takes command of the robot and reacts to events. First, it turns on the microphone and waits a couple of seconds for it to start up. Then it enters a ‘do forever’ loop where it first sends the ‘setstreamactivitythreshold
’ command with parameters 0, 10. This tells it to ignore video and react to audio levels higher than 10 (out of 100). Then it waits, possibly for a long time, for the robot to hear something, and output a line containing ‘streamactivity: audio’. At this, our program sends the ‘speech’ command to politely ask for silence, waits a few seconds for the synth-voice ouput to end, then the loop restarts and it goes back into listening mode.
(Note that the ‘setstreamactivitythreshold
’ command needs to be re-sent every time, at the beginning of the loop, since the listener is automatically turned off every time it is triggered.)
To make this script a bit more useful, instead of ‘synth-voice nagging’ you could, for example, post a new RSS news item using the ‘rssadd
’ command and have a service like IFTTT.com react to it and send a text message. Or, since IFTTT only checks at 15 minute intervals, you could use a more immediate method and send an alert via email using the ‘email
’ command, as in the next example