Teltonika FM1100 and TCP listner - python

Hy, here i am...
i'm writing a tcp listner in python to read and communicate with teltonika devices but i've problems when after receiving imei code, i try to send the akcnowledgment to the device, so it does not send me AVL data.
here is a simply code:
#!/usr/bin/env python
import socket
import time
import binascii
#Variables______________________________________#
imei_known = 'XXXXXXXXXXXXXXX'
COM = 0
TCP_IP = '192.168.1.115'
TCP_PORT = 55001
BUFFER_SIZE = 5024
MESSAGE_NO_OK = '00'
MESSAGE_OK = '01'
msg_ok = MESSAGE_OK.encode('utf-8')
msg_no_ok = MESSAGE_NO_OK.encode('utf-8')
#gps elememts (to be review)
long = [0] * 8
lat = [0] * 8
angle = [0] * 4
speed = [0] * 4
sat = [0] * 2
#_____________________________________________________________#
print ('Server listening on port:',TCP_PORT)
print ('\nWaiting for data input from FM1100...')
#socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((TCP_IP, TCP_PORT))
server_socket.listen(5)
client_socket, addr = server_socket.accept()
print ('\nConnection address:', addr)
#infinite loop
while 1:
if COM == 0:
print ('\nCOM num = ',COM)
data = client_socket.recv(BUFFER_SIZE)
imei = data.decode("iso-8859-1")
lista = list(imei)
#vector of 15 elements for IMEI code
lista_2 = [0] * 15
for n in range (0,15):
lista_2 [n] = lista[n+2]
imei=''.join(lista_2)
print ('\nDevice\'s IMEI:', imei)
print ('\nComparing IMEI...')
if imei_known == imei:
print('\nDevice Recognized ')
print('\nSending data to client...')
client_socket.send(b'0x01')
data = ''
else:
client_socket.send(msg_no_ok)
print('\nDevice NOT Recognized')
break
print('\nWaiting for AVL data...')

you must reply to FM1100 in hexadecimal. Like this:
client_socket.send('\x01')

Related

Socket recv() bug in python3.7

Client:
#The program should send two strings and the server should return the interclassed string back
import socket
import time
import sys
HEADERSIZE=10
firstString = input("First string: ")
secondString = input("Second string: ")
host = "127.0.0.1"
port = 8888
firstString = f'{len(firstString):<{HEADERSIZE}}'+firstString
secondString = f'{len(secondString):<{HEADERSIZE}}'+secondString
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.send(bytes(firstString, 'utf-8'))
s.send(bytes(secondString, 'utf-8'))
fullMsg=''
while 1:
msg = s.recv(8)
if len(msg)<=0:
break
fullMsg += msg.decode('utf-8')
print(fullMsg)
s.close()
Server:
#trebuie trimisa si dimensiunea
import socket
def interclass(firstString , secondString):
i =0
j =0
interString=''
while i < len(firstString) and j < len(secondString):
if firstString[i] < secondString[j]:
interString+=firstString[i]
i=i+1
else:
interString+=secondString[j]
j=j+1
while i < len(firstString):
interString += firstString[i]
i=i+1
while j < len(secondString):
interString+=secondString[j]
j=j+1
return interString
host = "127.0.0.1"
port = 8888;
HEADERSIZE=10
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(1)
while True:
conn, addr = s.accept()
messages=[]
newMsg = True
fullMsg = ''
msgLength = -1
while True:
msg = conn.recv(16)
if len(msg)<=0:
break
msg = msg.decode('utf-8')
fullMsg += msg
if len(fullMsg)>=HEADERSIZE and newMsg == True:
newMsg = False
msgLength = int(fullMsg[:HEADERSIZE-1])
fullMsg = fullMsg[HEADERSIZE:HEADERSIZE+1+msgLength]
if not newMsg and len(fullMsg)>=msgLength:
messages.append(fullMsg[:msgLength])
fullMsg = fullMsg[msgLength:]
newMsg = True
interString = interclass(messages[0], messages[1])
conn.sendall(bytes(interString,'utf-8'))
conn.close()
The application works until I try the part where I try to send data from the server. It all blocks at the recv() command in the client. I searched all the internet for a solution and I tried making it a non-blocked socket and deal with exception... Still not working. I would appreciate some help. Thanks!!

how can I set the interval to 10 ms and still matplotlib can animated?

I'm setting up a gateway that takes readings from two stations through TCP connection every 10 ms. the gateway should display these readings for each station using matplotlib and compute the average of these reading and display it as well.
the animated plots were working fine when I tested it for the three plots with setting the interval = 1000. But when I set the interval = 10 no subplots are shown. and when I set it to 500, at the start it works but after the stations connect to the gateway the animation freezes
I need the interval to be 10 ms because of the requirement
this is for station 1
#!/usr/bin/env python3
import socket
from random import randint
#import time
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 4444 # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT)) # connecting to local server
while True:
data = randint(1, 10)
data = str(data) # user input
s.send(data.encode('ascii')) # encoding the user input then sending to server
data = s.recv(1024)
data = data.decode('ascii')
this is for station 2
#!/usr/bin/env python3
import socket
from random import randint
#import time
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 5555 # The port used by the server
#time.sleep(.00000001)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT)) # connecting to local server
while True:
data = randint(1, 10)
data = str(data) # user input
s.send(data.encode('ascii')) # encoding the user input then sending to server
data = s.recv(1024)
data = data.decode('ascii')
#print (data)
and this is the gateway
#!/usr/bin/env python3
#
#
import _thread
import socket
import time
import matplotlib.pyplot as plt
import matplotlib.animation as animation
HOST = '127.0.0.1' # Standard loopback interface address (localhost)
PORT1 = 4444 # Port to listen on (non-privileged ports are > 1023)
PORT2 = 5555
Station1Data = 0
Station2Data = 0
average = 0
def server1():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT1))
s.listen()
conn, addr = s.accept()
with conn:
while True:
data = conn.recv(1024)
data = data.decode('ascii')
conn.send(data.encode('ascii'))
#print(data)
global Station1Data
Station1Data = int(data)
def server2():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT2))
s.listen()
conn, addr = s.accept()
with conn:
while True:
data = conn.recv(1024)
data = data.decode('ascii')
conn.send(data.encode('ascii'))
global Station2Data
Station2Data = int(data)
def average():
global Station1Data, Station2Data, average
while True:
average = (Station1Data+Station2Data)/2
try:
_thread.start_new_thread(server1, ())
_thread.start_new_thread(server2, ())
_thread.start_new_thread(average,())
except:
print("Error: unable to start thread")
fig = plt.figure()
#plt.xlabel('time')
#plt.ylabel('Mw Mw Mw')
ax1 = fig.add_subplot(3,1,1)
x = 19
xs = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]
ys = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
ax2 = fig.add_subplot(3,1,2)
x2 = 19
xs2 = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]
ys2 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
ax3 = fig.add_subplot(3,1,3)
x3=19
xs3 = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]
ys3 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
def animate(i):
global x,xs,ys,Station1Data
x = x+1
xs.append(x)
ys.append(Station1Data)
xs = xs[-20:]
ys = ys[-20:]
ax1.clear()
ax1.set_xticklabels([])
ax1.plot(xs, ys,'b')
ax1.set_title('Station1')
def animate2(i):
global x2,xs2,ys2,Station2Data
x2 = x2+1
xs2.append(x2)
ys2.append(Station2Data)
xs2 = xs2[-20:]
ys2 = ys2[-20:]
ax2.clear()
ax2.set_xticklabels([])
ax2.plot(xs2, ys2,'r')
ax2.set_title('Station2')
def animate3(i):
global x3,xs3,ys3,average
x3 = x3+1
xs3.append(x3)
ys3.append(average)
xs3 = xs3[-20:]
ys3 = ys3[-20:]
ax3.clear()
ax3.set_xticklabels([])
ax3.plot(xs3, ys3,'g')
ax3.set_title('average')
animation1 = animation.FuncAnimation(fig, animate, interval=10)
animation12 = animation.FuncAnimation(fig, animate2, interval=10)
animation13 = animation.FuncAnimation(fig, animate3, interval=10)
plt.show()
thanks in advance for your help
sorry if this is messy

EOFError: ran out of input. Getting this error when trying to pickle.loads from a socket

I have a numpy ndarray that I'm trying to send via socket connection. When I try to load it on the server, using pickle.loads I get EOFError: ran out of input.
client.py
import numpy as np
import socket, pickle
import struct
HOST = "192.168.143.xxx"
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
centers = np.zeros((100, 43919))
packet = pickle.dumps(centers)
length = struct.pack('>I', len(packet))
packet = length + packet
s.send(packet)
data = s.recv(8192)
data_new = pickle.loads(data)
s.close()
print ('Received', data_new)
server.py
import socket, pickle, numpy as np
import struct
HOST = ''
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(2)
while 1:
L = np.zeros((100, 43919))
#wait to accept a connection - blocking call
conn, addr = s.accept()
print ('Connected with ', addr)
buf = b''
while len(buf) < 4:
buf += conn.recv(4 - len(buf))
length = struct.unpack('>I', buf)[0]
print(length)
data = conn.recv(length)
if not data: break
M = pickle.loads(data) # HERE IS AN ERROR, the same as np.loads(...)
L += M
data_out = pickle.dumps(L)
conn.sendall(data_out)
conn.close()
s.close()
I've tried reading this, this and this but nothing helps.
I'm using Python 3.4.
EDIT:
The exact error is:
File server.py, line 30, in <module>:
M = pickle.loads(data) #HERE IS AN ERROR
EOFError: Ran out of input.
conn.recv(length) does not necessarily read length bytes, if there are less than that number available. You need to loop until you have enough.
See When does socket.recv(recv_size) return?
data = b''
l = length
while l > 0:
d = sock.recv(l)
l -= len(d)
data += d
There is a similar issue in your code that uses .send(), although in that case there is an easy fix: just use .sendall() as you do in the other place.

How to keep listening to the connected TCP sockets by "select"

All my clients sockets do the same thing: send a package every second(22 bytes)
Server code as below:
import select
import socket
import datetime
SList = []
class Tserver:
def __init__(self, portNum):
host = '127.0.0.1'
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server.bind((host, portNum))
self.server.listen(1)
def GETPACK():
# function for CRC check
def CRC(DATA_STR):
return 1
# generate 100 sockets to listen
for x in range(100):
SList.append(Tserver(x+10000))
inputs = []
# put in inputs
for x in range(100):
inputs.append(SList[x].server)
while(True):
ready_socks, _, _ = select.select(inputs, [], [])
for sock in ready_socks:
c, addr = sock.accept()
while(True):
data = c.recv(22)
if len(data) == 22: # To make sure the data-length is 22
# Turn the pack string into bytearray
data_bytes = bytearray()
data_bytes.extend(data)
if CRC(data_bytes) == 1:
print "Connected from client IP Address:" + str(addr)
# ID
ID = 256*data_bytes[1] + data_bytes[2]
print "ID: ", ID
now = datetime.datetime.now()
print "now: ", str(now)
if __name__ == "__main__":
GETPACK()
My server can only print the packages sent by the first connected socket.
And my question is how to print out all message from each ports whenever a package is sent to the server.
See this PyMOTW entry for a detailed explanation of how to use the select module to write a select-based server.
The main differences between that example and your code are:
You just create one listening socket - server. There is no need to listen on multiple ports.
The variable inputs will be a list consisting of server and any other open socket connections to clients.
Your service loop will look like:
while true:
readable, _, _ = select.select(inputs, [], [])
for r in readable:
if r is server:
# handle a new incoming connection
# this will add an entry to the variable inputs
else:
# read some data from socket r and process it
When you attempt to read from a client socket and get an EOF condition, you can close that socket and remove it from the inputs variable.
#ErikR Thanks for your help, i changed my code, and it worked fine.
The reason that my code doesn't work was because of two things:
1.I only create one connection to recv data from my clients.
2.The same connection can't be accepted again for recv, if the clients does't reconnect.(my code doesn't check the exception when clients shutdown)
Code as below:
import select, socket, datetime
SList = []
SconnList = []
class Tserver:
def __init__(self, portNum):
host = '127.0.0.1'
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
self.server.bind((host,portNum))
self.server.listen(1)
print "Server ports: "+str(portNum)
class Sconn:
def __init__(self, sock):
self.conn, self.addr = sock.accept()
def GETPACK():
# function for CRC check
def CRC(DATA_STR):
return 1
# generate 100 sockets to listen
for x in range(100):
SList.append(Tserver(x+10000))
inputs = []
# put in inputs
for x in range(100):
inputs.append(SList[x].server)
while(True):
ready_socks,_,_ = select.select(inputs, [], [])
for sock in ready_socks:
try:
SconnList.append(Sconn(sock))
SconnList.reverse()
inputs.append(SconnList[0].conn)
except:
data = sock.recv(22)
if len(data) == 22: # To make sure the data-length is 22
#Turn the pack string into bytearray
data_bytes = bytearray()
data_bytes.extend(data)
if CRC(data_bytes) == 1:
print "IP Address:" + str(sock.getsockname())
#ID
ID = 256*data_bytes[1] + data_bytes[2]
print "ID: ",ID
now = datetime.datetime.now()
print "now: ",str(now)
print ""
print ""
if __name__ == "__main__":
GETPACK()

Python : thread shuts down after receiving 0f byte over serial port

I am making program for communication with cash register, and while i was testing printer on it (printing numbers from 0 to 100), I noticed that every time i get this byte (0f in hex) and my thread either blocks or shuts down. My project is made of 2 programs, one is for communication with cash register and tcp, and other is just sitting on tcp port (will add DB later)
So here is the 4 threaded program:
#!/usr/bin/env python
import thread
import crcmod
import Queue
import serial
import socket
import time
#portovi
TCP_IP = '127.0.0.1'
TCP_PORT=5007
v =0
lockSerial = thread.allocate_lock()
lockTcp = thread.allocate_lock()
lockPrn = thread.allocate_lock()
serialBuff = []
tcpBuff = []
prnBuff = []
prnReady=1
stx = chr(0x02)
etx = chr(0x03)
ack = chr(0x06)
nack = chr(0x15)
prnCmd = ('PB','PD','PF','P'+chr(0xc2))
crc8 = crcmod.mkCrcFun(0x131, 0x00)
ser = serial.Serial( 0 , baudrate=19200, bytesize=8, parity='N', stopbits=2, timeout=None, xonxoff=0, rtscts=0, writeTimeout=None, dsrdtr=None)
ser.open()
ser.sendBreak()
sl = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sl.bind((TCP_IP, TCP_PORT))
sl.listen(1)
connl, addr = sl.accept()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT+1))
s.listen(1)
conn, addr = s.accept()
def toHex(s):
lst = []
for ch in s:
hv = hex(ord(ch)).replace('0x', '')
if len(hv) == 1:
hv = '0'+hv
lst.append(hv)
return reduce(lambda x,y:x+y, lst)
#hex2bit
def hex2bit(string):
novi = bin(int(string, 16))[2:]
if len(novi)<8:
pom=8-len(novi)
while pom!=0:
novi = str(0)+novi
pom=pom-1
return novi
def serialRecv():
messageSerRec = ''
global prnReady
while 1:
byte = ser.read()#shuts down here
if not toHex(byte)=='0f':#even if I change it it shuts down
if byte == ack:
print 'ACK'
elif byte == nack:
print 'NACK'
else:
if byte == stx:
messageSerRec = ''
elif byte == etx:
messageSerRecFin = messageSerRec[:-2]
chSum = int ('0x%s'%messageSerRec[-2:],0)
if chSum == crc8(messageSerRecFin):
lockSerial.acquire()
serialBuff.append(messageSerRecFin)
print "Serial Recv: ", messageSerRecFin
lockSerial.release()
ser.write(ack)
prnReady = 1
else: ser.write(nack)
else: messageSerRec = messageSerRec+byte
time.sleep(0.01)
def tcpSend():
while 1:
if serialBuff:
lockSerial.acquire()
conn.send(serialBuff[0])
print "Tcp Send: ", serialBuff[0]
serialBuff.remove(serialBuff[0])
lockSerial.release()
time.sleep(0.01)
def tcpRecv():
pom=""
while 1:
messageTcpRec = connl.recv(25)
i=0
if len(messageTcpRec)>0:
while i<len(messageTcpRec):
if not messageTcpRec[i]==';':
pom=pom+messageTcpRec[i]
else:
prnBuff.append(pom)
pom=""
i=i+1
print prnBuff
#if not messageTcpRec=="":
# print "Tcp Recv: ", messageTcpRec
# if messageTcpRec[:2] in prnCmd:
# lockPrn.acquire()
# prnBuff.append(messageTcpRec)
# lockPrn.release()
# elif tcpBuff:
# lockTcp.acquire()
# tcpBuff.append(messageTcpRec)
# lockTcp.release()
time.sleep(0.01)
def serialSend():
global prnReady
while 1:
#print "prnRdy=", prnReady
if tcpBuff:
print "tcpBuff:", tcpBuff[0]
lockTcp.acquire()
ser.write(stx+tcpBuff[0]+hex(crc8(tcpBuff[0]))[-2:].upper()+etx)
print "Serial Send: ", (tcpBuff[0])
tcpBuff.remove(tcpBuff[0])
lockTcp.release()
if prnBuff:
if prnReady == 1:
lockPrn.acquire()
ser.write(stx+prnBuff[0]+hex(crc8(prnBuff[0]))[-2:].upper()+etx)
print "Serial Send(prn): ", (prnBuff[0])
prnBuff.remove(prnBuff[0])
lockPrn.release()
prnReady = 0
time.sleep(0.01)
thread.start_new_thread(serialRecv,())
thread.start_new_thread(tcpSend,())
thread.start_new_thread(tcpRecv,())
thread.start_new_thread(serialSend,())
while 1:pass
s.close()
So thread serialRecv shuts of when it receives that byte
I've been trying to work this out for last 2-3 days and can't find solution.

Categories