

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# Raspberry Pi와 습도 센서 설정
<a name="iot-moisture-raspi-setup"></a>



Raspberry Pi에 microSD 카드를 삽입하고, 모니터, 키보드, 마우스, 이더넷 케이블(Wi-Fi를 사용하지 않는 경우)을 연결합니다. 전원 케이블은 아직 연결하지 마세요.

JST 점퍼 케이블을 습도 센서에 연결합니다. 점퍼의 반대쪽에 다음 4개 와이어가 있습니다.
+ 녹색: I2C SCL
+ 흰색: I2C SDA
+ 적색: 전원(3.5V)
+ 검은색: 접지

Raspberry Pi를 이더넷 잭으로 오른쪽에 고정합니다. 이 방향에서 상단에 GPIO 핀 열이 2개 있습니다. 습도 센서의 와이어를 핀 하단 열에 다음 순서로 연결합니다. 제일 왼쪽 핀부터 시작하여 적색(전원), 흰색(SDA), 녹색(SCL)을 연결합니다. 핀 하나는 건너뛰고 검은색(접지) 와이어를 연결합니다. 자세한 내용은 [Python 컴퓨터 배선](https://learn.adafruit.com/adafruit-stemma-soil-sensor-i2c-capacitive-moisture-sensor/python-circuitpython-test) 단원을 참조하세요.

전원 케이블을 Raspberry Pi에 연결하고 반대쪽 끝을 벽면 콘센트에 꽂아 전원을 켭니다.

**Raspberry Pi 구성**

1. **Welcome to Raspberry Pi(Raspberry Pi를 소개합니다)**에서 **다음**을 선택합니다.

1. 국가, 언어, 시간대 및 키보드 배열을 선택합니다. **다음**을 선택합니다.

1. Raspberry Pi 암호를 입력하고 **다음**을 선택합니다.

1. Wi-Fi 네트워크를 선택하고 **다음**을 선택합니다. Wi-Fi 네트워크를 사용하지 않을 때는 **건너뛰기**를 선택합니다.

1. **다음**을 선택하고 소프트웨어 업데이트를 확인합니다. 업데이트가 완료되면 **다시 시작**을 클릭하여 Raspberry Pi를 다시 시작합니다.

Raspberry Pi가 시작되면 I2C 인터페이스를 활성화합니다.

1. Raspbian 데스크톱 좌측 상단 모서리에서 Raspberry 아이콘을 클릭하고, **기본 설정**을 선택한 다음 **Raspberry Pi Configuration(Raspberry Pi 구성)**을 선택합니다.

1. **인터페이스** 탭에서 **I2C**의**활성화**를 선택합니다.

1. **확인**을 선택합니다.

CircuitPython의 Adafruit STEMMA 습도 센서용 라이브러리가 작성됩니다. Raspberry Pi에서 이를 실행하려면 Python 3 최신 버전을 설치해야 합니다.

1. 명령 프롬프트에서 다음 명령을 실행하여 Raspberry Pi 소프트웨어를 업데이트합니다.

   `sudo apt-get update`

   `sudo apt-get upgrade`

1. 다음 명령을 실행하여 Phthon 3 설치를 업데이트합니다.

   `sudo pip3 install --upgrade setuptools`

1. 다음 명령을 실행하여 Raspberry Pi GPIO 라이브러리를 설치합니다.

   `pip3 install RPI.GPIO`

1. 다음 명령을 실행하여 Adafruit Blinka 라이브러리를 설치합니다.

   `pip3 install adafruit-blinka`

   자세한 내용은 [Raspberry Pi에서 CircuitPython 라이브러리 설치](https://learn.adafruit.com/circuitpython-on-raspberrypi-linux/installing-circuitpython-on-raspberry-pi)를 참조하세요.

1. 다음 명령을 실행하여 Adafruit Seesaw 라이브러리를 설치합니다.

   `sudo pip3 install adafruit-circuitpython-seesaw`

1. 다음 명령을 실행하여 AWS IoT Device SDK for Python을 설치합니다.

   `pip3 install AWSIoTPythonSDK`

이제 Raspberry Pi에 필요한 라이브러리가 모두 설치되었습니다. **moistureSensor.py**라는 파일을 만들고 다음 Python 코드를 파일에 복사합니다.

```
from adafruit_seesaw.seesaw import Seesaw
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient
from board import SCL, SDA

import logging
import time
import json
import argparse
import busio

# Shadow JSON schema:
#
# {
#   "state": {
#       "desired":{
#           "moisture":<INT VALUE>,
#           "temp":<INT VALUE>            
#       }
#   }
# }

# Function called when a shadow is updated
def customShadowCallback_Update(payload, responseStatus, token):

    # Display status and data from update request
    if responseStatus == "timeout":
        print("Update request " + token + " time out!")

    if responseStatus == "accepted":
        payloadDict = json.loads(payload)
        print("~~~~~~~~~~~~~~~~~~~~~~~")
        print("Update request with token: " + token + " accepted!")
        print("moisture: " + str(payloadDict["state"]["reported"]["moisture"]))
        print("temperature: " + str(payloadDict["state"]["reported"]["temp"]))
        print("~~~~~~~~~~~~~~~~~~~~~~~\n\n")

    if responseStatus == "rejected":
        print("Update request " + token + " rejected!")

# Function called when a shadow is deleted
def customShadowCallback_Delete(payload, responseStatus, token):

     # Display status and data from delete request
    if responseStatus == "timeout":
        print("Delete request " + token + " time out!")

    if responseStatus == "accepted":
        print("~~~~~~~~~~~~~~~~~~~~~~~")
        print("Delete request with token: " + token + " accepted!")
        print("~~~~~~~~~~~~~~~~~~~~~~~\n\n")

    if responseStatus == "rejected":
        print("Delete request " + token + " rejected!")


# Read in command-line parameters
def parseArgs():

    parser = argparse.ArgumentParser()
    parser.add_argument("-e", "--endpoint", action="store", required=True, dest="host", help="Your device data endpoint")
    parser.add_argument("-r", "--rootCA", action="store", required=True, dest="rootCAPath", help="Root CA file path")
    parser.add_argument("-c", "--cert", action="store", dest="certificatePath", help="Certificate file path")
    parser.add_argument("-k", "--key", action="store", dest="privateKeyPath", help="Private key file path")
    parser.add_argument("-p", "--port", action="store", dest="port", type=int, help="Port number override")
    parser.add_argument("-n", "--thingName", action="store", dest="thingName", default="Bot", help="Targeted thing name")
    parser.add_argument("-id", "--clientId", action="store", dest="clientId", default="basicShadowUpdater", help="Targeted client id")

    args = parser.parse_args()
    return args


# Configure logging
# AWSIoTMQTTShadowClient writes data to the log
def configureLogging():

    logger = logging.getLogger("AWSIoTPythonSDK.core")
    logger.setLevel(logging.DEBUG)
    streamHandler = logging.StreamHandler()
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    streamHandler.setFormatter(formatter)
    logger.addHandler(streamHandler)


# Parse command line arguments
args = parseArgs()

if not args.certificatePath or not args.privateKeyPath:
    parser.error("Missing credentials for authentication.")
    exit(2)

# If no --port argument is passed, default to 8883
if not args.port: 
    args.port = 8883


# Init AWSIoTMQTTShadowClient
myAWSIoTMQTTShadowClient = None
myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(args.clientId)
myAWSIoTMQTTShadowClient.configureEndpoint(args.host, args.port)
myAWSIoTMQTTShadowClient.configureCredentials(args.rootCAPath, args.privateKeyPath, args.certificatePath)

# AWSIoTMQTTShadowClient connection configuration
myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(1, 32, 20)
myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout(10) # 10 sec
myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(5) # 5 sec

# Initialize Raspberry Pi's I2C interface
i2c_bus = busio.I2C(SCL, SDA)

# Intialize SeeSaw, Adafruit's Circuit Python library
ss = Seesaw(i2c_bus, addr=0x36)

# Connect to AWS IoT
myAWSIoTMQTTShadowClient.connect()

# Create a device shadow handler, use this to update and delete shadow document
deviceShadowHandler = myAWSIoTMQTTShadowClient.createShadowHandlerWithName(args.thingName, True)

# Delete current shadow JSON doc
deviceShadowHandler.shadowDelete(customShadowCallback_Delete, 5)

# Read data from moisture sensor and update shadow
while True:

    # read moisture level through capacitive touch pad
    moistureLevel = ss.moisture_read()

    # read temperature from the temperature sensor
    temp = ss.get_temp()

    # Display moisture and temp readings
    print("Moisture Level: {}".format(moistureLevel))
    print("Temperature: {}".format(temp))
    
    # Create message payload
    payload = {"state":{"reported":{"moisture":str(moistureLevel),"temp":str(temp)}}}

    # Update shadow
    deviceShadowHandler.shadowUpdate(json.dumps(payload), customShadowCallback_Update, 5)
    time.sleep(1)
```

파일을 찾을 수 있는 위치에 파일을 저장합니다. 다음 파라미터로 `moistureSensor.py` 명령줄을 실행할 수 있습니다.

엔드포인트  
사용자 지정 AWS IoT 엔드포인트입니다. 자세한 내용은 [디바이스 섀도우 REST API](device-shadow-rest-api.md) 단원을 참조하십시오.

rootCA  
 AWS IoT 루트 CA 인증서의 전체 경로입니다.

cert  
 AWS IoT 디바이스 인증서의 전체 경로입니다.

키  
 AWS IoT 디바이스 인증서 프라이빗 키의 전체 경로입니다.

thingName  
사물 이름(이 경우는 `RaspberryPi`)입니다.

clientId  
MQTT 클라이언트 ID입니다. `RaspberryPi`를 사용합니다.

명령줄의 모양은 다음과 같아야 합니다.

`python3 moistureSensor.py --endpoint {{your-endpoint}} --rootCA ~/certs/AmazonRootCA1.pem --cert ~/certs/raspberrypi-certificate.pem.crt --key ~/certs/raspberrypi-private.pem.key --thingName RaspberryPi --clientId RaspberryPi`

센서를 만지거나, 화분에 넣거나, 물 컵에 넣어 센서가 다양한 습도에 반응하는지 확인해봅니다. 필요할 경우 `MoistureSensorRule`에서 임계값을 변경할 수 있습니다. 습도 센서 판독값이 규칙의 SQL 쿼리 문에 지정된 값 아래로 떨어지면는 Amazon SNS 주제에 메시지를 AWS IoT 게시합니다. 습도와 온도 데이터가 있는 이메일 메시지가 수신되어야 합니다.

Amazon SNS에서 이메일 메시지 수신을 확인한 후에 **CTRL\+C**를 눌러 Python 프로그램을 저장합니다. Python 프로그램으로 전송되는 메시지로 요금이 발생할 가능성은 적지만 사용 후에는 프로그램을 중지시키는 것이 좋습니다.