5t0ff31

raspi python rs485

Nov 20th, 2016
359
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import serial, time
  2.  
  3. message_start = "/?%s!\r\n"
  4. message_login = "\x01P1\x02(00000000)\x03"
  5. message_read  = "\x01R1\x02%s()\x03"
  6. message_exit  = "\x01B0\x03"
  7. message_mode  = "\x060:1\r\n"
  8.  
  9. meter_list = ['001511420141','001511420142','001511420143']
  10. address_list = ['00000000', '00000003','00000004','00000010','00000036']
  11. error_list = [0,0,0]
  12.  
  13. state_disconnected=10
  14. state_wait_identification=11
  15. state_wait_password_prompt=12
  16. state_wait_password_verification=13
  17. state_wait_data_read=14
  18. state_data_available=15
  19.  
  20. state = state_disconnected
  21. wait_response = 1
  22. current_index = 0
  23. current_meter = 0
  24.  
  25. #ser = serial.Serial('/dev/pts/0', 115200, timeout=3)
  26. ser = serial.Serial('/dev/ttyUSB1', 9600, timeout=0.1, bytesize=serial.SEVENBITS, parity=serial.PARITY_EVEN)
  27.  
  28. def addBCC(data):
  29.    b = 0
  30.    for ch in data[1:]:
  31.       b ^= ord(ch)
  32.    data = data + chr(b)
  33.    return data
  34.  
  35. def sendMessage(message, param=None, bcc=0):
  36.    if param:
  37.       message = message % param
  38.       if bcc:
  39.          message = addBCC(message)
  40.       ser.write(message)
  41.    else:  
  42.       message = message.replace("%s","")
  43.       if bcc:
  44.          message = addBCC(message)
  45.       ser.write(message)
  46.    
  47. def sendExit():
  48.    global state, meter_index, error_list
  49.    sendMessage(message_exit, bcc=1)
  50.    state = state_disconnected
  51.    error_list[meter_index] += 1
  52.  
  53. def disconnect():
  54.    global state, meter_index, error_list
  55.    sendMessage(message_exit, bcc=1)
  56.    state = state_disconnected
  57.    print "logout"
  58.    
  59. def handle_wait_identification(data):  
  60.    global state, wait_response
  61.    if data.startswith('/YTL'):
  62.       print "ok. sending mode ..."
  63.       sendMessage(message_mode)
  64.       wait_response = 1
  65.       state = state_wait_password_prompt
  66.    else:
  67.       sendExit()
  68.       state = state_disconnected
  69.       print "error"  
  70.    
  71. def handle_wait_password_prompt(data):  
  72.    global state, wait_response
  73.    print data
  74.    print ord(data[0])
  75.    print ord(data[1])
  76.    print ord(data[2])
  77.    print ord(data[3])
  78.    if ord(data[0])==1 and ord(data[1])==80 and ord(data[2])==48:  
  79.    #if data.startswith('p0'):
  80.       print "ok. sending password ..."            
  81.       sendMessage(message_login, None, 1)
  82.       state = state_wait_password_verification          
  83.       wait_response = 1
  84.    else:
  85.       sendExit()
  86.       state = state_disconnected
  87.       print "error handle_wait_password"            
  88.  
  89. def send_data_request():
  90.    global state, wait_response, current_index
  91.    addr = address_list[current_index]
  92.    print "sending data request ... %s" % (addr)
  93.    sendMessage(message_read, addr, 1)
  94.    state = state_wait_data_read
  95.    wait_response = 1
  96.  
  97. def handle_wait_password_verification(data):
  98.    global state, wait_response
  99.    if data.startswith('\x06'):
  100.    #if data.startswith('a'):
  101.       print "password ok"
  102.       send_data_request()
  103.    else:
  104.       sendExit()
  105.       state = state_disconnected
  106.       print "error"            
  107.    
  108. def handle_wait_data_read(data):  
  109.    global state, wait_response, current_index
  110.    print data
  111.    current_index += 1
  112.    if current_index < len(address_list):
  113.       send_data_request()
  114.    else:
  115.       disconnect()
  116.       state = state_disconnected
  117.       print "done"            
  118.    
  119.  
  120. def read_meter_data(index):
  121.    global state, wait_response, current_index, meter_index
  122.    meter_index = index
  123.    time.sleep(0.1)
  124.    current_index = 0
  125.    meter_id = meter_list[meter_index]
  126.    print "start reading meter ... %s" % meter_id
  127.    sendMessage(message_start, meter_id)
  128.    state = state_wait_identification
  129.    wait_response = 1
  130.    while wait_response:
  131.       wait_response = 0
  132.       ser.flushInput()
  133.       time.sleep(0.2)
  134.       data = ser.read(64)
  135.       if data and len(data) > 0:  
  136.          print "received bytes: %d" % len(data)      
  137.          if state == state_wait_identification:        
  138.             handle_wait_identification(data)
  139.             continue
  140.          if state == state_wait_password_prompt:
  141.             handle_wait_password_prompt(data)
  142.             continue
  143.          if state == state_wait_password_verification:
  144.             handle_wait_password_verification(data)
  145.             continue
  146.          if state == state_wait_data_read:
  147.             handle_wait_data_read(data)        
  148.             continue      
  149.       else:
  150.          print "fail"
  151.          sendExit()
  152.          state = state_disconnected
  153.  
  154. max_steps = 1000
  155. for i in range(max_steps):
  156.    print "loop %d of %d ..." % (i, max_steps)
  157.    for meter in range(len(meter_list)):
  158.       read_meter_data(meter)    
  159.    for meter in range(len(meter_list)):
  160.       print "Errors for meter[%s]: %d" %  (meter_list[meter], error_list[meter])
  161.    
  162. ser.close()
Add Comment
Please, Sign In to add comment