I spent the last few days beginning to realize the plan of writing data fields as objects. There are several reasons for this change:
- Each field needs to have some inkling of what state it’s in so that (eg.) it does not send Tom and Doug the same error message every 20s.
- Each field needs to know a number of things about how it behaves: how to convert data, what to do with the converted data, how to respond to the data, and so on.
- There is some logic that each field will share, some that most fields will share, and some that none will share. The cleanest way I can think of to do this is to have each field object inherit from a DataField class (which is now mostly written) that knows how to register errors, issue commands, and so on.
It would, of course, be possible to do this without a single object — but it would be messy and difficult to add new fields. Some details are still to be worked out (ie., how should data be checked against allowable ranges) that will become clear once I know how more about the behavior of individual data fields.
Similarly, for scope and modularity reasons Core.py is going to become object oriented as well. Like the last group did it, there will be a WeatherCollecter object handling the data collection processes. The two challenges that promise to require most of my attention are:
- Organization! Core.py is going to have a lot of functions and complex logical structure, which is unlikely to jive well with the BASIC-like vision Tom has for the code. I’ll probably need to wrangle it into something sequential-ish while preserving the more pythonic bits (ifmain clause, connections to other modules, exception-based control flow, object-oriented style) simplicity has driven me toward.
- Error handling! I haven’t yet written a line of code I don’t worry about needing to wrap in a try statement or other such error-handling thing. This wants balancing with elegance and cleanliness, as spaghetti-code is a source of errors in and of itself…
In bigger news: the RTC saga appears to have been resolved. After approximately 15 hours of searching, it turned out that the only thing wrong with the tool I was hoping to use (ts4200ctl) was the usage statement. The –getrtc option is in fact not to display the hardware time, as the usage says, but to set system time from hardware time. Many thanks to Michael from TS for clearing this up. The new plan for fail-safing time is to call ts4200ctl –getrtc as part of the setup of Core.py and then sync the RTC to system time every so often (maybe in the same daily job that resets error flags) so that when internet or power is next lost, the RTC is as accurate as possible. This method doesn’t even require knowing if ntpd is active and connected to a ntp server, since there’s no harm in syncing the RTC to a system time that was last synced with the RTC itself.
Now, this is more or less what Unix systems are intended to do anyway — but in my testing I found it could take up to 7 min for this to happen on Vor (and possibly that was ntpd in action, not the RTC) so it might as well be coded right into Core.py.
Other updates: email alerts are working (using python’s smtplib) and most code is done, except for that which requires (a) knowledge of how to convert and respond to data and (b) knowledge of how the PIC will send data. Both of these are hard to say at this point, so I expect they won’t be written until most of the infrastructure upstream is finished. The rest will probably be finished and tested by a week from today — fingers crossed. This includes:
- configuring save locations and backups
- error proofing
- including time stuff as discussed above
- writing code to send commands to PIC
- writing code to set up scheduler
–Soren