Affluence tracking can have many benefits in areas such as urban planning, event management, retail, security, and marketing. The effective use of location-based technology has the potential to improve many aspects of city life.
One of these aspects is the management of cellular networks: the utilization of user traffic patterns can be a valuable source of information for the advanced management of cellular networks. This involves traffic predictions for network optimization or smart solutions to save energy.
In this respect, SmartTraffik combines IoT devices with cutting-edge cellular network technologies to integrate positioning information into network management processes. To do that, it relies on the oneM2M protocol to create a friendly ecosystem where both IoT devices and network entities can work together to improve connectivity in everyday life.
2. Why SmartTraffik?SmartTraffik project aims to provide a cost-effective solution for transparent monitoring of pedestrian flows without compromising their privacy or security.
Thus, the SmartTraffik system relies on Bluetooth nodes, which report anonymized inflow information to a centralized server, by using oneM2M lightweight messages. This information is lately processed by the system to detect mobility patterns within the coverage areas. Finally, these patterns are published internally in the system, being accessible to any network element subscribed to the system. This enables the identification of time-dependent mobility patterns as well as intelligent network planning.
Conversely, the modular design of the system eases the application of these patterns beyond cellular network management. In this sense, SmartTraffik's architecture enables the implementation of services on top of the system, opening a myriad of applications in smart cities such as indoor positioning, traffic management, or energy-saving plans.
For example, the proposed system can be used to detect the flow of people within a shopping center, offering anonymous affluence information in indoor scenarios. Similarly, in large-scale deployment of nodes, the system would generate vast amounts of data about mobility patterns of pedestrians and vehicles that would be of great use for traffic management in cities, anticipating busy hours at businesses (shift planning), etc.
3. How does SmartTraffik work?SmartTraffik is a comprehensive solution that combines an IoT sensor network and a cellular network to improve traffic management and mobility in urban environments.
SmartTraffik's IoT sensor network consists of Bluetooth nodes strategically placed at different points in the city. These nodes collect data on the movement of vehicles, pedestrians, and other traffic-related elements. This data is sent to a central virtual unit that is responsible for analyzing and calculating mobility patterns in real-time.
On the other hand, SmartTraffik's cellular network consists of a Radio Access Network (RAN) and a core network. The RAN enables the wireless connection of devices, such as connected vehicles or IoT sensors, through technologies such as 4G or 5G. The cellular core is responsible for connecting the access network to other networks and services, enabling integration with external systems.
In the RAN, SmartTraffik uses the open source paradigm called OpenRAN. OpenRAN adds flexibility to the network through the concept of the Radio Intelligent Controller (RIC). The RIC is a key element that allows the instantiation of third-party applications for intelligent management of the radio network. These applications can be developed by different vendors and allow real-time changes in network parameters to optimize the performance and efficiency of the cellular networks.
In this sense, we can summarize the proposed system in the following three entities:
- Bluetooth nodes (Application Entity, AE): They collect the Bluetooth information of devices that transit close to them. Also, they send the collected information to the system without processing.
- MaorIoT node (virtual AE): It analyzes all information from Bluetooth nodes and detect traffic patterns between them.
- Radio Intelligent Controller - RIC (AE): Uses the traffic patterns information to turn on/off the network, depending the affluence of the area.
These three entities communicate through the OneM2M protocol. For this purpose, the Mobius platform is used. The system architecture is depicted below.
In addition, these three type of nodes have been given permissions to communicate with each other through Access Control Policy's OneM2M functionality.
The following subsections provide a comprehensive description of each of the aforementioned entities.
3.1. Bluetooth nodesBluetooth nodes (BT nodes) basically consist of a Raspberry Pi, which collects information from nearby Bluetooth devices and send their anonymized MAC address.
To do that, the bluetooth scanner of the Raspberry Pi is initially activated by using the following command:
#!/bin/bash
stdbuf -oL bluetoothctl scan on > file.test
This command allows the Raspberry Pi to detect and dump all Bluetooth devices near it into a file, with the following format:
Discovery started
[[0;93mCHG[0m] Controller E4:5F:01:10:EA:FB Discovering: yes
[[0;92mNEW[0m] Device 68:64:4B:33:8F:82 68-64-4B-33-8F-82
[[0;92mNEW[0m] Device 57:F9:E2:A1:1B:EC 57-F9-E2-A1-1B-EC
[[0;92mNEW[0m] Device 10:5A:17:58:6A:2D TY
[[0;92mNEW[0m] Device F4:47:EF:35:42:25 Amazfit GTR
[[0;91mDEL[0m] Device 57:F9:E2:A1:1B:EC 57-F9-E2-A1-1B-EC
[[0;92mNEW[0m] Device 7E:AE:8C:9F:AB:B3 7E-AE-8C-9F-AB-B3
[[0;91mDEL[0m] Device F4:47:EF:35:42:25 Amazfit GTR
[[0;92mNEW[0m] Device F4:47:EF:35:42:25 Amazfit GTR
[[0;91mDEL[0m] Device 7E:AE:8C:9F:AB:B3 7E-AE-8C-9F-AB-B3
[[0;91mDEL[0m] Device F4:47:EF:35:42:25 Amazfit GTR
[[0;92mNEW[0m] Device 7E:AE:8C:9F:AB:B3 7E-AE-8C-9F-AB-B3
[[0;92mNEW[0m] Device F4:47:EF:35:42:25 Amazfit GTR
[[0;92mNEW[0m] Device 7D:90:94:EF:25:9E 7D-90-94-EF-25-9E
[[0;93mCHG[0m] Device 7E:AE:8C:9F:AB:B3 RSSI: -81
[[0;91mDEL[0m] Device F4:47:EF:35:42:25 Amazfit GTR
[[0;93mCHG[0m] Device 7E:AE:8C:9F:AB:B3 RSSI: -89
[[0;91mDEL[0m] Device 7D:90:94:EF:25:9E 7D-90-94-EF-25-9E
Then, the file is parsed in real time to obtain the MAC address of the new devices detected by the BT nodes. Besides, the MAC is converted to integer to facilitate its transmission through the system. To do that, the following code is used:
with open('file.test','r+') as f:
while True:
sleep(0.1)
newlines = f.readlines()
if newlines:
for newline in newlines:
match = re.search(r'([0-9A-F]{2}[:-]){5}([0-9A-F]{2})',newline)
if 'NEW' in newline:
mac = "0x" + match.group(0).replace(":","")
print(mac)
print(int(literal_eval(mac)))
print(f'[{datetime.now()}] New device: {match.group(0)} (md 5: {md5(match.group(0).encode()).hexdigest()})')
pub_msg['rqi'] = str(randint(0,1000000))
pub_msg['pc']['m2m:cin']['con'] = int(mac,16)
client.publish(topic_pub, json.dumps(pub_msg))
elif 'DEL' in newline:
print(f'[{datetime.now()}] Device deleted: {match.group(0)} (md5: {md5(match.group(0).encode()).hexdigest()})')
else:
f.truncate(0)
This information is sent to the system through the OneM2M protocol. Thus, the BT nodes are registered in the system, creating at the same time the container with the entity data. For this purpose, the discovery functionality is used beforehand to check that they are not yet registered in the system. Also, discovery is used to check if the access Control Policy for the BT nodes already exists and create it if not.
def on_discovery_resp(client,userdata,message):
global ID
print("received message from topic ",message.topic," =",str(message.payload.decode("utf-8")))
print()
msg_json = json.loads(message.payload.decode('utf-8'))
if msg_json.get('pc') and msg_json['pc'].get('m2m:uril'):
dev_list = msg_json["pc"]["m2m:uril"]
else:
dev_list = []
id_list = []
print(dev_list)
if(msg_json['rqi']==AE_id+'Init'):
for dev in dev_list:
node = re.search(r'(?<=Mobius[/]BTNode)(\w+)',dev)
if node != None:
id_list.append(int(node.group(0)))
if int(ID) in id_list:
print('Reconnecting...')
else:
print('Register and create resources')
topic_pub = "/oneM2M/req/"+AE_id + "/" +csi_mqtt + "/json"
topic_reg = "/oneM2M/reg_req/"+AE_id + "/" +csi_mqtt + "/json"
print('AE registration')
client.publish(topic_reg,
json.dumps({'to':csi,'fr':AE_id,'rqi':str(randint(0,100000)),'op':1,'ty':2,
'pc':{'m2m:ae':{
'rn':AE_id, 'api':'BluetoothDetector','rr':True, 'acpi':['Mobius/acp_BTNodes']}}}))
print('Container creation')
# New devs
client.publish(topic_pub,
json.dumps({'to':csi+'/'+AE_id,'fr':AE_id,'rqi':str(randint(0,100000)),'op':1,'ty':3,'pc':{'m2m:cnt':{'rn':'new_dev','mni':100}}})) #publish
# Del devs
client.publish(topic_pub,
json.dumps({'to':csi+'/'+AE_id,'fr':AE_id,'rqi':str(randint(0,100000)),'op':1,'ty':3,'pc':{'m2m:cnt':{'rn':'del_dev','mni':100}}})) #publish
elif(msg_json['rqi']==AE_id+'_Acp_discover'):
if('Mobius/acp_BTNodes' not in dev_list):
client.publish(topic_pub,
json.dumps({'to':csi,'fr':AE_id,'rqi':str(randint(0,100000)),'op':1,'ty':1,'pc':{'m2m:acp':
{'rn':'acp_BTNodes', 'pv': {
'acr': [
{'acor': ['CAdmin'], 'acop': 63},
{'acor': ['all'], 'acop': 3}
]
},
'pvs': {'acr':[{'acor':['CAdmin'], 'acop': 63}]}
}}})) #publishIn this way, the information obtained from the nodes is made public to any entity in the system.
3.2. MaorIoT node (virtual AE)MaorIoT node is a virtual entity which is in charge of detecting affluence patterns. To do so, it first register and create its container in the system. As in the case of BT nodes, a discovery of the entities is carried out to find out if it is already registered. At the same time, this discovery is used to obtain the containers of the BT nodes registered in the system, allowing a subscription to be made to each of them. Also, the discovery is used to check if the access Control Policy for this node has been created beforehand and if not, it is created.
def on_discovery(client,userdata,msg):
print('on discovery')
print(msg.payload)
msg_json = json.loads(msg.payload.decode('utf-8'))
registered = False
if msg_json.get('rqi') and msg_json['rqi']=='MAORIOT-acp':
if msg_json.get('pc') and msg_json['pc'].get('m2m:uril'):
dev_list = msg_json["pc"]["m2m:uril"]
else:
dev_list = []
if('Mobius/acp_MAORIOT' not in dev_list):
client.publish('/oneM2M/req/MAORIOT-AE/Mobius2/json',
json.dumps({'to':csi,'fr':'MAORIOT-AE','rqi':str(randint(0,100000)),'op':1,'ty':1,'pc':{'m2m:acp':
{'rn':'acp_MAORIOT', 'pv': {
'acr': [
{'acor': ['CAdmin','MAORIOT-AE'], 'acop': 63},
{'acor': ['all'], 'acop': 35}
]
},
'pvs': {'acr':[{'acor':['CAdmin'], 'acop': 63}]}
}}})) #publish
else:
if msg_json.get('rqi') and msg_json['rqi'].startswith('BTNodeInit') and f'{csi}/{msg_json["fr"]}' not in subscriptions:
mqttc.publish('/oneM2M/req/MAORIOT-AE/Mobius2/json',
json.dumps({'to':f'{csi}/{msg_json["fr"]}/new_dev','fr': 'MAORIOT-AE','rqi': str(randint(0,10000)),'op':1,'ty':23,
'pc':{'m2m:sub':{
'rn': 'New_dev_sub','nu': ["mqtt:/MAORIOT-AE"] , 'nct':1,
'enc':{
'net':[3],
}}}}))
subscriptions.add(f'{csi}/{msg_json["fr"]}')
for uri in set(msg_json['pc']['m2m:uril']).difference(subscriptions):
if(uri == "Mobius/MAORIOT-AE"):
registered = True
elif("BTNode" in uri):
#mqttc.subscribe(f'/oneM2M/req/{uri.split("/")[1]}/Mobius2/+')
#mqttc.message_callback_add(f'/oneM2M/req/{uri.split("/")[1]}/Mobius2/+',on_message_mac)
# Create subscription
mqttc.publish('/oneM2M/req/MAORIOT-AE/Mobius2/json',
json.dumps({'to': uri+"/new_dev",'fr': 'MAORIOT-AE','rqi': str(randint(0,10000)),'op':1,'ty':23,
'pc':{'m2m:sub':{
'rn': 'New_dev_sub','nu': ["mqtt:/MAORIOT-AE"] , 'nct':1,
'enc':{
'net':[3],
}}}}))
subscriptions.add(uri)
if(registered == False):
mqttc.publish('/oneM2M/reg_req/MAORIOT-AE/Mobius2/json',
json.dumps({'to': "Mobius",'fr': 'MAORIOT-AE','rqi': str(randint(0,10000)),'op':1,'ty':2,
'pc':{'m2m:ae':{
'rn': 'MAORIOT-AE', 'api':'Dev_tracker','rr':True, 'acpi': ['Mobius/acp_MAORIOT']}}}))
Thanks to the subscription to each BT node, this entity will be able to monitor the MACs detected in each area, allowing the creation of affluence patterns. For this purpose, it checks whether the same MAC address is captured in two different BT nodes:
def on_message_mac(client, userdata, msg):
print(msg.topic)
print(msg.payload)
msg_json = json.loads(msg.payload.decode('utf-8'))
if("m2m:sgn" in msg_json["pc"]):
# Publish ack
mqttc.publish('/oneM2M/resp/Mobius2/MAORIOT-AE/json',
json.dumps({'to': 'Mobius', 'fr': 'MAORIOT-AE', 'rqi': msg_json['rqi'], 'rsc': 2000 })) # rsc: 2xxx request received and done, 1xxx request received but in progress
mac_address = msg_json['pc']['m2m:sgn']['nev']['rep']['m2m:cin']['con']
#node = re.search(r'(?<=Mobius[/])(\w+)(?=[/]new_dev)', msg_json['to']).group(0)
node = msg_json['pc']['m2m:sgn']['nev']['rep']['m2m:cin']['cr']
print(msg_json)
print(node)
print(mac_address)
#node_address = str(msg.payload)
if tracking.get(mac_address):
if tracking.get(mac_address) != node:
print('Has changed!')
rn = tracking.get(mac_address)+'_to_'+node
if(rn not in pairs):
mqttc.publish('/oneM2M/req/MAORIOT-AE/Mobius2/json',
json.dumps({'to': "Mobius/MAORIOT-AE",'fr': 'MAORIOT-AE','rqi': str(randint(0,10000)),'op':1,'ty':3,
'pc':{'m2m:cnt':{
'rn': rn, 'mni':200}}}))
time.sleep(1)
mqttc.publish('/oneM2M/req/MAORIOT-AE/Mobius2/json',
json.dumps({'to': "Mobius/MAORIOT-AE/"+rn,'fr': 'MAORIOT-AE','rqi': str(randint(0,10000)),'op':1,'ty':4,
'pc':{'m2m:cin':{
'con': 1}}}))
#mqttc.publish('/oneM2M/req/'+tracking.get(mac_address)+'_to_'+node+'/Mobius2/json', 1)
tracking[mac_address] = node
Finally, the MaorIoT vAE creates a topic for each pair of BT nodes and publishes the number of MACs detected on that path.
def on_message(client, userdata, msg):
print(msg.topic)
print(msg.payload)
msg_json = json.loads(msg.payload.decode('utf-8'))
if(msg_json['rqi']=="discover_pairs"):
for uri in set(msg_json['pc']['m2m:uril']).difference(pairs):
if("_to_" in uri):
pairs.add(uri)
3.3. Radio Intelligent Controller (RIC)As mentioned above, the RIC is an entity that allows for quick and easy action on the network. To this end, we have developed an rAPP (as it is called in the OpenRAN standard) that allows this entity to be integrated into the system.
First of all, this rAPP allows the RIC to be registered in the system.
def on_ric_discovery(client, userdata, message):
print()
print('ric discovery')
print(message.topic)
print(message.payload)
msg = json.loads(message.payload)
if msg.get('pc') and msg['pc'].get('m2m:uril'):
if(msg.get('rqi') and msg['rqi'].startswith(f'{AE_id}_discovery_')):
if AE_id not in msg['pc']['m2m:uril']:
client.publish(f'/oneM2M/reg_req/{AE_id}/Mobius2/json',
json.dumps({'to':csi,
'fr':AE_id,
'rqi':AE_id+str(int(randint(0,10000))),
'op':1,
'ty':2,
'pc':{'m2m:ae':{
'rn':AE_id,
'api':'RIC-Actuator',
'rr':True,
'acpi':[f'Mobius/acp_{AE_id}']
}}}))
client.publish(f'/oneM2M/req/{AE_id}/Mobius2/json',
json.dumps({'to':f'{csi}/{AE_id:}',
'fr':AE_id,
'rqi':AE_id+str(int(randint(0,10000))),
'op':1,
'ty':3,
'pc':{'m2m:cnt':{
'rn':'cell_status',
'mni':100
}}}))
else:
print('Reconnecting')
elif(msg.get('rqi') and msg['rqi'].startswith(f'{AE_id}_acp')):
if msg.get('pc') and msg['pc'].get('m2m:uril'):
dev_list = msg["pc"]["m2m:uril"]
else:
dev_list = []
if(f'Mobius/acp_{AE_id}' not in dev_list):
client.publish(f'/oneM2M/req/{AE_id}/Mobius2/json',
json.dumps({'to':csi,'fr':AE_id,'rqi':str(randint(0,100000)),'op':1,'ty':1,'pc':{'m2m:acp':
{'rn':f'acp_{AE_id}', 'pv': {
'acr': [
{'acor': ['CAdmin',f'acp_{AE_id}'], 'acop': 63},
{'acor': ['GUI-test'], 'acop': 3}
]
},
'pvs': {'acr':[{'acor':['CAdmin'], 'acop': 63}]}
}}})) #publishIn addition, it subscribes to MaorIoT vAE, to obtain information on the inflow patterns generated by the system in the area that it offers cellular coverage. To do that, it uses the discovery function as below:
def on_discovery(client, userdata, message):
print()
print('on discovery')
print(message.topic)
print(message.payload)
msg = json.loads(message.payload)
# Container request
if msg.get('rqi') == rqi:
print(msg['pc']['m2m:uril'])
if msg.get('pc') and msg['pc'].get('m2m:uril'):
print(watch_pair)
containers = list(filter(lambda x: watch_pair[0] in x or watch_pair[1] in x,
msg['pc']['m2m:uril']))
if len(containers) != 2:
print('Tracking path does not exist')
exit(1)
client.publish(f'/oneM2M/req/{AE_id}/Mobius2/json',
json.dumps({'to':containers[0],
'fr':AE_id,
'op':1,
'ty':2,
'rqi':f'{AE_id}_{str(randint(0,100000))}',
'pc':{ 'm2m:sub':{
'rn': 'sub',
'nu': [f'mqtt:/{AE_id}'],
'nct':1,
'enc':{'net':[3]}
}
}}))
client.publish(f'/oneM2M/req/{AE_id}/Mobius2/json',
json.dumps({'to':containers[1],
'fr':AE_id,
'op':1,
'ty':2,
'rqi':f'{AE_id}_{str(randint(0,100000))}',
'pc':{ 'm2m:sub':{
'rn': 'sub',
'nu': [f'mqtt:/{AE_id}'],
'nct':1,
'enc':{'net':[3]}
}
}}))
This allows the RIC to be aware of the affluence of the area in which it provides network coverage.
def on_data_update(client, userdata, message):
global last
print()
print('New data')
print(message.topic)
print(message.payload)
msg = json.loads(message.payload)
client.publish('/oneM2M/resp/Mobius2/{AE_id}/json',
json.dumps({'to':csi,
'fr':AE_id,
'rqi': msg['rqi'],
'rsc': 2000 })) # rsc: 2xxx request received and done, 1xxx request received but in progress
idx = msg['pc']['m2m:sgn']['sur'].split('/')[-2]
last[idx] = float(msg['pc']['m2m:sgn']['nev']['rep']['m2m:cin']['con'])
data[idx].append(last[idx])
Finally, this information has been used in order to turn on and off the network cells. Thus, the policy is adjusted so that if more than 10 devices leave the network coverage area, the network will be switched off to save energy. This policy will be triggered when the RIC detects 10 devices in the wealth path of the system to which it is a subscriber.
cell_on = False
client.loop_start()
while(True):
data[watch_pair[0]] = [x for x in data[watch_pair[0]] if x > last[watch_pair[0]]-60]
data[watch_pair[1]] = [x for x in data[watch_pair[1]] if x > last[watch_pair[1]]-60]
print(f'{watch_pair[0]}: {len(data[watch_pair[0]])} devices/min')
print(f'{watch_pair[1]}: {len(data[watch_pair[1]])} devices/min')
if True:
pass
if len(data[watch_pair[0]])+len(data[watch_pair[1]]) > 10 and not cell_on:
# Request cell API to turn on
pass
elif len(data[watch_pair[0]])+len(data[watch_pair[1]]) < 10 and cell_on:
# Request cell API to turn off
pass
last[watch_pair[0]] += 0.1
last[watch_pair[1]] += 0.1
sleep(1)
client.loop_forever()
In this way, the idea of this rAPP is therefore to turn on and off the network cells based on the necessities, providing this way an energy-efficient solution for network management based on oneM2M.
4. Proof of conceptThe system described above has been deployed at the School of Telecommunications Engineering of the University of Malaga. Two nodes and a 5G cellular network have been deployed there.
In this scenario, the inflow of research staff is controlled in two directions. Depending on the direction, the deployed cellular network will be switched on or off.
In the video below you can see a short demonstration of the system, where people are leaving the area where the mobile network is connected. As soon as the system detects that there are people leaving the area, the network is automatically switched off.
5. Project summaryThis section provides an overview of the OneM2M functionalities used in SmartTraffik.
OneM2M Functions:
- Discover
- AEs and containers Creation
- Subscription & Notification
- Access Control Policy
Some of the aspects that could be further develop is the use of the filtering, grouping and location functions available in OneM2M to enable automatic search of the nodes in specific areas, where their data is desired to provide a service.
The proposed system provides an efficiently way to find traffic patterns, and applies it to network management in a simplified way: turning on/off of a network cell. This is only a simple use case to exploit the obtained mobility patterns. While the data collection could be slightly improved, there are more opportunities in the actuators part.
On the one hand, signal powers could help to count the number of devices that are stationary within an area where BT node is deployed. On the other hand, exploiting the database could enable the identification of users that repeats some routes in a daily basis.
Regarding the use cases of the traffic patterns, they could be applied to cellular network operation from different perspectives.
Here, some cells are put to low power mode or sleep mode during the night in order to save energy and basing on network counters. However, mobility patterns would enable a similar approach in an indoor scenario (e.g. a shopping centre) by activating or deactivating cells based on the numbers of users per area and the available capacity. The activation/deactivation of a cell becomes a incredible fast procedure in OpenRAN, where it is based on software-defined radio (SDR). This is also envisioned from the cell-free paradigm proposed in 6G, where physical Radio Remote Heads (pRRH) will operate as a single cell.
In addition, a potential use case would fit in city traffic optimization, for instance, by know the most common routes followed by people and vehicles, and adjusting the duration of traffic lights, even depending on the time of the day if possible. A BT node implementing our functionality could be added to traffic lights with this aim when replacing them for the Vehicle-to-Infrastructure (V2I) deployment in the upcoming years.
Comments