update status

This commit is contained in:
Jay 2017-09-05 18:36:35 +08:00
parent 2c89f32c8d
commit 1941ab0c52
18 changed files with 603 additions and 67 deletions

View File

@ -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,26 +79,50 @@ 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))
}
}
module.exports = new PrinterDevice()
module.exports = new PrinterDevice()

2
app.js
View File

@ -1,2 +1,2 @@
require('top-level-await')
require('./server')
require('./server')

View File

@ -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
}
}

View File

@ -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 => {

View File

@ -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: [

View File

@ -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

View File

@ -1,10 +1,10 @@
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()
}
}
module.exports = new LocalEvent()
module.exports = new LocalEvent()

View File

@ -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",

5
public/css/main.css Normal file
View File

@ -0,0 +1,5 @@
html, body{
height: 100%;
width: 100%;
background-color: #eee;
}

364
public/css/semantic.min.css vendored Executable file

File diff suppressed because one or more lines are too long

4
public/js/jquery-3.2.1.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

19
public/js/semantic.min.js vendored Executable file

File diff suppressed because one or more lines are too long

View File

@ -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
module.exports = router

View File

@ -26,7 +26,7 @@ try {
resolve(1)
})
})
await chk
await chk //eslint-disable-line
} catch (err) {
setupMode = true
}

View File

@ -0,0 +1,2 @@
</body>
</html>

13
views/includes/header.ejs Normal file
View File

@ -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>

38
views/install/index.ejs Normal file
View File

@ -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 %>