Last time, I outlined a plan for creating a remote access layer for THINC API. As I mentioned, the release of Okuma’s Remote API makes such a layer unnecessary. This is strictly for educational purposes.
A basic THINC simulator
Since I’m not developing at the control, it would be convenient to have a THINC API simulator that will run on my development machine. To my knowledge, Okuma does not provide such a thing. There’s a company that was working on one, but I haven’t seen any updates recently.
I don’t need the simulator to do anything special: it just needs to provide an interface identical to the real THINC API, so that I can at least run my application on my development machine. Since I don’t need any real THINC functionality, it’s fairly simple to create such a thing. For example, my CVariable class looks something like:
For now, I’ve coded a CMachine and a CVariables class by hand, along with all of the structures and enumerations needed for these two classes. If and when I get around to the full THINC API, though, I’ll create a utility that uses .NET Reflection to generate stubs for all of these classes and methods for me.
With my very limited THINC API simulator working, I can move into the core functionality of the project. I will need an engine that will instantiate all of my THINC API objects, and provide a mapping to all of the functions I want to access remotely.
I’ve implemented this as an Engine class. The engine stores a dictionary mapping between a string, and the object and method represented by that string. The Engine itself knows nothing about THINC API, but I’ve created a subclass named LatheEngine which handles all THINC implementation.
(This is the same as the interface pattern explained at the THINCster blog. The only difference is that I’m inheriting a base class with some existing implementation, rather than implementing an interface.)
LatheEngine creates an instance of CMachine and CVariables for each subsystem. It then goes through all of the methods in each class, registering them in the engine, in a format such as:
A partial list of the registered strings is visible in the next screenshot.
Once all of the appropriate mappings have been registered in the engine, I can pass the string “Machine/NC_RUN/GetExecutionMode” to a function on the Engine class (which LatheEngine has inherited). The Engine instance will look up the appropriate object and method based on this string, invoke it, and return the result to me.
So does it work? Have a look:
In the screenshot above, you can see that I first called Machine/NC_RUN/GetExecutionMode, which maps to CMachine.GetExecutionMode for the NC_RUN subsystem. The blank “Param name:” line is because my test routine prompts for parameters, ending when a blank parameter is entered.
Next I called CVariables.SetCommonVariableValue to set common variable 3 to the value 3.1416. I then called CVariables.GetCommonVariableValue to get the value of common variable 3. As the screenshot shows, the value of CV3 is now 3.1416.
The last request is a nonsense path, to demonstrate that an invalid path will result in an error.
By now I have an engine that will work for a limited subset of the THINC API, supporting CMachine and CVariables for lathe devices. (Actually, all I’ve shown is that it works with the dummy THINC API that I created so that I could run on my own development machine.)
Next I’ll need to support remote access. This means that I’ll need to implement an HTTP server that processes incoming requests and maps them to a path and parameters that I can feed into my Engine class.
Once that’s working, I should be able to access THINC API through a URL such as http://control-ip/Variables/NC_RUN/GetCommonVariableValue?intIndex=3. More details (and hopefully a working implementation) next time.