Преглед изворни кода

add space positioning logic

highing666 пре 4 година
родитељ
комит
40d45c643b

+ 29 - 0
app/api/routers/positioning.py

@@ -0,0 +1,29 @@
+from typing import List
+
+from fastapi import APIRouter, HTTPException, Query
+from loguru import logger
+
+from app.controllers.location.ble.space import get_space_location
+from app.models.domain.location import PositionSpaceResponse
+from app.schemas.bluetooth import IBeaconBase
+
+router = APIRouter()
+
+
+@router.post('/space/users/{user_id}/projects/{project_id}', response_model=PositionSpaceResponse)
+async def update_in_space(user_id: str, project_id: str, ibeacon_list: List[IBeaconBase]):
+    space_id = await get_space_location(project_id, ibeacon_list)
+    response = {
+        'userId': user_id,
+        'projectId': project_id
+    }
+
+    if space_id:
+        response.update({
+            'result': 'success',
+            'spaceId': space_id
+        })
+    else:
+        response.update({'result': 'failure'})
+
+    return response

+ 6 - 3
app/controllers/equipment/events.py

@@ -29,8 +29,9 @@ async def regulate_ahu_switch():
     async with AsyncClient() as client:
         platform = DataPlatformService(client, _PROJECT_ID)
         ahu_list = await platform.get_items_by_category('ATAH')
+        ahu_id_list = [item['id'] for item in ahu_list]
 
-    for ahu in ahu_list:
+    for ahu in ahu_id_list:
         await ahu_switch_control(_PROJECT_ID, ahu)
 
 
@@ -40,8 +41,9 @@ async def regulate_pau_switch():
     async with AsyncClient() as client:
         platform = DataPlatformService(client, _PROJECT_ID)
         pau_list = await platform.get_items_by_category('ATFU')
+        pau_id_list = [item['id'] for item in pau_list]
 
-    for pau in pau_list:
+    for pau in pau_id_list:
         await pau_switch_control(_PROJECT_ID, pau)
 
 
@@ -51,8 +53,9 @@ async def regulate_ventilation_fan_switch():
     async with AsyncClient() as client:
         platform = DataPlatformService(client, _PROJECT_ID)
         eq_list = await platform.get_items_by_category('VTSF')
+        eq_id_list = [item['id'] for item in eq_list]
 
-    for eq in eq_list:
+    for eq in eq_id_list:
         await ventilation_fan_switch_control(_PROJECT_ID, eq)
 
 

+ 49 - 0
app/controllers/location/ble/space.py

@@ -0,0 +1,49 @@
+from operator import attrgetter
+from typing import Dict, List
+
+from httpx import AsyncClient
+from loguru import logger
+
+from app.schemas.bluetooth import IBeaconBase
+from app.services.platform import DataPlatformService
+
+
+class SpacePositioningController:
+
+    def __init__(self, realtime_ibeacon_list: List[IBeaconBase], ibeacon_space_dict: Dict):
+        super(SpacePositioningController, self).__init__()
+        self.realtime_ibeacon_list = realtime_ibeacon_list
+        self.ibeacon_space_dict = ibeacon_space_dict
+
+    def run(self) -> str:
+        ibeacon_list = sorted(self.realtime_ibeacon_list, key=attrgetter('rssi'), reverse=True)
+        strongest_id = ''
+        for ibeacon in ibeacon_list:
+            if ibeacon.rssi != 0:
+                strongest = ibeacon
+                strongest_id = str(strongest.major) + '-' + str(strongest.minor)
+                break
+
+        return self.ibeacon_space_dict.get(strongest_id)
+
+
+@logger.catch()
+async def get_space_location(project_id: str, realtime_ibeacon_list: List[IBeaconBase]) -> str:
+    async with AsyncClient() as client:
+        platform = DataPlatformService(client, project_id)
+        spaces = await platform.get_items_by_category('Sp')
+
+    ibeacon_space_dict = dict()
+    for sp in spaces:
+        try:
+            major = str(sp['infos']['ctm-iBeacon-Major'])
+            minor = str(sp['infos']['ctm-iBeacon-Minor'])
+            if len(major) > 0 and len(minor) > 0:
+                k = major + '-' + minor
+                v = sp['id']
+                ibeacon_space_dict.update({k: v})
+        except KeyError:
+            pass
+
+    controller = SpacePositioningController(realtime_ibeacon_list, ibeacon_space_dict)
+    return controller.run()

+ 10 - 9
app/main.py

@@ -7,7 +7,7 @@ import uvicorn
 from fastapi import FastAPI
 from loguru import logger
 
-from app.api.routers import targets, equipment, space, item, user, bluetooth, devices
+from app.api.routers import targets, equipment, space, item, user, bluetooth, devices, nlp, positioning
 from app.core.config import settings
 from app.core.events import create_start_app_handler
 from app.core.logger import InterceptHandler
@@ -24,19 +24,20 @@ def get_application() -> FastAPI:
 
     application.add_event_handler('startup', create_start_app_handler())
 
-    application.include_router(equipment.router, prefix='/equip', tags=['equipment'])
-    application.include_router(space.router, prefix='/room', tags=['spaces'])
-    application.include_router(targets.router, prefix='/target', tags=['targets'])
-    application.include_router(item.router, prefix='/items', tags=['items'])
-    application.include_router(user.router, prefix='/users', tags=['users'])
-    application.include_router(bluetooth.router, prefix='/bluetooth', tags=['bluetooth'])
-    application.include_router(devices.router, prefix='/devices', tags=['devices'])
+    application.include_router(bluetooth.router, prefix='/bluetooth', tags=['BLE'])
+    application.include_router(devices.router, prefix='/devices', tags=['Devices'])
+    application.include_router(equipment.router, prefix='/equip', tags=['Equipment'])
+    application.include_router(item.router, prefix='/items', tags=['Items'])
+    application.include_router(nlp.router, prefix='/nlp-service', tags=['NLP'])
+    application.include_router(positioning.router, prefix='/positioning-service', tags=['Positioning Service'])
+    application.include_router(space.router, prefix='/room', tags=['Spaces'])
+    application.include_router(targets.router, prefix='/target', tags=['Targets'])
+    application.include_router(user.router, prefix='/users', tags=['Users'])
 
     return application
 
 
 app = get_application()
 
-
 if __name__ == '__main__':
     uvicorn.run(app, host='0.0.0.0', port=8000)

+ 13 - 0
app/models/domain/location.py

@@ -0,0 +1,13 @@
+from typing import Optional
+
+from pydantic import BaseModel
+
+
+class PositionResponseBase(BaseModel):
+    result: str
+    userId: Optional[str]
+
+
+class PositionSpaceResponse(PositionResponseBase):
+    spaceId: Optional[str]
+    projectId: Optional[str]

+ 4 - 2
app/services/platform.py

@@ -284,12 +284,14 @@ class DataPlatformService(Service):
         url = self._base_url.join('data-platform-3/object/subset_query')
         params = self._common_parameters()
         payload = {
+            'customInfo': True,
             'criteria': {
                 'type': [code]
             }
         }
 
         raw_info = await self._post(url, params, payload)
-        items_id_list = [item['id'] for item in raw_info['Content']]
+        items = raw_info.get('Content')
+        results = items if items else []
 
-        return items_id_list
+        return results

+ 0 - 0
app/services/tencent_nlp.py