serial-reader
This commit is contained in:
parent
691eb0cf23
commit
b7d265d92a
@ -30,11 +30,12 @@ if ( isset($model->card)){
|
|||||||
<?php $form = ActiveForm::begin([
|
<?php $form = ActiveForm::begin([
|
||||||
'enableAjaxValidation' => false,
|
'enableAjaxValidation' => false,
|
||||||
'method' => 'get',
|
'method' => 'get',
|
||||||
'action' => $route
|
'action' => $route,
|
||||||
|
'id' => 'reception-card-number-form'
|
||||||
]); ?>
|
]); ?>
|
||||||
<div class="row" >
|
<div class="row" >
|
||||||
<div class='col-md-12'>
|
<div class='col-md-12'>
|
||||||
<?php echo Html::textInput("number", $number ,['class' => 'form-control', 'placeholder' => 'Kártya/kulcs szám'])?>
|
<?php echo Html::textInput("number", $number ,['class' => 'form-control', 'placeholder' => 'Kártya/kulcs szám', 'id' => 'input-reception-card-number'])?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" >
|
<div class="row" >
|
||||||
|
|||||||
@ -9,230 +9,10 @@ use frontend\components\ReceptionWidget;
|
|||||||
<h1>Recepció</h1>
|
<h1>Recepció</h1>
|
||||||
<?php
|
<?php
|
||||||
echo ReceptionWidget::widget(['form' => $model, 'route' => ['customer/reception']]) ?>
|
echo ReceptionWidget::widget(['form' => $model, 'route' => ['customer/reception']]) ?>
|
||||||
<script>
|
|
||||||
const qrcodeReader = {
|
|
||||||
usbVendorId: 0x0c2e, usbProductId: 0x1094, name: 'qrcode'
|
|
||||||
};
|
|
||||||
|
|
||||||
const rfidReader = {
|
<?php if ( !isset($model->card)){ ?>
|
||||||
usbVendorId: 0x09d8, usbProductId: 0x0420, name: 'rfid'
|
<?= $this->render('serial', [
|
||||||
};
|
'model' => $model,
|
||||||
|
]) ?>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
const readers = [qrcodeReader,rfidReader];
|
|
||||||
|
|
||||||
let defaultOptions = {
|
|
||||||
device: {
|
|
||||||
name: '',
|
|
||||||
usbVendorId: 0x0,
|
|
||||||
usbProductId: 0x0
|
|
||||||
},
|
|
||||||
onChange: (value) => {
|
|
||||||
console.info('change', value)
|
|
||||||
},
|
|
||||||
onConnect: (e) => {
|
|
||||||
console.info('connect', e)
|
|
||||||
},
|
|
||||||
onDisConnect: () => {
|
|
||||||
console.info('disconnect', e)
|
|
||||||
},
|
|
||||||
onError: () => {
|
|
||||||
},
|
|
||||||
onPairRequired: (device) => {
|
|
||||||
console.info('pair required', device)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SerialReader {
|
|
||||||
connected = false;
|
|
||||||
port = null;
|
|
||||||
paired = false;
|
|
||||||
value = null;
|
|
||||||
options = null;
|
|
||||||
|
|
||||||
constructor(options) {
|
|
||||||
this.options = options;
|
|
||||||
}
|
|
||||||
|
|
||||||
initialize = async () => {
|
|
||||||
await this.connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
listen = async (options) => {
|
|
||||||
const port = options.port;
|
|
||||||
console.info("listening device", options?.device?.name);
|
|
||||||
while (port.readable) {
|
|
||||||
const reader = port.readable.getReader();
|
|
||||||
try {
|
|
||||||
while (true) {
|
|
||||||
const {value, done} = await reader.read();
|
|
||||||
const str = String.fromCharCode.apply(null, value);
|
|
||||||
if (done) {
|
|
||||||
// |reader| has been canceled.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
options.onChange(str, options.device);
|
|
||||||
// Do something with |value|...
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
// Handle |error|...
|
|
||||||
options.onError(e, options.device, 'listen');
|
|
||||||
} finally {
|
|
||||||
reader.releaseLock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
getPortByDevice = async (device) => {
|
|
||||||
const ports = await navigator.serial.getPorts([device]);
|
|
||||||
return ports.find(value => {
|
|
||||||
const info = value.getInfo();
|
|
||||||
return info.usbVendorId === device.usbVendorId;
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
connect = async () => {
|
|
||||||
const options = this.options;
|
|
||||||
this.port = await this.getPortByDevice({
|
|
||||||
usbVendorId: options.device.usbVendorId
|
|
||||||
});
|
|
||||||
if (!this.port) {
|
|
||||||
options.onPairRequired({device: options.device});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.paired = true;
|
|
||||||
console.info("opening port", options, this.port);
|
|
||||||
// Wait for the serial port to open.
|
|
||||||
await this.port.open({baudRate: 9600});
|
|
||||||
this.connected = true;
|
|
||||||
console.info("opened", this.port, options)
|
|
||||||
|
|
||||||
await this.listen({
|
|
||||||
...options,
|
|
||||||
port: this.port, onChange: (str) => {
|
|
||||||
options.onChange(str);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
isConnected = () => {
|
|
||||||
return this.connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
isPaired = () => {
|
|
||||||
return this.paired;
|
|
||||||
}
|
|
||||||
|
|
||||||
getValue = () => {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
requestPair = async () => {
|
|
||||||
await navigator.serial
|
|
||||||
.requestPort({
|
|
||||||
filters: [{
|
|
||||||
usbProductId: this.options.device.usbProductId,
|
|
||||||
usbVendorId: this.options.device.usbVendorId
|
|
||||||
}]
|
|
||||||
})
|
|
||||||
// .requestPort({filters: [{usbVendorId}]})
|
|
||||||
console.info("connecting");
|
|
||||||
await this.connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const ready = async () => {
|
|
||||||
const pikcAPort =
|
|
||||||
async () =>
|
|
||||||
{
|
|
||||||
const vendors = document.getElementById('vendors');
|
|
||||||
const deviceGroupName = vendors.value;
|
|
||||||
let filters = undefined;
|
|
||||||
const usbVendorId = readers.find(reader => reader.name === deviceGroupName)
|
|
||||||
if (deviceGroupName) {
|
|
||||||
let vendor = (deviceGroupName == 'rfid') ? rfidReader.usbVendorId : qrcodeReader.usbVendorId;
|
|
||||||
|
|
||||||
filters = [{
|
|
||||||
usbVendorId
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
const requestedPort = await navigator.serial
|
|
||||||
.requestPort({
|
|
||||||
filters
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const qrcode = new SerialReader({
|
|
||||||
...defaultOptions,
|
|
||||||
device: qrcodeReader,
|
|
||||||
onChange: (value) => {
|
|
||||||
console.info(value)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const rfid = new SerialReader({
|
|
||||||
...defaultOptions,
|
|
||||||
device: rfidReader,
|
|
||||||
onChange: (value) => {
|
|
||||||
console.info(value)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
await qrcode.initialize();
|
|
||||||
await rfid.initialize();
|
|
||||||
|
|
||||||
const btnRfid = document.getElementById("rfid");
|
|
||||||
const btnQRcode = document.getElementById("qrcode");
|
|
||||||
|
|
||||||
btnRfid.addEventListener('click', async () => {
|
|
||||||
await rfid.requestPair();
|
|
||||||
});
|
|
||||||
|
|
||||||
btnQRcode.addEventListener('click', async () => {
|
|
||||||
await qrcode.requestPair();
|
|
||||||
})
|
|
||||||
|
|
||||||
const sleep = m => new Promise(r => setTimeout(r, m))
|
|
||||||
const readStatus = async (millis) => {
|
|
||||||
const serialPorts = await navigator.serial.getPorts();
|
|
||||||
const infoDiv = document.getElementById('allowed_devices');
|
|
||||||
infoDiv.innerHTML = '';
|
|
||||||
for (let port of serialPorts) {
|
|
||||||
const {usbVendorId, usbProductId} = port.getInfo();
|
|
||||||
const infoDiv = document.createElement('div');
|
|
||||||
infoDiv.innerHTML = '' + usbVendorId + '|' + usbProductId;
|
|
||||||
infoDiv.append(infoDiv);
|
|
||||||
|
|
||||||
}
|
|
||||||
await sleep(millis);
|
|
||||||
await readStatus(millis);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
document.addEventListener('DOMContentLoaded', ready);
|
|
||||||
</script>
|
|
||||||
<div class="mt-3 ">
|
|
||||||
<h3>Engedélyezett eszközök</h3>
|
|
||||||
<div id="allowed_devices"></div>
|
|
||||||
<label for="vendors">Gyártók</label>
|
|
||||||
<select name="vendors" id="vendors" class="vendors">
|
|
||||||
<option value="">Mind</option>
|
|
||||||
<option value="qrcode">QRCode</option>
|
|
||||||
<option value="rfid">RFID</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<button class="btn btn-primary" id="rfid">Kártya Olvasó engedélyezése</button>
|
|
||||||
<button class="btn btn-primary" id="qrcode">QRCode Olvasó engedélyezése</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
// echo "Timezone:" . date_default_timezone_get();
|
|
||||||
//echo date("Y-m-d H:i");
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|||||||
266
frontend/views/customer/serial.php
Normal file
266
frontend/views/customer/serial.php
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
<style>
|
||||||
|
.warning-component {
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
|
||||||
|
const qrcodeReader = {
|
||||||
|
usbVendorId: 0x0c2e, usbProductId: 0x1094, name: 'qrcode'
|
||||||
|
};
|
||||||
|
|
||||||
|
const rfidReader = {
|
||||||
|
usbVendorId: 0x09d8, usbProductId: 0x0420, name: 'rfid'
|
||||||
|
};
|
||||||
|
|
||||||
|
const readers = [qrcodeReader, rfidReader];
|
||||||
|
const ports = {};
|
||||||
|
|
||||||
|
|
||||||
|
class SerialReader {
|
||||||
|
connected = false;
|
||||||
|
port = null;
|
||||||
|
value = null;
|
||||||
|
options = null;
|
||||||
|
|
||||||
|
constructor(options) {
|
||||||
|
this.options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
listen = async () => {
|
||||||
|
const options = this.options;
|
||||||
|
const port = options.port;
|
||||||
|
console.info("Listening port")
|
||||||
|
while (port.readable) {
|
||||||
|
const reader = port.readable.getReader();
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
const {value, done} = await reader.read();
|
||||||
|
const str = String.fromCharCode.apply(null, value);
|
||||||
|
if (done) {
|
||||||
|
// |reader| has been canceled.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
options.onChange(str);
|
||||||
|
// Do something with |value|...
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.info("Error while listening port", error);
|
||||||
|
// Handle |error|...
|
||||||
|
// options.onError(error, options.device, 'listen');
|
||||||
|
} finally {
|
||||||
|
console.info("stopped listening port");
|
||||||
|
reader.releaseLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
connect = async () => {
|
||||||
|
const options = this.options;
|
||||||
|
const port = options.port;
|
||||||
|
console.info("opening port", options, this.options.port);
|
||||||
|
await port.open({baudRate: 9600});
|
||||||
|
this.connected = true;
|
||||||
|
console.info("opened", options);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageLoadedAt = new Date().getTime();
|
||||||
|
|
||||||
|
const openCardNumber = (cardNumber) => {
|
||||||
|
if ( (new Date().getTime() - pageLoadedAt ) < 400 ){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const input = document.getElementById('input-reception-card-number');
|
||||||
|
const form = document.getElementById('reception-card-number-form');
|
||||||
|
|
||||||
|
input.value = cardNumber;
|
||||||
|
form.submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ready = async () => {
|
||||||
|
|
||||||
|
|
||||||
|
const startSerialReader = async (port) => {
|
||||||
|
const info = port.getInfo();
|
||||||
|
const id = info.usbVendorId + "_" + info.usbProductId;
|
||||||
|
const serialReader = new SerialReader({
|
||||||
|
port,
|
||||||
|
id,
|
||||||
|
onChange: (cardNumber) => openCardNumber(cardNumber)
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
ports[id] = serialReader;
|
||||||
|
await serialReader.connect();
|
||||||
|
serialReader.listen().then(() => console.info("listen finishend"))
|
||||||
|
}
|
||||||
|
|
||||||
|
const pickPort = async () => {
|
||||||
|
const vendors = document.getElementById('vendors');
|
||||||
|
const deviceGroupName = vendors.value;
|
||||||
|
console.info("vendorgroup selected", deviceGroupName);
|
||||||
|
let filters = readers
|
||||||
|
.filter(reader => reader.name === deviceGroupName).map(reader => ({'usbVendorId': reader.usbVendorId}));
|
||||||
|
|
||||||
|
console.info("Calling requestPort with filters", filters);
|
||||||
|
try {
|
||||||
|
|
||||||
|
const requestedPort = await navigator.serial
|
||||||
|
.requestPort({
|
||||||
|
filters: filters
|
||||||
|
});
|
||||||
|
|
||||||
|
await startSerialReader(requestedPort);
|
||||||
|
readStatus(0).then();
|
||||||
|
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
alert('Nem választott eszközt!')
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const btnRfid = document.getElementById("rfid");
|
||||||
|
const btnQRcode = document.getElementById("qrcode");
|
||||||
|
const btnSelectDevice = document.getElementById("selectDevice");
|
||||||
|
|
||||||
|
// btnRfid.addEventListener('click', async () => {
|
||||||
|
// await rfid.requestPair();
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// btnQRcode.addEventListener('click', async () => {
|
||||||
|
// await qrcode.requestPair();
|
||||||
|
// });
|
||||||
|
btnSelectDevice.addEventListener('click', async () => {
|
||||||
|
await pickPort();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const sleep = m => new Promise(r => setTimeout(r, m))
|
||||||
|
|
||||||
|
const readStatus = async (millis) => {
|
||||||
|
const serialPorts = await navigator.serial.getPorts();
|
||||||
|
const infoDiv = document.getElementById('allowed_devices');
|
||||||
|
infoDiv.innerHTML = '';
|
||||||
|
const table = document.createElement("table");
|
||||||
|
table.classList.add('table');
|
||||||
|
table.classList.add('table-bordered');
|
||||||
|
|
||||||
|
const header = document.createElement("thead");
|
||||||
|
const tbody = document.createElement("tbody");
|
||||||
|
const headerRow = document.createElement('tr');
|
||||||
|
header.appendChild(headerRow);
|
||||||
|
|
||||||
|
const createTd = (text) =>{
|
||||||
|
const td = document.createElement('td');
|
||||||
|
td.innerText = text;
|
||||||
|
return td;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
headerRow.appendChild(createTd("Vendor"))
|
||||||
|
headerRow.appendChild(createTd("Product"))
|
||||||
|
headerRow.appendChild(createTd("Típus"))
|
||||||
|
table.appendChild(header);
|
||||||
|
for (let port of serialPorts) {
|
||||||
|
const {usbVendorId, usbProductId} = port.getInfo();
|
||||||
|
const tableRow = document.createElement('tr');
|
||||||
|
const devices = readers.filter(reader => (reader.usbVendorId === usbVendorId));
|
||||||
|
let readerGroup = "Ismeretlen";
|
||||||
|
if (devices && devices.length) {
|
||||||
|
readerGroup = devices[0].name;
|
||||||
|
}
|
||||||
|
tableRow.innerHTML =
|
||||||
|
'<td>' + usbVendorId + '</td><td>' + usbProductId + '</td><td>' + readerGroup+'</td>';
|
||||||
|
tbody.appendChild(tableRow);
|
||||||
|
}
|
||||||
|
table.appendChild(tbody)
|
||||||
|
infoDiv.appendChild(table);
|
||||||
|
|
||||||
|
console.info("ports", serialPorts);
|
||||||
|
console.info("qr found", serialPorts.find(port => qrcodeReader.usbVendorId === port.getInfo().usbVendorId));
|
||||||
|
|
||||||
|
const displayWarningRfid = !serialPorts.find(port => rfidReader.usbVendorId === port.getInfo().usbVendorId);
|
||||||
|
const displayWarningQRCode = !serialPorts.find(port => qrcodeReader.usbVendorId === port.getInfo().usbVendorId);
|
||||||
|
console.info("displayWarningQRCode", displayWarningQRCode);
|
||||||
|
|
||||||
|
const warningComponentRfid = document.getElementById("warning-component-rfid");
|
||||||
|
const warningComponentQrcode = document.getElementById("warning-component-qrcode");
|
||||||
|
const setClassName = (element, className, active) => {
|
||||||
|
if (element) {
|
||||||
|
if (active) {
|
||||||
|
element.classList.add(className);
|
||||||
|
} else {
|
||||||
|
element.classList.remove(className);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setClassName(warningComponentRfid, 'show', displayWarningRfid);
|
||||||
|
setClassName(warningComponentRfid, 'hide', !displayWarningRfid);
|
||||||
|
setClassName(warningComponentQrcode, 'show', displayWarningQRCode);
|
||||||
|
setClassName(warningComponentQrcode, 'hide', !displayWarningQRCode);
|
||||||
|
if ( millis ){
|
||||||
|
await sleep(millis);
|
||||||
|
await readStatus(millis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const start = async () => {
|
||||||
|
const serialPorts = await navigator.serial.getPorts();
|
||||||
|
|
||||||
|
for (const port of serialPorts) {
|
||||||
|
await startSerialReader(port)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readStatus(1000).then();
|
||||||
|
|
||||||
|
|
||||||
|
start().then(() => console.info("Startup process ready"))
|
||||||
|
|
||||||
|
}
|
||||||
|
document.addEventListener('DOMContentLoaded', ready);
|
||||||
|
</script>
|
||||||
|
<div class="mt-3 ">
|
||||||
|
<h3>Engedélyezett eszközök</h3>
|
||||||
|
<div class="alert-danger warning-component " id="warning-component-rfid">
|
||||||
|
Rfid olvasó nem található
|
||||||
|
<br>
|
||||||
|
<ul>
|
||||||
|
<li>Válaszd ki az 'Eszköztipusok' lenyiló listából az RFID olvasót</li>
|
||||||
|
<li>Nyomd meg az olvasó engedélyezée gombot</li>
|
||||||
|
<li>A felugró ablakban válaszd ki ismét az rfid olvasót</li>
|
||||||
|
<li>Nyomd meg a csatlakozás (connect) gombot</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="alert-danger warning-component" id="warning-component-qrcode">
|
||||||
|
QRCode olvasó nem található
|
||||||
|
<br>
|
||||||
|
<ul>
|
||||||
|
<li>Válaszd ki az 'Eszköztipusok' lenyiló listából az QRCode olvasót</li>
|
||||||
|
<li>Nyomd meg az olvasó engedélyezée gombot</li>
|
||||||
|
<li>A felugró ablakban válaszd ki ismét az QRCode olvasót (Pl.: HF680)</li>
|
||||||
|
<li>Nyomd meg a csatlakozás (connect) gombot</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div id="allowed_devices"></div>
|
||||||
|
<label for="vendors">Eszköztipusok</label>
|
||||||
|
<select name="vendors" id="vendors" class="vendors">
|
||||||
|
<option value="">Mind</option>
|
||||||
|
<option value="qrcode">QRCode</option>
|
||||||
|
<option value="rfid">RFID</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
|
<button class="btn btn-primary" id="selectDevice">Olvasó engedélyezése</button>
|
||||||
|
<!-- <button class="btn btn-primary" id="rfid">Kártya Olvasó engedélyezése</button>-->
|
||||||
|
<!-- <button class="btn btn-primary" id="qrcode">QRCode Olvasó engedélyezése</button>-->
|
||||||
|
</div>
|
||||||
Loading…
Reference in New Issue
Block a user