About me
home
Portfolio
home
🎆

2 Time series 실습

Persisting and Querying Time Series Data(CrateDB)
1.
기본 GE
FIWARE QuantumLeap
time-based data-persistence GE로 시계열 데이터를 유지하고 query하기 위해 사용된다.
NGSI-V2와 NGSI-LD 모두 호환된다.
CrateDB
Distributed SQL DBMS for IoT
많은 수의 data point에서 데이터를 받을 수 있으며 실시간 query가 가능하다.
Historic data 검색을 통해 그래프 및 dash board 생성과 시각화가 가능하다.
2.
Analyzing time series data
시계열 데이터의 분석은 사용자의 응용 특성과 측정 데이터의 특성에 따라 달라진다.
일반적으로 사용되는 시계열 데이터 분석은 아래와 같다.
특정 시간 간격 안에서 최대 측정값 도출
특성 시간 간격 안에서 측정값의 평균 도출
특정 시간 간격 안에서 측정값이 합 도출
Grafana
오픈소스 시계열 분석 툴
3.
튜토리얼 사용 모듈 정리
Orion Context Broker(OCB)
IoT Agent for UltraLight 2.0(IA)
QuantumLeap
MongoDB
CrateDB
hold time-based historical context data
HTTP endpoint를 제공한다
OCB가 QuantumLeap에 데이터를 전송하면 이를 CrateDB에 저장하고 Grafana는 CrateDB에 접근해 데이터 받아 분석 진행
Docker를 실행했는데 CrateDB가 실행되지 않는 경우
windows를 쓰고있을 가능성이 크다. 이 경우 wsl2를 위한 virtual memory를 너무 작게 할당해줘서 그러니 이를 키워주자.
$ sudo vim /etc/sysctl.conf
들어가서 아래 문구를 추가해주고 나온다
vm.max_map_count=262144
$ sudo sysctl -p
Connecting FIWARE to a CrateDB database via QuantumLeap
1.
모듈 설정
QuantumLeap는 8668 포트를 통해 OCB로 부터 NGSI-LD notification을 listen하고 있다.
CrateDB는 4200 포트를 통해 접근 가능하며 직접 접근하거나 grafana 툴과 연결해 사용한다.
2.
Setting up Subscriptions
QuantumLeap에 직접적으로 context의 변화를 알려줘야 하며 이는 OCB로 전달한다.
먼저 경작시설에서 filling event를 살펴보자. Filling sensor가 채움의 정도를 측정하며 실제 세상의 이벤트를 전달해 준다고 생각하자. 우리는 모든 이벤트를 받아서 처리해야 한다.
이는 OCB의 /ngsi/ld/subscriptions/ endpoint에 POST request를 통해 처리할 수 있다.
NGSILD-Tenant 헤더는 fiware-service 헤더와 유사하다. 다만 subscription에서는 특정 IoT sensor에서 부터만 정보를 listen하는 filtering에 사용한다.
entities type: request body에 있으며 QuentumLeap이 특정 센서(FillingLevelSensor)의 데이터 변화를 전달받음을 보장하게 한다.
notification URL: 사용하는 포트와 꼭 일치해야 한다.
NGSI-LD의 경우 측정 값의 timestamp는 observedAt property가 갖고있다. CrateDB의 time_index column은 매치되는 데이터를 MongoDB의 observedAt 항목을 참조하여 할당하지 CrateDB에서 만들어진 시간을 사용하지 않는다.
curl -L -X POST 'http://localhost:1026/ngsi-ld/v1/subscriptions/' \ -H 'Content-Type: application/ld+json' \ -H 'NGSILD-Tenant: openiot' \ --data-raw '{ "description": "Notify me of all feedstock changes", "type": "Subscription", "entities": [{"type": "FillingLevelSensor"}], "watchedAttributes": ["filling"], "notification": { "attributes": ["filling", "location"], "format": "normalized", "endpoint": { "uri": "http://quantumleap:8668/v2/notify", "accept": "application/json" } }, "@context": "http://context/ngsi-context.jsonld" }'
JavaScript
복사
코드를 보면 endpoint /ngsi-ld/v1/subscriptions/ 에 POST로 등록을 함을 볼 수 있다. openiot를 NGSILD-Tenant로 할당하고 type은 subscription으로 할당한다.
이제 GPS 값을 읽는 경우를 살펴보자.
경작 시설의 경우 동물의 목줄에서 심박수와 GPS를 읽는 경우가 있으며 이 값은 지속적으로 바뀌는 값이다. 역시 /ngsi-ld/v1/subscriptions/ endpoint를 사용하며 request에 throttling 속성을 추가해준다.
NGSILD-Tenant 헤더는 fiware-service 헤더와 유사하다. 다만 subscription에서는 특정 IoT sensor에서 부터만 정보를 listen하는 filtering에 사용한다.
entities type: request body에 있으며 QuentumLeap이 특정 센서(FillingLevelSensor)의 데이터 변화를 전달받음을 보장하게 한다.
notification URL: 사용하는 포트와 꼭 일치해야 한다.
throttling: 측정 데이터 변화의 샘플링 rate를 의미한다
curl -L -X POST 'http://localhost:1026/ngsi-ld/v1/subscriptions/' \ -H 'Content-Type: application/ld+json' \ -H 'NGSILD-Tenant: openiot' \ --data-raw '{ "description": "Notify me of animal locations", "type": "Subscription", "entities": [{"type": "Device"}], "watchedAttributes": ["location", "status", "heartRate"], "notification": { "attributes": ["location", "status", "heartRate"], "format": "normalized", "endpoint": { "uri": "http://quantumleap:8668/v2/notify", "accept": "application/json" } }, "throttling": 10, "@context": "http://context/ngsi-context.jsonld" }'
JavaScript
복사
전체적으로 앞의 filling sensor와 같다. 다른 점은 notification attributes에 status가 추가된 점, 그리고 throttling이 추가된 점이다.
이제 등록한 subscription이 정상적으로 동작하는지 확인해보자.
curl -X GET \ 'http://localhost:1026/ngsi-ld/v1/subscriptions/' \ -H 'NGSILD-Tenant: openiot' | python -m json.tool
JavaScript
복사
정상적으로 출력됨을 볼 수 있다.
Time Series Data Queries(QuantumLeap API)
실행중인 QuantumLeap에 접근은 http://localhost:8668/v2/ui 를 통해 가능하다.
이제 QuantumLeap가 데이터를 유지하고있음을 query를 통해 확인해보자. filling001 센서에서 첫 3개의 값을 쿼리한다.
curl -X GET \ 'http://localhost:8668/v2/entities/urn:ngsi-ld:Device:filling001/attrs/filling?limit=3' \ -H 'Accept: application/json' \ -H 'Fiware-Service: openiot' \ -H 'Fiware-ServicePath: /'
JavaScript
복사
limit=3을 통해 첫 3개의 입력만을 받아 아래와 같은 결과가 나온다
{ "attrName": "filling", "entityId": "urn:ngsi-ld:Device:filling001", "index": [ "2022-05-25T01:33:41.178+00:00", "2022-05-25T01:33:41.178+00:00", "2022-05-25T01:33:41.375+00:00" ], "values": [ 0.99, 0.99, 0.99 ] }
JavaScript
복사
만약 결과가 안나오고 "No records were found for such query.” 이런 에러가 발생한다면 http://localhost:3000/app/farm/urn:ngsi-ld:Building:farm001 들어가서 fillingsensor에 변화를 줘보자.
이제 3개의 연속된 값이 아닌 offset을 주고 출력을 해보자.
curl -X GET \ 'http://localhost:8668/v2/entities/urn:ngsi-ld:Device:filling001/attrs/filling?offset=3&limit=3' \ -H 'Accept: application/json' \ -H 'Fiware-Service: openiot' \ -H 'Fiware-ServicePath: /'
JavaScript
복사
3의 offset을 가지고 데이터가 출력될 것이다.
{ "attrName": "filling", "entityId": "urn:ngsi-ld:Device:filling001", "index": [ "2022-05-25T01:33:41.773+00:00", "2022-05-25T01:33:41.791+00:00", "2022-05-25T01:33:42.177+00:00" ], "values": [ 1.0, 1.0, 0.98 ] }
JavaScript
복사
이제 전체 데이터의 합을 구해보자. 분단위로 최근 3분 동안의 합을 하는 경우 아래 코드를 실행하자.
curl -X GET \ 'http://localhost:8668/v2/entities/urn:ngsi-ld:Device:filling001/attrs/filling?aggrMethod=count&aggrPeriod=minute&lastN=3' \ -H 'Accept: application/json' \ -H 'Fiware-Service: openiot' \ -H 'Fiware-ServicePath: /'
JavaScript
복사
만약 시간 단위로 합하고 싶다면 minute을 hour로 바꿔주고 lastN=3을 사용하지 않는 경우 지워도 괜찮다.
Time Series Data Queries(CrateDB API)
지금까지는 QuantumLeap를 통해 CrateDB에 접근해 데이터를 얻었다. 이제 CrateDB에 직접 접근을 해보자. 역시 CrateDB의 endpoint로 접근하면 되는데 <servername:port>/_sql로 접근하자.
Accessing Time Series Data Programmatically
QuanromLeap은 좋은 툴이지만 graphical하지는 않다. 따라서 wirecloud, knowage와 같은 dashboard 요소와 함께 사용해야 한다.
우리가 CrateDB로 지금까지 실습을 진행한 이유는 Grafana와 호환성이 좋기 때문이다. Grafana는 sensor data 전체를 시각화하는데 매우 좋은 툴이다.