-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstate_model.py
55 lines (42 loc) · 1.57 KB
/
state_model.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import json
import time
class StateStore:
def load(self):
with open('state.json', 'r') as fp:
self.state = json.load(fp)
def flush(self):
with open('state.json', 'w') as fp:
json.dump(self.state, fp, indent=4)
def get(self, dev_type, dev_address, template=None):
return self.state.get(f'0x{dev_type}{dev_address}', template)
def set(self, dev_type, dev_address, data):
self.state[f'0x{dev_type}{dev_address}'] = data
self.flush()
return data
def upsert(self, dev_type, dev_address, attributes=None, allow_joining=True):
state = self.get(dev_type, dev_address, {'joined': False})
state['type'] = dev_type
state['address'] = dev_address
state['last_seen'] = int(time.time())
state['count'] = state.get('count', 0) + 1
if attributes:
state['attributes'] = attributes
if allow_joining or state['joined']:
self.set(dev_type, dev_address, state)
return state
def seen(self, dev_type, dev_address):
state = self.get(dev_type, dev_address)
def not_seen_for(self, period=60*20):
now = time.time()
for name, data in self.state.items():
if now - data.get('last_seen', 0) > period:
yield (name, data)
if __name__ == '__main__':
state = StateStore()
state.load()
state.flush()
state.set('0e', '123456', {'foo': 'bar'})
state.seen('0e', '123456')
print(state.get('0e', '123456'))
for name, data in state.not_seen_for():
print(name)