Fix UUID race conditions

Previously, the default `get_uuid` method calculated the uuid as a function of the device ID and the counter position, but as the function for incrementing/retrieving the counter wasn't properly atomic, this led in some cases to duplicate model ids (and hence likely a couple instances of data loss :crying_cat_face:).

This PR does two things:
- Makes the default uuid generation `get_uuid` method be random (uuid4), rather than being based on the counter.
- Makes the counter incrementing more atomic, to avoid race conditions (seems quite robust, from testing, especially compared to the old one).
This helps dramatically with avoiding race condition. Before I could replicate the race condition easily with `time.sleep`s, but now I'm unable to replicate it.