- To help Public and emergency Services
- With location of their vehicles
- Communicate with Trackee
- To help users Find these service vehicles That is nearest to them.
- Ambulance Command Center
- Public Transport Command Center
- Police Vehicle Command Center
- Vehicle Towing Command Center
- Garbage Management Command Center
- And more….
- Bus/Train/Metro
- Police Vehicle
- Towing Vehicle
- Garbage management Vehicle
- And More…….
- Me and You
1. Vehicle
2. Person
3. Number beds in hospital (Covid use case)
4. and many more.
- Redis HASH key allows us to store info
- Redis SEARCH Helps Tracker to get the location of all Trackees and authenticate using multiple parameters ( email and phone )
- Redis GEO helps us to give the distance ( GEO RADIUS )
- Redis RPUSH and LPOP works to perform simple emergency PERSISTENT messaging
- Api calls to exsting GPS location providers
- Simple Mobile app ( for trackees )
- Browser based interface ( mainly for trackers and users ).
- There is a flag in the API app setting to sync with RDBMS.
- We have following FT indexes for Redis Search
###Note the indexes and how they are called
############################
#InDexes Redis Search #
############################
#FT.CREATE idx:users ON hash PREFIX 1 "users:" SCHEMA searchable_email TEXT SORTABLE phone TEXT SORTABLE password TEXT SORTABLE
#searchable email is created to avoid issues with "@" in email
users_idx = Client('idx:users', conn=RedisClient)
#FT.CREATE idx:trackerlist ON hash PREFIX 1 "users:" SCHEMA isTracker TEXT SORTABLE exposed TEXT SORTABLE
#this is used to send tokens to logged in users
trackerList_idx = Client('idx:trackerlist', conn=RedisClient)
#FT.CREATE idx:trackers ON hash PREFIX 1 "users:" SCHEMA Trackers TEXT SORTABLE
# this is to search the hashes for all users who have tracker as me to be added in Locations(GET) api
trackers_idx = Client('idx:trackers', conn=RedisClient)
###############################
-
Register
- User enters details and submits
- check if user exists on redis
users_idx.search("{}|{}".format(email, phone))- check if user exists in db if dbsync is enabled
- if exists send error
- We create an hash key (users:"phone number of user") and upload all data
RedisClient.hset('users:{}'.format(key), mapping=user_data) - Data looks like
- users {
- email: text, as in id@domain.com,
- phone: text,
- password: text ( hashed ),
- Token: text ,
- isTracker: "True" or "False" ,
- exposed: "True" or "False" ,
- searchable_email: stored as fn_ln_domain_com,
- alias: text ,
- Verification_Code: text (random generated),
- email_verified: "True" or "False",
- Trackers: "[list of trackers]",
- Location: "[longi, lati]",
- last_update: date as string }
- Trackers and Locations are arrays stored as string
- password is sha512 hashed
- users {
- if RDBMS sync is on , data is written to rdbms else its all upto redis
- Send Confirm email link to email
- User enters details and submits
-
VerifyEmail
- The user clicks on the link Verification_Code is changed to a new one ( To avoid reuse ).
db_Veri_Code= RedisClient.hget("users:{}".format(phone),'Verification_Code')- if codes match email_verified is set to True and
RedisClient.hset('users:{}'.format(phone), mapping={"email_verified":"True", "Verification_Code":new_code})- Success and failure message given as required
- if RDBMS sync is on , data is written to rdbms else its all upto redis
-
Login
- User is authenticated
- Check if user exists on redis
RedisClient.hexists("users:{}".format(phone),'password')- Check if user exists in db if dbsync is enabled
- If in db and not un redis pull gfrom dn and add
RedisClient.hset('users:{}'.format(phone), mapping=user_data)- If does exists send error
- The authe happens on all 3 : phone, email and password we use redis search here on idx:users
`users_idx.search("@searchable_email:{} @phone:{} @password:{}".format(searchable_email, phone, password)) - If success send user details along with tokens ( phone, email, alias, token, isTracker)
- User is authenticated
-
Load the UI
-
For All calls needing registered user authentication is done based on token and id
RedisClient.hget("users:{}".format(phone),'Token') -
Once the user turns on tracking switch.
-
Trackee
-
Note: Trackee has a mobile app as well
-
Trackee's need to add their trackers .they can have multiple trackers.
#fetch existing trackers list and add the new one to list existing_trackers= ast.literal_eval(RedisClient.hget("users:{}".format(phone),"Trackers").decode("utf-8")) if tracker not in existing_trackers: existing_trackers.append(tracker) #Update back the list RedisClient.hset("users:{}".format(phone),key='Trackers',value=str(existing_trackers))- Note: Same concept is followed to delete the trackers from the list
-
Fetches the location from the device ( mobile , browser)
-
Makes an api call at the requested Update frequency ( default 60s ) and set the location
RedisClient.hset("users:{}".format(phone),key='Location',value=str(location)) -
Trackee can update alias --> this is valid when same drivers drive different bus numbers.
RedisClient.hset("users:{}".format(phone),key='alias',value=alias) -
-
Tracker
-
Fetches the location from the device ( mobile , browser)
-
Makes an api call at the requested Update frequency ( default 60s )
- updateFrequency can be changed on the fly and is not stored in backend
RedisClient.hset("users:{}".format(phone),key='Location',value=str(location)) -
Also fetches the location of all Trackees from REDIS and puts markers on the graph.
- we use redis search here on idx:trackers
trackers_idx.search(phone) -
Tracker can invite users and Filter from the list of current users whom he want to see.
-
-
Tracker and Trackee can message each other and other ( all ) in case of emergencies.
- uses redis pubsub and Server side events *
#publish a message RedisMq.rpush("messages:{}".format(Msg_to), json.dumps(message)) #read a message RedisMq.lpop("messages:{}".format(phone)) -
Logout
- Clear all stored credentials
-
No login is required
-
They choose the service from list
- The list is obtained using Redis Search idx:trackerlist
trackerList_idx.search("@isTracker:True @exposed:True")- Only services flagged as exposed and isTracker=True are shown in list
-
on Search GEO radius is used for services with in 50KM and top 5 are returned
#below longitude and latitude is of the searching user RedisClient.georadius(service, longitude, latitude, 50, unit="km", withdist=True, withcoord=True, count=5, sort="ASC")











