Add diagnostics interface

It's not completely polished yet, but it provides some convenience access to publishing diagnostics.

An example program would look like:

```python
from pal_python import DiagnosticPublisher as Diag

class Blarg:
    def __init__(self):
        self.diag = Diag("blarg: Blarg test")

    def update_diag(self, data):
        with self.diag.lock:
            self.diag.fields['Test failure rate'] = '{0:.4f}%'.format(data.fail_rate)
            if data.lost:
                self.diag.fields['Current state'] = 'LOST'
                self.diag.message("Houston, we might be lost, a bit.")
                self.diag.level(Diag.WARN)

    def loop(self):
        data = do_stuff()
        self.update_diag(data)
```
For `OK`, `WARN` and `ERROR` you might want to use `DM.DiagnosticStatus.OK`, `DM.DiagnosticStatus.WARN` and `DM.DiagnosticStatus.ERROR`.
Apparently there's nothing for `STALE`