Skip to content

Commit

Permalink
firmware: Dont send MQTT messages if only .since attribute changes
Browse files Browse the repository at this point in the history
Can happen when pressing openbutton inside/outside for a long time
  • Loading branch information
jonnor committed Jan 12, 2020
1 parent ac2fa33 commit 9d92d81
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
22 changes: 21 additions & 1 deletion firmware/dlockoslo.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,26 @@ def process(self, inport, msg):
self.send('error', 'Unknown port {}'.format(inport))
self.ack(msg)

def is_state_change(current, next):

# avoid modifying inputs
current = copy.deepcopy(current)
next = copy.deepcopy(next)

# ignore changes that are only metadata
current.lock.since = None
next.lock.since = None
current.lock.until = None
next.lock.until = None
current.opener.since = None
next.opener.since = None
current.opener.until = None
next.opener.until = None

state_changed = repr(next.__dict__) != repr(current.__dict__)
return state_changed


class LockParticipant(msgflo.Participant):
def __init__(self, role):
d = copy.deepcopy(participant_definition)
Expand Down Expand Up @@ -372,7 +392,7 @@ def recalculate_state(self, mqtt_request=None):
next = next_state(self.state, Inputs(**inputs))
set_outputs(self.state, self.output_files)

state_changed = next.__dict__ != self.state.__dict__
state_changed = is_state_change(self.state, next)
if state_changed:
entry = { 'inputs': inputs, 'state': next.__dict__ }
log.info(entry)
Expand Down
32 changes: 32 additions & 0 deletions firmware/test_doorsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,36 @@ def test_bolt_present_periodic_update(bolt_present):
assert states.bolt_present_updated > last_updated, 'should update'
assert states.bolt_present_updated == 90.0

def test_state_change_identity():
states = dlockoslo.States()
change = dlockoslo.is_state_change(states, states)
assert change == False

def test_state_change_equivalence():
state1 = dlockoslo.States()
state2 = dlockoslo.States()
change = dlockoslo.is_state_change(state1, state2)
assert change == False

def test_state_change_only_since_until():
state1 = dlockoslo.States()
state2 = dlockoslo.States()
print(id(state1), id(state2))
state2.opener.since = 100
state2.opener.until = 110
state2.opener.since = 100
state2.opener.until = 110

change = dlockoslo.is_state_change(state1, state2)
assert change == False, '.since and .until should be ignored'

def test_state_change_unlocking():
state1 = dlockoslo.States()
state1.lock = dlockoslo.Locked(since=10)
state2 = dlockoslo.States()
state2.lock = dlockoslo.Unlocked(since=20)

change = dlockoslo.is_state_change(state1, state2)
assert change == True, 'unlocking is state change'


0 comments on commit 9d92d81

Please sign in to comment.