기존에 안드로이드에서 MQTT를 이용하여 메세지를 주고 받는걸 확인 했다. 이를 응용해서 전등을 컨트롤하는 예제를 만들어보자.
1. MQTT 로 보낼 TOPIC, JSON 구조 정하기
이 글과 2부에서 작성한 서버와 통신할 안드로이드 어플을 만들고자 합니다. 그러므로 TOPIC은 이 글을 따라가겠습니다.
해당 글에서 안드로이드로부터 오는 메세지를 받는 토픽은 아래와 같습니다.
MyHome/Light/Pub/Server
그리고 전등의 변경된 상태값을 받기 위한 토픽은 아래와 같습니다.
MyHome/Light/Result
이렇게 TOPIC은 정해졌습니다.
다음으로는 JSON 구조입니다.
TOPIC과 마찬가지로 2부에서 작성된 코드를 따라가겠습니다.
코드가 작성된 게시글은 아래 링크를 따라가면 있습니다.
위 링크에서 가져온 안드로이드 파트 JSON 구조는 아래와 같습니다.
{"Light": {"sender": '유저이름', "message":'ON 혹은 OFF', "destination":'컨트롤 할 전등', "room":'전등 카테고리'}}
- 데이터를 ' 로 감싼 이유는 해당 위치에 데이터가 들어간다는걸 구분하기 위함입니다. 실제로는 " 로 감싸집니다.
만약 redhat 이란 유저가 부엌 싱크대 불을 끄려고 한다면 저는 아래처럼 메세지가 생성됩니다.
{"Light": {"sender": "RedHat", "message":"OFF", "destination":"sink", "room":"kitchen"}}
2. 필요 라이브러리 설치하기
JSON을 사용하기 위해 GSON을 사용해 보겠습니다.
implementation group: 'com.google.code.gson', name: 'gson', version: '2.9.0'
위 코드를 "build gradle" 파일 내에 있는 "dependencies" 에 추가합니다.
2. 코드 작성(JAVA)
※ 코드는 이전에 작성한 안드로이드에서 MQTT 사용하기 예제 코드를 가져왔습니다.
public class MainActivity extends AppCompatActivity {
private String ServerIP = "tcp://192.168.0.254:1883";
private String TOPIC_PUB = "MyHome/Light/Pub/Server"; // 1. pub TOPIC
private String TOPIC_SUB = "MyHome/Light/Result"; // 2. sub TOPIC
private MqttClient mqttClient = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sub_javaactivity);
Button button = findViewById(R.id.button_send_java);
try {
mqttClient = new MqttClient(ServerIP, MqttClient.generateClientId(), null);
mqttClient.connect();
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
// 3. JSON
Gson gson = new Gson();
JsonObject object = new JsonObject();
object.addProperty("sender", "RedHat");
object.addProperty("message", "OFF");
object.addProperty("destination", "sink");
object.addProperty("room", "kitchen");
JsonObject packageObject = new JsonObject();
packageObject.add("Light", object);
String message = gson.toJson(packageObject);
mqttClient.publish(TOPIC_PUB, new MqttMessage(message.getBytes()));
} catch (MqttException e) {
e.printStackTrace();
}
}
});
mqttClient.subscribe(TOPIC_SUB);
mqttClient.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable throwable) {
Log.d("MQTTService", "Connection Lost");
}
@Override
public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
// 4. Sub Message
Log.d("MQTTService", "Message Arrived : " + mqttMessage.toString());
}
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
Log.d("MQTTService", "Delivery Complete");
}
});
} catch (MqttException e) {
e.printStackTrace();
}
}
}
기존 코드와 같은 내용은 넘어가고 변경된 점만 설명하겠습니다.
1번. 메세지 발송(Pub) TOPIC입니다.
해당 토픽으로 데이터를 전송합니다. 이후 서버에서 처리하여 각 스위치로 컨트롤 메세지를 전송합니다.
2번. 메세지 수신(Sub) TOPIC입니다.
전등의 상태값이 변경이 되었을때 해당 상태값을 받을 토픽입니다.
3번. JSON 타입의 메세지 설정입니다.
4가지 인자가 있는데, 순서대로 아래와 같습니다.
sender, message, destination, room
해당 코드는 value를 위에서 말한 예시로 하드코딩으로 넣었는데 실제로 적용하고 싶으면 list등으로 데이터를 정리하고
각 방에 맞는 버튼이 클릭 될 경우 해당 값들을 넣는 방식으로 수정하시면 됩니다.
4번. 메시지 수신입니다.
변경된 전등의 상태값이 수신됩니다. 안드로이드에서 뿐만 아니라 다른 부분(직접 컨트롤 등)에서 상태값이 변경되어도 바로 오게 됩니다.
아래는 위 코드 관련 궁금할만한 내용들을 정리했습니다.
● XML 코드는 어떻게 되나요?
· 기존 빈 화면에서 버튼 하나만 추가했습니다. 코드는 아래와 같습니다.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
● 전등의 변경된 상태값은 굳이 왜 MQTT로 받나요? HTTP로 받으면 리턴값을 바로 받을 수 있지 않나요?
· 저는 어플이 켜져있을때 다른 사람이 컨트롤 하더라도 그 값이 똑같이 바로바로 동기화 되길 원해서 이렇게 작성했습니다.
'홈 IoT > 안드로이드' 카테고리의 다른 글
안드로이드에서 MQTT 통신 하기(예제) (4) | 2021.09.25 |
---|