임베디드 프로그래밍 Lecture #08 2017. 11. 20.

Slides:



Advertisements
Similar presentations
명품 JAVA Programming 제 3 장 반복문, 배열, 예외처리.
Advertisements

Vision System Lab, Sang-Hun Han
11장. 프로토콜 핸들러 AI &HC I LAB 김 성 현.
14. 위피 게임: 가위바위보 게임 초기에 점수=0 처음 이기면 10 점 그 다음부터 이기면 점수=현재 점수*2 지면
어서와 Java는 처음이지! 제2장 자바 프로그래밍 기초.
10. 예외 처리.
임베디드 프로그래밍 Lecture #
임베디드 프로그래밍 Lecture #
컴퓨터 응용 및 실습 Part1. OOP&Java Programming data type Review
Chap05 상속 5.1 상속의 개요 5.2 멤버 변수의 상속 5.3 메소드의 상속과 오버라이딩(Overriding)
7장 배열 ②.
Programming for the java Virtual machine
제14장 원격 메소드 호출 김 기 환. 조 명 휘.
명품 JAVA Programming 제 13 장 스레드와 멀티태스킹.
명품 JAVA Essential.
12장. JSP에서 자바빈 활용 제12장.
J2ME(Java 2 Micro Edition) 무선 장치용 UI의 핵심 컴포넌트
제 4장 문 장 배정문 혼합문 제어문 표준 입출력.
제6장 제어(Control) 6.1 구조적 프로그래밍(Structured Programming)
명품 JAVA Programming.
2 서블릿의 기초.
5 익셉션 처리.
2주 실습강의 Java의 기본문법(1) 인공지능연구실.
Chapter 02 자바 기본구조 자바 프로그래밍의 기초적인 문법을 소개
임베디드 프로그래밍 Lecture #
제7장 제어구조 I – 식과 문장.
[ 단원 08 ] 예외처리와 스레드.
명품 JAVA Programming.
Java RMI (Remote Method Invocation)
임베디드 프로그래밍 Lecture #
[INA470] Java Programming Youn-Hee Han
8장 자바 입출력.
JAVA 프로그래밍 6장 객체지향프로그래밍의 핵심.
객체지향 언어와 클래스, 객체 ㅎㅎ 개요 클래스의 선언, 객체의 생성 및 속성 참조 방식 멤버 변수 메소드 한빛미디어(주)
자바 5.0 프로그래밍.
임베디드 프로그래밍 Lecture #
01. 직렬화와 역직렬화에 대하여 객체의 직렬화 직렬화와 역직렬화
AOP 개념 및 Spring의 AOP 기능.
명품 JAVA Programming 제 16 장 네트워크.
명품 Java Programming.
최용술 장 Thread 최용술
명품 JAVA Essential.
Chap07 예외 처리 7.1 예외의 개요 7.2 예외 관련 클래스 7.3 예외 처리.
10장 다중 스레드 10.1 스레드 개요 10.2 Thread 클래스 10.3 스레드 생성
2장 자바환경과 자바 프로그램 2.1 자바 개발 환경 2.2 자바 통합환경 2.3 자바 응용 프로그램과 애플릿 프로그램
프로그램 분석의 구현.
DataScience Lab. 박사과정 김희찬 (월)
주소록 프로그램.
제 4주 2014년 1학기 강원대학교 컴퓨터학부 담당교수: 정충교
Web Socket.
03. 안드로이드를 위한 Java 문법 제목. 03. 안드로이드를 위한 Java 문법 제목.
Ch.1 Iterator Pattern <<interface>> Aggregate +iterator
Chap10 다중 스레드 Section 1 : 스레드 개요 Section 2 : Thread 클래스와 스레드 생명주기
임베디드 프로그래밍 Lecture #
Web programming Chap 04 상속 김 정 석
제 2장 어휘구조와 자료형 토 큰 리 터 럴 주 석 자 료 형 배 열 형.
SpringFramework 중간고사 요약 REST by SpringFramework.
Java Chapter 4 ~ 주차.
컴퓨터공학실습(I) 3주 인공지능연구실.
Spring DI 이해 및 활용.
자바 5.0 프로그래밍.
Chapter 02. 소프트웨어와 자료구조.
Java 3장. 자바의 기본 구조 I : 변수, 자료형, 연산자 public class SumTest {
제8장 쓰레드 프로그래밍.
[ 단원 06 ] 상속과 다형성.
자바 5.0 프로그래밍.
C# 10장. 참조형.
이번 시간에는... 지난 시간까지 2회차에 걸쳐 WML의 택스트 포맷, 이미지 처리, 페이지 이동, 태스크 수행과 이벤트 처리 및 WML 사용자 Input 처리 태그 등, WML 개발에 대해서 알아보았습니다. 이번 시간에는 2회차에 걸쳐, WML 스크립트 개발에 대해서.
Java의 정석 제 7 장 객체지향개념 II-3 Java 정석 남궁성 강의
임베디드 프로그래밍 Lecture #
Presentation transcript:

임베디드 프로그래밍 Lecture #08 2017. 11. 20

목 차 명령 기반 장치 제어 구현 관제점(Control Point) 인터페이스 구현 관제점 기반 장치 클래스 구현 관제점 관리자 클래스 구현 CLI Console 구현

관제점(control Point) (1) 관제점(CP: Control Point) IoT 장치를 구성하는 센서(Sensor)와 액추에이터(Actuator)는 다양한 종류가 존재하며 인터페이스 방식도 다양 센서와 엑추에이터 장치를 일관된 방법으로 제어할 수 있는 추상화된 인터페이스가 필요 기본 추상 인터페이스: 식별 정보 – 내부 식별 정보(정수) / 사용자 인식 식별 정보(문자열) 상태값 – 장치의 상태를 하나의 상태값으로 표시 상태값 접근(access) – Get(Input)/Set(Output) 상태값 변화 알림(push) 관제점(CP) : 상기의 추상 인터페이스를 제공하는 객체

관제점(control Point) (2) 관제점(CP: Control Point) 종류 상태값에 따른 분류 디지털(Digital) 관제점 – 2가지 상태(0/1) 아날로그(Analog) 관제점 – 다양한 상태값을 가짐 입출력여부에 따른 분류 입력(Input) 관제점 - 읽기만 가능 출력(Output) 관제점 - 쓰기도 가능 관제점 타입(CP Type) DI(Digital Input) / DO(Digital Output) / AI(Analog Input) / AO(Analog Output)

관제점(control Point) (3) 관제점 구현의 제약 사항 내부 관제점 식별자 사용자 인식 관제점 식별자 상태값 관제점 생성 시에 자동 할당 외부에서 변경 불가능 사용자 인식 관제점 식별자 필요에 따라 외부에서 변경 가능 상태값 정수 타입 지정 디지털 관제점 – 0/1, 아날로그 관제점 – 주로 8~12 bit 정수 Thread Safe – 상호배제(Mutual Exclusion) 보장

관제점(control Point) (4) 관제점 구현의 제약 사항 관제점의 상태 변화 알림(Pushing) 출력 관제점 외부의 관제점 상태값 설정 요청에 의해 값이 변경될 때 현재의 상태값이 이전 상태값과 다를 때 입력 관제점 입력 변화에 의한 이벤트(Event) 발생 – DI CP 이벤트를 지원하지 않는 경우에는 주기적인 폴링(Polling) – AI CP 관제점의 정보를 요약하여 출력하는 인터페이스 제공

관제점(control Point) (5) 관제점 구현의 제약 사항 출력 관제점은 상태값에 대한 읽기/쓰기를 모두 지원 입력 관제점에 상태값 쓰기 인터페이스 추가

관제점 컨테이너(CP Container) 관제점 생성 및 관리 인터페이스를 제공하는 객체 관제점 일괄 생성 및 목록 유지 관제점 접근 인터페이스 관제점 목록 접근 인터페이스 관제점 일관 종료(닫기) 관제점 컨테이너는 유일한 인스턴스가 존재하여야 한다 동일한 관제점을 여러 개 생성할 수 없으므로 관제점 컨테이너의 인스턴스도 여 러 개 생성될 수 없다

명령어 처리기(Command Processor)(1) 관제점은 객체로 존재하기 때문에 외부에서 접근하기에는 제약적 관제점에 대한 외부의 일관된 제어 인터페이스가 필요 명령어 처리기(Command Processor) 관제점에 대한 제어 동작을 명령어(command)로 정의 명령어 처리를 통해 관제점 제어 명령어 추가를 통해 기능 확장이 용이 명령어가 Text 형식 전달  다양한 사용자 인터페이스 또는 외부 통신 프로토콜 과의 접목이 용이

명령어 처리기(Command Processor)(2) 명령어 처리기-명령어 help – 현재 지원하는 명령어와 간단한 설명 출력 list – 관제점 목록 출력 set – 관제점의 상태값 설정 get – 관제점의 상태값 읽기 rename – 관제점의 사용자 인식 식별자 변경

콘솔(Console) 콘솔(Console) CLI(Command Line Interface) 방식으로 사용자 인터페이스를 제공하는 객체 또는 프로그램 일반적으로 명령어 입력을 위한 prompt를 화면에 출력 사전에 정의된 명령어를 입력 받아 자체적으로 처리하거나 명령어 처 리기 객체를 통해 처리하고 결과를 화면에 출력 인터페이스 장치 또는 통신 방식에 따라 분류 Terminal Console – 터미널 장치로 사용 UART Console – UART 통신 채널 사용 Remote Console – 인터넷 기반의 통신 채널 사용, 다양한 통신 프로토콜 사용 가 능

명령 기반 장치 제어 프로그램 명령 기반 장치 제어 프로그램 터미널 장치를 통해 명령어를 사용하여 IoT 장치를 제어하는 프로그램 객체 구성: CP Container Command Processor Console CP #1 CP #2 CP #n • • •

테스트 하드웨어 구성 라즈베리파이 회로 구성: 핀 연결 장치 연결 핀 LED GPIO Blink LED GPIO18(12) TMP102BB PCF8591BB Alert GPIO23(16) 장치 연결 핀 LED GPIO GPIO17(11), GPIO27(13), GPIO22(15) PCF8591BB SDA(3), SCL(5) TMP102BB SDA(3), SCL(5), Alert(GPIO23(16)) Blink LED GPIO18(12)

장치 제어 콘솔 프로그램(1) 프로젝트 생성 : JiotCliApp 개발 플랫폼: Spring Tool Suite(STS)

장치 제어 콘솔 프로그램(2) 패티지 생성 : com.example.cli – CLI Interface 관련 객체 및 메인 객체 포함 com.example.i2c_dev – i2c 장치 제어 관련 객체 포함 com.example.thing – 관제점 구현 관련 객체 포함

장치 제어 콘솔 프로그램(3) Resource 추가: src/main/resources 폴더에 lib 폴더 생성 lib 폴더에 dio.jar, dio.properties, java.policy 파일 추가 pom.xml 설정 dio.jar를 로컬 maven repository에서 설치하는 plugin 추가 dio.jar에 대한 dependency 추가 배포 패키지 생성 plugin 추가

pom.xml 설정:

장치 제어 콘솔 프로그램(4) I2C 장치 인터페이스 구현 강의 4~5에서 구현 com.example.i2c_dev 패키지에 이미 구현한 동일 패키지 소스를 추가

장치 제어 콘솔 프로그램(5) 관제점 구현 package com.example.thing; import java.util.Observable; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.atomic.AtomicInteger; public abstract class ControlPoint extends Observable { public static enum Type { DI, DO, TDO, AI, AO }; protected static final ScheduledExecutorService POLLING = Executors.newSingleThreadScheduledExecutor(); private static final AtomicInteger COUNT = new AtomicInteger(0); private int id; private String name; protected AtomicInteger presentValue = new AtomicInteger(0); public ControlPoint() { id = COUNT.getAndIncrement(); name = getClass().getName() + "-" + id; } public int getId() { return id; } public String getName() { return name; public void setName(String name) { this.name = name; fireChanged("name"); public int getPresentValue() { return presentValue.get(); protected void fireChanged() { setChanged(); notifyObservers();

장치 제어 콘솔 프로그램(6) 관제점 구현 (계속) protected void fireChanged(Object arg) { setChanged(); notifyObservers(arg); } @Override public String toString() { // TODO Auto-generated method stub return getName() + "(" + getId() + ") [type=" + getType() + ", enabled=" + isEnabled() + "]"; public abstract void open(); public abstract void close(); public abstract boolean isEnabled(); public abstract Type getType();

장치 제어 콘솔 프로그램(7) 출력 관제점 구현 package com.example.thing; public abstract class OutputControlPoint extends ControlPoint { public abstract void setPresentValue(int value); }

장치 제어 콘솔 프로그램(8) CommandExecutable Interface 구현 package com.example.thing; public interface CommandExecutable { int executeCommmad(String[] command); }

장치 제어 콘솔 프로그램(9) DI 관제점 구현 package com.example.thing; import java.io.IOException; import jdk.dio.ClosedDeviceException; import jdk.dio.DeviceManager; import jdk.dio.DeviceNotFoundException; import jdk.dio.UnavailableDeviceException; import jdk.dio.UnsupportedDeviceTypeException; import jdk.dio.gpio.GPIOPin; import jdk.dio.gpio.PinEvent; import jdk.dio.gpio.PinListener; public class GPIOPinControlPoint extends ControlPoint { private int pinId; private GPIOPin pinDev; public GPIOPinControlPoint(int pinId) { super(); this.pinId = pinId; } @Override public void open() { try { pinDev = (GPIOPin)DeviceManager.open( pinId, GPIOPin.class); presentValue.set(pinDev.getValue() ? 1 : 0); } catch (UnsupportedDeviceTypeException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (DeviceNotFoundException e) { } catch (UnavailableDeviceException e) { } catch (IOException e) { }

try { pinDev.setInputListener(new PinListener() { @Override public void valueChanged(PinEvent arg0) { int oldValue = getPresentValue(); int newValue = pinDev.getValue() ? 1 : 0; presentValue.set(newValue); if (oldValue != newValue) { fireChanged(); } } catch (UnavailableDeviceException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClosedDeviceException e) { } catch (IOException e) { }); @Override public void close() { if (isEnabled()) { try { pinDev.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } pinDev = null; public boolean isEnabled() { return (pinDev != null && pinDev.isOpen()); public Type getType() { // TODO Auto-generated method stub return Type.DI;

장치 제어 콘솔 프로그램(10) DO 관제점 구현 package com.example.thing; import java.io.IOException; import jdk.dio.ClosedDeviceException; import jdk.dio.DeviceManager; import jdk.dio.DeviceNotFoundException; import jdk.dio.UnavailableDeviceException; import jdk.dio.UnsupportedDeviceTypeException; import jdk.dio.gpio.GPIOPin; public class GPIOPinOutputControlPoint extends OutputControlPoint { private int pinId; private GPIOPin pinDev; public GPIOPinOutputControlPoint(int pinId) { super(); this.pinId = pinId; } @Override public void open() { try { pinDev = (GPIOPin)DeviceManager.open( pinId, GPIOPin.class); } catch (UnsupportedDeviceTypeException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (DeviceNotFoundException e) { } catch (UnavailableDeviceException e) { } catch (IOException e) { } setPresentValue(0);

@Override public void close() { if (isEnabled()) { try { pinDev.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } pinDev = null; public boolean isEnabled() { return (pinDev != null && pinDev.isOpen()); public Type getType() { return Type.DO; public void setPresentValue(int value) { int oldValue = getPresentValue(); if (writeValue(value) && oldValue != getPresentValue()) { fireChanged(); private boolean writeValue(int value) { boolean success = false; try { pinDev.setValue(value == 1); presentValue.set(value); success = true; } catch (UnavailableDeviceException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClosedDeviceException e) { } catch (IOException e) { } return success;

장치 제어 콘솔 프로그램(11) TDO 관제점 구현 package com.example.thing; import java.io.IOException; import java.util.concurrent.Semaphore; import jdk.dio.ClosedDeviceException; import jdk.dio.DeviceManager; import jdk.dio.DeviceNotFoundException; import jdk.dio.UnavailableDeviceException; import jdk.dio.UnsupportedDeviceTypeException; import jdk.dio.gpio.GPIOPin; public class AsyncToggleOutputPoint extends OutputControlPoint implements CommandExecutable { private int pinId; private GPIOPin pinDev; private Thread toggleThread; private Semaphore toggleSem = null; private boolean bRun = true; private boolean bToggle = false; private int interval; public AsyncToggleOutputPoint(int pinId) { super(); this.pinId = pinId; bRun = true; bToggle = false; interval = 500; toggleSem = new Semaphore(1); try { toggleSem.acquire(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } public void setInterval(int interval) { this.interval = interval;

public AsyncToggleOutputPoint(int pinId) { super(); this.pinId = pinId; bRun = true; bToggle = false; interval = 500; toggleSem = new Semaphore(1); try { toggleSem.acquire(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } public void setInterval(int interval) { this.interval = interval; @Override public void open() { pinDev = (GPIOPin)DeviceManager.open( pinId, GPIOPin.class); } catch (UnsupportedDeviceTypeException e) { } catch (DeviceNotFoundException e) { } catch (UnavailableDeviceException e) { } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { setPresentValue(0); pinDev.setValue(false); } catch (UnavailableDeviceException e1) { e1.printStackTrace(); } catch (ClosedDeviceException e1) { } catch (IOException e1) { toggleThread = new Thread(new Runnable() { @Override public void run() { while (bRun) { toggleSem.acquire(); } catch (InterruptedException e) { while (bToggle) { pinDev.setValue(true); Thread.sleep(interval);

if (!bRun || !bToggle) { pinDev.setValue(false); break; } Thread.sleep(interval); } catch (InterruptedException e) { e.printStackTrace(); } catch (IOException e) { } // while } // while }); toggleThread.start(); @Override public void close() { if (isEnabled()) { if (toggleThread != null) { try { bRun = false; toggleThread.join(); // TODO Auto-generated catch block try { pinDev.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } pinDev = null; @Override public boolean isEnabled() { return (pinDev != null && pinDev.isOpen()); public Type getType() { return Type.TDO; public void setPresentValue(int value) { bToggle = (value == 1); if (bToggle) { // start toggling toggleSem.release(); presentValue.set(value);

@Override public int executeCommmad(String[] command) { if (command.length >= 2) { if (command[0] != null && command[0].equals("interval")) { setInterval(Integer.parseInt(command[1])); return Integer.parseInt(command[1]); } return 0;

장치 제어 콘솔 프로그램(12) AO 관제점 구현 package com.example.thing; import java.io.IOException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import com.example.i2c_dev.drivers.PCF8591Device; public class PCF8591AnalogIOPoint extends OutputControlPoint { private static AtomicReference<PCF8591Device> adcDevice = new AtomicReference<PCF8591Device>(); private static PCF8591Device getAdcDevice() { try { if (adcDevice.get() == null) adcDevice.set(new PCF8591Device()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return adcDevice.get(); private static final AtomicInteger OPEN_COUNT = new AtomicInteger(0); private static final int PWM_PIN = 4; private int aioPin; private Future pollingFuture; public PCF8591AnalogIOPoint(int aioPin) { super(); this.aioPin = aioPin; } @Override public void open() { OPEN_COUNT.incrementAndGet(); if (isAnalogInput()) { pollingFuture = POLLING.scheduleWithFixedDelay( new Runnable() { public void run() { int oldValue = presentValue.get(); int newValue = getAdcDevice().analogRead(aioPin);

presentValue.set(newValue); if (oldValue != newValue) { fireChanged(); } }, 0, 1, TimeUnit.SECONDS); @Override public void close() { int ref_count = OPEN_COUNT.decrementAndGet(); if (ref_count >= 0) { if (isAnalogInput()) { pollingFuture.cancel(false); if (ref_count == 0) { getAdcDevice().close(); adcDevice.set(null); else { OPEN_COUNT.set(0); public boolean isEnabled() { return (getAdcDevice().device.isOpen()); @Override public Type getType() { return isAnalogInput() ? Type.AI : Type.AO; } public void setPresentValue(int value) { try { if (!isAnalogInput()) { int oldValue = presentValue.get(); getAdcDevice().analogWrite(value); presentValue.set(value); if (oldValue != value) { fireChanged(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); private boolean isAnalogInput() { return (this.aioPin < PWM_PIN);

장치 제어 콘솔 프로그램(13) 명령어 처리기(Command Processor) 구현 package com.example.cli; import java.io.IOException; import java.lang.reflect.Array; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; import com.example.thing.CommandExecutable; import com.example.thing.ControlPoint; import com.example.thing.ControlPointContainer; import com.example.thing.OutputControlPoint; public class Commander { private static AtomicReference<Commander> instance = new AtomicReference<Commander>(); public static Commander getInstance() { if (instance.get() == null) { instance.set(new Commander()); } return instance.get(); public interface Command { public String execute(String[] command); public String getHelp(); } private Map<String, Command> commands = new HashMap<String, Command>(); private Commander() { commands.put("list", new Command() { @Override public String execute(String[] command) { StringBuilder sb = new StringBuilder(); Collection<ControlPoint> points = ControlPointContainer.getInstance().getControlPoints(); sb.append("ControlPointContainer has " + points.size() +"'s control points."); for (ControlPoint point : points) { sb.append(point.toString()) .append(System.lineSeparator()); return sb.toString();

@Override public String getHelp() { return "list: display a list for control points"; } }); commands.put("set", new Command() { public String execute(String[] command) { if (command.length != 3) { return "Invalid set command"; } else { int pointId = Integer.parseInt(command[1]); ControlPoint point = ControlPointContainer.getInstance().getControlPoint(pointId); if (point == null) { return "Cannot find a point(" + pointId + ")"; } else if (point instanceof OutputControlPoint) { int value = Integer.parseInt(command[2]); OutputControlPoint writablePoint = (OutputControlPoint)point; writablePoint.setPresentValue(value); return null; return "It is not a output point(" + pointId + ")"; @Override public String getHelp() { return "set: set the present value of point. format" + "-> set [point id] [value]"; } }); commands.put("get", new Command() { public String execute(String[] command) { if (command.length != 2) { return "Invalid get command"; } else { int pointId = Integer.parseInt(command[1]); ControlPoint point = ControlPointContainer.getInstance().getControlPoint(pointId); if (point == null) { return "Cannot find a point(" + pointId + ")"; return String.valueOf(point.getPresentValue()); return "get: get the present value of point. format" + "-> get [point id]";

commands.put("rename", new Command() { @Override public String execute(String[] command) { if (command.length != 3) { return "Invalid rename command"; } else { int pointId = Integer.parseInt(command[1]); ControlPoint point = ControlPointContainer.getInstance().getControlPoint(pointId); if (point == null) { return "Cannot find a point(" + pointId + ")"; point.setName(command[2]); return null; } public String getHelp() { return "rename: change the name of point. format" + "-> rename [point id] [new name]"; }); commands.put("exec", new Command() { if (command.length < 3) { return "Invalid exec command"; int pointId = Integer.parseInt(command[1]); ControlPoint point = ControlPointContainer.getInstance().getControlPoint(pointId); if (point == null) { return "Cannot find a point(" + pointId + ")"; } else if (point instanceof CommandExecutable) { String[] subCommand = Arrays.copyOfRange(command, 2, command.length); int value = ((CommandExecutable)point).executeCommmad(subCommand); return String.valueOf(value); } else { return "It is not a command-executable point(" + pointId + ")"; } @Override public String getHelp() { return "exec: execute extended command for control point. format" + "-> exec [point id] [command] [value] ..."; });

public String execute(String[] command) throws IOException { if (command.length == 0) { return null; } if (command[0].equals("help")) { return help(); Command cmd = commands.get(command[0]); if (cmd == null) { return "Invalid command: " + command[0]; return cmd.execute(command); private String help() { StringBuilder sb = new StringBuilder(); sb.append("Thing's commands") .append(System.lineSeparator()); for (Command command : commands.values()) { sb.append(command.getHelp()) return sb.toString(); public void register(String name, Command cmd) { commands.put(name, cmd); public void unregister(String name) { commands.remove(name);

장치 제어 콘솔 프로그램(14) 콘솔(Console) 구현 package com.example.cli; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.nio.channels.Channels; import java.util.Observable; import java.util.Observer; import com.example.thing.ControlPoint; import jdk.dio.DeviceManager; import jdk.dio.uart.UART; import jdk.dio.uart.UARTConfig; public class UARTConsole implements Observer { private UART uart = null; private BufferedReader in; private BufferedWriter out; public UARTConsole(UARTConfig config) throws IOException { /* uart = (UART) DeviceManager.open(config); in = new BufferedReader(Channels.newReader(uart, "UTF-8")); out = new BufferedWriter(Channels.newWriter(uart, "UTF-8")); uart.setReceiveTimeout(100); */ in = new BufferedReader(new InputStreamReader(System.in)); out = new BufferedWriter(new OutputStreamWriter(System.out)); } public void run() throws IOException { System.out.println("Waiting command..."); write("Please input command: "); for (String line = in.readLine(); line == null || !line.equals("quit"); line = in.readLine()) { if(line == null) continue; System.out.println("Received message: " + line); String[] command = line.split(" "); String result;

try{ result = Commander.getInstance().execute(command); }catch(Throwable ex){ result = "Exception happend: " + ex.getMessage(); } if(result != null) write(result); else write(""); write("Good bye!"); close(); @Override public void update(Observable ob, Object arg) { if(ob instanceof ControlPoint){ ControlPoint point = (ControlPoint) ob; if(arg == null){ write("[Observer] Changed value (" + point.getName() + "): " + point.getPresentValue()); }else{ if (arg.toString().equals("name")) { write("[Observer] Changed name (" + point.getName() + "): " + point.getName()); else { write("[Observer] Changed (" + point.getName() + "): " + arg); private void write(String result) { try { out.write(result); out.newLine(); out.write("Console >> "); out.flush(); } catch (IOException ex) { } private void close() throws IOException { in.close(); out.close(); if (uart != null) uart.close();

장치 제어 콘솔 프로그램(15) 메인 클래스 구현 package com.example.cli; import java.io.IOException; import com.example.thing.ControlPoint; import com.example.thing.ControlPointContainer; import jdk.dio.uart.UARTConfig; public class CLIMain { public static void main(String[] args) throws IOException { ControlPointContainer pointHandler = ControlPointContainer.getInstance(); pointHandler.start(); UARTConfig config = new UARTConfig( "ttyAMA0", 1, 9600, UARTConfig.DATABITS_8, UARTConfig.PARITY_NONE, UARTConfig.STOPBITS_1, UARTConfig.FLOWCONTROL_NONE ); UARTConsole console = new UARTConsole(config); for(ControlPoint point: pointHandler.getControlPoints()){ point.addObserver(console); } console.run(); pointHandler.stop();

장치 제어 콘솔 프로그램(16) 배포 패키지 생성 및 배포 Maven Install 명령어 실행으로 배포 패키지 생성 Samba를 통해 RaspberryPi의 pi 홈 디렉토리 공유 배포 패키지 배포

장치 제어 콘솔 프로그램(17) 실행 및 테스트