micropython-samples/sequence/check_mid.py

65 wiersze
2.0 KiB
Python

# check_mid.py Check a sequence of incrementing message ID's.
# Released under the MIT licence. See LICENSE.
# Copyright (C) Peter Hinch 2020
# For use in test scripts: message ID's increment without bound rather
# than modulo N. Assumes message ID's start with 0 or 1.
# Missing and duplicate message counter. Handles out-of-order messages.
# Out of order messages will initially be missing to arrive later.
# The most recent n message ID's are therefore not checked. If a
# message is missing after n have been received, it is assumed lost.
class CheckMid:
def __init__(self, buff=15):
self._buff = buff
self._mids = set()
self._miss = 0 # Count missing message ID's
self._dupe = 0 # Duplicates
self._oord = 0 # Received out of order
self.bcnt = 0 # Client reboot count. Running totals over reboots:
self._tot_miss = 0 # Missing
self._tot_dupe = 0 # Dupes
self._tot_oord = 0 # Out of order
@property
def miss(self):
return self._miss + self._tot_miss
@property
def dupe(self):
return self._dupe + self._tot_dupe
@property
def oord(self):
return self._oord + self._tot_oord
def __call__(self, mid):
mids = self._mids
if mid <= 1 and len(mids) > 1: # Target has rebooted
self._mids.clear()
self._tot_miss += self._miss
self._tot_dupe += self._dupe
self._tot_oord += self._oord
self._miss = 0
self._dupe = 0
self._oord = 0
self.bcnt += 1
if mid in mids:
self._dupe += 1
elif mids and mid < max(mids):
self._oord += 1
mids.add(mid)
if len(mids) > self._buff:
oldest = min(mids)
mids.remove(oldest)
self._miss += min(mids) - oldest - 1
# Usage/demo
#cm = CheckMid(5)
#s1 = (1,2,3,4,5,8,9,10,11,12,13,17,17,16,18,19,20,21,22,23,24,29,28,27,26,30,31,32,33,34,35,36,1,2,3,4,5,6,7,8)
#for x in s1:
#cm(x)
#print(cm.dupe, cm.miss, cm.oord, cm.bcnt)