We are starting a brand new project this week to develop an ASCOM Dome driver for Dodscott Observatory. Our customer has given permission to film the process and to open-source the code, so we'll be filming the whole process and showcasing some of the techniques, tricks and tips we use at Tigra Astronomy. For you, the viewer, it will be as if you are sitting in a chair next to me and you'll get to see the entire development process, warts and all. We hope you'll find it useful!
Episode 1: File/New Project
In this episode, we bootstrap the solution with a unit test project and begin writing the first test. We introduce our preferred unit testing framework, Machine.Specifications and our super whizzy test runner plug-in called NCrunch. We import our Reactive Communications library and use it to create our transaction base class.
Episode 2 - Finding a Direction
In this episode I grope for a direction at this early stage in the project and use another "Ice Breaker" test to help point the way. By the end, we have created our first transaction type and laid down a creational pattern for the many unit tests that will follow. The project is starting to take shape and gather momentum.
Source code: https://bitbucket.org/account/user/tigra-astronomy/projects/DOD
Reactive Communications for ASCOM: http://tigra-astronomy.com/reactive-communications-for-ascom
Episode 2A - Taking a Drink from the Fire Hose
Bonus episode! Having watched the previous episode back, I felt that I needed to spend a couple of minutes explaining the conceptual basis of the Reactive Communications Library and why transactions work the way they do and backing that up with a practical demonstration. It is an essential concept that will affect everything else about the driver architecture, so worth spending the extra time on it now.
Episode 3 - Dome State Transaction
In this episode I develop a new transaction class to receive dome state responses (with tests, of course!). The class is very similar to the ShutterStateTransaction class that we developed in episode 2. The similarity makes me wonder whether I should factor out a base class, but I decide to override the DRY Principle in favour of code readability and simplicity. Did I make the right choice? Perhaps we will refactor in a later episode. We can feel secure in doing so, because we have unit tests. I also point out some of the nice features of the tools I use on a daily basis: ReSharper and NCrunch.
Episode 4 - It's Alive!
In this episode I implement a ControllerActions class that uses the transactions previously developed. Once this is all tested, I "run a spike" and connect up to the hardware. We see real live device communications for the first time. I take this opportunity to demonstrate some of the logging features built into the Reactive Comms library.
Episode 5 - Getting in a State
In this episode, I lay down the foundations of the state machine that will coordinate the internal logic of the driver and arbitrate conflicting inputs. I create incipient implementations of the first two states - the ReadyState that the system will be in when nothing is moving, and the ShutterMovingState, which will deal with shutter operations.
Episode 6 - Testing the State Machine, Mocking and Aspect Oriented Programming
We develop tests for the state machine and introduce the use of mock objects using the FakeItEasy mocking framework. Our tests drive teh creation of a HardwareStatus class, which we speculate may later form the basis of a View Model for a user interface. We implement the INotifyPropertyChanged interface on the hardware status class, then show how this can be done declaratively using a technique known as Aspect Oriented Programming.
Episode 7 - Getting Asynchronous
We begin to develop some asynchronous code to monitor an ongoing shutter operation. The project stalls a little bit as I struggle to find direction and eventually get back on track.
Episode 8 - Testing the Async Monitoring and Finding Some Problems
In this episode, we continue to drive code development with tests for the asynchronous monitoring. The tests uncover some issues and we fix those up.
Episode 9 - Slash and Burn
In this episode we add the ASCOM LocalServer hub and the ASCOM dome driver that will implement the IDomeV2 interface. We copy the LocalServer code from another driver project rather than starting from a blank template. It's more about deleting stuff than adding.