update status
This commit is contained in:
parent
2c89f32c8d
commit
1941ab0c52
|
@ -1,31 +1,33 @@
|
|||
const EventEmitter = require('events')
|
||||
const EventEmitter = require('events') // eslint-disable-line
|
||||
const escpos = require('escpos')
|
||||
const config = require('./config.json')
|
||||
// const config = require('./config.json')
|
||||
const fs = require('fs')
|
||||
const iconv = require('iconv-lite')
|
||||
|
||||
class PrinterDevice {
|
||||
constructor() {
|
||||
constructor () {
|
||||
this._serial = ''
|
||||
this._feed = 8
|
||||
this._isOpen = false
|
||||
this._device = null
|
||||
this._printer = null
|
||||
this._type = null // type = serial or console
|
||||
}
|
||||
|
||||
encodeStr(str){
|
||||
if(!str || typeof str != 'string') return false
|
||||
encodeStr (str) {
|
||||
if (!str || typeof str !== 'string') return false
|
||||
return iconv.encode(str, 'big5')
|
||||
}
|
||||
|
||||
async connect() {
|
||||
async connect () {
|
||||
let chkSerial = await new Promise((resolve, reject) => {
|
||||
fs.access(config.printer.serial, err => {
|
||||
fs.access(this._serial, err => {
|
||||
if (err) return resolve(false)
|
||||
return resolve(true)
|
||||
})
|
||||
})
|
||||
if (chkSerial) {
|
||||
this._device = new escpos.Serial(config.printer.serial)
|
||||
this._device = new escpos.Serial(this._serial)
|
||||
this._type = 'serial'
|
||||
} else {
|
||||
this._device = new escpos.Console()
|
||||
|
@ -35,8 +37,8 @@ class PrinterDevice {
|
|||
this.openSerial()
|
||||
}
|
||||
|
||||
async openSerial() {
|
||||
if (!this._device || this._type != 'serial') return
|
||||
async openSerial () {
|
||||
if (!this._device || this._type !== 'serial') return
|
||||
this._isOpen = await new Promise((resolve, reject) => {
|
||||
this._device.open(err => {
|
||||
if (err) return resolve(false)
|
||||
|
@ -45,7 +47,7 @@ class PrinterDevice {
|
|||
})
|
||||
}
|
||||
|
||||
async printerString(str) {
|
||||
async printerString (str) {
|
||||
if (!this._isOpen || !this._printer) return false
|
||||
|
||||
this._printer.font('a')
|
||||
|
@ -66,8 +68,8 @@ class PrinterDevice {
|
|||
case 's':
|
||||
let size = tmp.substring(2)
|
||||
let sarr = size.trim().split(',')
|
||||
if (sarr.length != 2) break
|
||||
if(!isFinite(sarr[0]) || !isFinite(sarr[1])) break
|
||||
if (sarr.length !== 2) break
|
||||
if (!isFinite(sarr[0]) || !isFinite(sarr[1])) break
|
||||
sarr = sarr.map(t => Math.floor(t))
|
||||
this._printer.size(sarr[0], sarr[1])
|
||||
break
|
||||
|
@ -77,25 +79,49 @@ class PrinterDevice {
|
|||
}
|
||||
}
|
||||
|
||||
this._printer.cut(true, config.printer.cutFeed || 4)
|
||||
this._printer.cut(true, this._feed || 4)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
async close() {
|
||||
async printTestPage () {
|
||||
await this.connect()
|
||||
if (!this._isOpen) return false
|
||||
this._printer.align('ct')
|
||||
this._printer.size(1, 1)
|
||||
this._printer.text('Print Test Page')
|
||||
this._printer.align('lt')
|
||||
this._printer.size(1, 1)
|
||||
this._printer.text('Test Page Content')
|
||||
await this.close()
|
||||
return true
|
||||
}
|
||||
|
||||
async close () {
|
||||
if (!this._device) return
|
||||
if (this._type == 'serial') {
|
||||
if (this._type === 'serial') {
|
||||
let self = this
|
||||
await new Promise((resolve, reject) => {
|
||||
self._printer.close(() => {
|
||||
self._printer = null
|
||||
self._isOpen = false
|
||||
resolve(1)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get isOpen() {
|
||||
return this._isOpen ? true : false
|
||||
get isOpen () {
|
||||
return !!this._isOpen
|
||||
}
|
||||
|
||||
set serial (str) {
|
||||
this._serial = str
|
||||
}
|
||||
|
||||
set feed (str) {
|
||||
if (!isFinite(str)) return
|
||||
this._feed = Math.floor(parseInt(str))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ const notifyDesciptor = new bleno.Descriptor({
|
|||
})
|
||||
|
||||
class DataCharacteristic extends bleno.Characteristic {
|
||||
constructor() {
|
||||
constructor () {
|
||||
super({
|
||||
uuid: config.uuid.service.func.data,
|
||||
properties: ['write', 'writeWithoutResponse', 'notify'],
|
||||
|
@ -23,15 +23,15 @@ class DataCharacteristic extends bleno.Characteristic {
|
|||
this._notifyFunc = null
|
||||
}
|
||||
|
||||
onWriteRequest(data, offset, withoutResponse, callback) {
|
||||
onWriteRequest (data, offset, withoutResponse, callback) {
|
||||
console.log(`offset :: ${offset} , withoutRes :: ${withoutResponse}`)
|
||||
console.log(`get data`, data)
|
||||
|
||||
if (data.length == 1 && data[0] == 0x00) {
|
||||
if (data.length === 1 && data[0] === 0x00) {
|
||||
tmp = []
|
||||
idx = 0
|
||||
failFlag = false
|
||||
} else if (data.length == 1 && data[0] == 0xff) {
|
||||
} else if (data.length === 1 && data[0] === 0xff) {
|
||||
console.log(Buffer.from(tmp).toString())
|
||||
if (!failFlag) {
|
||||
localEvent.emit('print', Buffer.from(tmp).toString())
|
||||
|
@ -53,17 +53,17 @@ class DataCharacteristic extends bleno.Characteristic {
|
|||
}
|
||||
}
|
||||
|
||||
sendNotidy(str) {
|
||||
sendNotidy (str) {
|
||||
if (!this._notifyFunc) return
|
||||
this._notifyFunc(Buffer.from(str))
|
||||
}
|
||||
|
||||
onSubscribe(maxValueSize, cb) {
|
||||
onSubscribe (maxValueSize, cb) {
|
||||
console.log(maxValueSize)
|
||||
this._notifyFunc = cb
|
||||
}
|
||||
|
||||
onUnsubscribe() {
|
||||
onUnsubscribe () {
|
||||
this._notifyFunc = null
|
||||
}
|
||||
}
|
||||
|
|
13
ble/index.js
13
ble/index.js
|
@ -1,24 +1,21 @@
|
|||
const config = require('../config.json')
|
||||
const bleno = require('bleno')
|
||||
const adapterName = 'BLE_Printer'
|
||||
const serverUUID = config.uuid.main
|
||||
const localEvent = require('./localEvent')
|
||||
const fs = require('fs')
|
||||
const localEvent = require('./localEvent') //eslint-disable-line
|
||||
const MainService = require('./main-service')
|
||||
|
||||
bleno.on('stateChange', state => {
|
||||
console.log(`bt device state ${state}`)
|
||||
if (state == 'poweredOn') {
|
||||
|
||||
bleno.startAdvertising(adapterName, [serverUUID], (error) => {
|
||||
|
||||
})
|
||||
if (state === 'poweredOn') {
|
||||
bleno.startAdvertising(adapterName, [serverUUID])
|
||||
} else {
|
||||
bleno.stopAdvertising()
|
||||
}
|
||||
})
|
||||
|
||||
bleno.on('advertisingStart', function (error) {
|
||||
console.log('on -> advertisingStart: ' + (error ? 'error ' + error : 'success'));
|
||||
console.log('on -> advertisingStart: ' + (error ? 'error ' + error : 'success'))
|
||||
|
||||
if (!error) {
|
||||
bleno.setServices([new MainService()], error => {
|
||||
|
|
|
@ -6,7 +6,7 @@ const GdataCharacteristic = require('./gdata-characteristic')
|
|||
const dataCharacteristic = new GdataCharacteristic()
|
||||
|
||||
class MainService extends bleno.PrimaryService {
|
||||
constructor() {
|
||||
constructor () {
|
||||
super({
|
||||
uuid: config.uuid.service.id,
|
||||
characteristics: [
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
const bleno = require('bleno')
|
||||
const config = require('./config.json')
|
||||
|
||||
class TimeCharacteristic extends bleno.Characteristic {
|
||||
constructor() {
|
||||
super({
|
||||
uuid: config.uuid.service.func.time,
|
||||
properties: ['read'],
|
||||
descriptors: [
|
||||
new bleno.Descriptor({
|
||||
uuid: '88ff',
|
||||
value: 'Now Time'
|
||||
})
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
onReadRequest(offset, callback) {
|
||||
console.log(`offset :: ${offset}`)
|
||||
callback(this.RESULT_SUCCESS, new Buffer(`${Date.now()}`))
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TimeCharacteristic
|
|
@ -1,8 +1,8 @@
|
|||
const EventEmitter = require('events')
|
||||
const util = require('util')
|
||||
const util = require('util') //eslint-disable-line
|
||||
|
||||
class LocalEvent extends EventEmitter {
|
||||
constructor(){
|
||||
constructor () { // eslint-disable-line
|
||||
super()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
"version": "0.0.1",
|
||||
"main": "app.js",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"check":"standard --fix --verbose"
|
||||
},
|
||||
"dependencies": {
|
||||
"bleno": "^0.4.2",
|
||||
"escpos": "^2.4.3",
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
html, body{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: #eee;
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,12 +1,100 @@
|
|||
/* eslint-disable no-throw-literal */
|
||||
const KoaRouter = require('koa-router')
|
||||
const router = new KoaRouter()
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const Printer = require('../PrinterDev')
|
||||
const KoaBody = require('koa-body')
|
||||
const uuid = require('uuid')
|
||||
|
||||
router.use(async (c, n) => {
|
||||
c.data = {
|
||||
title: 'Printer System Setup'
|
||||
}
|
||||
try {
|
||||
await n()
|
||||
} catch (err) {
|
||||
if (typeof err === 'string') {
|
||||
c.body = err
|
||||
} else {
|
||||
c.body = err.toString()
|
||||
}
|
||||
}
|
||||
|
||||
if (c.async) {
|
||||
c.body = {
|
||||
status: 0,
|
||||
msg: c.body
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
router
|
||||
.get('/', async (c, n) => {
|
||||
c.redirect('/install')
|
||||
})
|
||||
.all('/install', async (c, n) => {
|
||||
c.body = 'install'
|
||||
.get('/install', async (c, n) => {
|
||||
// get ttys
|
||||
let ttys = await new Promise((resolve, reject) => {
|
||||
fs.readdir(path.resolve('/dev'), (err, list) => {
|
||||
if (err) return resolve([])
|
||||
let arr = []
|
||||
for (let it of list) {
|
||||
if (it.startsWith('tty')) {
|
||||
arr.push(path.resolve('/dev', it))
|
||||
}
|
||||
}
|
||||
resolve(arr)
|
||||
})
|
||||
})
|
||||
c.data.ttys = ttys
|
||||
await c.render('install/index', c.data)
|
||||
})
|
||||
.post('/install/printer_test', KoaBody(), async (c, n) => {
|
||||
c.async = true
|
||||
let arr = c.request.body
|
||||
if (!arr.device) throw '請輸入印表機連接埠'
|
||||
let device = arr.device
|
||||
let feed = arr.feed || 8
|
||||
if (!isFinite(feed) || feed < 0) throw '切紙前換行必須是整數'
|
||||
feed = typeof feed !== 'number' ? Math.floor(parseInt(feed)) : feed
|
||||
|
||||
Printer.serial = device
|
||||
Printer.feed = feed
|
||||
|
||||
let status = await Printer.printTestPage()
|
||||
|
||||
if (!status) c.body = '測試失敗'
|
||||
else c.body = '測試成功'
|
||||
})
|
||||
.post('/install/write_config', KoaBody(), async (c, n) => {
|
||||
c.async = true
|
||||
let arr = c.request.body
|
||||
if (!arr.tty) throw '請輸入印表機連接埠'
|
||||
if (!arr.ble || (arr.ble !== 'yes' && arr.ble !== 'no')) throw '請輸入藍牙啟用設定'
|
||||
let feed = arr.feed || 8
|
||||
if (!isFinite(feed) || feed < 0) throw '切紙前換行必須是整數'
|
||||
feed = typeof feed !== 'number' ? Math.floor(parseInt(feed)) : feed
|
||||
|
||||
let json = {
|
||||
ble: {
|
||||
enable: false,
|
||||
uuid: {
|
||||
main: '',
|
||||
service: '',
|
||||
characteristic: ''
|
||||
},
|
||||
printer: {
|
||||
serial: '',
|
||||
feed: 8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
json.ble.enable = arr.ble === 'yes'
|
||||
json.ble.uuid.main = uuid.v4()
|
||||
json.ble.uuid.service = uuid.v4()
|
||||
json.ble.uuid.characteristic = uuid.v4()
|
||||
})
|
||||
|
||||
module.exports = router
|
|
@ -26,7 +26,7 @@ try {
|
|||
resolve(1)
|
||||
})
|
||||
})
|
||||
await chk
|
||||
await chk //eslint-disable-line
|
||||
} catch (err) {
|
||||
setupMode = true
|
||||
}
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title><%- title %></title>
|
||||
<link rel="stylesheet" href="/css/semantic.min.css">
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
<script src="/js/jquery-3.2.1.min.js"></script>
|
||||
<script src="/js/semantic.min.js"></script>
|
||||
</head>
|
||||
<body>
|
|
@ -0,0 +1,38 @@
|
|||
<%- include ../includes/header.ejs %>
|
||||
|
||||
<div class="ui container" style="padding-top: 20px;">
|
||||
<h1 class="ui header">系統安裝設定</h1>
|
||||
<form id="setup" class="ui form">
|
||||
<h3 class="ui dividing header">印表機設定</h3>
|
||||
<div class="field">
|
||||
<label for="tty">印表機連接埠</label>
|
||||
<select name="tty" id="tty">
|
||||
<option value="">選擇裝置</option>
|
||||
<% for(let i of ttys) { %>
|
||||
<option value="<%= i %>"><%= i %></option>
|
||||
<% } %>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="feed">切紙前空行</label>
|
||||
<input type="text" name="feed" value="8" id="feed">
|
||||
</div>
|
||||
<div class="field">
|
||||
<button class="ui button mini" type="button" id="test-printer">測試印表機</button>
|
||||
</div>
|
||||
|
||||
<h3 class="ui dividing header">藍芽列印設定</h3>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" class="hidden" id="en-ble">
|
||||
<label for="en-ble">啟用藍芽</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 40px; text-align: right;">
|
||||
<button class="ui button blue" type="submit">送出設定</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<%- include ../includes/footer.ejs %>
|
Loading…
Reference in New Issue