개발도구 없이 Java 프로그램을 직접 컴파일하고 실행하기

2020-08-29

.

JAVA_TIL(20200829)

  • study program : youtube 생활코딩 채널 ‘JAVA1’

[실습목표]

  • 이클립스와 같은 개발도구를 사용하지 않고 자바로 만든 프로그램을 컴파일하고 실행해보자.

  • 어떤 컴퓨터에서든, 어떤 환경에서든지 자바만 있다면 이클립스 같은 개발도구 없이 자바 프로그램을 실행할 수 있다.

  • 자바 확장자가 붙은 소스코드를 클래스 확장자가 붙은 실행파일로 컴파일하고 클래스 확장자가 붙은 파일을 실행해보자. 거기에 추가로 실행할때 입력값도 줘보자. 입력값에 따라 프로그램이 다르게 동작해보는 것을 확인해보자.

실습 1) Program.java 파일을 Program.class로 컴파일해서 실행해보려고 한다.

실습 2) OkJavaGoinHome.java라는 라이브러리가 포함된 소스코드 파일을 class 확장자로 컴파일하고, run 해본다.

실습 3) 마찬가지로 OkJavaGoinHomeInput.java 파일을 class 확장자로 컴파일하고, run 해보는데 input을 어떻게 처리할지 이것도 해볼 것이다.

[실습내용]

  • 실습환경

Amazonlinux AMI EC2

  • 사전준비

실습파일을 해당 ec2에 업로드, sudo yum update -y로 패키지 업데이트후 자바설치

# tree 패키지 설치
[ec2-user@ip-10-1-10-254 practice]$ sudo yum install tree -y

[ec2-user@ip-10-1-10-254 practice]$ ls
Data_and_operation  HelloWorldGUI   MyApp
HelloWorld          HelloWorld_IOT  Programming

# 자바 설치
[ec2-user@ip-10-1-10-254 practice]$ sudo yum install -y java-1.8.0-openjdk-devel.x86_64

[ec2-user@ip-10-1-10-254 practice]$ java -version
openjdk version "1.8.0_252"
OpenJDK Runtime Environment (build 1.8.0_252-b09)
OpenJDK 64-Bit Server VM (build 25.252-b09, mixed mode)

자바를 컴파일하기 위해서는 javac라는 것을 이용해서 컴파일할 수 있다.

[ec2-user@ip-10-1-10-254 practice]$ javac
Usage: javac <options> <source files>
where possible options include:
  -g                         Generate all debugging info
  -g:none                    Generate no debugging info
  -g:{lines,vars,source}     Generate only some debugging info
  -nowarn                    Generate no warnings
  -verbose                   Output messages about what the compiler is doing
  -deprecation               Output source locations where deprecated APIs are used
  -classpath <path>          Specify where to find user class files and annotation processors
  -cp <path>                 Specify where to find user class files and annotation processors
  -sourcepath <path>         Specify where to find input source files
  -bootclasspath <path>      Override location of bootstrap class files
  -extdirs <dirs>            Override location of installed extensions
  -endorseddirs <dirs>       Override location of endorsed standards path
  -proc:{none,only}          Control whether annotation processing and/or compilation is done.
  -processor <class1>[,<class2>,<class3>...] Names of the annotation processors to run; bypasses default discovery process
  -processorpath <path>      Specify where to find annotation processors
  -parameters                Generate metadata for reflection on method parameters
  -d <directory>             Specify where to place generated class files
  -s <directory>             Specify where to place generated source files
  -h <directory>             Specify where to place generated native header files
  -implicit:{none,class}     Specify whether or not to generate class files for implicitly referenced files
  -encoding <encoding>       Specify character encoding used by source files
  -source <release>          Provide source compatibility with specified release
  -target <release>          Generate class files for specific VM version
  -profile <profile>         Check that API used is available in the specified profile
  -version                   Version information
  -help                      Print a synopsis of standard options
  -Akey[=value]              Options to pass to annotation processors
  -X                         Print a synopsis of nonstandard options
  -J<flag>                   Pass <flag> directly to the runtime system
  -Werror                    Terminate compilation if warnings occur
  @<filename>                Read options and filenames from file

그러면 이 javac라는 것은 어디에 있는가 아래의 명령어로 확인할 수 있다.

# 자바의 경로
[ec2-user@ip-10-1-10-254 practice]$ readlink -f $(which java)
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.amzn2.0.1.x86_64/jre/bin/java

# javac의 경로
[ec2-user@ip-10-1-10-254 practice]$ readlink -f $(which javac)
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.amzn2.0.1.x86_64/bin/javac

내가 java라고 명령을 내렸을때 저 명령이 현재 어디에 있건간에 실행되는 이유는 뭐때문일까. 바로 path라고 하는 환경변수 때문이다.

java라고 명령을 내리면 운영체제는 현재 디렉토리에 자바가 있는지 확인하고, 없으면 환경변수 경로를 찾아서 자바라는 파일이 있으면 그거를 실행하게 된다. 만약에 못찾는다면 Error를 발생시킬것이다.

  • 환경변수 확인방법
[ec2-user@ip-10-1-10-254 practice]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ec2-user/.local/bin:/home/ec2-user/bin
  • 환경변수 설정법

.bash_profile 마지막줄 아래에 경로를 추가해주면 된다.

[ec2-user@ip-10-1-10-254 practice]$ vim ~/.bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH

실습 1) Program.java 파일을 Program.class로 컴파일해서 실행해보자.

image

  • Program.java
public class Program {

    public static void main(String[] args) {

        System.out.println(1);
        System.out.println(2);
        System.out.println(3);

    }

}

ec2에서 아래와 같이 명령어를 실행하여 실습해본다.

[ec2-user@ip-10-1-10-254 Programming]$ ls
ClassApp.java  InstanceApp.java  OkJavaGoInHomeInput.java  OkJavaGoInHome.java  org  Program.java

[ec2-user@ip-10-1-10-254 Programming]$ javac Program.java

# javac 명령어로 Program.class가 생성되었다.
[ec2-user@ip-10-1-10-254 Programming]$ ls
ClassApp.java  InstanceApp.java  OkJavaGoInHomeInput.java  OkJavaGoInHome.java  org  Program.class  Program.java

# 자바는 현재 디렉토리에 Program.class 파일이 있는지를 찾아보고 있다면 그거를 실행시킨다. 
[ec2-user@ip-10-1-10-254 Programming]$ java Program
1
2
3

# Program.class을 실행하라 그러면 Program.class에서 클래스파일의 이름을 찾는다 다시말해서 소스코드 안에서 Program class를 찾는다.
#  다음에 main을 찾는다  다음에 main 중괄호 안에 있는 코드를 순차적으로 실행하고 종료한다.
[ec2-user@ip-10-1-10-254 Programming]$ cat Program.java

public class Program {

        public static void main(String[] args) {

                System.out.println(1);
                System.out.println(2);
                System.out.println(3);

        }

}

실습 2) OkJavaGoinHome.java라는 라이브러리가 포함된 소스코드 파일을 class 확장자로 컴파일하고, run 해본다.

  • OkJavaGoinHome.java
## OkJavaGoinHome.java 코드에서 Elevator, Security, Lightning 객체는 아래와 같이 
## 외부의 패키지에서 import  것들이다.
import org.opentutorials.iot.Elevator;
import org.opentutorials.iot.Lighting;
import org.opentutorials.iot.Security;

public class OkJavaGoInHome {

    public static void main(String[] args) {

        String id = "JAVA APT 507";

        // Elevator call 
        Elevator myElevator = new Elevator(id);
        myElevator.callForUp(1);

        // Security off 
        Security mySecurity = new Security(id);
        mySecurity.off();

        // Light on
        Lighting hallLamp = new Lighting(id+" / Hall Lamp");
        hallLamp.on();

        Lighting floorLamp = new Lighting(id+" / floorLamp");
        floorLamp.on();

    }

}

아래와 같이 iot 폴더안에 있는 파일들을 패키지라고 부른다. 작은 프로그램들이 모여있는 패키지인 것이다.

여기에 Elevator.java라는 파일이 있고, 이 파일을 컴파일하면 Elevator.class가 생성된다. 이 Elevator.class를 로딩하는 코드가 위에서 import org.opentutorials.iot.Elevator;이다. Lightning과 Security도 마찬가지이다.

그래서 이런 패키지들이 임포트되었기 때문에 Elevator,Lightning,Security 메서드를 아래의 파일목록에서 각각의 class로 부터 참조해서 쓸 수 있게 된다.

[ec2-user@ip-10-1-10-254 iot]$ pwd
/home/ec2-user/practice/Programming/org/opentutorials/iot

[ec2-user@ip-10-1-10-254 iot]$ ll
total 72
-rw-rw-r-- 1 ec2-user ec2-user 1290 Aug 29 05:46 Aircon.class
-rw-rw-r-- 1 ec2-user ec2-user  500 Aug 29 05:46 Aircon.java
-rw-rw-r-- 1 ec2-user ec2-user 1137 Aug 29 05:46 ColorDimmingLights.class
-rw-rw-r-- 1 ec2-user ec2-user  379 Aug 29 05:46 ColorDimmingLights.java
-rw-rw-r-- 1 ec2-user ec2-user 1002 Aug 29 05:46 DimmingLights.class
-rw-rw-r-- 1 ec2-user ec2-user  320 Aug 29 05:46 DimmingLights.java
-rw-rw-r-- 1 ec2-user ec2-user 1186 Aug 29 05:46 Elevator.class
-rw-rw-r-- 1 ec2-user ec2-user  401 Aug 29 05:46 Elevator.java
-rw-rw-r-- 1 ec2-user ec2-user 1261 Aug 29 05:46 Lighting.class
-rw-rw-r-- 1 ec2-user ec2-user  440 Aug 29 05:46 Lighting.java
-rw-rw-r-- 1 ec2-user ec2-user  146 Aug 29 05:46 OnOff.class
-rw-rw-r-- 1 ec2-user ec2-user  104 Aug 29 05:46 OnOff.java
-rw-rw-r-- 1 ec2-user ec2-user 1279 Aug 29 05:46 Refrigerator.class
-rw-rw-r-- 1 ec2-user ec2-user  493 Aug 29 05:46 Refrigerator.java
-rw-rw-r-- 1 ec2-user ec2-user 1334 Aug 29 05:46 Security.class
-rw-rw-r-- 1 ec2-user ec2-user  518 Aug 29 05:46 Security.java
-rw-rw-r-- 1 ec2-user ec2-user  980 Aug 29 05:46 Speaker.class
-rw-rw-r-- 1 ec2-user ec2-user  245 Aug 29 05:46 Speaker.java

일단 실습을 위해서 /home/ec2-user/practice/Programming/org/opentutorials/iot에서 class 파일을 모두 삭제해준다.

그리고 javac로 OkJavaGoInHome.java를 컴파일 해본다. 그러면 class 파일이 생성될 것이고, iot 패키지 폴더 아래에 class 파일들이 쭉 생성된 것을 확인할 수 있다.

OkJavaGoInHome.java는 내부적으로 이 iot 패키지 안에 있는 여러 파일들을 전부 필요로 하기 때문에 자바 컴파일러가 패키지 안에 있는 .java들도 컴파일을 해준것이다.

[ec2-user@ip-10-1-10-254 iot]$ ls
Aircon.class              DimmingLights.class  Lighting.class  Refrigerator.class  Speaker.class
Aircon.java               DimmingLights.java   Lighting.java   Refrigerator.java   Speaker.java
ColorDimmingLights.class  Elevator.class       OnOff.class     Security.class
ColorDimmingLights.java   Elevator.java        OnOff.java      Security.java

[ec2-user@ip-10-1-10-254 iot]$ rm *.class

[ec2-user@ip-10-1-10-254 iot]$ ls
Aircon.java              DimmingLights.java  Lighting.java  Refrigerator.java  Speaker.java
ColorDimmingLights.java  Elevator.java       OnOff.java     Security.java

[ec2-user@ip-10-1-10-254 iot]$ cd /home/ec2-user/practice/Programming

[ec2-user@ip-10-1-10-254 Programming]$ ls
ClassApp.java  InstanceApp.java  OkJavaGoInHomeInput.java  OkJavaGoInHome.java  org  Program.class  Program.java

[ec2-user@ip-10-1-10-254 Programming]$ javac OkJavaGoInHome.java

[ec2-user@ip-10-1-10-254 Programming]$ ls
ClassApp.java     OkJavaGoInHome.class      OkJavaGoInHome.java  Program.class
InstanceApp.java  OkJavaGoInHomeInput.java  org                  Program.java

[ec2-user@ip-10-1-10-254 Programming]$ cd /home/ec2-user/practice/Programming/org/opentutorials/iot

[ec2-user@ip-10-1-10-254 iot]$ ls
Aircon.java              Elevator.class  Lighting.java  Refrigerator.java  Speaker.java
ColorDimmingLights.java  Elevator.java   OnOff.class    Security.class
DimmingLights.java       Lighting.class  OnOff.java     Security.java

위와 같이 실습을 해보고 iot 폴더안에 class 파일들을 또 모두 삭제해준다.

그리고 Programming 폴더에 lib이라는 폴더를 하나 만들고 org 폴더를 몽땅 lib 안으로 이동시켜준다.

(org 폴더를 lib 폴더 안에 넣어서 OkJavaGoInHome.java와 org 폴더가 같은 디렉토리선에 있지 않도록 해준 것이다.)

그런 다음에 다시 javac OkJavaGoInHome.java 명령을 해보자.

[ec2-user@ip-10-1-10-254 iot]$ rm *.class

[ec2-user@ip-10-1-10-254 iot]$ ls
Aircon.java              DimmingLights.java  Lighting.java  Refrigerator.java  Speaker.java
ColorDimmingLights.java  Elevator.java       OnOff.java     Security.java

[ec2-user@ip-10-1-10-254 iot]$ cd /home/ec2-user/practice/Programming

[ec2-user@ip-10-1-10-254 Programming]$ ls
ClassApp.java     OkJavaGoInHome.class      OkJavaGoInHome.java  Program.class
InstanceApp.java  OkJavaGoInHomeInput.java  org                  Program.java

[ec2-user@ip-10-1-10-254 Programming]$ mkdir lib

[ec2-user@ip-10-1-10-254 Programming]$ mv org lib/org

[ec2-user@ip-10-1-10-254 Programming]$ ls
ClassApp.java     lib                   OkJavaGoInHomeInput.java  Program.class
InstanceApp.java  OkJavaGoInHome.class  OkJavaGoInHome.java       Program.java

[ec2-user@ip-10-1-10-254 Programming]$ cd lib

[ec2-user@ip-10-1-10-254 lib]$ ls
org

[ec2-user@ip-10-1-10-254 lib]$ cd ..

# 우리가 컴파일하고 있는 OkJavaGoInHome.java와 org 패키지가 같은 디렉토리에 있지 않기 때문에
# 각각의 패키지들이 존재하지 않는다고 Error가 발생한다.
[ec2-user@ip-10-1-10-254 Programming]$ javac OkJavaGoInHome.java
OkJavaGoInHome.java:1: error: package org.opentutorials.iot does not exist
import org.opentutorials.iot.Elevator;
                            ^
OkJavaGoInHome.java:2: error: package org.opentutorials.iot does not exist
import org.opentutorials.iot.Lighting;
                            ^
OkJavaGoInHome.java:3: error: package org.opentutorials.iot does not exist
import org.opentutorials.iot.Security;
                            ^
OkJavaGoInHome.java:12: error: cannot find symbol
                Elevator myElevator = new Elevator(id);
                ^
  symbol:   class Elevator
  location: class OkJavaGoInHome
OkJavaGoInHome.java:12: error: cannot find symbol
                Elevator myElevator = new Elevator(id);
                                          ^
  symbol:   class Elevator
  location: class OkJavaGoInHome
OkJavaGoInHome.java:16: error: cannot find symbol
                Security mySecurity = new Security(id);
                ^
  symbol:   class Security
  location: class OkJavaGoInHome
OkJavaGoInHome.java:16: error: cannot find symbol
                Security mySecurity = new Security(id);
                                          ^
  symbol:   class Security
  location: class OkJavaGoInHome
OkJavaGoInHome.java:20: error: cannot find symbol
                Lighting hallLamp = new Lighting(id+" / Hall Lamp");
                ^
  symbol:   class Lighting
  location: class OkJavaGoInHome
OkJavaGoInHome.java:20: error: cannot find symbol
                Lighting hallLamp = new Lighting(id+" / Hall Lamp");
                                        ^
  symbol:   class Lighting
  location: class OkJavaGoInHome
OkJavaGoInHome.java:23: error: cannot find symbol
                Lighting floorLamp = new Lighting(id+" / floorLamp");
                ^
  symbol:   class Lighting
  location: class OkJavaGoInHome
OkJavaGoInHome.java:23: error: cannot find symbol
                Lighting floorLamp = new Lighting(id+" / floorLamp");
                                         ^
  symbol:   class Lighting
  location: class OkJavaGoInHome
11 errors

이럴때 사용하는 것이 javac에서 --class-path <path> 또는 --cp <path> 옵션이다.

OkJavaGoInHome.java가 컴파일되기 위해 필요한 class파일이 어디에 있는지를 지정해 줄 수 있는 것이다.

이 옵션으로 다시한번 javac로 컴파일해보면 컴파일은 잘 되는 것을 확인할 수 있다.

컴파일을 했으니까 java로 실행을 해보는데 실행을 하면 아래와 같이 Error가 날 것이다.

이것도 마찬가지로 OkJavaGoInHome.class를 실행하는데 필요한 패키지들이 동일한 디렉토리 선상에 위치하지 않고 있기 때문이다.

[ec2-user@ip-10-1-10-254 Programming]$ javac -cp ".:lib" OkJavaGoInHome.java

[ec2-user@ip-10-1-10-254 Programming]$ java OkJavaGoInHome
Exception in thread "main" java.lang.NoClassDefFoundError: org/opentutorials/iot/Elevator
        at OkJavaGoInHome.main(OkJavaGoInHome.java:12)
Caused by: java.lang.ClassNotFoundException: org.opentutorials.iot.Elevator
        at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
        ... 1 more

이것도 그러면 경로를 지정해서 실행할 수 있도록 아래와 같이 명령을 해주면 될텐데 또 error가 난다.

자바를 실행시키는 디렉토리에 있는 OkJavaGoInHome.class 파일을 찾도록 약속되어 있는데 명시적으로 lib이라고 명시하면 lib에서만 찾기 때문이다.

그래서 그 아래에 있는 명령어와 같이 실행하면 정상적으로 프로그램이 실행되는 것을 확인할 수 있다.

[ec2-user@ip-10-1-10-254 Programming]$ java -cp "lib" OkJavaGoInHome
Error: Could not find or load main class OkJavaGoInHome
    
# 현재 디렉토리에서 OkJavaGoInHome.class를 열어서 거기에 있는 main안에 있는걸
# 실행시키다가 elevator 코드가 있으면 그거를 lib 밑에 있는 패키지를 참조할  있도록 해준것이다.
# 이렇게 다른사람이 사용할  있도록 정리정돈된 프로그램들을 라이브러리라고 부른다.
[ec2-user@ip-10-1-10-254 Programming]$ java -cp ".:lib" OkJavaGoInHome
JAVA APT 507  Elevator callForUp stopFloor : 1
JAVA APT 507  Security off
JAVA APT 507 / Hall Lamp  Lighting on
JAVA APT 507 / floorLamp  Lighting on

그러면 다시 org 파일을 원복하고, iot 폴더 밑에 class 파일들을 다시 삭제해보자

[ec2-user@ip-10-1-10-254 Programming]$ cd lib

[ec2-user@ip-10-1-10-254 lib]$ mv org /home/ec2-user/practice/Programming/
    
[ec2-user@ip-10-1-10-254 lib]$ cd ..

[ec2-user@ip-10-1-10-254 Programming]$ rm -rf lib

[ec2-user@ip-10-1-10-254 Programming]$ cd /home/ec2-user/practice/Programming/org/opentutorials/iot

[ec2-user@ip-10-1-10-254 iot]$ rm *.class

[ec2-user@ip-10-1-10-254 iot]$ cd /home/ec2-user/practice/Programming

[ec2-user@ip-10-1-10-254 Programming]$ tree .
.
├── ClassApp.java
├── InstanceApp.java
├── OkJavaGoInHome.class
├── OkJavaGoInHomeInput.java
├── OkJavaGoInHome.java
├── org
│   └── opentutorials
│       └── iot
│           ├── Aircon.java
│           ├── ColorDimmingLights.java
│           ├── DimmingLights.java
│           ├── Elevator.java
│           ├── Lighting.java
│           ├── OnOff.java
│           ├── Refrigerator.java
│           ├── Security.java
│           └── Speaker.java
├── Program.class
└── Program.java

3 directories, 16 files

실습 3) OkJavaGoinHomeInput.java 파일을 class 확장자로 컴파일하고, run 해보는데 input을 주는 것도 해보자.

  • OkJavaGoinHomeInput.java
import javax.swing.JOptionPane;

import org.opentutorials.iot.DimmingLights;
import org.opentutorials.iot.Elevator;
import org.opentutorials.iot.Lighting;
import org.opentutorials.iot.Security;

public class OkJavaGoInHomeInput {

    // paramter, 매개변수
    public static void main(String[] args) {

        String id = args[0];
        String bright = args[1];

        // Elevator call 
        Elevator myElevator = new Elevator(id);
        myElevator.callForUp(1);

        // Security off 
        Security mySecurity = new Security(id);
        mySecurity.off();

        // Light on
        Lighting hallLamp = new Lighting(id+" / Hall Lamp");
        hallLamp.on();

        Lighting floorLamp = new Lighting(id+" / floorLamp");
        floorLamp.on();

        DimmingLights moodLamp = new DimmingLights(id+" moodLamp");
        moodLamp.setBright(Double.parseDouble(bright));
        moodLamp.on();

    }

}

아래 명령어와 같이 OkJavaGoInHomeInput.java를 컴파일해서 실행해보자.

그러면 Error가 발생할 것이다.

[ec2-user@ip-10-1-10-254 Programming]$ javac OkJavaGoInHomeInput.java

[ec2-user@ip-10-1-10-254 Programming]$ tree .
.
├── ClassApp.java
├── InstanceApp.java
├── OkJavaGoInHome.class
├── OkJavaGoInHomeInput.class
├── OkJavaGoInHomeInput.java
├── OkJavaGoInHome.java
├── org
│   └── opentutorials
│       └── iot
│           ├── Aircon.java
│           ├── ColorDimmingLights.java
│           ├── DimmingLights.class
│           ├── DimmingLights.java
│           ├── Elevator.class
│           ├── Elevator.java
│           ├── Lighting.class
│           ├── Lighting.java
│           ├── OnOff.class
│           ├── OnOff.java
│           ├── Refrigerator.java
│           ├── Security.class
│           ├── Security.java
│           └── Speaker.java
├── Program.class
└── Program.java

3 directories, 22 files

[ec2-user@ip-10-1-10-254 Programming]$ java OkJavaGoInHomeInput
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
        at OkJavaGoInHomeInput.main(OkJavaGoInHomeInput.java:13)

위에 소스코드에서 String id = args[0]; 라인에서 문제가 발생했기 때문에 Error가 난것이다.

args에 입력값을 안줬기 때문에 당연히 Error가 난 것이다.

따라서 아래와 같이 arg를 추가해서 실행시키면 원하는대로 동작을 할 것이다.

[ec2-user@ip-10-1-10-254 Programming]$ java OkJavaGoInHomeInput "Seoul APT 507" "70"
Seoul APT 507  Elevator callForUp stopFloor : 1
Seoul APT 507  Security off
Seoul APT 507 / Hall Lamp  Lighting on
Seoul APT 507 / floorLamp  Lighting on
Seoul APT 507 moodLamp  DimmingLights bright : 70.0
Seoul APT 507 moodLamp  Lighting on

[ec2-user@ip-10-1-10-254 Programming]$ java OkJavaGoInHomeInput "Pusan APT 903" "50"
Pusan APT 903  Elevator callForUp stopFloor : 1
Pusan APT 903  Security off
Pusan APT 903 / Hall Lamp  Lighting on
Pusan APT 903 / floorLamp  Lighting on
Pusan APT 903 moodLamp  DimmingLights bright : 50.0
Pusan APT 903 moodLamp  Lighting on