드라이버의 요소와 구조

SmartThings Edge Device Driver는 4가지의 요소로 이루어져 있습니다.

* config 파일
* 핑거프린트(Fingerprint) (쓰고 싶다면)
* 드라이버의 코드
* 드라이버를 쓸 수 있는 기기의 프로필

구조
--

```
package
├── src
│   ├── init.lua
│   ├── file1.lua
│   ├── file2.lua
│   └── <folder>
│       ├── init.lua
│       └── file3.lua
├── profiles
│       ├── { Profile Name }.yaml
│       └── { Other Profile Name }.yaml
├── config.yaml
└── fingerprints.yaml (optional)
```

## config 파일

config 파일은 매니페스트이며 드라이버의 메타데이터를 갖고 있습니다.

**예시**

```
# config.yaml
name: 'Hello World'
packageKey: 'helloworld.example'
permissions:
  lan: {}
  discovery: {}

```

* **name :** 드라이버 이름
* **packageKey:** 패키지의 고유 식별자
* **permissions:** 기기를 다루려면 있어야 하는 권한의 리스트

permissions는 드라이버가 데이터를 보내고 받을 수 있는 외부 API를 다루는 데에 쓰입니다. 옵션은 매우 많고 여러 기기의 타입들이 있을 때만 쓸 수 있습니다. 다음의 요소 가운데에서 하나를 고를 수 있습니다.

LAN :

```
permissions:
  lan: {}
  discovery: {}

```

Zigbee :

```
permissions:
  zigbee: {}

```

Z-Wave :

```
permissions:
  zwave: {}

```

## 핑거프린트(Fingerprint)

일반적으로 SmartThins 호환 허브에 잡힌 몇몇 기기들은 핑거프린트(Fingerprint)를 써서 SmartThings 플랫폼에 불러올 수 있습니다. 허브에서 기기를 찾으면 기기의 일부 속성을 읽고 기기의 핑거프린트(Fingerprinit)를 만듭니다. 그러면 핑거프린트(Fingerprint)가 SmartThings Cloud로 보내져서 SmartThings Cloud에 있는 Edge Driver들 가운데에 맞는 핑거프린트(Fingerprint)를 찾습니다. 핑거프린트(Fingerprint)가 잘 맞으면 핑거프린트(Fingerprint)가 있는 Edge Driver가 허브에 깔리고 기기를 쓸 수 있습니다.

핑거프린트(Fingerprint)에는 2가지 타입이 있습니다.

* **Manufacturer** 핑거프린트(Fingerprint)는 기기의 메이커와 모델의 정보를 바탕으로 SmartThings 플랫폼에 붙이는 기기가 드라이버에 있는 정보와 똑같은 지 알아볼 때 씁니다.
* **Generic** 핑거프린트(Fingerprint)는 기기가 쓸 수 있다고 알려 주는 기능을 기기에 따라 드라이버와 맞추어 봅니다.

이러한 핑거프린트(Fingerprint)가 어떤 타입으로 있는 지 알아 내는 것은 프로토콜과 핑거프린트(Fingerprint)의 타입에 따라 다릅니다. 다음은 여러 핑거프린트(Fingerprint)의 카테고리에 대한 예시를 알아 보겠습니다.

### 같이 쓰이는 값

모든 핑거프린트(Fingerprint)에 쓰이는 3가지 값이 있습니다.

* id: 드라이버에서 미리 쓰여진 핑거프린트(Fingerprint)의 이름이자 고유 식별자입니다.
* deviceProfileName: 기기가 써야 하는 기기의 프로필의 이름입니다(드라이버의 패키지 에서 쓰여짐).
* deviceLabel: SmartThings 플랫폼에서 기기가 껴 있는 여러 데이터를 만들 때 넣어지는 기기의 이름에 쓰이는 라벨입니다. 이 라벨은 SmartThings의 모바일 애플리케이션과 같은 SmartThings의 클라이언트와 대시보드에서 보여집니다.

# fingerprints.yaml
matterManufacturer:
  - id: "Samsung/DoorLock/Wifi"
    deviceLabel: Samsung Door Lock WiFi
    vendorId: 0x10E1
    productId: 0x3002
    deviceProfileName: base-lock

```

* **vendorId:** matter 기기의 메이커를 알려 줍니다.
* **productId:** matter 기기의 productID 알려 줍니다.

# fingerprints.yaml
matterGeneric:
  - id: generic-temperature-and-humidity
    deviceLabel: "Temperature and Humdity Sensor"
    deviceTypes:
      - id: 0x0302 # Temperature Sensor
      - id: 0x0307 # Humidity Sensor
    deviceProfileName: temperature-and-humidity-sensor

```

* **deviceTypes:** 기기를 찾을 때 맞춰주는 Matter 기기의 타입입니다.

# fingerprints.yaml
zigbeeManufacturer:
  - id: "SmartThings/motionv4"
    manufacturer: SmartThings
    model: motionv4
    deviceProfileName: { Profile Name }
    deviceLabel: { Device Label }

```

* manufacturer: 기기의 메이커를 알려 줍니다.
* model: Reported: 기기의 알려 줍니다.

# fingerprints.yaml
zigbeeGeneric:
  - id: "dimmer-generic"
    deviceLabel: "Zigbee Dimmer"
    zigbeeProfiles:
      - 0x0104
      - 0xC05E
    deviceIdentifiers:
      - 0x0101
      - 0x0104
        - 0x0006
        - 0x0008
      client:
        - 0x0019

```

* zigbeeProfiles(쓰고 싶다면): 드라이버와 잘 맞을 수도 있는 Zigbee 프로필의 ID입니다. 이것은 선택 사항이며 거의 모든 핑거프린트(Fingerprint)를 그냥 빈칸으로 비워 둘 수도 있습니다. zigbeeProfiles을 만들지 않으면 기본값은 `0x0104`(HA) 및 `0xC05E`(ZLL) 기기와 잘 맞게 됩니다.
* deviceIdentifiers(쓰고 싶다면): 기기에서 알려 준 기기의 ID입니다. 이것은 선택 사항이며 만약에 이 것을 비워 둔다면 모든 기기의 ID와 맞춰볼 수 있습니다. 이 것을 쓰게 된다면 기기에 있는 ID가 deviceIdentifiers와 똑같은 지를 알아 본 다음에 맞춘다는 것으로 알아 듣습니다.
* clusters : clusters는 아래로 2개의 값이 묶여 있으며 2개의 값의 가운데에서 1~2개를 골라야 합니다.
	+ clusters > server: Zigbee 기기가 서버로 쓸 수 있게 되는 것을 알리는 clusters입니다. 핑거프린트(Fingerprint)에 쓰여진 모든 clusters는 기기에서도 똑같아야 합니다.
	+ clusters > client: Zigbee 기기가 클라이언트로 쓸 수 있게 되는 것을 알리는 clusters입니다. 핑거프린트(Fingerprint)에 쓰여진 모든 clusters는 기기에서도 똑같아야 합니다.

# fingerprints.yaml
zwaveManufacturer:
  - id: "GE/Switch/03"
    deviceLabel: GE Switch 03
    manufacturerId: 0x0063
    productType: 0x5250
    productId: 0x3130
    deviceProfileName: switch-binary

```

* **manufacturerId:** Manufacturer 타입의 기기에서의 알림 명령으로, 기기가 알리는 기기 메이커의 ID의 값입니다.
* **productType:** Manufacturer 타입의 기기에서의 알림 명령으로, 기기가 알리는 제품 ID의 값입니다.
* **productId:** Manufacturer 타입의 기기에서의 알림 명령으로, 기기가 알리는 기기의 타입의 값입니다.

manufacturerId는 비어 있으면 안 되며 productId 또는 productType 가운데에서 하나는 비어 있으면 안됩니다.

#### Generic 핑거프린트(Fingerprint)

```
zwaveGeneric:
  - id: "generic-switch"
    deviceLabel: Z-Wave Switch
    genericType: 0x10
    specificType:
      - 0x01
      - 0x03
        - 0x25
      controlled:
        - 0x86
      either:
        - 0x2B
        - 0x40
    deviceProfileName: switch-binary

```

* **genericType:** Generic 타입의 기기에서의 알림 명령으로, Z-Wave 기기가 알리는 Generic 기기의 타입입니다. 1바이트의 크기로 이루어져있습니다.
* **specificType:** Z-Wave 기기가 알리는 Specific 기기의 타입입니다. 1바이트의 크기로 이루어져 있습니다.
* **commandClasses** (쓰고 싶다면): 기기에 쓸 수 있는 케이스일 때 리스트에서 3개의 command classes를 쓸 수 있습니다. 즉, 제어되는 것들의 리스트인 `controlled`, 지원되는 것의 리스트인 `supported`, 어느 쪽이든 될 수 있는 `clusters`가 있습니다.

핑거프린트(Fingerprint) 파일이 제대로 돌아 가게 하려면 genericType 또는 specificType 가운데에서 하나는 비어 있으면 안됩니다.

## 드라이버

드라이버는 Lua로 이루어진 코드입니다. 이 코드는 허브에서 돌아가며 기기와 허브가 데이터를 주고 받을 때 있어야 하는 코드를 쓰는 전처리를 할 수 있습니다(이 문서의 **구조 문단**에서 볼 수 있습니다).

드라이버의 코드를 보려면 **첫 Lua 드라이버를 써 보세요**에서 볼 수 있습니다.

## 기기의 프로필

기기의 프로필에서는 기기의 타입과 SmartThings 플랫폼에서 돌아가는 기기의 기능을 알 수 있습니다. 아래의 예는 SmartThings 플랫폼에서 전등 스위치로 나타나게 해 주는 기기의 프로필인 `hello world` 예제입니다.

```
# hello-world-profile
name: hello-world.v1
components:
- id: main
  capabilities:
  - id: switch
    version: 1
  categories:
  - name: Light

```

## `Hello World` 예제를 깔아보세요

SmartThings Edge를 시작할 준비가 되셨나요? 어떻게 Edge Driver를 허브에 업로드하고 허브 연결 기기를 허브에 붙이는 지 알아 보려면 아래의 `Hello World` 예제 Edge Driver를 깔아보세요.

1. 아래 리포지토리를 컴퓨터에 다운받습니다.
```
git clone git@github.com:SmartThingsDevelopers/SampleDrivers.git
```
2. 디렉토리를 `SampleDrivers`로 바꿉니다.
```
cd SampleDrivers
```
3. 패키지를 빌드하고 SmartThings Cloud에 올립니다.
```
smartthings edge:drivers:package hello-world
```
빌드가 잘 되면 다음과 같이 뜨게 됩니다.
```
┌────────────────────┬───────────────────┐
│ Driver Id                              │ xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx │
│ Name                                   │ Hello World                          │
│ Package Key                            │ helloworld.example                   │
│ Version                                │ 2021-07-07T13:31:53.699513           │
└────────────────────────────────────────┘
```
4. `smartthings edge:channels:create` 을 쳐서 드라이버들을 담을 수 있는 드라이버 채널을 만듭니다. 스크린에 뜨는 대로 따라서 채널을 맞게 잘 둡니다. 채널을 더 알고 싶으면 **드라이버 채널**에서 알 수 있습니다.
```
smartthings edge:channels:create

? Channel name: personal-drivers
? Channel description: My custom drivers
? Channel terms of service URL: my-tos.com

┌───────────┬───────────────────┐
│ Channel Id           │ xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx │
│ Name                 │ personal-drivers                     │
│ Description          │ My custom drivers                    │
│ Type                 │ DRIVER                               │
│ Terms Of Service URL │ https://example.com/tos              │
│ Created Date         │ 2021-07-07T14:48:44.316949Z          │
│ Last Modified Date   │ 2021-07-07T14:48:44.316952Z          │
└───────────┴───────────────────┘
```
5. 만들어 둔 채널에 새 드라이버를 밀어 넣습니다.
```
smartthings edge:channels:assign <YOUR-DRIVER-ID> <YOUR-DRIVER-VERSION> -C <YOUR-CHANNEL-ID>
```
6. Enroll으로 채널에 허브를 이어줍니다. 이렇게 하면 채널과 채널에 묶인 모든 드라이버가 허브에 보여집니다.
```
smartthings edge:channels:enroll -C <YOUR-CHANNEL-ID> <DEVICE-ID-OF-YOUR-HUB>
```

SmartThings CLI에 `smartthings devices --type=HUB`를 치면 허브의 기기 ID를 찾을 수 있습니다.
7. 새로 만든 드라이버를 골라서 허브에 깔아봅니다.
```
smartthings edge:drivers:install
```
8. 드라이버를 깔 허브를(이 때는 **#1**)를 고르고 **Enter** 키를 누릅니다.
```
    ┌──┬───────────────────┬─────────┬─────┬───┐
    │ #  │ Device Id                            │ Name             │ Location │ Room │
    ├──┼───────────────────┼─────────┼─────┼───┤
    │ 1  │  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx│ SmartThings Hub  │ Home     │      │
    └──┴───────────────────┴─────────┴─────┴───┘
    ? Enter id or index
```
9. 드라이버를 깔려는 채널을 고르고 **Enter** 키를 누릅니다.
```
    ┌───┬─────────┬───────────────────┐
    │ #    │ Name             │ Channel Id                           │
    ├───┼─────────┼───────────────────┤
    │ 1    │ personal-drivers │ xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx │
    └───┴─────────┴───────────────────┘
    ? Select a channel to install the driver from.
```
10. 설치할 드라이버를 고르고(이 때는 **#1**) **Enter** 키를 누릅니다.
```
    ┌───┬───────────┬───────────────────┐
    │ #    │ Name                 │ Driver Id                            │
    ├───┼───────────┼───────────────────┤
    │ 1    │ Hello World          │ xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx │
    └───┴───────────┴───────────────────┘
    ? Select a driver to install.
```
11. SmartThings 앱 **기기 추가** > **주변 기기 검색** 메뉴에서 기기를 찾을 수 있습니다.