About me
home
Portfolio
home
🌦️

6 Historical data on World map 실습

본 FIWARE tutorial의 마지막 내용이다.
World map을 사용해 디바이스가 보낸 정보를 지도에 나타내보는 시각화 과정에 대해 알아보자.
전체적인 내용은 5장 Historical data of Custom FIWARE와 동일하다.
다만 location에 대한 내용과 Grafana를 추가한 버전이라고 생각하면 된다.
1.
로컬 서비스 프로비저닝
curl -iX POST 'http://localhost:4041/iot/services' \ -H 'fiware-service: youngCustomDevice' \ -H 'fiware-servicepath: /escTest' \ -H 'Content-Type: application/json' \ --data-raw '{ "services": [ { "apikey": "rtestaeyoungtest0818", "cbroker": "http://orion:1026", "entity_type": "Device", "timezone": "Asia/Seoul", "resource": "/iot/d", "attributes": [ { "object_id": "t", "type": "Property", "name": "acoustic", "metadata": { "unitCode": {"type": "Property", "value": "PER" }} }, { "object_id": "argmax", "name": "max", "type": "Float" }, { "object_id": "c1", "name": "class1", "type": "Float" }, { "object_id": "c2", "name": "class2", "type": "Float" }, { "object_id": "c3", "name": "class3", "type": "Float" }, { "object_id": "c4", "name": "class4", "type": "Float" }, { "object_id": "c5", "name": "class5", "type": "Float" }, { "object_id": "c6", "name": "class6", "type": "Float" }, { "object_id": "c7", "name": "class7", "type": "Float" }, { "object_id": "c8", "name": "class8", "type": "Float" }, { "object_id": "c9", "name": "class9", "type": "Float" }, { "object_id": "c10", "name": "class10", "type": "Float" } ], "static_attributes": [ { "name": "category", "type": "Property", "value": "sensor" }, { "name": "supportedProtocol", "type": "Property", "value": "ul20" } ] } ] }'
JavaScript
복사
서비스 프로비저닝 결과 확인한다.
curl -X GET \ 'http://localhost:4041/iot/services' \ -H 'fiware-service: youngCustomDevice' \ -H 'fiware-servicepath: /escTest' | python3 -m json.tool
JavaScript
복사
{ "count": 1, "services": [ { "commands": [], "lazy": [], "attributes": [ { "object_id": "t", "type": "Property", "name": "acoustic", "metadata": { "unitCode": { "type": "Property", "value": "PER" } } }, { "object_id": "argmax", "name": "max", "type": "Float" }, { "object_id": "c1", "name": "class1", "type": "Float" }, { "object_id": "c2", "name": "class2", "type": "Float" }, { "object_id": "c3", "name": "class3", "type": "Float" }, { "object_id": "c4", "name": "class4", "type": "Float" }, { "object_id": "c5", "name": "class5", "type": "Float" }, { "object_id": "c6", "name": "class6", "type": "Float" }, { "object_id": "c7", "name": "class7", "type": "Float" }, { "object_id": "c8", "name": "class8", "type": "Float" }, { "object_id": "c9", "name": "class9", "type": "Float" }, { "object_id": "c10", "name": "class10", "type": "Float" } ], "_id": "636b4d3882a8c05de2936ef4", "resource": "/iot/d", "apikey": "rtestaeyoungtest0818", "service": "youngcustomdevice", "subservice": "/escTest", "timezone": "Asia/Seoul", "__v": 0, "static_attributes": [ { "name": "category", "type": "Property", "value": "sensor" }, { "name": "supportedProtocol", "type": "Property", "value": "ul20" } ], "internal_attributes": [], "entity_type": "Device" } ] }
JavaScript
복사
2.
Device 프로비져닝
Raspberry Pi에서 디바이스를 등록하자.
curl -L -X POST 'http://172.16.63.209:4041/iot/devices' \ -H 'fiware-service: youngcustomdevice' \ -H 'fiware-servicepath: /escTest' \ -H 'Content-Type: application/json' \ --data-raw '{ "devices": [ { "device_id": "acoustic01", "entity_name": "urn:ngsi-ld:Device:acoustic02", "entity_type": "Device", "timezone": "Asia/Seoul", "attributes": [ { "object_id": "t", "name": "acoustic", "type": "Property", "metadata": { "unitCode": { "type": "Property", "value": "PER" } } } ], "static_attributes": [ {"name": "category", "type":"Property", "value": ["sensor"]}, {"name": "supportedProtocol", "type": "Property", "value": ["ul20"]}, {"name": "latitude", "type": "Float", "value": 37.585384}, {"name": "longtitude", "type": "Float", "value": 127.057310} ] } ] }'
JavaScript
복사
아래 코드를 서버에서 실행해 확인한다.
curl -L -X GET 'http://localhost:1026/ngsi-ld/v1/entities/?type=Device' \ -H 'NGSILD-Tenant: youngcustomdevice' \ -H 'NGSILD-Path: /escTest' \ -H 'Link: <http://context/ngsi-context.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"' | python3 -m json.tool
JavaScript
복사
아래와 같은 결과가 나오면 성공이다.
{ "id": "urn:ngsi-ld:Device:acoustic02", "type": "Device", "latitude": { "type": "Property", "value": 37.585384 }, "longtitude": { "type": "Property", "value": 127.05731 }, "category": { "type": "Property", "value": "sensor" }, "supportedProtocol": { "type": "Property", "value": "ul20" } }
JavaScript
복사
c.
Setting up subscriptions
Subscriptions 등록을 처리해주자.
attributes는 간단하게 등록하기 위해 latitude, longtitude, max만 사용하며 다른 값을 넣어도 상관없다.
curl -L -X POST 'http://localhost:1026/ngsi-ld/v1/subscriptions/' \ -H 'Content-Type: application/ld+json' \ -H 'NGSILD-Tenant: youngCustomDevice' \ --data-raw '{ "description": "Classification result from Pi", "type": "Subscription", "entities": [{"type": "Device"}], "watchedAttributes": ["latitude", "longtitude", "max"], "notification": { "attributes": ["latitude", "longtitude", "max"], "format": "normalized", "endpoint": { "uri": "http://quantumleap:8668/v2/notify", "accept": "application/json" } }, "@context": "http://context/ngsi-context.jsonld" }'
JavaScript
복사
정상 등록을 아래 코드로 확인한다.
curl -X GET \ 'http://localhost:1026/ngsi-ld/v1/subscriptions/' \ -H 'NGSILD-Tenant: youngCustomDevice' | python3 -m json.tool
JavaScript
복사
아래와 같은 결과가 나오면 문제없이 동작한다.
{ "id": "urn:ngsi-ld:Subscription:fc0a1648-6023-11ed-8753-0242ac120006", "type": "Subscription", "description": "Classification result from Pi", "entities": [ { "type": "https://uri.fiware.org/ns/data-models#Device" } ], "watchedAttributes": [ "latitude", "longtitude", "max" ], "status": "active", "isActive": true, "notification": { "attributes": [ "latitude", "longtitude", "max" ], "format": "normalized", "endpoint": { "uri": "http://quantumleap:8668/v2/notify", "accept": "application/json" }, "status": "ok", "timesSent": 2, "lastNotification": "2022-11-09T12:04:28.027Z", "lastSuccess": "2022-11-09T12:04:28.028Z" } }
JavaScript
복사
4.
데이터 추가
실제 데이터를 추가하면서 정상 동작을 검증해보자.
아래 코드를 라즈베리파이에서 실행해 서버로 데이터를 전송하자.
5장에서도 언급했지만 모든 ip주소는 자신이 구축한 서버로 변경해서 진행해야한다.
curl -L -X POST 'http://172.16.63.209:7896/iot/d?k=rtestaeyoungtest0818&i=acoustic02' \ -H 'Content-Type: text/plain' \ --data-raw 'argmax|0.8|c1|0.2|c2|0.4|c3|0.6|c4|0.8|c5|1.0|c6|1.2|c7|1.4|c8|1.6|c9|1.8|c10|2.0'
JavaScript
복사
curl -L -X POST 'http://172.16.63.209:7896/iot/d?k=rtestaeyoungtest0818&i=acoustic01' \ -H 'Content-Type: text/plain' \ --data-raw 'c1|0.3|c2|0.2|c3|0.5|c4|0.7|c5|0.8|c6|1.4|c7|1.2|c8|1.4|c9|1.4|c10|2.5'
JavaScript
복사
curl -L -X POST 'http://172.16.63.209:7896/iot/d?k=rtestaeyoungtest0818&i=acoustic01' \ -H 'Content-Type: text/plain' \ --data-raw 'c1|0.7|c2|0.5|c3|0.4|c4|0.5|c5|0.4|c6|1.6|c7|1.1|c8|1.0|c9|1.3|c10|2.0'
JavaScript
복사
curl -L -X POST 'http://172.16.63.209:7896/iot/d?k=rtestaeyoungtest0818&i=acoustic01' \ -H 'Content-Type: text/plain' \ --data-raw 'c1|0.8|c2|0.6|c3|0.3|c4|0.4|c5|0.5|c6|1.5|c7|1.0|c8|1.1|c9|1.1|c10|1.8'
JavaScript
복사
curl -L -X POST 'http://172.16.63.209:7896/iot/d?k=rtestaeyoungtest0818&i=acoustic01' \ -H 'Content-Type: text/plain' \ --data-raw 'c1|0.5|c2|0.8|c3|0.1|c4|0.5|c5|0.7|c6|1.0|c7|0.8|c8|1.2|c9|1.5|c10|1.5'
JavaScript
복사
이때 값을 여러개로 바꾸면서 서로 다른 데이터를 5번 정도 전송하자.
이제 QuantumLeap에서 들어온 데이터가 정상적으로 crate db에 들어갔는지 확인해보자.
5.
Grafana 시각화
grafana 시각화를 진행하자.
위 주소로 들어가서 로그인한다. 초기 아이디/비밀번호는 admin/admin이다.
이때 crate db를 함께 사용하면 편하니 5장의 매뉴얼을 보고 crate db도 함께 세팅하자.
이어지는 설명의 앞부분 역시 5장의 내용과 겹치는 부분이 있으니 복습한다 생각하고 같이 진행하자.
먼저 Grafana에 DB를 등록한다.
이어서 대쉬보드를 만들자.
좌측 + 버튼을 누르고 dashboard를 누르자. 그리고 choose visualization을 누르고 worldmap panel을 선택한다.
이후 일단은 월드맵 패널은 추가 설정 없이 좌측에서 queries를 누른다. 헷갈릴 수 있으니 아래 그림에 빨강으로 표시한다.
여기서 우리가 사용할 DB의 쿼리문을 작성해준다.
아래 format을 Table로 함에 유의하자.
이제 db를 등록했으니 지도로 넘어가서 아래 그림처럼 세팅해준다.
Location data를 table로 설정하고 아래 필드 매핑에서 coordinates로 바꿔 좌표를 통해 위치를 알려주는 방식이다.
잘 안보일 수 있으니 Map data options를 따로 올린다.
Threshold는 값이 세기를 3단계로 설정하는데 그 중간 바운더리를 말한다. 바꿔가면서 지도 좌측 아래 신호등 모양 값을 보면 이해할 수 있다.
최종 지도는 아래 그림과 같다. 실험에서 사용한 좌표는 과학기술관의 좌표다(37.585384, 127.05731). 따라서 지도에서 과학기술관을 찾아서 들어가면 볼 수 있다.
DB에 값이 업데이트 되면서 원이 여러개가 겹칠 수 있다. 이 경우 map data options에서 current로 설정해주면 최신 값만 표시가되니 이 점 유의해서 바꾸자.
이렇게 해서 지도에 값을 표시하는 내용까지 마무리했다.
작성된 기본 내용을 바탕으로 다양한 시도를 해보며 자신의 어플리케이션을 발전시키자.

5. Grafana 시각화 부분부터 수행 못함 (23.01.27 김영준)