황원재 황원재 2 days ago
edgex
@dbef5997778a8ebd4d7705f86cd8a0ce0ef9370b
 
edgex/Edge-X_3.1.postman_collection.json (added)
+++ edgex/Edge-X_3.1.postman_collection.json
@@ -0,0 +1,189 @@
+{
+	"info": {
+		"_postman_id": "2a12e246-acc0-4fe5-950b-430ac62ee60e",
+		"name": "Edge-X 3.1",
+		"schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json",
+		"_exporter_id": "15354547"
+	},
+	"item": [
+		{
+			"name": "ping",
+			"request": {
+				"method": "GET",
+				"header": [
+					{
+						"key": "Content-Type",
+						"value": "application/json",
+						"type": "text"
+					}
+				],
+				"url": "http://edgex_ip:59880/api/v3/ping"
+			},
+			"response": []
+		},
+		{
+			"name": "Create Device Profile",
+			"request": {
+				"method": "POST",
+				"header": [
+					{
+						"key": "Content-Type",
+						"value": "application/json",
+						"type": "text",
+						"disabled": true
+					}
+				],
+				"body": {
+					"mode": "formdata",
+					"formdata": [
+						{
+							"key": "file",
+							"type": "file",
+							"src": "/home/hwj/snap/postman/248/Postman/files/sensorClusterDeviceProfile.yaml"
+						}
+					]
+				},
+				"url": "http://edgex_ip:59881/api/v3/deviceprofile/uploadfile"
+			},
+			"response": []
+		},
+		{
+			"name": "Device Profile All",
+			"request": {
+				"method": "GET",
+				"header": [
+					{
+						"key": "Content-Type",
+						"value": "application/json",
+						"type": "text"
+					}
+				],
+				"url": "http://edgex_ip:59881/api/v3/deviceprofile/all"
+			},
+			"response": []
+		},
+		{
+			"name": "Device Profile",
+			"request": {
+				"method": "GET",
+				"header": [],
+				"url": "http://edgex_ip:59881/api/v3/deviceprofile/name/SensorCluster"
+			},
+			"response": []
+		},
+		{
+			"name": "Create Device",
+			"request": {
+				"method": "POST",
+				"header": [
+					{
+						"key": "Content-Type",
+						"value": "application/json",
+						"type": "text"
+					}
+				],
+				"body": {
+					"mode": "raw",
+					"raw": "    [\n        {\n            \"apiVersion\" : \"v3\",\n            \"device\": {\n                \"name\": \"Temp_and_Humidity_sensor_cluster_01\",\n                \"description\": \"VORA-Kit\",\n                \"adminState\": \"UNLOCKED\",\n                \"operatingState\": \"UP\",\n                \"labels\": [\n                    \"temperature\",\n                    \"humidity\"\n                ],\n                \"location\": \"Seoul\",\n                \"serviceName\": \"device-rest\",\n                \"profileName\": \"SensorCluster\",\n                \"protocols\": {\n                    \"example\": {\n                        \"host\": \"dummy\",\n                        \"port\": \"1234\",\n                        \"unitID\": \"1\"\n                    }\n                }\n            }\n        }\n    ]",
+					"options": {
+						"raw": {
+							"language": "json"
+						}
+					}
+				},
+				"url": "http://edgex_ip:59881/api/v3/device"
+			},
+			"response": []
+		},
+		{
+			"name": "Device All",
+			"request": {
+				"method": "GET",
+				"header": [],
+				"url": "http://edgex_ip:59881/api/v3/device/all"
+			},
+			"response": []
+		},
+		{
+			"name": "Device",
+			"request": {
+				"method": "GET",
+				"header": [],
+				"url": "http://edgex_ip:59881/api/v3/device/name/Temp_and_Humidity_sensor_cluster_01"
+			},
+			"response": []
+		},
+		{
+			"name": "Temperature Test",
+			"request": {
+				"method": "POST",
+				"header": [],
+				"body": {
+					"mode": "raw",
+					"raw": "30",
+					"options": {
+						"raw": {
+							"language": "json"
+						}
+					}
+				},
+				"url": "http://edgex_ip:59986/api/v3/resource/Temp_and_Humidity_sensor_cluster_01/temperature"
+			},
+			"response": []
+		},
+		{
+			"name": "Reading event count",
+			"request": {
+				"method": "GET",
+				"header": [],
+				"url": "http://edgex_ip:59880/api/v3/event/count/device/name/Temp_and_Humidity_sensor_cluster_01"
+			},
+			"response": []
+		},
+		{
+			"name": "Reading Sensor data",
+			"request": {
+				"method": "GET",
+				"header": [],
+				"url": "http://edgex_ip:59880/api/v3/reading/device/name/Temp_and_Humidity_sensor_cluster_01"
+			},
+			"response": []
+		},
+		{
+			"name": "Create Streams",
+			"request": {
+				"method": "POST",
+				"header": [],
+				"body": {
+					"mode": "raw",
+					"raw": "{\n    \"sql\": \"create stream edgex_tutorial() WITH (FORMAT=\\\"JSON\\\", TYPE=\\\"edgex\\\")\"\n}",
+					"options": {
+						"raw": {
+							"language": "json"
+						}
+					}
+				},
+				"url": "http://edgex_ip:59720/streams"
+			},
+			"response": []
+		},
+		{
+			"name": "Create Rules - temphum",
+			"request": {
+				"method": "POST",
+				"header": [],
+				"body": {
+					"mode": "raw",
+					"raw": "{\n    \"id\": \"temphum\",\n    \"sql\": \"SELECT * FROM edgex_tutorial\",\n    \"actions\": [\n        {\n        \"mqtt\": {\n            \"server\": \"tcp://192.168.0.11:30100\",\n            \"topic\": \"temphum\"\n        }\n    },\n    {\n        \"log\":{}\n    }\n    ]\n}",
+					"options": {
+						"raw": {
+							"language": "json"
+						}
+					}
+				},
+				"url": "http://edgex_ip:59720/rules"
+			},
+			"response": []
+		}
+	]
+}(파일 끝에 줄바꿈 문자 없음)
 
edgex/Temp_Hum_Sensor.py (added)
+++ edgex/Temp_Hum_Sensor.py
@@ -0,0 +1,37 @@
+import sys, time, requests, json
+import Adafruit_DHT
+
+sensor = Adafruit_DHT.DHT11
+pin = 2
+
+edgexip = "blueshift.xslab.co.kr"
+edgexfort ="9797"
+
+try:
+
+    while True :
+
+        rawHum, rawTemp = Adafruit_DHT.read_retry(sensor, pin)
+
+        if rawHum is not None and rawTemp is not None :
+
+            urlTemp = 'http://%s:%s/api/v1/resource/Temp_and_Humidity_sensor_cluster_01/temperature' % (edgexip, edgexfort)
+            urlHum  = 'http://%s:%s/api/v1/resource/Temp_and_Humidity_sensor_cluster_01/humidity' % (edgexip, edgexfort)
+
+            humval = str(rawHum)
+            tempval = str(rawTemp)
+
+            headers = {'content-type': 'application/json'}
+            response = requests.post(urlTemp, data=json.dumps(int(rawTemp)), headers=headers,verify=False)
+            response = requests.post(urlHum, data=json.dumps(int(rawHum)), headers=headers,verify=False)
+
+            print("Temp: %s\N{DEGREE SIGN}C, humidity: %s%%" % (tempval, humval))
+
+        else :
+            print('Read error')
+            time.sleep(100)
+except KeyboardInterrupt:
+    print("Terminated by Keyboard")
+
+finally:
+    print("End of Program")
 
edgex/docker-compose.yml (added)
+++ edgex/docker-compose.yml
@@ -0,0 +1,488 @@
+#  * Copyright 2023 Intel Corporation.
+#  *
+#  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+#  * in compliance with the License. You may obtain a copy of the License at
+#  *
+#  * http://www.apache.org/licenses/LICENSE-2.0
+#  *
+#  * Unless required by applicable law or agreed to in writing, software distributed under the License
+#  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+#  * or implied. See the License for the specific language governing permissions and limitations under
+#  * the License.
+#  *
+#  * EdgeX Foundry, Napa release
+#  *******************************************************************************/
+#
+#
+#
+# ************************ This is a generated compose file ****************************
+#
+# DO NOT MAKE CHANGES that are intended to be permanent to EdgeX edgex-compose repo.
+#
+# Permanent changes can be made to the source compose files located in the compose-builder folder
+# at the top level of the edgex-compose repo.
+#
+# From the compose-builder folder use `make build` to regenerate all standard compose files variations
+#
+name: edgex
+services:
+  app-rules-engine:
+    container_name: edgex-app-rules-engine
+    depends_on:
+      consul:
+        condition: service_started
+      core-data:
+        condition: service_started
+    environment:
+      EDGEX_PROFILE: rules-engine
+      EDGEX_SECURITY_SECRET_STORE: "false"
+      SERVICE_HOST: edgex-app-rules-engine
+    hostname: edgex-app-rules-engine
+    image: registry.xslab.co.kr/lecture/docker-app-service-configurable-arm64:3.1.0
+    networks:
+      edgex-network: null
+    ports:
+    - mode: ingress
+      host_ip: 0.0.0.0
+      target: 59701
+      published: "59701"
+      protocol: tcp
+    read_only: true
+    restart: always
+    security_opt:
+    - no-new-privileges:true
+    user: 2002:2001
+    volumes:
+    - type: bind
+      source: /etc/localtime
+      target: /etc/localtime
+      read_only: true
+      bind:
+        create_host_path: true
+  consul:
+    command:
+    - agent
+    - -ui
+    - -bootstrap
+    - -server
+    - -client
+    - 0.0.0.0
+    container_name: edgex-core-consul
+    hostname: edgex-core-consul
+    image: registry.xslab.co.kr/lecture/docker-edgex-consul-arm64:1.16.2
+    networks:
+      edgex-network: null
+    ports:
+    - mode: ingress
+      host_ip: 0.0.0.0
+      target: 8500
+      published: "8500"
+      protocol: tcp
+    read_only: true
+    restart: always
+    security_opt:
+    - no-new-privileges:true
+    user: root:root
+    volumes:
+    - type: volume
+      source: consul-config
+      target: /consul/config
+      volume: {}
+    - type: volume
+      source: consul-data
+      target: /consul/data
+      volume: {}
+  core-command:
+    container_name: edgex-core-command
+    depends_on:
+      consul:
+        condition: service_started
+      core-metadata:
+        condition: service_started
+      database:
+        condition: service_started
+    environment:
+      EDGEX_SECURITY_SECRET_STORE: "false"
+      EXTERNALMQTT_URL: tcp://edgex-mqtt-broker:1883
+      SERVICE_HOST: edgex-core-command
+    hostname: edgex-core-command
+    image: registry.xslab.co.kr/lecture/docker-core-command-go-arm64:3.1.0
+    networks:
+      edgex-network: null
+    ports:
+    - mode: ingress
+      host_ip: 0.0.0.0
+      target: 59882
+      published: "59882"
+      protocol: tcp
+    read_only: true
+    restart: always
+    security_opt:
+    - no-new-privileges:true
+    user: 2002:2001
+    volumes:
+    - type: bind
+      source: /etc/localtime
+      target: /etc/localtime
+      read_only: true
+      bind:
+        create_host_path: true
+  core-common-config-bootstrapper:
+    container_name: edgex-core-common-config-bootstrapper
+    depends_on:
+      consul:
+        condition: service_started
+    environment:
+      ALL_SERVICES_DATABASE_HOST: edgex-redis
+      ALL_SERVICES_MESSAGEBUS_HOST: edgex-redis
+      ALL_SERVICES_REGISTRY_HOST: edgex-core-consul
+      APP_SERVICES_CLIENTS_CORE_METADATA_HOST: edgex-core-metadata
+      DEVICE_SERVICES_CLIENTS_CORE_METADATA_HOST: edgex-core-metadata
+      EDGEX_SECURITY_SECRET_STORE: "false"
+    hostname: edgex-core-common-config-bootstrapper
+    image: registry.xslab.co.kr/lecture/docker-core-common-config-bootstrapper-go-arm64:3.1.0
+    networks:
+      edgex-network: null
+    read_only: true
+    security_opt:
+    - no-new-privileges:true
+    user: 2002:2001
+    volumes:
+    - type: bind
+      source: /etc/localtime
+      target: /etc/localtime
+      read_only: true
+      bind:
+        create_host_path: true
+  core-data:
+    container_name: edgex-core-data
+    depends_on:
+      consul:
+        condition: service_started
+      core-metadata:
+        condition: service_started
+      database:
+        condition: service_started
+    environment:
+      EDGEX_SECURITY_SECRET_STORE: "false"
+      SERVICE_HOST: edgex-core-data
+    hostname: edgex-core-data
+    image: registry.xslab.co.kr/lecture/docker-core-data-go-arm64:3.1.0
+    networks:
+      edgex-network: null
+    ports:
+    - mode: ingress
+      host_ip: 0.0.0.0
+      target: 59880
+      published: "59880"
+      protocol: tcp
+    read_only: true
+    restart: always
+    security_opt:
+    - no-new-privileges:true
+    user: 2002:2001
+    volumes:
+    - type: bind
+      source: /etc/localtime
+      target: /etc/localtime
+      read_only: true
+      bind:
+        create_host_path: true
+  core-metadata:
+    container_name: edgex-core-metadata
+    depends_on:
+      consul:
+        condition: service_started
+      database:
+        condition: service_started
+    environment:
+      EDGEX_SECURITY_SECRET_STORE: "false"
+      SERVICE_HOST: edgex-core-metadata
+    hostname: edgex-core-metadata
+    image: registry.xslab.co.kr/lecture/docker-core-metadata-go-arm64:3.1.0
+    networks:
+      edgex-network: null
+    ports:
+    - mode: ingress
+      host_ip: 0.0.0.0
+      target: 59881
+      published: "59881"
+      protocol: tcp
+    read_only: true
+    restart: always
+    security_opt:
+    - no-new-privileges:true
+    user: 2002:2001
+    volumes:
+    - type: bind
+      source: /etc/localtime
+      target: /etc/localtime
+      read_only: true
+      bind:
+        create_host_path: true
+  database:
+    container_name: edgex-redis
+    hostname: edgex-redis
+    image: registry.xslab.co.kr/lecture/redis:7.0.14
+    networks:
+      edgex-network: null
+    ports:
+    - mode: ingress
+      host_ip: 0.0.0.0
+      target: 6379
+      published: "6379"
+      protocol: tcp
+    read_only: true
+    restart: always
+    security_opt:
+    - no-new-privileges:true
+    user: root:root
+    volumes:
+    - type: volume
+      source: db-data
+      target: /data
+      volume: {}
+  device-rest:
+    container_name: edgex-device-rest
+    depends_on:
+      consul:
+        condition: service_started
+      core-data:
+        condition: service_started
+      core-metadata:
+        condition: service_started
+    environment:
+      EDGEX_SECURITY_SECRET_STORE: "false"
+      SERVICE_HOST: edgex-device-rest
+    hostname: edgex-device-rest
+    image: registry.xslab.co.kr/lecture/docker-device-rest-go-arm64:3.1.0
+    networks:
+      edgex-network: null
+    ports:
+    - mode: ingress
+      host_ip: 0.0.0.0
+      target: 59986
+      published: "59986"
+      protocol: tcp
+    read_only: true
+    restart: always
+    security_opt:
+    - no-new-privileges:true
+    user: 2002:2001
+    volumes:
+    - type: bind
+      source: /etc/localtime
+      target: /etc/localtime
+      read_only: true
+      bind:
+        create_host_path: true
+#  device-virtual:
+#    container_name: edgex-device-virtual
+#    depends_on:
+#      consul:
+#        condition: service_started
+#      core-data:
+#        condition: service_started
+#      core-metadata:
+#        condition: service_started
+#    environment:
+#      EDGEX_SECURITY_SECRET_STORE: "false"
+#      SERVICE_HOST: edgex-device-virtual
+#    hostname: edgex-device-virtual
+#    image: edgexfoundry/device-virtual-arm64:3.1.0
+#    networks:
+#      edgex-network: null
+#    ports:
+#    - mode: ingress
+#      host_ip: 0.0.0.0
+#      target: 59900
+#      published: "59900"
+#      protocol: tcp
+#    read_only: true
+#    restart: always
+#    security_opt:
+#    - no-new-privileges:true
+#    user: 2002:2001
+#    volumes:
+#    - type: bind
+#      source: /etc/localtime
+#      target: /etc/localtime
+#      read_only: true
+#      bind:
+#        create_host_path: true
+  kuiper-manager:
+    container_name: ekuiper-manager
+    image: registry.xslab.co.kr/lecture/kuiper-manager:1.9.5
+    ports:
+    - "9082:9082"
+    networks:
+      edgex-network: null
+    environment:
+      DEFAULT_EKUIPER_ENDPOINT: "http://edgex-kuiper:59720" 
+  rules-engine:
+    container_name: edgex-kuiper
+    depends_on:
+      database:
+        condition: service_started
+    environment:
+      CONNECTION__EDGEX__REDISMSGBUS__PORT: "6379"
+      CONNECTION__EDGEX__REDISMSGBUS__PROTOCOL: redis
+      CONNECTION__EDGEX__REDISMSGBUS__SERVER: edgex-redis
+      CONNECTION__EDGEX__REDISMSGBUS__TYPE: redis
+      EDGEX__DEFAULT__PORT: "6379"
+      EDGEX__DEFAULT__PROTOCOL: redis
+      EDGEX__DEFAULT__SERVER: edgex-redis
+      EDGEX__DEFAULT__TOPIC: edgex/rules-events
+      EDGEX__DEFAULT__TYPE: redis
+      KUIPER__BASIC__CONSOLELOG: "true"
+      KUIPER__BASIC__RESTPORT: "59720"
+    hostname: edgex-kuiper
+    image: registry.xslab.co.kr/lecture/kuiper:1.11.4
+    networks:
+      edgex-network: null
+    ports:
+    - "9081:9081"
+    - mode: ingress
+      host_ip: 0.0.0.0
+      target: 59720
+      published: "59720"
+      protocol: tcp
+    read_only: true
+    restart: always
+    security_opt:
+    - no-new-privileges:true
+    user: kuiper:kuiper
+    volumes:
+    - type: bind
+      source: /etc/localtime
+      target: /etc/localtime
+      read_only: true
+      bind:
+        create_host_path: true
+    - type: volume
+      source: kuiper-data
+      target: /kuiper/data
+      volume: {}
+    - type: volume
+      source: kuiper-etc
+      target: /kuiper/etc
+      volume: {}
+    - type: volume
+      source: kuiper-log
+      target: /kuiper/log
+      volume: {}
+    - type: volume
+      source: kuiper-plugins
+      target: /kuiper/plugins
+      volume: {}
+  support-notifications:
+    container_name: edgex-support-notifications
+    depends_on:
+      consul:
+        condition: service_started
+      database:
+        condition: service_started
+    environment:
+      EDGEX_SECURITY_SECRET_STORE: "false"
+      SERVICE_HOST: edgex-support-notifications
+    hostname: edgex-support-notifications
+    image: registry.xslab.co.kr/lecture/docker-support-notifications-go-arm64:3.1.0
+    networks:
+      edgex-network: null
+    ports:
+    - mode: ingress
+      host_ip: 0.0.0.0
+      target: 59860
+      published: "59860"
+      protocol: tcp
+    read_only: true
+    restart: always
+    security_opt:
+    - no-new-privileges:true
+    user: 2002:2001
+    volumes:
+    - type: bind
+      source: /etc/localtime
+      target: /etc/localtime
+      read_only: true
+      bind:
+        create_host_path: true
+  support-scheduler:
+    container_name: edgex-support-scheduler
+    depends_on:
+      consul:
+        condition: service_started
+      database:
+        condition: service_started
+    environment:
+      EDGEX_SECURITY_SECRET_STORE: "false"
+      INTERVALACTIONS_SCRUBAGED_HOST: edgex-core-data
+      INTERVALACTIONS_SCRUBPUSHED_HOST: edgex-core-data
+      SERVICE_HOST: edgex-support-scheduler
+    hostname: edgex-support-scheduler
+    image: registry.xslab.co.kr/lecture/docker-support-scheduler-go-arm64:3.1.0
+    networks:
+      edgex-network: null
+    ports:
+    - mode: ingress
+      host_ip: 0.0.0.0
+      target: 59861
+      published: "59861"
+      protocol: tcp
+    read_only: true
+    restart: always
+    security_opt:
+    - no-new-privileges:true
+    user: 2002:2001
+    volumes:
+    - type: bind
+      source: /etc/localtime
+      target: /etc/localtime
+      read_only: true
+      bind:
+        create_host_path: true
+  ui:
+    container_name: edgex-ui-go
+    environment:
+      EDGEX_SECURITY_SECRET_STORE: "false"
+      SERVICE_HOST: edgex-ui-go
+    hostname: edgex-ui-go
+    image: registry.xslab.co.kr/lecture/docker-edgex-ui-go-arm64:3.1.0
+    networks:
+      edgex-network: null
+    ports:
+    - mode: ingress
+      target: 4000
+      published: "4000"
+      protocol: tcp
+    read_only: true
+    restart: always
+    security_opt:
+    - no-new-privileges:true
+    user: 2002:2001
+    volumes:
+    - type: bind
+      source: /etc/localtime
+      target: /etc/localtime
+      read_only: true
+      bind:
+        create_host_path: true
+networks:
+  edgex-network:
+    name: edgex_edgex-network
+    driver: bridge
+volumes:
+  consul-config:
+    name: edgex_consul-config
+  consul-data:
+    name: edgex_consul-data
+  db-data:
+    name: edgex_db-data
+  kuiper-data:
+    name: edgex_kuiper-data
+  kuiper-etc:
+    name: edgex_kuiper-etc
+  kuiper-log:
+    name: edgex_kuiper-log
+  kuiper-plugins:
+    name: edgex_kuiper-plugins
 
edgex/docker-install.sh (added)
+++ edgex/docker-install.sh
@@ -0,0 +1,45 @@
+#! /bin/bash
+# sudo로 실행 필요
+# docker 설치
+
+apt-get update
+apt-get install -y ca-certificates curl gnupg lsb-release
+
+install -m 0755 -d /etc/apt/keyrings
+curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
+chmod a+r /etc/apt/keyrings/docker.asc
+
+echo \
+  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
+  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
+  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
+
+apt-get update
+apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
+
+# Cgroup를 systemd로 설정
+cat > /etc/docker/daemon.json <<EOF
+{
+  "exec-opts": ["native.cgroupdriver=systemd"],
+  "log-driver": "json-file",
+  "log-opts": {
+    "max-size": "100m"
+  },
+  "storage-driver": "overlay2"
+}
+EOF
+
+mkdir -p /etc/systemd/system/docker.service.d
+systemctl daemon-reload
+systemctl restart docker
+sudo systemctl enable docker
+
+# 일반유저 Docker 사용
+usermod -aG docker vraptor
+
+apt-get install -y bash-completion
+
+curl https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker -o /etc/bash_completion.d/docker.sh
+
+apt-get install -y docker-compose
+
 
edgex/random_data_push.py (added)
+++ edgex/random_data_push.py
@@ -0,0 +1,60 @@
+import time, sys, requests, json
+#import board
+#import adafruit_dht
+import random
+
+# 데이터 핀 3번을 사용면, GPIO2로 설정
+#pin = board.D2
+#dhtDevice = adafruit_dht.DHT11(pin)
+
+# EdgeX server ip
+edgexip = "edgex_ip"
+
+while True:
+    try:
+        # 온도 및 습도 값을 읽어옴
+
+        #온도
+        #temperature_c = dhtDevice.temperature
+        temperature_c = random.uniform(35, 40)
+        temperature_f = temperature_c * (9 / 5) + 32
+        
+        #습도
+        #humidity = dhtDevice.humidity
+        humidity = random.uniform(20, 80)
+        
+        print(
+                "온도: {:.1f} F / {:.1f} C    습도: {:.1f} % ".format(
+                temperature_f, temperature_c, humidity
+            )
+        )
+
+        if temperature_c is not None and humidity is not None :
+            urlTemp = 'http://%s:59986/api/v3/resource/Temp_and_Humidity_sensor_cluster_01/temperature' % edgexip
+            urlHum  = 'http://%s:59986/api/v3/resource/Temp_and_Humidity_sensor_cluster_01/humidity' % edgexip
+
+            headers = {'content-type': 'application/json'}
+            response = requests.post(urlTemp, data=json.dumps(int(temperature_c)), headers=headers,verify=False)
+            response = requests.post(urlHum, data=json.dumps(int(humidity)), headers=headers,verify=False)
+
+
+
+
+        else:
+            print('Read error')
+            time.sleep(100)
+
+
+    except RuntimeError as error:
+        # 오류 발생 시 계속 진행
+        print(error.args[0])
+        time.sleep(2.0)
+        continue
+    except Exception as error:
+        # 예기치 않은 오류 시 종료
+        # dhtDevice.exit()
+        print("Unexpected error:", error)
+        sys.exit()
+        raise error
+
+    time.sleep(2.0)
 
edgex/sensorClusterDeviceProfile.yaml (added)
+++ edgex/sensorClusterDeviceProfile.yaml
@@ -0,0 +1,44 @@
+name: "SensorCluster"
+manufacturer: "xslab"
+model: "VORA-Kit"
+labels: 
+- "temperature"
+- "humidity"
+description: "Sensor cluster providing metrics for temperature and humidity"
+
+deviceResources:
+-
+  name: "temperature"
+  isHidden: false  #is hidden is false by default so this is just making it explicit for purpose of the walkthrough demonstration
+  description: "Sensor cluster temperature values"
+  properties:
+    valueType:  "Int64"
+    readWrite: "RW"  #designates that this property can only be read and not set
+    minimum: -50
+    maximum: 100
+    defaultValue: "0"
+    attributes:  # 프로토콜별 속성 추가
+      mqtt-topic: "sensor/temp"
+      unit: "Celsius"
+-
+  name: "humidity"
+  isHidden: false
+  description: "Sensor cluster humidity values"
+  properties:
+    valueType:  "Int64"
+    readWrite: "RW"  #designates that this property can only be read and not set
+    minimum: 0
+    maximum: 100
+    defaultValue: "0"
+    attributes:  # 프로토콜별 속성 추가
+      mqtt-topic: "sensor/hum"
+      unit: "Percent"
+
+deviceCommands:
+-
+  name: "Counts"
+  readWrite: "R"
+  isHidden: false
+  resourceOperations:
+  - { deviceResource: "temperature" }
+  - { deviceResource: "humidity" }
 
howto_lib_make (added)
+++ howto_lib_make
@@ -0,0 +1,2 @@
+Shared Library 와 Static Library 를 공부하기 위한 Makefile 예제 소스 입니다.
+
 
k8s/calico.yaml (added)
+++ k8s/calico.yaml
This file is too big to display.
 
k8s/docker-install.sh (added)
+++ k8s/docker-install.sh
@@ -0,0 +1,45 @@
+#! /bin/bash
+# sudo로 실행 필요
+# docker 설치
+
+apt-get update
+apt-get install -y ca-certificates curl gnupg lsb-release
+
+install -m 0755 -d /etc/apt/keyrings
+curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
+chmod a+r /etc/apt/keyrings/docker.asc
+
+echo \
+  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
+  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
+  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
+
+apt-get update
+apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
+
+# Cgroup를 systemd로 설정
+cat > /etc/docker/daemon.json <<EOF
+{
+  "exec-opts": ["native.cgroupdriver=systemd"],
+  "log-driver": "json-file",
+  "log-opts": {
+    "max-size": "100m"
+  },
+  "storage-driver": "overlay2"
+}
+EOF
+
+mkdir -p /etc/systemd/system/docker.service.d
+systemctl daemon-reload
+systemctl restart docker
+sudo systemctl enable docker
+
+# 일반유저 Docker 사용
+usermod -aG docker vraptor
+
+apt-get install -y bash-completion
+
+curl https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker -o /etc/bash_completion.d/docker.sh
+
+apt-get install -y docker-compose
+
 
k8s/influxdb-v2.yaml (added)
+++ k8s/influxdb-v2.yaml
@@ -0,0 +1,81 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: influxdb
+spec:
+  type: NodePort
+  selector:
+    app: influxdb
+  ports:
+  - name: web
+    port: 8086
+    protocol: TCP
+    targetPort: 8086
+    nodePort: 30201
+---
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+  labels:
+    app: influxdb
+  name: influxdb
+spec:
+  serviceName: "influxdb"
+  replicas: 1
+  selector:
+    matchLabels:
+      app: influxdb
+  template:
+    metadata:
+      labels:
+        app: influxdb
+    spec:
+      containers:
+      - name: influxdb
+        image: registry.xslab.co.kr/lecture/influxdb:2.7.6
+        ports:
+        - name: gui
+          containerPort: 8086
+        volumeMounts:
+        - name: data
+          mountPath: /root/.influxdbv2
+  volumeClaimTemplates:
+    - metadata:
+        name: data
+      spec:
+        storageClassName: local-path
+        accessModes:
+        - ReadWriteOnce
+        resources:
+          requests:
+            storage: 10Gi
+---
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: influxdb-setup
+spec:
+  template:
+    spec:
+      restartPolicy: Never
+      containers:
+        - name: create-credentials
+          image: registry.xslab.co.kr/lecture/influxdb:2.7.6
+          command:
+            - influx
+          args:
+            - setup
+            - --host
+            - http://influxdb.default.svc.cluster.local:8086
+            - --bucket
+            - xslab-bucket
+            - --org
+            - xslab-org
+            - --password
+            - xslab1234
+            - --username
+            - xslab
+            - --token
+            - xslab-token
+            - --force
+
 
k8s/k8s-install-setup.sh (added)
+++ k8s/k8s-install-setup.sh
@@ -0,0 +1,37 @@
+#! /bin/bash
+# sudo로 실행 필요
+
+# K8s 설치
+# 네트워크 설정
+cat << EOF | sudo tee /etc/modules-load.d/k8s.conf
+overlay 
+br_netfilter
+EOF
+
+modprobe overlay
+modprobe br_netfilter
+
+cat << EOF | sudo tee /etc/sysctl.d/k8s.conf
+net.bridge.bridge-nf-call-iptables  = 1
+net.bridge.bridge-nf-call-ip6tables = 1
+net.ipv4.ip_forward                 = 1
+EOF
+
+sysctl --system
+
+# Containerd config 수정
+mkdir -p /etc/containerd
+containerd config default | sudo tee /etc/containerd/config.toml
+sed  -i 's/ SystemdCgroup = false/ SystemdCgroup = true/' /etc/containerd/config.toml
+sudo systemctl restart containerd
+
+# K8s 설치
+apt-get update
+apt-get install -y apt-transport-https ca-certificates curl
+curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
+echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
+apt-get update
+apt-get install -y kubelet kubeadm kubectl
+apt-mark hold kubelet kubeadm kubectl
+echo 'source <(kubectl completion bash)' >> /root/.bashrc
+kubectl completion bash >/etc/bash_completion.d/kubectl
 
k8s/local-path-storage.yaml (added)
+++ k8s/local-path-storage.yaml
@@ -0,0 +1,130 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: local-path-storage
+
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: local-path-provisioner-service-account
+  namespace: local-path-storage
+
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: local-path-provisioner-role
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "nodes", "persistentvolumeclaims", "configmaps" ]
+    verbs: [ "get", "list", "watch" ]
+  - apiGroups: [ "" ]
+    resources: [ "endpoints", "persistentvolumes", "pods" ]
+    verbs: [ "*" ]
+  - apiGroups: [ "" ]
+    resources: [ "events" ]
+    verbs: [ "create", "patch" ]
+  - apiGroups: [ "storage.k8s.io" ]
+    resources: [ "storageclasses" ]
+    verbs: [ "get", "list", "watch" ]
+
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: local-path-provisioner-bind
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: local-path-provisioner-role
+subjects:
+  - kind: ServiceAccount
+    name: local-path-provisioner-service-account
+    namespace: local-path-storage
+
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: local-path-provisioner
+  namespace: local-path-storage
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: local-path-provisioner
+  template:
+    metadata:
+      labels:
+        app: local-path-provisioner
+    spec:
+      serviceAccountName: local-path-provisioner-service-account
+      containers:
+        - name: local-path-provisioner
+          image: rancher/local-path-provisioner:master-head
+          imagePullPolicy: IfNotPresent
+          command:
+            - local-path-provisioner
+            - --debug
+            - start
+            - --config
+            - /etc/config/config.json
+          volumeMounts:
+            - name: config-volume
+              mountPath: /etc/config/
+          env:
+            - name: POD_NAMESPACE
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.namespace
+      volumes:
+        - name: config-volume
+          configMap:
+            name: local-path-config
+
+---
+apiVersion: storage.k8s.io/v1
+kind: StorageClass
+metadata:
+  name: local-path
+provisioner: rancher.io/local-path
+volumeBindingMode: WaitForFirstConsumer
+reclaimPolicy: Delete
+
+---
+kind: ConfigMap
+apiVersion: v1
+metadata:
+  name: local-path-config
+  namespace: local-path-storage
+data:
+  config.json: |-
+    {
+            "nodePathMap":[
+            {
+                    "node":"DEFAULT_PATH_FOR_NON_LISTED_NODES",
+                    "paths":["/opt/local-path-provisioner"]
+            }
+            ]
+    }
+  setup: |-
+    #!/bin/sh
+    set -eu
+    mkdir -m 0777 -p "$VOL_DIR"
+  teardown: |-
+    #!/bin/sh
+    set -eu
+    rm -rf "$VOL_DIR"
+  helperPod.yaml: |-
+    apiVersion: v1
+    kind: Pod
+    metadata:
+      name: helper-pod
+    spec:
+      containers:
+      - name: helper-pod
+        image: busybox
+        imagePullPolicy: IfNotPresent
+
+
 
k8s/rabbitmq.yaml (added)
+++ k8s/rabbitmq.yaml
@@ -0,0 +1,46 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: rabbitmq
+spec:
+  ports:
+  - name: mqtt
+    port: 1883
+    protocol: TCP
+    targetPort: 1883
+    nodePort: 30101
+  - name: amqp
+    port: 5672
+    protocol: TCP
+    targetPort: 5672
+    nodePort: 30102
+  - name: management
+    port: 15672
+    protocol: TCP
+    targetPort: 15672
+    nodePort: 30103
+  selector:
+    app: rabbitmq
+  type: NodePort
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: rabbitmq
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: rabbitmq
+  template:
+    metadata:
+      labels:
+        app: rabbitmq
+    spec:
+      containers:
+      - name: rabbitmq
+        image: registry.xslab.co.kr/lecture/rabbitmq:3.11.15
+        ports:
+        - containerPort: 1883
+        - containerPort: 5672
+        - containerPort: 15672
 
k8s/telegraf-v2.yaml (added)
+++ k8s/telegraf-v2.yaml
@@ -0,0 +1,63 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: telegraf-config
+data:
+  telegraf.conf: |+
+    [[outputs.influxdb_v2]]
+      urls         = ["http://influxdb.default.svc.cluster.local:8086"]
+      organization = "xslab-org"
+      bucket       = "xslab-bucket"
+      token        = "xslab-token"
+
+    [[inputs.mqtt_consumer]]
+    servers = ["rabbitmq.default.svc.cluster.local:1883"]
+      qos = 0
+      topics = [
+        "temphum"
+    ]
+    data_format = "json"
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: telegraf
+spec:
+  selector:
+    matchLabels:
+      app: telegraf
+  minReadySeconds: 5
+  template:
+    metadata:
+      labels:
+        app: telegraf
+    spec:
+      containers:
+        - image: registry.xslab.co.kr/lecture/telegraf:1.30.3
+          name: telegraf
+          ports:
+            - containerPort: 8125
+              name: telegraf
+          volumeMounts:
+            - name: telegraf-config-volume
+              mountPath: /etc/telegraf/telegraf.conf
+              subPath: telegraf.conf
+              readOnly: true
+      volumes:
+        - name: telegraf-config-volume
+          configMap:
+            name: telegraf-config
+---
+apiVersion: v1
+kind: Service
+metadata:
+    name: telegraf
+spec:
+    ports:
+      - name: telegraf
+        port: 8125
+        targetPort: 8125
+        nodePort: 30202
+    selector:
+        app: telegraf
+    type: NodePort
Add a comment
List