Looks like a good solution is to write some kind of long-running scheduler/controller that is the only process allowed to manipulate the shift registers. It can also act as a state manager to keep track of the status of stations. I really don’t want to require people to set up task queues or other network processes, so I’ll probably do it as a simple HTTP-based system that uses threads.
Precisely. You might even want to go a step further and decouple the scheduler from the controller. You’d have one process (the controller, or perhaps more aptly named, the driver) which is the only process that actually interfaces with the shift registers (it would be a single, running process). It should support low-level commands like set_state and get_state which sets/gets the entire state of the shift registers (again, getting the state would have to be implemented by simply recalling the last state that was sent). It might also support some slightly higher-level commands like turning on/off specific stations. Then the scheduler (or better yet, the controller, if you’re calling the other thing the driver) would operate at the level of individual scheduled programs, and it would handle when a program activates specific stations during the execution of a program, when programs are executed, and (most relevant to this thread) what happens when multiple programs are trying to run at the same time (e.g., whether programs are smartly combined, or one overwrites the other, or one is delayed until the other is finished, etc.) This process would also be a single, long-running thread (and technically could be in the same process as the driver; the decoupling is more for organization). You may want to look at some existing scheduling libraries to help with the timing stuff (e.g., http://pythonhosted.org/APScheduler/).
I’m thrilled that you’re working on a separate implementation. I’ve been happy with the interval program in conjunction with the mobile web app, but there’s never anything wrong with healthy competition, especially in the open source community.