diff --git a/PixelHub-Server/PixelHub/PixelBot.cs b/PixelHub-Server/PixelHub/PixelBot.cs
new file mode 100644
index 0000000..f3b6dd6
--- /dev/null
+++ b/PixelHub-Server/PixelHub/PixelBot.cs
@@ -0,0 +1,61 @@
+﻿using System;
+using System.Net.Sockets;
+using System.Threading.Tasks;
+using System.IO;
+
+namespace PixelHub.Server
+{
+	/// <summary>
+	/// Provides an interface through which you can communicate with and control a Hull PixelBot.
+	/// </summary>
+	public class PixelBot
+	{
+		public bool Connected { get; private set; } = false;
+		TcpClient client;
+
+		StreamReader incoming;
+		StreamWriter outgoing;
+
+		/// <summary>
+		/// Initializes a new <see cref="PixelHub.Server.PixelBot"/> instance and connects it to a Hull Pixelbot.
+		/// </summary>
+		/// <param name="inClient">The Tcp connection between the PixelHub server and the Hull PixelBot.</param>
+		public PixelBot(TcpClient inClient)
+		{
+			client = inClient;
+		}
+
+		/// <summary>
+		/// Starts listening for and handling messages that come from the remote PixelBot.
+		/// </summary>
+		/// <param name="client">Client.</param>
+		public async Task Handle(TcpClient client)
+		{
+			if (Connected)
+				throw new InvalidOperationException("Only one connection handling loop can be active at once!");
+
+			Connected = true;
+
+			incoming = new StreamReader(client.GetStream());
+			outgoing = new StreamWriter(client.GetStream()) { AutoFlush = true };
+
+			string nextLine;
+			while((nextLine = await incoming.ReadLineAsync()) != null)
+			{
+				Console.WriteLine("Got message from client: '{0}'", nextLine.Trim());
+			}
+
+			Connected = false;
+		}
+
+		/// <summary>
+		/// Sends the given command to the remote PixelBot.
+		/// </summary>
+		/// <param name="command">The command to send.</param>
+		public async Task Send(PixelCommand command)
+		{
+			await outgoing.WriteLineAsync(command.AsCompiledCommand());
+		}
+	}
+}
+
diff --git a/PixelHub-Server/PixelHub/PixelCommand.cs b/PixelHub-Server/PixelHub/PixelCommand.cs
new file mode 100644
index 0000000..130f640
--- /dev/null
+++ b/PixelHub-Server/PixelHub/PixelCommand.cs
@@ -0,0 +1,75 @@
+﻿using System;
+
+namespace PixelHub
+{
+	public enum PixelWheel
+	{
+		None,
+		Left,
+		Right,
+		Both
+	}
+
+	/// <summary>
+	/// Specifies a single command that is to be sent to a PixelBot.
+	/// </summary>
+	class PixelCommand
+	{
+		/// <summary>
+		/// The wheel(s) that should be operated upon.
+		/// </summary>
+		public PixelWheel Wheel { get; set; }
+
+		/// <summary>
+		/// The duration, in milliseconds, that the left wheel should turn for.
+		/// </summary>
+		public int DurationLeft { get; set; }
+		/// <summary>
+		/// The duration, in milliseconds, that the right wheel should turn for.
+		/// </summary>
+		/// <value>The duration right.</value>
+		public int DurationRight { get; set; }
+
+		/// <summary>
+		/// The duration, in milliseconds, that the wheels should turn for.
+		/// </summary>
+		/// <description>
+		/// This property sets both the <see cref="DurationLeft" /> and <see cref="DurationRight" /> properties.
+		/// The getter returns the maximum of the two durations.
+		/// </description>
+		public int Duration {
+			get {
+				return Math.Max(DurationLeft, DurationRight);
+			}
+			set {
+				DurationLeft = value;
+				DurationRight = value;
+			}
+		}
+
+		/// <summary>
+		/// Creates a new <see cref="PixelCommand" /> instance.
+		/// </summary>
+		/// <param name="inWheel">The wheel to turn.</param>
+		/// <param name="inDuration">The duration , in milliseconds, to turn the wheels for.</param>
+		public PixelCommand(PixelWheel inWheel, int inDuration)
+		{
+			Wheel = inWheel;
+			Duration = inDuration;
+		}
+
+		/// <summary>
+		/// Compiles the PixelCommand into a raw command string that cna be understood by the PixelBot.
+		/// </summary>
+		/// <returns>The compiled command, ready to be sent over the wire to the PixelBot.</returns>
+		public string AsCompiledCommand()
+		{
+			return $"Move:L={DurationLeft},Right={DurationRight}";
+		}
+
+		public override string ToString()
+		{
+			return string.Format("PixelCommand: Targets Wheel={0} for Duration={1}ms", Wheel, Duration);
+		}
+	}
+}
\ No newline at end of file
diff --git a/PixelHub-Server/PixelHub/PixelHub.cs b/PixelHub-Server/PixelHub/PixelHub.cs
index 88b0993..851a7fd 100644
--- a/PixelHub-Server/PixelHub/PixelHub.cs
+++ b/PixelHub-Server/PixelHub/PixelHub.cs
@@ -6,7 +6,7 @@ using SBRL.Utilities;
 using System.IO;
 using System.Collections.Generic;
 
-namespace PixelHub
+namespace PixelHub.Server
 {
 	/// <summary>
 	/// Provides the server component of the Hull Pixelbot server that can be used to control any number of pixel bots at once.
@@ -18,12 +18,23 @@ namespace PixelHub
 		int port;
 
 		TcpListener server;
-		List<TcpClient> clients = new List<TcpClient>();
+
+		/// <summary>
+		/// A list of PixelBots that are currently connected to the PixelHub.
+		/// </summary>
+		public List<PixelBot> ConnectedBots = new List<PixelBot>();
 
 		/// <summary>
 		/// Whether the Hull Pixelbot serve is currently active and listening.
 		/// </summary>
 		public bool Active { get; private set; } = false;
+		/// <summary>
+		/// The IPAddress that the PixelHub is (or should be) bound to.
+		/// </summary>
+		/// <remarks>
+		/// You can only set this Property with generating an exception if the server
+		/// hasn't already been started with List().
+		/// </remarks>
 		public IPAddress BindAddress
 		{
 			get {
@@ -35,6 +46,7 @@ namespace PixelHub
 				bindAddress = value;
 			}
 		}
+
 		public int Port
 		{
 			get {
@@ -80,21 +92,14 @@ namespace PixelHub
 		{
 			logger.WriteLine("Accepted connection from {0}.", client.Client.RemoteEndPoint);
 
-			clients.Add(client);
+			PixelBot pixelBot = new PixelBot(client);
+			ConnectedBots.Add(pixelBot);
 
-			using (StreamReader incoming = new StreamReader(client.GetStream()))
-			using (StreamWriter outgoing = new StreamWriter(client.GetStream()) { AutoFlush = true })
-			{
-				string nextLine;
-				while((nextLine = await incoming.ReadLineAsync()) != null)
-				{
-					Console.WriteLine("Got message from client: '{0}'", nextLine.Trim());
-				}
-			}
+			await pixelBot.Handle();
 
-			clients.Remove(client);
+			ConnectedBots.Remove(pixelBot);
 
-			Console.WriteLine("Lost connection from {0}.", client.Client.RemoteEndPoint);
+			logger.WriteLine("Lost connection from {0}.", client.Client.RemoteEndPoint);
 		}
 	}
 }
diff --git a/PixelHub-Server/PixelHub/PixelHub.csproj b/PixelHub-Server/PixelHub/PixelHub.csproj
index 8faa0fb..a152533 100644
--- a/PixelHub-Server/PixelHub/PixelHub.csproj
+++ b/PixelHub-Server/PixelHub/PixelHub.csproj
@@ -5,7 +5,7 @@
     <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
     <ProjectGuid>{B051D556-1D7A-48B0-8D4D-ABD2FBEBB6EF}</ProjectGuid>
     <OutputType>Exe</OutputType>
-    <RootNamespace>PixelServer</RootNamespace>
+    <RootNamespace>PixelHub.Server</RootNamespace>
     <AssemblyName>PixelServer</AssemblyName>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
   </PropertyGroup>
@@ -40,6 +40,8 @@
     <Compile Include="SBRL.Utilities\ForgetTask.cs" />
     <Compile Include="SBRL.Utilities\Utilities.cs" />
     <Compile Include="SBRL.Utilities\PrefixedWriter.cs" />
+    <Compile Include="PixelCommand.cs" />
+    <Compile Include="PixelBot.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup>
diff --git a/PixelHub-Server/PixelHub/Program.cs b/PixelHub-Server/PixelHub/Program.cs
index cf42520..e43006f 100644
--- a/PixelHub-Server/PixelHub/Program.cs
+++ b/PixelHub-Server/PixelHub/Program.cs
@@ -6,9 +6,9 @@ using System.Threading.Tasks;
 using SBRL.Utilities;
 using PixelHub.Net;
 
-namespace PixelHub
+namespace PixelHub.Server
 {
-	static class Program
+	static class ServerProgram
 	{
 		private static int port = 5050;
 		private static PrefixedWriter systemWriter = new PrefixedWriter(Console.Out) { Prefix = "[System] " };
