npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@protyze/web_pen_sdk

v0.6.13

Published

Neosmartpen typescript library

Downloads

9

Readme

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) | Title | Description | | |-----------|-------|-------------| - | | 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..

| Methods | Parameters |Description | | --- | --- |--- | | RequestVersionInfo | | 펜의 현재 버전을 요청 | | SetPassword | oldone: string, newone: string | 펜에 설정된 비밀번호를 변경 요청 | | InputPassword | password: string | 펜에 비밀번호를 전송 | | RequestPenStatus | | 펜의 각종 설정 확인을 요청 | | SetRtcTime | | 펜에 설정된 시각을 현재 시각으로 변경 요청 | | SetAutoPowerOffTime | minute: number | 펜에 설정된 자동종료 시간을 변경 요청 ( 최대 3600 분 ) | | SetPenCapPowerOnOffEnable | enable: boolean | 펜에 설정된 펜 뚜껑을 이용한 전원 ON/OFF 기능 변경 요청 | | SetAutoPowerOnEnable | enable: boolean | 펜에 설정된 펜 뚜껑 혹은 필기를 이용한 전원 ON 기능 변경 요청 | | SetBeepSoundEnable | enable: boolean | 펜에 설정된 비프음 기능 변경 요청 | | SetHoverEnable | enable: boolean | 펜에 설정된 호버 기능 변경 요청 ( 호버 : 필기 위치 가늠을 위한 시각적 Dot 표시 기능) | | SetOfflineDataEnable | enable: boolean | 펜에 설정된 오프라인 필기 데이터 저장 기능 변경 요청 | | SetColor | color: number | 펜에 설정된 LED 색상 변경 요청 ( argb ) | | RequestAvailableNotes | sections: number[ ], owners: number[ ], notes: number[ ] | null| 펜에 실시간 필기 데이터에 대한 전송을 요청 ( notes 가 null 일 경우 노트 구분 없이 요청 ) | | RequestOfflineNoteList | section: number, owner: number | 펜에 저장된 오프라인 필기 데이터의 페이지 정보(book)를 요청 ( SO 가 0 일 경우 모든 note 리스트 반환 ) | | RequestOfflinePageList | section: number, owner: number, note: number | 펜에 저장된 오프라인 필기 데이터의 페이지 정보(page)를 요청 ( SOB 가 일치하는 한 노트의 page ) | | RequestOfflineData | section: number, owner: number, note: number, deleteOnFinished: boolean, pages: number[ ] | 펜에 저장된 오프라인 필기 데이터를 요청 ( P 가 빈 배열일 경우 노트 내 모든 page 요청 ) ( deleteOnFinished 가 true일 경우 전송 완료된 데이터 삭제 )| | RequestOfflineDelete | section: number, owner: number, notes: number[ ] | 펜에 저장된 오프라인 필기 데이터에 대한 삭제를 요청 | | RequestFirmwareInstallation | file: file, version: string, isCompressed: boolean | 펜에 설치된 펌웨어를 업그레이드하기 위한 질의 | | RequestFirmwareUpload | offset: number, data: Uint8Array, status: number | 펜에 펌웨어 데이터를 업로드 | | RequestProfileCreate | name: string, password: string | 펜에 프로파일 생성을 요청 | | ReqeustProfileDelete | name: string, password: string | 펜에 설정된 프로파일 제거 요청 | | RequestProfileInfo | name: string | 펜에 설정된 프로파일 정보 요청 | | RequestProfileWriteValue | name: string, passsword: string, data: { [key: string]: any } | 펜에 설정된 프로파일 내 데이터 작성 요청 | | RequestProfileReadValue | name: string, keys: string[ ] | 펜에 설정된 프로파일 내 데이터 정보 요청 | | RequestProfileDeleteValue | name: 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으로 컨버팅해서 사용하도록 수정