Beacons as separate tracked devices / Driver Id.

AlfSolli3 years ago

Hi.
Could not find by search, so perhaps someone can point me in the right direction;

Got BLE beacons working with my Teltonika trackers. In the traccar server I use, they show up as separate entries under Event 385 with Beacon1Uuid, Beacon1Major, Beacon1Minor and Beacon1Rssi. (Following as many beacons that are nearby at the moment)
Is there a trick to filter out such entries, so individual beacons show up on the map as separate tracked devices?

Anton Tananaev3 years ago

No.

AlfSolli3 years ago

Alright, I really needed that, so challenge accepted.

Since we forward all events and positions to our main platform, I created a handler in it's endpoint to look for these beacon entries, loop through the list and send it back to the traccar server + position of the vehicle with osmand protocol.
Voila, individual beacons as standalone devices in traccar. In case anyone else needs the same functionality.
One immediate drawback is the beacons will have the exact same position as the vehicle with the gsm tracker. Until it drives of far enough to loose signal to the beacons, then they'll stick almost where they where left.

Works beautifully though.

Joystick3 years ago

Hi AlfSolli, that is something I am very interested in but dont have the knowledge to do myself. I understand how to forward positions and events but dont know what syntax to use to read/forward individual attributes from the list of attributes in positions. Any chance you could share more info on how you manage to read and forward the info from the beacons please?

AlfSolli3 years ago

Hi Pete.
Briefly explained; From traccar, I just forward everything (events, positions) to our main platform's API. (this is a flask/python3 API)
I also forward it in json format for easier parsing.

The python api then looks for "beacon1Uuid" in request.json['position']['attributes'].
It's actually 'beacon'+str(counter)+'Uuid', where counter starts at 1 and loops to 101.
For each hit in this loop, I do a requests.post(ourtraccarserver+'/?id='+Beacon1Uuid+'&lat='+TrackersLat+'&lon='+TrackersLng,
auth=HTTPBasicAuth(ourtraccar_username, ourtraccar_password))

Note that you'd need to create a device for each beacon in traccar with a name and the Beacons UUID for this to work.
If you're using python/flask, I can share the endpoint class with you. It's a very basic proof of concept, and contains a bit of code specific to our solution, but it's easily either removed or rewritten for your use.

If you're not already using python, you could throw this together into a new little python service for this specific use.
But as far as I know, you can only forward positions to one url from traccar.
(Could be solved by forwarding it to your other needs in this script of course)

Joystick3 years ago

Thanks AlfSolli, the information is very helpful. I dont currently use python/flask but had a quick look at it and it appears it might be the solution for me as well. If its not too much effort ill appreciate if you could share the endpoint class and i will amend to suite my needs. Will save me some time. Thanks in advance mate.

AlfSolli3 years ago

@Pete
Sure.
It's very crude and just a proof of concept, and I'll have to rewrite a lot before considering it mature, but here you go:
(Also, apologies for the late response )

class TraccarData(Resource):
    def post(self): # There is no security here!
        response = []
        print("Post request: "+str(request.json))
        if 'position' in request.json:
            counter = 1
            while counter < 101:
                if 'beacon'+str(counter)+'Uuid' in request.json['position']['attributes']:
                    device_serial = request.json['position']['attributes']['beacon'+str(counter)+'Uuid']+':'+str(request.json['position']['attributes']['beacon'+str(counter)+'Major'])+':'+str(request.json['position']['attributes']['beacon'+str(counter)+'Minor'])
                    #print("Found UUID: "+request.json['position']['attributes']['beacon'+str(counter)+'Uuid'])
                    #print("Found Major: "+str(request.json['position']['attributes']['beacon'+str(counter)+'Major']))
                    #print("Found Minor: "+str(request.json['position']['attributes']['beacon'+str(counter)+'Minor']))
                    #print("Looking for serial "+device_serial)
                    lat = str(request.json['position']['latitude'])
                    lng = str(request.json['position']['longitude'])
                    timestamp = str(request.json['position']['serverTime'])
                    # Could do speed and altitude as well
                    asset = AssetsModel.find_by_nodeidentifier(device_serial)
                    if asset:
                        server = TraccarServersModel.find_by_id(asset.traccar_server_id)
                        if server:
                            spliturl = server.internal_address.split(":")
                            osmandurl = spliturl[0]+':'+spliturl[1]+':5055'
                            print("Lat: "+lat+" Lng: "+lng+" time: "+timestamp+" server url: "+osmandurl)
                            print("Found asset "+asset.name+" with traccar Id: "+str(asset.traccar_id))
                            traccarInfo = TraccarConfigModel.find_by_company_id(asset.company_id)
                            if traccarInfo:
                                #rawdata = requests.post('http://demo.traccar.org:5055/?id=123456&lat={0}&lon={1}&timestamp={2}&hdop={3}&altitude={4}&speed={5}')
                                rawdata = requests.post(osmandurl+'/?id='+str(asset.node_identifier)+'&lat='+lat+'&lon='+lng,
                                                auth=HTTPBasicAuth(traccarInfo.traccar_username, traccarInfo.traccar_password))
                                print("Rawdata: "+str(rawdata))
                            else:
                                print("Traccar config not found for asset "+asset.node_identifier+" in company id "+asset.company_id)
                        else:
                            print("Traccar server not found for asset "+asset.node_identifier)
                    else:
                        print("Asset not found.")
                counter += 1
            response.append({'status': 'OK'})
        else:
            response.append({'status': 'position is all we handle right now.'})
        return response
Andreas Kern3 years ago

Hello AlfSolli,

at first your idea to solve the problem to show beacons as devices is great. And perhaps this would be a great feature for me in the future too.
But i have another question and i would have liked to send you a private message if it was possible.
I use different teltonika devices and for testing with beacons i use a FMB001.
My problem is, that not in every record beacon data is sent to the server. In my opinion this is important to have a reliant detection of beacons to create some alarms when beacon is out of reach.
Did you find a solution to set the right parameters in config file or do you copy device attributes in traccar?

It would be very kind to let me know.
Thanks in advance!

Andreas Kern

AlfSolli3 years ago

Hi.
I'm still figuring out the exact and optimal parameter on my device (I use Fmb010 and Slim tags as well as Coin ID beacons).
I use attributes copying, but only for driverUniqueId.
I use a similar technique to send in this information, because I could not find out how computed attributes worked and also I need to separate the beacons that belong to a driver among all the ones that are tools&equipment.

You can reach me at [removed] if you have any questions that doesn't need to be on the forum.

Anton Tananaev3 years ago

Please don't share personal contact information on the forum.

AlfSolli3 years ago

Apologies.
Doesn't seem to be a way to send private messages on this forum, and since I didn't know what it was about, I didn't want to insist on sharing it publicly either.

Joystick3 years ago

Hi Alfsolli thanks for sharing the info mate.