3
# This is an example Python module for controlling Fyre
4
# in remote control mode. Run it for a quick demonstration,
5
# or import it in your own scripts.
12
RESPONSE_PROGRESS = 251
15
RESPONSE_UNRECOGNIZED = 500
16
RESPONSE_BAD_VALUE = 501
17
RESPONSE_UNSUPPORTED = 502
20
class FyreException(Exception):
21
def __init__(self, code, message, command=None):
22
msg = "%d %s" % (code, message)
24
msg = "%s (in response to %r" % (msg, command)
25
Exception.__init__(self, msg)
29
"""This class represents a socket connection to
30
a remote Fyre server (fyre -r)
34
def __init__(self, host):
35
if host.find(":") >= 0:
36
host, port = host.split(":")
39
port = self.defaultPort
41
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
42
self.socket.connect((host, port))
43
self.file = self.socket.makefile()
46
# Read the server's greeting
47
code, message = self._readResponse()
48
if code != RESPONSE_READY:
49
raise FyreException(code, message)
52
"""Send all pending asynchronous commands. If any
53
of them returned an error, this raises an
54
exception indicating which command resulted
55
in which response code.
58
for command in self.asyncQueue:
59
code, message = self._readResponse()
60
if code < 200 or code >= 300:
61
raise FyreException(code, message, command)
64
def _readResponse(self):
65
"""Read the server's next response, returning
66
a (response_code, message) tuple.
68
line = self.file.readline().strip()
69
code, message = line.split(" ", 1)
70
return int(code), message
72
def command(self, *tokens):
73
"""Send a command in which the return value doesn't
74
matter except for detecting errors. This command
75
will be buffered, and any errors won't be detected
76
until the next flush().
78
cmd = " ".join(map(str, tokens))
79
self.file.write(cmd + "\n")
80
self.asyncQueue.append(cmd)
82
def query(self, *tokens):
83
"""Immediately send a command in which we care about
84
the response value. This forces a flush() first,
85
so errors from other commands may be first discovered
86
here. Returns a (response_code, message) tuple.
89
cmd = " ".join(map(str, tokens))
90
self.file.write(cmd + "\n")
92
return self._readResponse()
94
def setParams(self, **kwargs):
95
"""Set any number of parameters, given as keyword arguments.
96
Like command(), these will not take effect until the next
99
for item in kwargs.iteritems():
100
self.command("set_param", "%s=%s" % item)
103
if __name__ == "__main__":
105
# This connects to the Fyre server, sets up a bunch of image
106
# parameters, (copied straight out of a saved .png file) then
107
# varies some of the parameters to create a simple animation.
108
# This could be extended into a more complex animation, maybe
109
# even one based on sensors or a simulation.
113
if len(sys.argv) > 1:
118
fyre = FyreServer(host)
119
fyre.command("set_render_time", 0.02)
120
fyre.setParams(size = "400x300",
130
emphasize_transient = 1,
131
transient_iterations = 3,
132
initial_conditions = "circular_uniform",
133
initial_xscale = 0.824000,
134
initial_yscale = 0.018000)
135
fyre.command("set_gui_style", "simple")
139
fyre.setParams(initial_xoffset = t * 1.5,
140
initial_yoffset = math.sin(t) * 0.1)
141
fyre.command("calc_step")