2016-04-06 51 views
0

我正在通過RFID閱讀器收到我的消息。我所試圖做的是消除重複和只添加到列表以下兩個條件:如何選擇附加列表?

  1. 如果他們的ID(epc在這種情況下)是獨一無二的,(完成)
  2. datetime (每5分鐘,所以我可以跟蹤相同的標籤仍然是由RFID閱讀器讀取)是間隔5分鐘後

    import paho.mqtt.client as mqtt 
    import json 
    
    testlist = []  
    
    def on_message(client, userdata, msg): 
        payloadjson = json.loads(msg.payload.decode('utf-8')) 
        line = payloadjson["value"].split(',') 
        epc = line[1] 
        datetime = payloadjson['datetime'] 
        # datetime is in this string format '2016-04-06 03:21:17' 
    
        payload = {'datetime': datetime, 'epc': epc[11:35]} 
    
        # this if-statement satisfy condition 1 
        if payload not in testlist: 
         testlist.append(payload) 
         for each in teslist: 
          print (each) 
    
    test = mqtt.Client(protocol = mqtt.MQTTv31) 
    test.connect(host=_host, port=1883, keepalive=60, bind_address="") 
    test.on_connect = on_connect 
    test.on_message = on_message 
    test.loop_forever() 
    

我怎麼能達到條件2?

UPDATE
我的目標不明確道歉,我試圖實現

我希望的輸出是這個樣子:

{'datetime': 2016-04-06 03:21:17', 'epc': 00000001} # from Tag A 
{'datetime': 2016-04-06 03:21:18', 'epc': 00000002} # from Tag B 
... 
... 
# 5 minutes later 
{'datetime': 2016-04-06 03:21:17', 'epc': 00000001} # from Tag A 
{'datetime': 2016-04-06 03:21:18', 'epc': 00000002} # from Tag B 
{'datetime': 2016-04-06 03:26:17', 'epc': 00000001} # from Tag A 
{'datetime': 2016-04-06 03:26:18', 'epc': 00000002} # from Tag B 
... 
... 
# Another 5 minutes later 
{'datetime': 2016-04-06 03:21:17', 'epc': 00000001} # from Tag A 
{'datetime': 2016-04-06 03:21:18', 'epc': 00000002} # from Tag B 
{'datetime': 2016-04-06 03:26:17', 'epc': 00000001} # from Tag A 
{'datetime': 2016-04-06 03:26:18', 'epc': 00000002} # from Tag B 
{'datetime': 2016-04-06 03:31:17', 'epc': 00000001} # from Tag A 
{'datetime': 2016-04-06 03:31:18', 'epc': 00000002} # from Tag B 
... 
... 

回答

1

你的問題有點不清楚。假設您想要更新testlist,如果它是新的epc,或者自上次更新epc以來已經超過5分鐘。在這種情況下,dict()可以很好地工作。使用標準庫中的datetime模塊計算日期或時間的差異。

import paho.mqtt.client as mqtt 
import json 
import datetime as dt 

TIMELIMIT = dt.timedelta(minutes=5) 

testlist = {}  ## <<-- changed this to a dict() 

def on_message(client, userdata, msg): 
    payloadjson = json.loads(msg.payload.decode('utf-8')) 
    line = payloadjson["value"].split(',') 
    epc = line[1] 

    # this converts the time stamp string to something python can 
    # use in date/time calculations 
    when = dt.datetime.strptime(payloadjson['datetime'], '%Y-%m-%d %H:%M:%S') 

    if epc not in testlist or when - testlist[epc] > TIMELIMIT: 
     testlist[epc] = when 

     for epc, when in teslist.items(): 
      print (epc, when) 
+0

謝謝你的答案!請問'testlist ['epc']'和'testlist [epc]'有什麼區別?根據我目前的理解,前者僅僅意味着使用'epc'作爲dict'testlist'的關鍵字,那麼後者呢?背後有什麼「魔力」? –

+1

''epc''是一個由三個字符'e','p'和'c'組成的字符串。 'testlist ['epc']'使用該文字字符串作爲鍵。相反,'epc'是一個變量名,可以綁定到任何值。例如,'epc = 42'將名稱'epc'綁定到值'42'。 'testlist [epc]'使用綁定到名字'epc'的值作爲鍵。 – RootTwo

2

這可能是一個更簡單方法:

class EPC(object): 
    def __init__(self, epc, date): 
     self.epc = epc 
     self.datetime = date 
    def __eq__(self, other): 
     difference = datetime.strptime(self.datetime, '%Y-%m-%d %H:%M:%S') - datetime.strptime(other.datetime, '%Y-%m-%d %H:%M:%S') 
     return self.epc == other.epc and timedelta(minutes=-5) < difference < timedelta(minutes=5) 
    def __ne__(self, other): 
     difference = datetime.strptime(self.datetime, '%Y-%m-%d %H:%M:%S') - datetime.strptime(other.datetime, '%Y-%m-%d %H:%M:%S') 
     return self.epc != other.epc or (self.epc == other.epc and (difference > timedelta(minutes=5) or difference < timedelta(minutes=-5))) 

payload = EPC(date, epc[11:35]) 
if payload not in test_list: 
    test_list.append(payload) 
1

我不知道epc值是否可以來回切換。也就是說,是否可能出現epc值'A',然後epc值'B',然後epc值'A'再次出現? (也可能是A,B,C,等等?)

如果假設是隻會有一個標籤,那麼只要看看最近的條目:

last_tag = testlist[-1] 
last_dt = last_tag['datetime'] 

現在你可以比較一下目前datetime與以前的值,看看它是否適合你的窗口。

請注意,由於日期時間不斷變化,因此將日期時間代碼放入has中並不適用於您的現有代碼,因此payload not in testlist將始終爲真,除非您獲得兩個完全相同的RFID讀數第二。

0

有解決你的問題有幾點:

  1. 對於ID唯一性,你需要檢查的epc場而已,而不是整個​​對象,因爲​​對象包括datetime。您可以使用set來存儲所有看到的ID。
  2. 的時間檢測,使用datetimetimedelta要比較的對象時
# -*- coding: utf-8 -*- 
""" 
06 Apr 2016 
To answer http://stackoverflow.com/questions/36440618/ 
""" 

# Import statements 

# import paho.mqtt.client as mqtt 
import json 
import datetime as dt 

testlist = [] 
seen_ids = set() # The set of seen IDs 
five_minutes = dt.timedelta(minutes=5) # The five minutes differences 

def on_message(client, userdata, msg): 
    payloadjson = json.loads(msg.payload.decode('utf-8')) 
    line = payloadjson["value"].split(',') 
    epc = line[1] 
    datetime = payloadjson['datetime'] 
    # datetime is in this string format '2016-04-06 03:21:17' 

    # Convert the string into datetime object 
    datetime = dt.datetime.strptime(datetime, '%Y-%m-%d %H:%M:%S') 

    payload = {'datetime': datetime, 'epc': epc[11:35]} 

    # this if-statement satisfy condition 1 
    if payload['epc'] not in seen_ids: # Need to use another set 
     should_add = True    # The flag whether to add 
     if len(testlist) > 0: 
      last_payload = testlist[-1] 
      diff = payload['datetime'] - last_payload['datetime'] 
      if diff < five_minutes:  # If the newer one is less than five minutes, do not add 
       should_add = False 
     if should_add: 
      seen_ids.add(payload['epc']) # Mark as seen 
      testlist.append(payload) 
      print ('Content of testlist now:') 
      for each in testlist: 
       print (each) 

class Message(object): 
    def __init__(self, payload): 
     self.payload = payload 

def main(): 
    test_cases = [] 
    for i in range(10): 
     payload = '{{"value":",{}","datetime":"2016-04-06 03:{:02d}:17"}}'.format('0'*34+str(i), i) 
     test_case = Message(payload) 
     test_cases.append(test_case) 
    for test_case in test_cases: 
     on_message(None, None, test_case) 

if __name__ == '__main__': 
    main() 

會打印:

 
Content of testlist now: 
{'epc': u'000000000000000000000000', 'datetime': datetime.datetime(2016, 4, 6, 3, 0, 17)} 
Content of testlist now: 
{'epc': u'000000000000000000000000', 'datetime': datetime.datetime(2016, 4, 6, 3, 0, 17)} 
{'epc': u'000000000000000000000005', 'datetime': datetime.datetime(2016, 4, 6, 3, 5, 17)}