Building Access
Consideration
There are no limitation for how we store the integration data, team can had decision making for this. We can store the data to postgreSQL, SQLite or just file base, but there are several points we need to stick with
- I/O workload
- Performance
- Filtering
Resource From Client
Sample JSON Data
Before dive into building access section, take a look below data are provided from the clients for understanding the brief concept of the data relation.
Document
Swagger from FS: https://onebangkok-api.dreamy-germain.119-59-118-127.plesk.page/swagger/index.html
Data Structure
Location Mapping Data
{
"count": 86,
"locationMapping": [
{
"beaconID": 1,
"beaconName": "Beacons01",
"beaconMajorCode": "0101",
"beaconMinorCode": "010101",
"locationID": 1,
"locationName": "T4-L1 Zone1",
"locationNameThai": "โลเคชั่น01",
"projectID": 1,
"projectName": "One Bangkok",
"towerID": 1,
"towerName": "Tower4(T4)",
"zoneID": 1,
"zoneName": "Zone 1",
"zoneNameThai": "โซน 1",
"floorID": 1,
"floorName": "L1",
"createTime": "2023-06-01 13:45:31.390",
"updateTime": "2023-07-06 00:25:39.227",
"active": "True"
}
]
}
Person Data
{
"count": 1,
"data": [
{
"personID": "a50c364f-52ef-4d8c-96f4-67c854ef8ca7",
"tenantIDs": [
24
],
"phones": [
"0999999999"
],
"emails": [
"t.shin@pjoe.com"
],
"locations": [
{
"locationID": 1,
"locationName": "T4-L1 Zone1",
"isDefault": false
},
{
"locationID": 2,
"locationName": "T4-L1 Zone2",
"isDefault": false
},
{
"locationID": 3,
"locationName": "T4-L1 Zone3",
"isDefault": false
},
{
"locationID": 4,
"locationName": "T4-L1 Zone4",
"isDefault": false
}
],
"updateTime": "2023-08-25T10:56:18.283",
"active": false,
"status": "I"
}
]
}
Tower Data
{
"count": 2,
"data": [
{
"towerID": 1,
"towerName": "Tower4(T4)",
"nameEng": null,
"nameThai": null,
"createTime": "05/31/2023 14:52:40",
"createBy": 1,
"updateTime": "05/31/2023 14:52:40",
"updateBy": 1,
"active": "True",
"locations": [
{
"locationID": 1,
"locationName": "T4-L1 Zone1",
"projectID": 1,
"projectName": "One Bangkok",
"towerID": 1,
"towerName": "Tower4(T4)",
"zoneID": 1,
"zoneName": "Zone 1",
"floorName": "L1"
},
{
"locationID": 2,
"locationName": "T4-L1 Zone2",
"projectID": 1,
"projectName": "One Bangkok",
"towerID": 1,
"towerName": "Tower4(T4)",
"zoneID": 2,
"zoneName": "Zone 2",
"floorName": "L1"
}
]
},
{
"towerID": 2,
"towerName": "O3",
"nameEng": null,
"nameThai": null,
"createTime": "05/31/2023 14:52:56",
"createBy": 1,
"updateTime": "09/12/2023 15:28:20",
"updateBy": 1,
"active": "True",
"locations": [
{
"locationID": 85,
"locationName": "O3-L1 Zone1",
"projectID": 1,
"projectName": "One Bangkok",
"towerID": 2,
"towerName": "O3",
"zoneID": 1,
"zoneName": "Zone 1",
"floorName": "L1"
},
{
"locationID": 86,
"locationName": "O3-L1 Zone2",
"projectID": 1,
"projectName": "One Bangkok",
"towerID": 2,
"towerName": "O3",
"zoneID": 2,
"zoneName": "Zone 2",
"floorName": "L1"
}
]
}
]
}
Tenant Data
{
"count": 24,
"data": [
{
"tenantID": 1,
"tenantName": "Defualt Tenant",
"nameEng": "Defualt Tenant",
"nameThai": "ดีฟอลท์ เทแนนท์",
"phone": "0999999999",
"email": "Tenant@Email.com",
"address": null,
"showKiosk": true,
"showReception": true,
"remark": null,
"createTime": "2023-06-27T00:00:00",
"createBy": 1,
"updateTime": "2023-06-27T00:00:00",
"updateBy": 1,
"active": true,
"tenantAuthFloors": [
{
"locationID": 1,
"isDefaultFloor": true
},
{
"locationID": 2,
"isDefaultFloor": false
},
{
"locationID": 15,
"isDefaultFloor": false
},
{
"locationID": 16,
"isDefaultFloor": true
},
{
"locationID": 30,
"isDefaultFloor": true
}
]
},
{
"tenantID": 2,
"tenantName": "FowordSystem",
"nameEng": "ForwardSystem",
"nameThai": "ฟอร์เวิร์ดซิสเต็ม",
"phone": null,
"email": "admin@Forwardsystem.com",
"address": null,
"showKiosk": true,
"showReception": true,
"remark": null,
"createTime": "2023-06-27T13:29:08.403",
"createBy": 1,
"updateTime": "2023-06-27T13:29:08.403",
"updateBy": 1,
"active": true,
"tenantAuthFloors": [
{
"locationID": 16,
"isDefaultFloor": true
},
{
"locationID": 1,
"isDefaultFloor": false
}
]
}
]
}
API Credential
Every API request to FS needs to get token from below API for token, and put in Bearer {token} header
curl -X 'POST' \
'https://onebangkok-api.dreamy-germain.119-59-118-127.plesk.page/api/Login/Login' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"username": "xxx",
"password": "xxx"
}'
Turnstile
Flow
Elevator Calling
Concept
- One Tenant contains many Locations
- One Tower contains many Locations
- One Person can access many Locations
- One floor can have many locations
- One Location can be link with many Beacons
There are 2 types of flows for elevator calling:
- user inside the building who like to go to other floor by using mobile application
- user outside the building who will pass the tunstile and enter the elevator
Flow (Outside Building)
Concept
- User pass turnstile by show QRCode
- FS call elevator after user passed turnstile
- FS call MTEL webhook for notifying the elevator has been called, refer to here
- MTEL display lift information on mobile app
Flow (Inside Building)
Concept
- Call elevator on mobile application
- Detect ibeacons via bluetooth
- Get beaconMajorCode and beaconMinorCode
Flow
- flowchart
- sequence diagram
- Pass beacon codes to system
- System find towerID by beacon codes from database (Location Mapping Data)
- Database return towerID to system
- System find locations from database by towerID (Tower Data)
- Also filtered by accessible locations by Person Data
- Database return available locations to system
- System find tenant from database by locationID (Tenant Data)
- Database return tenant data to system
- System return tenant, locations and tower data to mobile application for display
- Mobile request call lift (system -> fs)
Special Case Handling
Users might got bluetooth signals from iBeacon even though they haven't passed the turnstile.
For this scenario, FS prepares an API to MTEL to get the status that determine wether the users can call elevator via mobile app.

When user click Call elevator button, MTEL needs to call API to check the users are capable of calling the lift.
FS APIs
The APIs prepared from FS to MTEL
Call Lift
Refer to here
https://onebangkok-api.dreamy-germain.119-59-118-127.plesk.page/api/AuthorizeFloor/getCallLift
request
{
"personID": "7C0426AF-EE20-4D8F-A7AD-305A5CAC65ED",
"locationID": "1",
"destinationFloorID": "17"
}
response
{
"message": "Successfully!",
"status": 0,
"data": {
"personID": "7c0426af-ee20-4d8f-a7ad-305a5cac65ed",
"liftName": "D",
"floorID": 17,
"floorName": "L17"
}
}
example
curl --location 'https://onebangkok-api.dreamy-germain.119-59-118-127.plesk.page/api/AuthorizeFloor/getCallLift' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer xxx' \
--data '
{
"personID": "a50c364f-52ef-4d8c-96f4-67c854ef8ca7",
"locationID": 1,
"floorID": 12
}'
MTEL APIs
The APIs prepared from MTEL to FS
Lift Notification
For FS to notify MTEL when lift has been called, intends to display lift information Refer to here TBC
Visitor Pass
Flow
- Create pass on mobile application and share to the visitor
- Visitor enter the building and passed the turnstile
- Forward System sends notification to an API endpoint that provided from MTEL
Visitor Pass Creation
https://onebangkok-api.dreamy-germain.119-59-118-127.plesk.page/api/PreRegister/invitePreRegister
request
{
"guestInviteDocNo": '11111111111111111',
"guestInviteName": 'John Doe',
"tenantID": 1, // from tenantMapping data to Mtel API
"locationID": 3, // from locationMapping data to Mtel API
"personID": "14342eb6-6690-40b4-bc74-f68cbac5e70a",
"inviteSchedule": [
{
"endDate": "2024-10-17T17:32:38.257Z",
"startDate": "2024-10-17T07:32:38.257Z"
}
]
}
response
{
"message": "Successfully!",
"status": 0,
"data": {
"inviteID": "27a449a8-7ea2-4934-26ae-08dba4b3d0e9"
}
}
example
curl --location 'https://onebangkok-api.dreamy-germain.119-59-118-127.plesk.page/api/PreRegister/invitePreRegister' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VyX0lEIjoiMTAwMDAiLCJSb2xlX0lEIjoiMiIsIlVzZXJfTmFtZSI6Im10ZWwiLCJuYmYiOjE2OTg0MDM3NzEsImV4cCI6MTY5OTAwODU3MSwiaWF0IjoxNjk4NDAzNzcxLCJpc3MiOiJGb3J3YXJkU3lzdGVtIiwiYXVkIjoiRm9yd2FyZFN5c3RlbSJ9.uaepaEiWyW0JxZ4HeCMDFZHPAxp2RrZcWfAI2VchNq8}' \
--data '{
"guestInviteDocNo": "1111111111111221111",
"guestInviteName": "John Doe",
"tenantID": 24,
"locationID": 2,
"personID": "a50c364f-52ef-4d8c-96f4-67c854ef8ca7",
"inviteSchedule": [
{
"endDate": "2023-11-18T17:32:38.257Z",
"startDate": "2023-11-18T07:32:38.257Z"
}
]
}'
Visitor Pass Acknowledgement
The API need to be created by MTEL side, the payload format below is returned from FS side
{
"notifyData": [
{
"personID": "cdbae67e-e525-4f4b-9623-228785792028",
"liftName": "C",
"floorID": 3,
"floorName": "3"
},
{
"personID": "dcd96733-8879-49ba-60ed-08db7baa8193",
"liftName": "E",
"floorID": 17,
"floorName": "17"
}
]
}