총 6개의 포스트로 이루어지며 아래 글목록을 보시면 확인이 가능합니다.
개요
.Net 으로 구현된 서비스를 활용해서 SmartThings App 을 인증하는 과정에 대해서 설명하고
저장된 데이터를 확인하며 마무리 하겠습니다.
기능 목록
- 인증 url 생성 (Swagger UI)
- 등록된 Redirect Uri 요청을 수신
- 지정된 시간 간격으로 MS SQL 데이터베이스에서 토큰 정보를 조회해서 갱신
- 지정된 시간 간격으로 SmartThings 에서 조회한 온도 및 습도 데이터를 InfluxDB 에 저장합니다.
개발환경
- Framework : .Net 9
- IDE : Visual Studio 2022
- Projectd Template : ASP.NET Core 웹 API
- Language : C#
사전 정보 확인
SmartThings 디바이스 정보
현재 소스 코드는 온도와 습도 데이터만 지원합니다.
필요한 항목이 있으면 추가 구현이 필요합니다.
온도 또는 습도가 지원되는 디바이스만 사용합니다.
https://my.smartthings.com 에 브라우저로 접속해서 로그인하면 등록된 디바이스 목록을 확인할 수 있습니다.
저의 경우 Android 스마트폰의 SmartThings App 에서 구성해 놓은 상태입니다.

위 화면에서 에어컨을 클릭한 다음 표시되는 DeviceId 를 복사해 두시면 됩니다.
본인이 보유한 장비들을 모두 확인합니다.

InfluxDB 정보
이전 포스트에서 생성한 InfluxDB 정보를 미리 확인합니다.
SmartThings App 생성
이전 포스트에서 생성한 SmartThings App 정보(ClientId, ClientSecret, RedirectUri) 를 확인합니다.
생성 후 24시간 지났다면 다음 포스트 참조해서 다시 생성합니다.
서비스 구현
소스 코드 내려 받기
다음 Github 에서 소스 코드를 다운로드해서 Visual Studio 에서 솔루션을 열어줍니다.
소스 코드 수정
appsettings.json 파일을 수정합니다.
SmartThingsOption 과 InfluxDBOption 의 중괄호({{Options}})로 둘러싸인 항목들을 자신의 환경에 맞춰 수정합니다.
SmartThingsOption 의 Targets 목록은 자신이 보유한 SmartThings 디바이스에 맞게 아래 템플릿 형태로 수정하셔야 합니다.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "Data Source={{Host}},{{Port}};User ID={{User}};Password={{Password}};Initial Catalog={{Database}};Integrated Security=False;MultipleActiveResultSets=True;TrustServerCertificate=True"
},
"SmartThingsOption": {
"ClientId": "{{ClientId}}",
"ClientSecret": "{{ClientSecret}}",
"RedirectUri": "https://{{Host}}/Auth/AuthorizationCallback",
"Scope": "r:devices:*+w:devices:*+x:devices:*",
"Targets": [
{
"DeviceId": "{{DeviceId}}",
"DeviceName": "에어컨",
"Attributes": [
{
"Capability": "temperatureMeasurement",
"Attribute": "temperature"
},
{
"Capability": "relativeHumidityMeasurement",
"Attribute": "humidity"
}
]
},
{
"DeviceId": "{{DeviceId}}",
"DeviceName": "제습기",
"Attributes": [
{
"Capability": "relativeHumidityMeasurement",
"Attribute": "humidity"
}
]
}
]
},
"InfluxDBOption": {
"Url": "{{Protocol}}://{{Host}}:{{Port}}",
"Token": "{{Token}}",
"Bucket": "{{Bucket}}",
"Org": "{{Org}}"
}
}
터널 서비스
로컬 개발 단계이므로 외부에서 접근이 가능하게 터널 서비스를 활용한다.
SmartThings App 생성시 등록한 RedirectUri 로 Redirect 가 되어야 하기 때문이다.
자세한 설명은 다음 포스트를 참조하면 된다.
SmartThings App 인증 및 토큰 확보
인증 과정
SmartThings App 을 생성한 후 최초 인증 단계가 필요하고 다음 순서대로 진행을 해야 한다.
- 인증 url 을 생성해서 인증 요청을 하면 삼성 계정에 로그인을 한다.
- SmartThings 에 등록된 위치에 접근할 수 있는 권한을 확인한다.
- SmartThings App 생성시 등록한 RedirectUri 로 Code 가 전달이 된다.
- Code 값을 포함해서 인증서 발급 요청을 해서 AccessToken 과 RefreshToken 을 발급 받는다.
- (반복) AccessToken 의 유효 기간이 지나기 전에 RefreshToken 으로 토큰 갱신 요청을 해서 새로운 AccessToken 과 RefreshToken 을 발급 받는다.
인증 url 생성
Visual Studio 에서 F5 키를 눌러서 프로젝트를 시작하면 Swagger UI 를 확인할 수 있다.
해당 서비스에서 /Auth/AuthorizationCallback 으로 Redirect 요청을 받아서 인증을 거쳐야 하기 때문에
인증 과정이 끝날 때 까지 계속 실행이 되어 있어야 한다.

Visual Studio 출력 창을 보면 다음과 같이 오류 로그를 확인할 수 있다.
지금은 무시하면 된다.
인증이 되지 않아 토큰 갱신에 실패하고 있다.
Api.Services.SmartThingsService: Error: Failed to refresh token: BadRequest, Response: {"error":"invalid_request","error_description":"refresh_token parameter not provided"}
[0001-01-01 00:00:00.000 +09:00] /
다시 Swagger UI 로 와서 첫번째 GetAuthorizationUrl 을 선택해서 실행하면 인증 Url 을 생성해서 리턴해 준다.
Response body 에서 복사하기 눌러서 url 을 복사한다.

인증 요청
인증 url 을 새 탭에서 붙여넣기 해서 접속하면 삼성 계정에 로그인을 해야한다.

로그인 정상적으로 완료되면 다음과 같이 SmartThings 에 등록된 위치 목록이 나타난다.

위치를 선택해서 인증 버튼을 클릭한다.

다음과 같이 토큰 정보가 리턴이 되면 정상적으로 인증이 되었음을 알 수 있다.
이 단계에서 MSSQL 데이터베이스에 해당 토큰 정보가 업데이트가 된다.

다시 Visual Studio 출력 창을 확인해 보면 다음과 같이 SmartThings 에서 데이터를 수신해서 데이터베이스에 저장이 되는 것을 확인할 수 있다.
Api.Services.SmartThingsService: Information: Loaded 2 device IDs from config.
Api.Services.SmartThingsService: Information: Collecting data for device: 에어컨
System.Net.Http.HttpClient.Default.LogicalHandler: Information: Start processing HTTP request GET https://api.smartthings.com/v1/devices/8f0fcbe2-5dae-25af-c670-828ee2f02859/status
System.Net.Http.HttpClient.Default.ClientHandler: Information: Sending HTTP request GET https://api.smartthings.com/v1/devices/8f0fcbe2-5dae-25af-c670-828ee2f02859/status
System.Net.Http.HttpClient.Default.ClientHandler: Information: Received HTTP response headers after 54.1438ms - 200
System.Net.Http.HttpClient.Default.LogicalHandler: Information: End processing HTTP request after 58.8369ms - 200
Api.Services.SmartThingsService: Information: Device 에어컨: temperature = 25
Api.Services.SmartThingsService: Information: Device 에어컨: humidity = 44
Api.Services.SmartThingsService: Information: Collecting data for device: 제습기
System.Net.Http.HttpClient.Default.LogicalHandler: Information: Start processing HTTP request GET https://api.smartthings.com/v1/devices/f64cdad6-2681-6d62-013d-2f0592c5052d/status
System.Net.Http.HttpClient.Default.ClientHandler: Information: Sending HTTP request GET https://api.smartthings.com/v1/devices/f64cdad6-2681-6d62-013d-2f0592c5052d/status
System.Net.Http.HttpClient.Default.ClientHandler: Information: Received HTTP response headers after 42.4772ms - 200
System.Net.Http.HttpClient.Default.LogicalHandler: Information: End processing HTTP request after 47.1194ms - 200
Api.Services.SmartThingsService: Information: Device 제습기: humidity = 55
ProductAppInfo.cs 파일을 보면 마지막에 토큰 갱신과 데이터 수집 간격이 있다.
1분 간격으로 데이터가 쌓이고 있으므로 실행된 상태로 잠시 데이터가 저장되는 시간을 기다려 준다.
namespace Api.Environments;
public static class ProductAppInfo {
public const string AppName = "SmartThingsData";
public const string DeveloperName = "Jaeyong Park";
public const string AdminEmail = "[email protected]";
public const string AdminPassword = "password";
internal const string SwaggerRoute = "/Swagger";
internal static readonly TimeSpan DelaySmartThingsTokenRefresh = TimeSpan.FromHours(1);
internal static readonly TimeSpan DelaySmartThingsDataCollect = TimeSpan.FromMinutes(1);
}
데이터 확인
InfluxDB UI 에서 저장된 데이터를 확인해 봅니다.
Data Explorer 페이지에서 지정된 Bucket 를 선택해서 조회해 보면 다음과 같이 저장된 데이터를 확인할 수 있다.

0 Comments