0.6.13 • Published 2 years ago

@protyze/web_pen_sdk v0.6.13

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

Neo smartpen SDK for Web Platform

Web Pen SDK

This document is written to be used the web_pen_sdk for NeoSmartPen.

Installation

# web_pen_sdk setting

$ npm install web_pen_sdk
$ yarn add web_pen_sdk

Description

PenHelper

scanPen, connectDevice, serviceBinding_16, serviceBinding_128, characteristicBinding, disconnect, dotCallback, handleDot, messageCallback, handleMessage, ncodeToScreen, ncodeToScreen_smartPlate, isSamePage

펜 연결 설정/해제

1-1. scanPen

블루투스 펜 연결을 위해 디바이스를 스캔하는 로직입니다.

/** This function scans the device for bluetooth pen connection. */
scanPen = async () => { ... }
// Usage with react hook

const scanPen = () => {
  PenHelper.scanPen();
};

<Button onClick={scanPen}></Button>

1-2. connectDevice

실제 블루투스 장비와의 연결을 시도합니다.

connectDevice = async (device: any) => { ... }

1-3. serviceBinding_16, serviceBinding_128

블루투스 service를 16bit/128bit UUID로 binding 합니다.

serviceBinding_16 = async (service: any, device: any) => { ... }
serviceBinding_128 = async (service: any, device: any) => { ... }

1-4. characteristicBinding

블루투스 펜 장비의 연결이 완료된 후 발생되는 펜 event를 처리하기 위해 PenController를 설정합니다. 연결된 펜의 정보, Dot 처리 등 모든 펜 event는 PenController를 통해 처리됩니다. 해당 penController는 PenHelper.pens[] 안에 저장됩니다.

characteristicBinding = (read: any, write: any, device: any) => { ... }
// PenHelper.ts
this.pens = [penController, penController, ...];

// penController 사용씬 2-1 참조

1-5. disconnect

블루투스 장비 연결을 해제합니다.

disconnect = (penController: any) => { ... }
// Usage with react hook

const disconnectPen = () => {
  PenHelper.disconnect(controller);
}

펜 이벤트 정보

2-1. messageCallback, handleMessage

블루투스 펜의 이벤트를 처리합니다.

handleMessage = (controller: any, type: any, args: any) => { ... }
Type (Hex)TitleDescription
1 (0x01)PEN_AUTHORIZED펜 인증성공-
2 (0x02)PEN_PASSWORD_REQUEST비밀번호 요청-
4 (0x04)PEN_DISCONNECTED펜 연결해제-
6 (0x06)PEN_CONNECTION_SUCCESS펜 연결 성공-
17 (0x11)PEN_SETTING_INFO펜의 상태정보(배터리, 메모리 등)펜 충전시 배터리정보 -> 128
18 (0x12)PEN_SETUP_SUCCESS펜 설정 변경 성공-
19 (0x13)PEN_SETUP_FAILURE펜 설정 변경 실패-
26 (0x1a)PEN_USING_NOTE_SET_RESULT실시간 필기 데이터 요청 결과-
82 (0x52)PASSWORD_SETUP_SUCCESS패스워드 설정 성공-
83 (0x53)PASSWORD_SETUP_FAILURE패스워드 설정 실패-
84 (0x54)PEN_ILLEGAL_PASSWORD_0000신규 패스워드 0000 제한-
99 (0x63)EVENT_LOW_BATTERY배터리 잔량 부족시 이벤트-
100 (0x64)EVENT_POWER_OFF전원 OFF 이벤트-
34 (0x22)PEN_FW_UPGRADE_STATUS펜 펌웨어 업그레이드 상태-
35 (0x23)PEN_FW_UPGRADE_SUCCESS펜 펌웨어 업그레이드 성공-
36 (0x24)PEN_FW_UPGRADE_FAILURE펜 펌웨어 업드레이드 실패1=동일버전/2=공간부족/3=실패/4=압축지원X
37 (0x25)PEN_FW_UPGRADE_SUSPEND펜 펌웨어 업그레이드 중단-
48 (0x30)OFFLINE_DATA_NOTE_LIST오프라인 데이터 노트 리스트-
49 (0x31)OFFLINE_DATA_PAGE_LIST오프라인 데이터 페이지 리스트-
50 (0x32)OFFLINE_DATA_SEND_START오프라인 데이터 보내기 시작-
51 (0x33)OFFLINE_DATA_SEND_STATUS오프라인 데이터 보내는 상태-
52 (0x34)OFFLINE_DATA_SEND_SUCCESS오프라인 데이터 보내기 성공-
53 (0x35)OFFLINE_DATA_SEND_FAILURE오프라인 데이터 보내기 실패-
165 (0xa5)OFFLINE_DATA_DELETE_RESPONSE오프라인 데이터 삭제 상태-
84 (0x54)PEN_CONNECTION_FAILURE_BTDUPLICATE중복되는 블루투스 펜 연결 시도시 실패-
193 (0xc1)PEN_PROFILE펜의 프로필-
115 (0x73)RES_PDS펜 PDS-
104 (0x68)EVENT_DOT_ERROR펜 Dot 이벤트 에러-
105 (0x69)EVENT_DOT_PUI펜 Dot PUI 정보-
244 (0xf4)RES_LOG_INFO펜 로그 정보-
245 (0xf5)RES_LOG_DATA펜 로그 데이터-
// Usage with react hook

const [controller, setController] = useState();
const [penVersionInfo, setPenVersionInfo] = useState();
const [battery, setBattery] = useState();

useEffect(() => {
  PenHelper.messageCallback = async (mac, type, args) => {
    messageProcess(mac, type, args);
  }
});

const messageProcess = (mac, type, args) => {
  switch(type) {
    case PenMessageType.PEN_SETTING_INFO:
      const _controller = PenHelper.pens.filter((c) => c.info.MacAddress === mac)[0];
      setController(_controller);  // 해당 펜의 controller를 등록해준다.
      setBattery(args.Battery);  // 배터리 상태정보를 저장 -> 충전중일 때 128로 표시
      ...
    case PenMessageType.PEN_DISCONNECTED:  // 펜 연결해제시 모든 상태값 초기화
      setController(null);
      setPenInfo(null);
      setBattery(null);
    case PenMessageType.PEN_PASSWORD_REQUEST: ...  // 패스워드 요청시 처리
      onPasswordRequired(args);
    case PenMessageType.PEN_SETUP_SUCCESS:  // 팬 연결 성공시 처리
      if (controller) {
        setPenVersionInfo(controller.info);
      }
      ...
  }
}

...

const onPasswordRequired = (args: any) => {
  const password = input();
  ...
  if (args.RetryCount >= 10) {
    alert('펜의 모든정보가 초기화 됩니다.');
  }
  ...
  controller.InputPassword(password);  // 등록된 펜 controller를 사용하여 비밀번호를 전달한다.
}
...

펜 Dot 처리

3-1. dotCallback, handleDot

펜에서 넘어온 dot 데이터는 penController에 등록된 callback 함수인 handleDot을 통해 처리됩니다.

handleDot = (controller: any, args: any) => { ... }

3-2. ncodeToScreen

일반적인 ncode dot 좌표값을 view에 보여지게 하기 위하여 view size에 맞춰 변환시키는 로직입니다.

/**
 * This function is to convert the general ncode dot coordinate values ​​according to the view size in order to be shown in the view.
 * 
 * @param {Dot} dot
 * @param {View} view
 * @param {PaperSize} paperSize
 * @returns {ScreenDot}
 */
ncodeToScreen = (dot: Dot, view: View, paperSize: PaperSize) => { 
  ... 
}

3-3. ncodeToScreen_smartPlate

SmartPlate의 ncode dot 좌표값을 view에 보여지게 하기 위하여 view size에 맞춰 변환시키는 로직입니다.

/**
 * This function is to convert the SmartPlate ncode dot coordinate values ​​according to the view size in order to be shown in the view.
 * 
 * @param {Dot} dot
 * @param {View} view
 * @param {number} angle - possible angle value [0', 90', 180', 270']
 * @param {PaperSize} paperSize
 * @returns {ScreenDot}
 */
ncodeToScreen_smartPlate = (dot: Dot, view: View, angle: number, paperSize: PaperSize) => {
  ...
}
// Usage with react hook

useEffect(() => {
  PenHelper.dotCallback = async (mac, dot) => {
    strokeProcess(dot);
  }
});

const strokeProcess = (dot: Dot) => {
  ...
  const view = { width: canvasFb.width, height: canvasFb.height };

  let screenDot: ScreenDot;
  if (PenHelper.isSamePage(dot.pageInfo, PlateNcode_3)) {  // SmartPlate
    screenDot = PenHelper.ncodeToScreen_smartPlate(dot, view, angle, paperSize);
  } else {  // Default
    screenDot = PenHelper.ncodeToScreen(dot, view, paperSize);
  }
  ...
}

Additional

4. isSamePage

서로 다른 ncode 페이지 정보(SOBP)를 바탕으로 같은 페이지인지 구별하기 위한 로직입니다. SOBP는 페이지를 구별하기 위한 정보로서, Section/Owner/Book/Page의 줄임말입니다.

/**
 * This function is to distinguish whether it is the same page based on different ncode page information (SOBP).
 * 
 * @param {PageInfo} page1
 * @param {PageInfo} page2
 * @returns {boolean}
 */
isSamePage = (page1: PageInfo, page2: PageInfo) => {
  ...
}

NoteServer

extractMarginInfo, getNoteImage

1. extractMarginInfo

펜으로부터 받은 페이지 정보(SOBP)를 바탕으로 nproj로 부터 해당 ncode 페이지의 margin info를 추출하는 로직입니다.

/**
 * This function is to extract the margin info of the ncode page from nproj based on pageInfo.
 * 
 * @param {PageInfo} pageInfo
 * @returns {PaperSize}
 */
const extractMarginInfo = async (pageInfo: PageInfo) => {
  ...
}

2. getNoteImage

펜으로부터 받은 페이지 정보(SOBP)를 바탕으로 노트의 이미지를 받아오기 위한 로직입니다.

/**
 * This function is to get the note image based on pageInfo.
 * 
 * @param {PageInfo} pageInfo
 * @param {React.dispatch} setImageBlobUrl
 * @returns {boolean} - success -> setImageBlobUrl(imageBlobUrl)
 */
const getNoteImage = async (pageInfo: PageInfo, setImageBlobUrl: any) => {
  ...
}
// Usage with react hook

const [imageBlobUrl, setImageBlobUrl] = useState<string>();
const [paperSize, setPaperSize] = useState<PaperSize>();

useEffect(() => {
  async function getNoteImageUsingAPI(pageInfo) {
    await NoteServer.getNoteImage(pageInfo, setImageBlobUrl);
    const paperSize: PaperSize = await NoteServer.extractMarginInfo(pageInfo);
    setPaperSize(paperSize);
  }

  if (pageInfo) {
    getNoteImageUsingAPI(pageInfo);
  }
}, [pageInfo]);

PenController

RequestVersionInfo, SetPassword, InputPassword, RequestPenStatus, SetRtcTime, SetAutoPowerOffTime, SetPenCapPowerOnOffEnable, SetAutoPowerOnEnable, SetBeepSoundEnable, SetHoverEnable, SetOfflineDataEnable, SetColor, RequestAvailableNotes, RequestOfflineNoteList, RequestOfflinePageList, RequestOfflineData, RequestOfflineDelete, RequestFirmwareInstallation, RequestFirmwareUpload, RequestProfileInfo.., RequestProfileReadValue..

MethodsParametersDescription
RequestVersionInfo펜의 현재 버전을 요청
SetPasswordoldone: string, newone: string펜에 설정된 비밀번호를 변경 요청
InputPasswordpassword: string펜에 비밀번호를 전송
RequestPenStatus펜의 각종 설정 확인을 요청
SetRtcTime펜에 설정된 시각을 현재 시각으로 변경 요청
SetAutoPowerOffTimeminute: number펜에 설정된 자동종료 시간을 변경 요청 ( 최대 3600 분 )
SetPenCapPowerOnOffEnableenable: boolean펜에 설정된 펜 뚜껑을 이용한 전원 ON/OFF 기능 변경 요청
SetAutoPowerOnEnableenable: boolean펜에 설정된 펜 뚜껑 혹은 필기를 이용한 전원 ON 기능 변경 요청
SetBeepSoundEnableenable: boolean펜에 설정된 비프음 기능 변경 요청
SetHoverEnableenable: boolean펜에 설정된 호버 기능 변경 요청 ( 호버 : 필기 위치 가늠을 위한 시각적 Dot 표시 기능)
SetOfflineDataEnableenable: boolean펜에 설정된 오프라인 필기 데이터 저장 기능 변경 요청
SetColorcolor: number펜에 설정된 LED 색상 변경 요청 ( argb )
RequestAvailableNotessections: number , owners: number , notes: number | null펜에 실시간 필기 데이터에 대한 전송을 요청 ( notes 가 null 일 경우 노트 구분 없이 요청 )
RequestOfflineNoteListsection: number, owner: number펜에 저장된 오프라인 필기 데이터의 페이지 정보(book)를 요청 ( SO 가 0 일 경우 모든 note 리스트 반환 )
RequestOfflinePageListsection: number, owner: number, note: number펜에 저장된 오프라인 필기 데이터의 페이지 정보(page)를 요청 ( SOB 가 일치하는 한 노트의 page )
RequestOfflineDatasection: number, owner: number, note: number, deleteOnFinished: boolean, pages: number 펜에 저장된 오프라인 필기 데이터를 요청 ( P 가 빈 배열일 경우 노트 내 모든 page 요청 ) ( deleteOnFinished 가 true일 경우 전송 완료된 데이터 삭제 )
RequestOfflineDeletesection: number, owner: number, notes: number 펜에 저장된 오프라인 필기 데이터에 대한 삭제를 요청
RequestFirmwareInstallationfile: file, version: string, isCompressed: boolean펜에 설치된 펌웨어를 업그레이드하기 위한 질의
RequestFirmwareUploadoffset: number, data: Uint8Array, status: number펜에 펌웨어 데이터를 업로드
RequestProfileCreatename: string, password: string펜에 프로파일 생성을 요청
ReqeustProfileDeletename: string, password: string펜에 설정된 프로파일 제거 요청
RequestProfileInfoname: string펜에 설정된 프로파일 정보 요청
RequestProfileWriteValuename: string, passsword: string, data: { key: string: any }펜에 설정된 프로파일 내 데이터 작성 요청
RequestProfileReadValuename: string, keys: string 펜에 설정된 프로파일 내 데이터 정보 요청
RequestProfileDeleteValuename: string, password: string, keys: string 펜에 설정된 프로파일 내 데이터 제거 요청

전체적인 Flow

Library Set

import { PenHelper, NoteServer, PenMessageType } from 'web_pen_sdk';

Step1: PenHelper.scanPen()을 사용하여 pen 연결을 합니다.

/** Connect SmartPen to Web service */
PenHelper.scanPen();

Step2: 펜에 발생되는 이벤트(연결, 배터리정보 등)를 처리합니다.

useEffect(() => {
  PenHelper.messageCallback = async (mac, type, args) => {
    messageProcess(mac, type, args)
  }
});

const messageProcess = (mac, type, args) => {
  switch(type) {
    case PenMessageType.x:
    ...
  }
}

Step3: 펜으로부터 실시간 dot data를 받아옵니다.

/** Data Parsing from SmartPen */
PenHelper.dotCallback = (mac, dot) => {
  strokeProcess(dot);
}

const strokeProcess = (dot: Dot) => {
  ...
}

Step4: NoteServer.extractMarginInfo()를 사용하여 ncode paper의 size 정보를 받아옵니다.

/** Use NoteServer.extractMarginInfo() function to get size information of the ncode paper. */
const [paperSize, setPaperSize] = useState<PaperSize>();

const paperSize: PaperSize = await NoteServer.extractMarginInfo(pageInfo);

Step5: NoteServer.getNoteImage()를 사용하여 note의 image url을 받아옵니다.

/** Use NoteServer.getNoteImage() function to get image url of the note. */
const [imageBlobUrl, setImageBlobUrl] = useState<string>();

await NoteServer.getNoteImage(pageInfo, setImageBlobUrl);

Step6: 스마트펜으로부터 받은 ncode dot 데이터를 view 사이즈에 맞게 변환하여 사용합니다.

/**
 * Draw on Canvas with SmartPen
 * Coordinate Transformation with ncode_dot based on view_size, ncode_size
 */ 
const strokeProcess = (dot: Dot) => {
  const view = { width: canvasFb.width, height: canvasFb.height };

  // case Default:
  const screenDot = PenHelper.ncodeToScreen(dot, view, paperSize);
  // case SmartPlate:
  const screenDot = PenHelper.ncodeToScreen_smartPlate(dot, view, angle, paperSize)

  /** Create path data using screenDot */
const path = new Path(screenDot.x, screenDot.y);
}

🐾 Sample Page

https://github.com/MHCHOI3/web-sdk-sample2

📑 web_pen_sdk 공식문서

Google Docs

📜 License

Copyright(c) 2022, NeoLAB Convergence INC. No license allowed.

Release Note

~2022. 05. 05. (MHCHOI)

Updates

  • web_pen_sdk 패키지 배포
  • Sample page 구성

2022. 05. 06. (MHCHOI)

New Features

  • Pen Event Handler - 펜에서 발생되는 이벤트(연결, 해제, 패스워드 요구 등)를 처리하는 로직 추가

Updates

  • Pen Event Handler 추가에 따른 readme 업데이트
  • Sample Page에 펜 연결해제 기능 추가, 배터리 정보 표시될 수 있도록 업데이트
  • 펜 충전시 배터리 상태정보는 128을 가진다. -> 추가 설명 업데이트

2022. 05. 09. (WONHO)

New Features

  • SettingInfo, VersionInfo type declaration

Updates

  • SettingInfo, VersionInfo type 정의에 따른 코드 수정
  • PenHelper 안에 정의된 any type 수정

2022. 05. 13. (WONHO, ver.0.5.2)

New Features

  • DotErrorInfo type declaration
  • Dot Event 시 비정상 TimeStamp 시 Error 처리

Updates

  • 펜 비밀번호 설정, 변경, 해제 관련 messageType 추가 및 수정
  • 오프라인 및 실시간 데이터 관련 messageType 추가 및 수정
  • hover를 제외한 모든 Dot는 DotFilter 거치도록 수정
  • Packet Escape 로직 수정

2022. 05. 16. (WONHO, ver.0.5.3)

Updates

  • SupportedProtocolVersion 수정

2022. 05. 17. (WONHO, ver.0.5.4)

New Features

  • PEN_CONNECTION_SUCCESS MessageType declaration
  • ONLINE_PEN_HOVER_EVENT - v2.18 용 펜 hover 이벤트 로직 추가

Updates

  • SupportedProtocolVersion 수정

2022. 05. 18. (WONHO, ver.0.5.5)

Updates

  • SDK 내에서 자동으로 setHover 안하도록 수정

2022. 05. 31. (WONHO, ver.0.5.6)

New Features

  • Profile Feature - 펜 프로파일의 생성, 삭제, 조회 및 프로파일 항목의 생성, 삭제, 조회 로직 추가
  • Firmware Feature - 펌웨어 업데이트 로직 추가
  • PenDisk Init - 펜 디스크 초기화 요청 추가

Updates

  • 과밀한 통신 상태에서 블루투스 쓰기 진행 시 중첩연결에 따른 에러 방지 위한 코드 추가

2022. 06. 27. (WONHO, ver.0.5.7)

New Features

  • PUI Feature - 펜으로 스마트클래스킷 (부기보드) PUI 클릭 시, 메시지 출력 로직 추가

2022. 07. 04. (WONHO, ver.0.6.6)

New Features

  • PUI Feature - PUI 좌표 하드코딩으로 수정

2022. 07. 05. (WONHO, ver.0.6.7)

New Features

  • PUI Feature - PUI 좌표 nproj를 json으로 컨버팅해서 사용하도록 수정