FOR TIPS, gUIDES & TUTORIALS

subscribe to our Youtube

GO TO YOUTUBE

4167 questions

4739 answers

3460 comments

0 members

We are migrating to our new platform at https://community.teltonika.lt. Moving forward, you can continue discussions on this new platform. This current platform will be temporarily maintained for reference purposes.
0 votes
9,690 views
in Vehicle tracking by anonymous

this is my current script:


import socket
port = 12050
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', port))
s.listen(1)
conn, addr = s.accept()
print('Connected by ', addr)
imei = conn.recv(1024)
conn.send('\x01')

while True:
    try:
        data = conn.recv(1024)
        if not data:
            break
        print(data)

    except socket.error:
        print("Error Occured.")
        break
 


The output is some strange characters:

2 Answers

+1 vote
by anonymous
Well because you are printing binary data.

import binascii

print(binascii.hexlify(data))

Regards
Best answer
by anonymous
Thanks for the help

Kind regards
by
i edited this script and i got it working with data extraction.
But i can get datas only one time, when the gps tracker connect to my server. How can i continue to recieve data?
from the wiki page of codec i understoon that i have to send back the number of record i recieved. right?
i tried to send it back as a string, but no luck.
Ho can i keep getting new data from the connection?
by anonymous

000000000000014508050000016ad5e71f5800069087fa1b1605dd004b00680e0000fa0d0701004503f0001500ef004f02fa0004b5000bb6000818000043105802c700000007f100000000000000016ad5e62d28000690828d1b160613004c00690f0007000c0601014503f0011500ef014f0204b5000bb6000818000743105802c70000001af100000000000000016ad5e5cf680006907f411b16145e004b00bb0f000e000c0601014503f0011500ef014f0204b5000bb6000818000e43105802c700000004f100000000000000016ad5e5cb800006907fd31b1615e8004b00e40f0010000c0601014503f0011500ef014f0204b5000bb6000818001043105802c700000054f100000000000000016ad5e5a858000690a8781b161347004b01170e002c000c0601014503f0011500ef004f0204b5000bb6000818002c43105802c700000000f1000000000005000074f3

parsing according to: https://wiki.teltonika.lt/view/Codec#Codec_8

00000000    4 zeroes
00000145    data_len 0x145 == 325
08            codec_id 0x08 == records
05            number of data == 5 records
rec #1 start:
0000016ad5e71f58    TS == 1558366855000 == Mon, 20 May 2019 18:28:21 +0000 (https://www.unixtimestamp.com/index.php)
00            prio == low
069087fa1b1605dd004b00680e0000    == GPS data
fa            io element avl_id which generated (caused) this record == 0xFA == 250 == trip @ https://wiki.teltonika.lt/view/FMB_AVL_ID
0d            number of io elements in this record == 13
07            number of 1 byte len io elements == 7
    01        1st 1 byte io element avl_id == 0x01 == Digital Input 1
    00        value == 0 == OFF
    45        2nd 1 byte io element avl_id == 0x45 == 69 == GNSS Status
    03        value == 3 == In sleep state
    f0
    00
    15
    00
    ef
    00
    4f
    02
    fa
    00
04        number of 2 byte len io elements == 4
    b5
    000b
    b6
    0008
    18
    0000
    43
    1058
02        number of 4 byte len io elements == 2
    c7
    00000007
    f1
    00000000
00        number of 8 byte len io elements == 0
rec #1 end
rec #2 start:
0000016ad5e62d28000690828d1b160613004c00690f0007000c0601014503f0011500ef014f0204b5000bb6000818000743105802c70000001af100000000000000016ad5e5cf680006907f411b16145e004b00bb0f000e000c0601014503f0011500ef014f0204b5000bb6000818000e43105802c700000004f100000000000000016ad5e5cb800006907fd31b1615e8004b00e40f0010000c0601014503f0011500ef014f0204b5000bb6000818001043105802c700000054f100000000000000016ad5e5a858000690a8781b161347004b01170e002c000c0601014503f0011500ef004f0204b5000bb6000818002c43105802c700000000f10000000000
...
05            number of data == 5
000074f3    CRC16. first two bytes are zeroes

Regards

by
ok thank you so much.

Now i wrote this code:

import socket
import binascii

def decodethis(data):
    codec = int(data[16:18], 16)
    if (codec == 8):
        lenght = int(data[8:16], 16)
        record = int(data[18:20], 16)
        timestamp = int(data[20:36], 16)
        priority = int(data[36:38], 16)
        lon = int(data[38:46], 16)
        lat = int(data[46:54], 16)
        alt = int(data[54:58], 16)
        angle = int(data[58:62], 16)
        sats = int(data[62:64], 16) #maybe
        speed = int(data[64:68], 16)
        print("Record: " + str(record) + "\nTimestamp: " + str(timestamp) + "\nLat,Lon: " + str(lat) + ", " + str(lon) + "\nAltitude: " + str(alt) + "\nSats: " +  str(sats) + "\nSpeed: " + str(speed) + "\n")
        return "0000" + str(record).zfill(4)

port = 7777
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', port))
s.listen(1)
conn, addr = s.accept()
print('Connected by ', addr)
imei = conn.recv(1024)
try:
    message = '\x01'
    message = message.encode('utf-8')
    conn.send(message)
except:
    print("Errore nell'invio della risposta. Magari non è il nostro device?")

while True:
    try:
        data = conn.recv(1024)
        if not data:
            break
        recieved = binascii.hexlify(data)
        print(recieved)
        record = decodethis(recieved).encode('utf-8')
        conn.send(record)
    except socket.error:
        print("Error Occured.")
        break

       

this is my python. i can recieve the data. But when i send the response back to the device the program ends without any errror. Is it a normal behaviur?
by anonymous

If program quits - device just disconnects from your server.

And why device disconnects - its because you send incorrect answer to records received.

Next time just add debug. I.e. what kind of response you are sending to device?
**********************

record = int(5)
msg = "0000" + str(record).zfill(4)
print(type(msg), msg)
yields:<class 'str'> 00000005
You correctly made a hex string response, but you need to send back to device not hex string - but binary.


so change:
conn.send(message.encode('utf-8'))

**********************

 

 

NOTE: Also waiting for only 1024 bytes - is incorrect. Device can send a bit larger packet than that.

Because 1024 is usually avl_data buffer. But TCP header is like 20-22 bytes or so. So actually device can send a bit bigger packet than 1024 bytes.

Regards

by
I don't understand how to convert hex to binary...

Should i responde with

> binascii.unhexlify(record)

With this response almost everytime it respond me with other data but sometimes it close the connection. The number to be encoded is the "Number of Data" after the Codec ID right? Maybe he lost 3g connection? Is there a way to know what happened?

Another question: if i have multiple devices should i run multiple instance of this program in different ports or there's another smarter way?
by anonymous
"Should i responde with"

conn.send(message.encode('utf-8'))

************

"Number of Data" after the Codec ID right?

yes.

****************

maybe he lost 3g connection? Is there a way to know what happened?

connect to device via usb - and save log to file. and see what happens.

**************

Another question: if i have multiple devices should i run multiple instance of this program in different ports or there's another smarter way?

external port - one. But internal ports are many. so you can use single program.

https://realpython.com/python-sockets/#handling-multiple-connections

https://stackoverflow.com/questions/10810249/python-socket-multiple-clients

etc

Regards
by

ok, thank you.

i understand how to analyze the IO values. but after the io there should be the Record ID and than the CRC. but i have a lot of data between the record id and the last io value

i'm refering to this test message that i saved from the device:
00000000000000c508030000016ad5e71f5800069087fa1b1605dd004b00680e0000fa0d0701004503f0001500ef004f02fa0004b5000bb6000818000043105802c700000007f100000000000000016ad5e62d28000690828d1b160613004c00690f0007000c0601014503f0011500ef014f0204b5000bb6000818000743105802c70000001af100000000000000016ad5e5cf680006907f411b16145e004b00bb0f000e000c0601014503f0011500ef014f0204b5000bb6000818000e43105802c700000004f10000000000030000317d

i don't understand what the bold text means. from the text before the bold i can get that there are 13 io data in total (7 of 1byte, 4 of 2bytes, 2 of 4bytes, but i cannot parse the rest

by

I am successfully able to get the data from one device. but how we can make the server to receive the data packet from more than one device at a time? how we can differentiate the data packet with respect to the device as the data packet does not contain any information(IMEI number or other details) about the device?

Regards

by
import socket

import threading

import binascii

port = 1234

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.bind(('', port))

def decodethis(data):

    codec = int(data[16:18], 16)

    if (codec == 8):

        lenght = int(data[8:16], 16)

        record = int(data[18:20], 16)

        timestamp = int(data[20:36], 16)

        priority = int(data[36:38], 16)

        lon = int(data[38:46], 16)

        lat = int(data[46:54], 16)

        alt = int(data[54:58], 16)

        angle = int(data[58:62], 16)

        sats = int(data[62:64], 16) #maybe

        speed = int(data[64:68], 16)

        print("Record: " + str(record) + "\nTimestamp: " + str(timestamp) + "\nLat,Lon: " + str(lat) + ", " + str(lon) + "\nAltitude: " + str(alt) + "\nSats: " +  str(sats) + "\nSpeed: " + str(speed) + "\n")

        return "0000" + str(record).zfill(4)

def handle_client(conn, addr):

    print(f"[NEW CONNECTION] {addr} connected.")

    connected = True

    while connected:

        imei = conn.recv(1024)

        try:

            message = '\x01'

            message = message.encode('utf-8')

            conn.send(message)

        except:

            print("Error sending reply. Maybe it's not our device")

        try:

            data = conn.recv(1024)

            recieved = binascii.hexlify(data)

            record = decodethis(recieved).encode('utf-8')

            conn.send(record)

        except socket.error:

            print("Error Occured.")

            break

    conn.close()   

          

def start():

    s.listen()

    print(" Server is listening ...")

    while True:

        conn, addr = s.accept()

        thread = threading.Thread(target=handle_client, args=(conn, addr))

        thread.start()

        print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")

print("[STARTING] server is starting...")

start()
0 votes
by anonymous

try this simple..python socket programming