16 changed files with 442 additions and 112 deletions
-
2src/main/java/a8k/app/constant/AppConstant.java
-
8src/main/java/a8k/app/controler/api/v1/app/data/ReactionResultControler.java
-
7src/main/java/a8k/app/hardware/channel/A8kCanBusConnection.java
-
12src/main/java/a8k/app/hardware/channel/A8kCanBusService.java
-
83src/main/java/a8k/app/hardware/channel/LisUartChannelConnection.java
-
164src/main/java/a8k/app/hardware/channel/PrinterUartChannel.java
-
34src/main/java/a8k/app/service/appsetup/A8kSubModuleRegInitService.java
-
15src/main/java/a8k/app/service/data/ReactionRecordMgrService.java
-
151src/main/java/a8k/app/service/peripheral/PrinterService.java
-
6src/main/java/a8k/app/service/statemgr/GStateMgrService.java
-
1src/main/java/a8k/app/service/utils/ReactionPlate2DCodeHelper.java
-
1src/main/java/a8k/app/utils/ZStringUtils.java
-
3src/main/java/a8k/extui/mgr/ExtApiPageGroupCfgMgr.java
-
58src/main/java/a8k/extui/page/driver/PrinterDebugPage.java
-
6src/main/java/a8k/extui/page/extsetting/db/ReactionRecordMgrDebugPage.java
-
3src/main/resources/application.yml
@ -1,83 +0,0 @@ |
|||||
package a8k.app.hardware.channel; |
|
||||
|
|
||||
import a8k.app.config.IflytophaldConnectionConfig; |
|
||||
import jakarta.annotation.PostConstruct; |
|
||||
import lombok.RequiredArgsConstructor; |
|
||||
import lombok.Value; |
|
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
import org.java_websocket.client.WebSocketClient; |
|
||||
import org.java_websocket.enums.ReadyState; |
|
||||
import org.java_websocket.handshake.ServerHandshake; |
|
||||
import org.springframework.scheduling.annotation.Scheduled; |
|
||||
import org.springframework.stereotype.Component; |
|
||||
|
|
||||
import java.net.URI; |
|
||||
|
|
||||
// |
|
||||
//@Slf4j |
|
||||
//@Component |
|
||||
//@RequiredArgsConstructor |
|
||||
//public class LisUartChannelConnection { |
|
||||
// WebSocketClient conn; |
|
||||
// IflytophaldConnectionConfig iflytophaldConnectionConfig; |
|
||||
// |
|
||||
// @PostConstruct |
|
||||
// void init() { |
|
||||
// conn = new WebSocketClient(URI.create(iflytophaldConnectionConfig.getDatachUrl("lis"))) { |
|
||||
// @Override |
|
||||
// public void onOpen(ServerHandshake serverHandshake) { |
|
||||
// LisUartChannelConnection.this.onOpen(serverHandshake); |
|
||||
// } |
|
||||
// |
|
||||
// @Override |
|
||||
// public void onMessage(String s) { |
|
||||
// LisUartChannelConnection.this.onMessage(s); |
|
||||
// } |
|
||||
// |
|
||||
// @Override |
|
||||
// public void onClose(int i, String s, boolean b) { |
|
||||
// LisUartChannelConnection.this.onClose(i, s, b); |
|
||||
// } |
|
||||
// |
|
||||
// @Override |
|
||||
// public void onError(Exception e) { |
|
||||
// LisUartChannelConnection.this.onError(e); |
|
||||
// } |
|
||||
// }; |
|
||||
// } |
|
||||
// |
|
||||
// |
|
||||
// public void onOpen(ServerHandshake serverHandshake) { |
|
||||
// log.info("a8k canbus connect sucess"); |
|
||||
// } |
|
||||
// |
|
||||
// public void onMessage(String s) { |
|
||||
// } |
|
||||
// |
|
||||
// public void onClose(int i, String s, boolean b) { |
|
||||
// log.warn("a8k canbus lost connection..."); |
|
||||
// } |
|
||||
// |
|
||||
// public void onError(Exception e) { |
|
||||
// log.info("a8k can-websocket-channel on error"); |
|
||||
// } |
|
||||
// |
|
||||
// // |
|
||||
// // PRIVATE |
|
||||
// // |
|
||||
// @Scheduled(fixedRate = 1000) |
|
||||
// private void autoConnect() { |
|
||||
// if (!conn.isOpen()) { |
|
||||
// if (conn.getReadyState().equals(ReadyState.NOT_YET_CONNECTED)) { |
|
||||
// try { |
|
||||
// conn.connect(); |
|
||||
// } catch (IllegalStateException ignored) { |
|
||||
// } |
|
||||
// } else if (conn.getReadyState().equals(ReadyState.CLOSED)) { |
|
||||
// conn.reconnect(); |
|
||||
// } |
|
||||
// } |
|
||||
// } |
|
||||
//} |
|
||||
|
|
||||
// |
|
@ -0,0 +1,164 @@ |
|||||
|
package a8k.app.hardware.channel; |
||||
|
|
||||
|
import a8k.OS; |
||||
|
import a8k.app.config.IflytophaldConnectionConfig; |
||||
|
import a8k.app.utils.ByteArray; |
||||
|
import a8k.app.utils.ZStringUtils; |
||||
|
import cn.hutool.core.util.ByteUtil; |
||||
|
import cn.hutool.core.util.CharsetUtil; |
||||
|
import jakarta.annotation.PostConstruct; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.java_websocket.client.WebSocketClient; |
||||
|
import org.java_websocket.enums.ReadyState; |
||||
|
import org.java_websocket.handshake.ServerHandshake; |
||||
|
import org.springframework.scheduling.annotation.Scheduled; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import java.io.UnsupportedEncodingException; |
||||
|
import java.net.URI; |
||||
|
import java.nio.charset.StandardCharsets; |
||||
|
import java.util.LinkedList; |
||||
|
import java.util.List; |
||||
|
import java.util.Queue; |
||||
|
|
||||
|
|
||||
|
@Slf4j |
||||
|
@Component |
||||
|
@RequiredArgsConstructor |
||||
|
public class PrinterUartChannel { |
||||
|
WebSocketClient conn; |
||||
|
|
||||
|
private final IflytophaldConnectionConfig config; |
||||
|
private Queue<byte[]> sendQueue = new LinkedList<>(); |
||||
|
|
||||
|
@PostConstruct |
||||
|
void init() { |
||||
|
String url = config.getDatachUrl("printer"); |
||||
|
log.info("PrinterUartChannel url: {}", url); |
||||
|
conn = new WebSocketClient(URI.create(url)) { |
||||
|
@Override |
||||
|
public void onOpen(ServerHandshake serverHandshake) { |
||||
|
PrinterUartChannel.this.onOpen(serverHandshake); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onMessage(String s) { |
||||
|
PrinterUartChannel.this.onMessage(s); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onClose(int i, String s, boolean b) { |
||||
|
PrinterUartChannel.this.onClose(i, s, b); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onError(Exception e) { |
||||
|
PrinterUartChannel.this.onError(e); |
||||
|
} |
||||
|
}; |
||||
|
conn.connect(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 打印字符串 |
||||
|
* @param fmt 格式化字符串 |
||||
|
* @param args 参数 |
||||
|
* 1. 打印%时候,需要使用%%,否则会报错 |
||||
|
* |
||||
|
*/ |
||||
|
public void printf(String fmt, Object... args) { |
||||
|
if (conn.isOpen()) { |
||||
|
String s = String.format(fmt, args); |
||||
|
try { |
||||
|
byte[] toSend = s.getBytes("GBK"); |
||||
|
pushToSend(toSend); |
||||
|
} catch (UnsupportedEncodingException e) { |
||||
|
log.error("charset error", e); |
||||
|
} |
||||
|
} else { |
||||
|
log.warn("PrinterUartChannel is not open"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void printfEnd() { |
||||
|
if (conn.isOpen()) { |
||||
|
printf("\r\n"); |
||||
|
printf("\r\n"); |
||||
|
printf("\r\n"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// |
||||
|
// PRIVATE |
||||
|
// |
||||
|
|
||||
|
|
||||
|
private void onOpen(ServerHandshake serverHandshake) { |
||||
|
log.info("a8k canbus connect sucess"); |
||||
|
} |
||||
|
|
||||
|
private void onMessage(String s) { |
||||
|
} |
||||
|
|
||||
|
private void onClose(int i, String s, boolean b) { |
||||
|
log.warn("a8k canbus lost connection..."); |
||||
|
} |
||||
|
|
||||
|
private void onError(Exception e) { |
||||
|
log.info("a8k can-websocket-channel on error"); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
synchronized private void pushToSend(byte[] toSend) { |
||||
|
sendQueue.add(toSend); |
||||
|
} |
||||
|
|
||||
|
synchronized private byte[] popToSend() { |
||||
|
if (!sendQueue.isEmpty()) { |
||||
|
return sendQueue.poll(); |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
// conn.send(toSend); |
||||
|
// if (toSend.length > 10) { |
||||
|
// OS.forceSleep(150); |
||||
|
// } |
||||
|
@Scheduled(fixedRate = 400) |
||||
|
private void autoSend() { |
||||
|
while (true) { |
||||
|
var tosend = popToSend(); |
||||
|
if (tosend != null) { |
||||
|
if (conn.isOpen()) { |
||||
|
conn.send(tosend); |
||||
|
} |
||||
|
if (tosend.length > 2) { |
||||
|
break; |
||||
|
} |
||||
|
} else { |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
@Scheduled(fixedRate = 1000) |
||||
|
private void autoConnect() { |
||||
|
if (!conn.isOpen()) { |
||||
|
if (conn.getReadyState().equals(ReadyState.NOT_YET_CONNECTED)) { |
||||
|
try { |
||||
|
conn.connect(); |
||||
|
} catch (IllegalStateException ignored) { |
||||
|
} |
||||
|
} else if (conn.getReadyState().equals(ReadyState.CLOSED)) { |
||||
|
conn.reconnect(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
@ -0,0 +1,151 @@ |
|||||
|
package a8k.app.service.peripheral; |
||||
|
|
||||
|
import a8k.app.dao.type.db.ProjExtInfoCard; |
||||
|
import a8k.app.dao.type.db.ReactionReport; |
||||
|
import a8k.app.hardware.channel.PrinterUartChannel; |
||||
|
import a8k.app.optalgo.type.ReactionResultStatus; |
||||
|
import a8k.app.service.data.ProjInfoMgrService; |
||||
|
import a8k.app.service.statemgr.GStateMgrService; |
||||
|
import a8k.app.type.a8k.BloodType; |
||||
|
import a8k.app.type.a8k.opt.A8kOptType; |
||||
|
import a8k.app.type.a8k.opt.OptScanResult; |
||||
|
import a8k.app.type.a8k.proj.A8kResultUnit; |
||||
|
import a8k.app.type.a8k.proj.ProjInfo; |
||||
|
import a8k.app.type.a8k.state.SampleInfo; |
||||
|
import a8k.app.type.exception.AppException; |
||||
|
import a8k.extui.factory.FakeOptScanResultFactory; |
||||
|
import a8k.extui.factory.ProjExtInfoCardFactory; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
import java.text.SimpleDateFormat; |
||||
|
import java.util.ArrayList; |
||||
|
import java.util.Date; |
||||
|
import java.util.List; |
||||
|
|
||||
|
@Component |
||||
|
@Slf4j |
||||
|
@RequiredArgsConstructor |
||||
|
public class PrinterService { |
||||
|
private final PrinterUartChannel printer; |
||||
|
private final ProjInfoMgrService projInfoMgrService; |
||||
|
private final GStateMgrService gStateMgrService; |
||||
|
|
||||
|
String bloodTypeToString(BloodType bloodType) { |
||||
|
return switch (bloodType) { |
||||
|
case WHOLE_BLOOD -> "全血"; |
||||
|
case SERUM_OR_PLASMA -> "血清/血浆"; |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
public void printDemoReactionReport() { |
||||
|
|
||||
|
ProjExtInfoCard.A8kResultUintFn resultBuilder0 = // |
||||
|
new ProjExtInfoCard.A8kResultUintFn(A8kResultUnit.coi, A8kResultUnit.iuPml, A8kResultUnit.uPl, 2.0, 2.0, 3.0, 3.0); |
||||
|
ProjExtInfoCard.A8kResultUintFn resultBuilder1 =// |
||||
|
new ProjExtInfoCard.A8kResultUintFn(A8kResultUnit.coi, A8kResultUnit.iuPml, A8kResultUnit.uPl, 2.0, 2.0, 3.0, 3.0); |
||||
|
ProjExtInfoCard.A8kResultUintFn resultBuilder2 =// |
||||
|
new ProjExtInfoCard.A8kResultUintFn(A8kResultUnit.coi, A8kResultUnit.iuPml, A8kResultUnit.uPl, 2.0, 2.0, 3.0, 3.0); |
||||
|
List<ReactionReport.ReactionResult> reactionResults = new ArrayList<>(); |
||||
|
reactionResults.add(new ReactionReport.ReactionResult("Tn-I", "Tn-I", 1.0, resultBuilder0.toResultUnitConverters())); |
||||
|
reactionResults.add(new ReactionReport.ReactionResult("CK-MB", "CK-MB", 2.0, resultBuilder1.toResultUnitConverters())); |
||||
|
reactionResults.add(new ReactionReport.ReactionResult("Myoglobin", "MG", 3.0, resultBuilder2.toResultUnitConverters())); |
||||
|
|
||||
|
|
||||
|
ReactionReport record = new ReactionReport(); |
||||
|
record.sampleBloodType = BloodType.WHOLE_BLOOD; |
||||
|
record.sampleBarcode = "ASDF123456789"; |
||||
|
record.sampleUserid = "U1023"; |
||||
|
record.sampleId = "1122334456"; |
||||
|
record.projName = "HSCrp"; |
||||
|
record.lotId = "CA2312345"; |
||||
|
record.projId = 1; |
||||
|
record.setExpiryDate(new Date()); |
||||
|
record.operator = "张三"; |
||||
|
record.projShortName = "CA"; |
||||
|
record.appVersion = gStateMgrService.getAppVersion(); |
||||
|
record.mcuVersion = gStateMgrService.getMcuVersion(); |
||||
|
record.sn = gStateMgrService.getSn(); |
||||
|
record.subProjNum = reactionResults.size(); |
||||
|
record.projInfoIdCardVersion = 1; |
||||
|
record.projInfo = null; |
||||
|
record.results = reactionResults; |
||||
|
record.detailOptData = null; |
||||
|
|
||||
|
print(record); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void print(ReactionReport report) { |
||||
|
/* |
||||
|
* 日期: 2023-10-01 12:00:00 |
||||
|
* 操作人: 张三 |
||||
|
* 软件版本: 1.0.0 |
||||
|
* MCU版本: 1.0.0 |
||||
|
* 仪器序列号: 123456789 |
||||
|
* |
||||
|
* UID:sampleUserid |
||||
|
* 条码ID: sampleBarcode |
||||
|
* |
||||
|
* 样本类型:全血/血清/血浆 |
||||
|
* 项目名称: |
||||
|
* 批次号: |
||||
|
* |
||||
|
* <子项目名称> |
||||
|
* 结果: |
||||
|
* 结果(单位1): |
||||
|
* 结果(单位2): |
||||
|
* |
||||
|
* <子项目名称> |
||||
|
* 结果: |
||||
|
* 结果(单位1): |
||||
|
* 结果(单位2): |
||||
|
* |
||||
|
*/ |
||||
|
// 定义日期格式 |
||||
|
if(report == null) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
||||
|
printer.printf("*****************************\r\n"); |
||||
|
printer.printf(" 日期: %s\r\n", dateFormat.format(report.creatDate)); |
||||
|
printer.printf(" 操作人: %s\r\n", report.operator); |
||||
|
printer.printf(" 软件版本: %s\r\n", report.appVersion); |
||||
|
printer.printf(" MCU版本: %s\r\n", report.mcuVersion); |
||||
|
printer.printf(" 仪器序列号: %s\r\n", report.sn); |
||||
|
printer.printf(" \r\n"); |
||||
|
printer.printf(" \r\n"); |
||||
|
printer.printf(" UID: %s\r\n", report.sampleUserid); |
||||
|
printer.printf(" BARCODE: %s\r\n", report.sampleBarcode); |
||||
|
printer.printf(" \r\n"); |
||||
|
printer.printf(" 样本类型: %s\r\n", bloodTypeToString(report.sampleBloodType)); |
||||
|
printer.printf(" 项目名称: %s\r\n", report.projName); |
||||
|
printer.printf(" 批次号: %s\r\n", report.lotId); |
||||
|
printer.printf(" \r\n"); |
||||
|
printer.printf(" \r\n"); |
||||
|
for (var result : report.results) { |
||||
|
if (result == null) |
||||
|
continue; |
||||
|
printer.printf(" 子项目名称: %s\r\n", result.subProjName); |
||||
|
if (result.status.equals(ReactionResultStatus.SUCCESS)) { |
||||
|
printer.printf(" 结果: %s\r\n", result.result); |
||||
|
for (int j = 0; j < result.resultConverters.size(); j++) { |
||||
|
var converter = result.resultConverters.get(j); |
||||
|
if (converter == null) |
||||
|
continue; |
||||
|
printer.printf(" 结果(单位%d): %s\r\n", j + 1, converter.convert(result.result)); |
||||
|
} |
||||
|
printer.printf(" \r\n"); |
||||
|
} else { |
||||
|
printer.printf(" ERROR\r\n"); |
||||
|
printer.printf(" %s\r\n", result.errorInfo); |
||||
|
printer.printf(" \r\n"); |
||||
|
} |
||||
|
} |
||||
|
printer.printf("*****************************\r\n"); |
||||
|
printer.printfEnd(); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,58 @@ |
|||||
|
package a8k.extui.page.driver; |
||||
|
|
||||
|
import a8k.OS; |
||||
|
import a8k.app.hardware.channel.PrinterUartChannel; |
||||
|
import a8k.app.hardware.driver.PipetteCtrlDriver; |
||||
|
import a8k.app.service.peripheral.PrinterService; |
||||
|
import a8k.extui.mgr.ExtApiPageMgr; |
||||
|
import a8k.extui.type.ExtUIPageCfg; |
||||
|
import jakarta.annotation.PostConstruct; |
||||
|
import jakarta.annotation.Resource; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
@Component |
||||
|
@Slf4j |
||||
|
@RequiredArgsConstructor |
||||
|
public class PrinterDebugPage { |
||||
|
|
||||
|
private final PrinterUartChannel printerUartChannel; |
||||
|
private final ExtApiPageMgr extApiPageMgr; |
||||
|
private final PrinterService printerService; |
||||
|
|
||||
|
|
||||
|
public void printf(String str) { |
||||
|
printerUartChannel.printf(str + "\r\n"); |
||||
|
} |
||||
|
|
||||
|
public void printerTest() { |
||||
|
printerUartChannel.printf("ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"); |
||||
|
OS.forceSleep(100); |
||||
|
printerUartChannel.printf("abcdefghijklmnopqrstuvwxyz\r\n"); |
||||
|
OS.forceSleep(100); |
||||
|
printerUartChannel.printf("0123456789\r\n"); |
||||
|
OS.forceSleep(100); |
||||
|
printerUartChannel.printf("!@#$%%*()^_+\r\n"); |
||||
|
OS.forceSleep(100); |
||||
|
printerUartChannel.printf("~`!@#$%%^&*()_+|\\{}[]:\";'<>?,./\r\n"); |
||||
|
OS.forceSleep(100); |
||||
|
printerUartChannel.printf("中文测试\r\n"); |
||||
|
OS.forceSleep(100); |
||||
|
printerUartChannel.printfEnd(); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void printDemoReactionReport() { |
||||
|
printerService.printDemoReactionReport(); |
||||
|
} |
||||
|
|
||||
|
@PostConstruct |
||||
|
void init() { |
||||
|
ExtUIPageCfg page = new ExtUIPageCfg(this); |
||||
|
page.addFunction("printf", this::printf); |
||||
|
page.addFunction("printerTest", this::printerTest); |
||||
|
page.addFunction("打印报告(示例)", this::printDemoReactionReport); |
||||
|
extApiPageMgr.addPage(page); |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue