Files
pylibibuddy/server.py
2016-08-20 11:56:23 +01:00

241 lines
6.9 KiB
Python

#!/usr/bin/python
import logging
import sys
import socket
import pwd
import os
import time
from ConfigParser import RawConfigParser
from plibbuddy import BuddyDevice
#########################################
# Decoding macros
##########################################
def macro_color (red, green, blue):
message = 'C:%d:%d:%d' % (red, green, blue)
message += "\nX\nS\nZ\nZ\n"
return message
def macro_heart ():
message = 'H:1'
message += "\nX\nS\nZ\nZ\n"
return message
def macro_move_flap():
message = "ML\nX\nS\nS\n"
message += "MR\nX\nS\nS\n"
message += "ML\nX\nS\nS\n"
return message + macro_flap()
def macro_flap (heart=0):
message = ''
for i in range(2):
message += "L\n"
message += "WU\n"
if heart:
message += "H:1\n"
message += "X\nS\nL\n"
message += "WD\nX\nS\n"
return message
def macro_heart2():
message = "H:1\nX\nS\n"
message += "Z\nS\n"
message += "H:1\nX\nS\n"
message += "Z\nS\n\nZ\nZ\n"
return message
def macro_demo(num = 1):
message = ''
for i in range(num):
message += "C:1:0:0\nH:0\nML\nWD\nX\nS\nS\n"
message += "C:0:1:0\nH:1\nMR\nWU\nX\nS\nS\n"
message += "C:0:0:1\nH:0\nML\nWD\nX\nS\nS\n"
message += "C:1:0:1\nH:1\nMR\nWU\nX\nS\nS\n"
message += "C:1:1:0\nH:0\nML\nWD\nX\nS\nS\n"
message += "C:0:1:1\nH:1\nMR\nWU\nX\nS\nS\n"
message += "C:1:1:1\nH:0\nML\nWD\nX\nS\nS\n"
message += "Z\nZ\n"
return message
def do_color(buddy, red, green, blue):
r, g, b = buddy.getColors()
try:
param1 = int(red)
param2 = int(green)
param3 = int(blue)
except:
param1 = -1
param2 = -1
param3 = -1
if (param1 == -1):
param1 = r
if (param2 == -1):
param2 = g
if (param3 == -1):
param3 = b
buddy.setHeadColors(param1, param2, param3)
buddy.doCmd(0.5)
def decode_buddy(buddy, msg):
orders = msg.split("\n")
for str in (orders):
cod = str.split(':')
param = 0
if cod[0] == 'RED' or cod[0] == 'R':
try: do_color(buddy, cod[1], -1, -1)
except: pass
elif cod[0] == 'GREEN' or cod[0] == 'G':
try: do_color(buddy,-1, cod[1], -1)
except: pass
elif cod[0] == 'BLUE' or cod[0] == 'B':
try: do_color(buddy, -1, -1, cod[1])
except: pass
elif cod[0] == 'YELLOW':
try: do_color(buddy, cod[1], cod[1], -1)
except: pass
continue
elif cod[0] == 'SAPHIRE':
try: do_color(buddy, -1, cod[1], cod[1])
except: pass
elif cod[0] == 'VIOLET':
try: do_color(buddy, cod[1], -1, cod[1])
except: pass
elif cod[0] == 'HEART' or cod[0] == 'H':
try:
param = int(cod[1])
except:
param = 0
buddy.setHeart(param)
elif cod[0] == 'C':
try: do_color(buddy, cod[1], cod[2], cod[3])
except: pass
elif cod[0] == 'MR':
buddy.flick(buddy.RIGHT)
continue
elif cod[0] == 'ML':
buddy.flick(buddy.LEFT)
elif cod[0] == 'SLEEP' or cod[0] == 'S':
time.sleep(0.1)
elif cod[0] == 'WU':
buddy.wing(buddy.UP)
elif cod[0] == 'WD':
buddy.wing(buddy.DOWN)
elif cod[0] == 'EXEC' or cod[0] == 'X':
buddy.pumpMessage()
elif cod[0] == 'CLEAR' or cod[0] == 'L':
buddy.resetMessage()
elif cod[0] == 'RESET' or cod[0] == 'Z':
buddy.resetMessage()
buddy.pumpMessage()
elif cod[0] == 'MACRO_FLAP':
decode_buddy(buddy, macro_move_flap())
elif cod[0] == 'MACRO_FLAP2':
decode_buddy(buddy, macro_flap())
elif cod[0] == 'MACRO_RED':
decode_buddy(buddy, macro_color(1, 0, 0))
elif cod[0] == 'MACRO_GREEN':
decode_buddy(buddy, macro_color(0, 1, 0))
elif cod[0] == 'MACRO_BLUE':
decode_buddy(buddy, macro_color(0,0,1))
elif cod[0] == 'MACRO_YELLOW':
decode_buddy(buddy, macro_color(1,1,0))
elif cod[0] == 'MACRO_VIOLET':
decode_buddy(buddy, macro_color(1,0,1))
elif cod[0] == 'MACRO_SAPHIRE':
decode_buddy(buddy, macro_color(0,1,1))
elif cod[0] == 'MACRO_LBLUE':
decode_buddy(buddy, macro_color(1,1,1))
elif cod[0] == 'MACRO_HEART':
decode_buddy(buddy, macro_heart())
elif cod[0] == 'MACRO_HEART2':
decode_buddy(buddy, macro_heart2())
elif cod[0] == 'DEMO':
decode_buddy(buddy, macro_demo())
#######################################
# MAIN program
#######################################
# Default config
config = RawConfigParser(
{ 'port': 8888,
'address': '0.0.0.0',
'deamon': False,
'user': 'nobody',
'loglevel': 'info',
'logfile': 'console',
'usbproduct': 0001,
}
)
config._sections = {'network':{}, 'system':{}}
config_files = [ 'pybuddy.cfg',
'~/.pybuddy.cfg',
'/etc/pybuddy/pybuddy.cfg',
'/usr/local/etc/pybuddy.cfg']
# Parse config
if len(sys.argv) > 1:
config_files.append(sys.argv[1])
config_read = config.read(config_files)
if config.get('system', 'logfile') != 'console':
logging.basicConfig(
filename = config.get('system', 'logfile'),
format = '%(asctime)s %(levelname)-8s %(message)s',
)
else:
logging.basicConfig(
stream = sys.stderr,
format = '%(asctime)s %(levelname)-8s %(message)s'
)
log = logging.getLogger('pybuddy')
if config.get('system', 'loglevel') == 'debug':
log.setLevel(logging.DEBUG)
elif config.get('system', 'loglevel') == 'info':
log.setLevel(logging.INFO)
if config_read:
log.info('Read config file: %s', config_read[0])
# Initialize device
log.info('Starting search...')
try:
buddy = BuddyDevice(0, int(config.get("system", "usbproduct")))
except NoBuddyException, e:
log.error('Not found!')
sys.exit(1)
if config.get('system', 'daemon') == True:
# Daemonize
log.info('Starting daemon...')
if os.fork() == 0:
os.setsid()
else:
sys.exit(0)
# Create server socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((config.get('network', 'address'), int(config.get('network', 'port'))))
# Drop privileges
try:
uid = pwd.getpwnam(config.get('system', 'user'))[2]
except KeyError:
log.error('Username %s not found, exiting...', config.get('system', 'user'))
sys.exit(1)
os.setuid(uid)
# Main message loop
while 1:
try:
message, address = s.recvfrom(8192)
log.debug('Got data from %s', address)
decode_buddy(buddy, message)
except (KeyboardInterrupt, SystemExit):
raise