wait messages
This commit is contained in:
parent
2849b54adc
commit
5285d3fe7f
13 changed files with 294 additions and 173 deletions
|
|
@ -229,7 +229,7 @@ DWORD Epd3Base::Epd3U::StartCom()
|
|||
step = 7;
|
||||
CommsInitialized = 1;
|
||||
Dll3RV = SetMultipleDiscoveryMode(epdComsHandle, false);
|
||||
Dll3RV = SetResponseTimeout(epdComsHandle, 1000);
|
||||
Dll3RV = SetResponseTimeout(epdComsHandle, ResponseTimeout);
|
||||
//Dll3RV = GetRetryCount(epdComsHandle, &retries); = 3
|
||||
}
|
||||
}
|
||||
|
|
@ -324,6 +324,7 @@ int Epd3Base::Epd3U::OpenDev(DiscoveryId DeviceID)
|
|||
if (epdComsHandle != nullptr)
|
||||
{
|
||||
Dll3RV = Connect3(epdComsHandle, DeviceID, true);
|
||||
SetDisconnectCallback(epdComsHandle, disconnectcallback);
|
||||
}
|
||||
else { Dll3RV = r_InvalidCommsHandle; }
|
||||
return Dll3RV;
|
||||
|
|
@ -496,13 +497,17 @@ int Epd3Base::Epd3U::SetTime() //Only R3
|
|||
/// <returns>0 = ok</returns>
|
||||
int Epd3Base::Epd3U::ReadStatus()
|
||||
{
|
||||
int r; //0=ok
|
||||
int rv; //0=ok
|
||||
//constexpr int maxbatch = 2;
|
||||
//int batchstep;
|
||||
//int s[maxbatch];
|
||||
//int r[maxbatch];
|
||||
int step = 0;
|
||||
uint8_t length = 0;
|
||||
countsRead = 0; utc = 0; seconds = 0;
|
||||
memset(WearerID, 0, WearerIDLength + 1);
|
||||
memset(WearerName, 0, WearerNameLength + 1);
|
||||
r = SetResponseTimeout(epdComsHandle, 2000);
|
||||
rv = SetResponseTimeout(epdComsHandle, ResponseTimeout);
|
||||
Error = 0;
|
||||
if (port == 0) {
|
||||
EpdID = 4567;
|
||||
|
|
@ -526,14 +531,31 @@ int Epd3Base::Epd3U::ReadStatus()
|
|||
HardVersion = HardVersionMinor = SoftVersion = FunctionFlags = 0;
|
||||
|
||||
step = 1;
|
||||
|
||||
//batchstep = 0;
|
||||
SetFunctionReturnValue(eFunctions::ReadStatus,0);
|
||||
token = BeginReadStatus(epdComsHandle, nullptr);
|
||||
r = Commit3(epdComsHandle);
|
||||
SetCommitReturnValue(r);
|
||||
if (!r) r = EndReadStatus(epdComsHandle, token, &epd3status);
|
||||
r = SetEndReturnValue(r);
|
||||
if (r != 0) goto error;
|
||||
|
||||
//batchstep = 1;
|
||||
//
|
||||
//s[batchstep] = SetFunctionReturnValue(ReadEpdIdentities, 0);
|
||||
//btoken[batchstep] = BeginReadEpdIdentities(epdComsHandle, nullptr);
|
||||
|
||||
//batchstep = 2;
|
||||
//s[batchstep] = SetFunctionReturnValue(ReadCounts, 0);
|
||||
//btoken[batchstep] = BeginReadCounts(epdComsHandle, nullptr, 0, nullptr);
|
||||
|
||||
/*batchstep = 3;
|
||||
s[batchstep] = SetFunctionReturnValue(ReadRTC, 0);
|
||||
btoken[batchstep] = BeginReadRTC(epdComsHandle, nullptr);*/
|
||||
|
||||
// after
|
||||
rv = CommitAndSetRV();
|
||||
|
||||
//batchstep = 0; //ReadStatus
|
||||
//r = Commit3(epdComsHandle); SetCommitReturnValue(r);
|
||||
if (!rv) rv = EndReadStatus(epdComsHandle, token, &epd3status);
|
||||
rv = SetEndReturnValue(rv);
|
||||
if (rv != 0) goto error;
|
||||
|
||||
IssueCount = epd3status.IssueCount;
|
||||
OperatingStatus = epd3status.OperatingStatus;
|
||||
|
|
@ -543,16 +565,18 @@ int Epd3Base::Epd3U::ReadStatus()
|
|||
|
||||
uint32_t EpdID32;
|
||||
uint32_t capabilities;
|
||||
MarkNumber_t MarkNumber;
|
||||
MarkNumber_t MarkNumber;
|
||||
VersionNumber_t VersionNumber;
|
||||
|
||||
step = 2;
|
||||
//batchstep = 1; //ReadEpdIdentities
|
||||
|
||||
SetFunctionReturnValue(ReadEpdIdentities,0);
|
||||
token = BeginReadEpdIdentities(epdComsHandle, nullptr);
|
||||
r = Commit3(epdComsHandle); SetCommitReturnValue(r);
|
||||
if (!r) r = EndReadEpdIdentities(epdComsHandle, token, &EpdID32, (EpdTypes*)&EpdType, &capabilities, &MarkNumber, &VersionNumber, NULL, 0);
|
||||
r = SetEndReturnValue(r);
|
||||
if (r != 0) goto error;
|
||||
rv = CommitAndSetRV();
|
||||
if (!rv) rv = EndReadEpdIdentities(epdComsHandle, token, &EpdID32, (EpdTypes*)&EpdType, &capabilities, &MarkNumber, &VersionNumber, NULL, 0);
|
||||
rv = SetEndReturnValue(rv);
|
||||
if (rv != 0) goto error;
|
||||
|
||||
|
||||
EpdID = EpdID32;
|
||||
|
|
@ -566,57 +590,32 @@ int Epd3Base::Epd3U::ReadStatus()
|
|||
DecodeStatus(); //Alarm status...
|
||||
|
||||
step = 3;
|
||||
//batchstep = 2;
|
||||
SetFunctionReturnValue(ReadCounts,0);
|
||||
token = BeginReadCounts(epdComsHandle, nullptr, 0, nullptr);
|
||||
r = Commit3(epdComsHandle); SetCommitReturnValue(r);
|
||||
if (!r) r = EndReadCounts(epdComsHandle, token, Counts, MaxCounts, &countsRead, &utc, &seconds);
|
||||
r= SetEndReturnValue(r);
|
||||
rv = CommitAndSetRV();
|
||||
if (!rv) rv = EndReadCounts(epdComsHandle, token, Counts, MaxCounts, &countsRead, &utc, &seconds);
|
||||
rv= SetEndReturnValue(rv);
|
||||
// - 101 = InvalidParam
|
||||
// - 104 = FunctionFail,
|
||||
if (r) goto error; // (r != 0 && r != -104) { Error = GetErrorCode(); goto error; }
|
||||
if (rv) goto error; // (r != 0 && r != -104) { Error = GetErrorCode(); goto error; }
|
||||
decodeCounters(countsRead); //HG,SG ..
|
||||
|
||||
//Wearer
|
||||
step = 4;
|
||||
if (EPDIssued) {
|
||||
IdString_t mk3WearerID;
|
||||
//Mk2 EPDs only support Name and Primary ID
|
||||
SetFunctionReturnValue(ReadWearerId,0);
|
||||
token = BeginReadWearerId(epdComsHandle, static_cast<uint16_t>(WearerIdType::WearerId_Name), nullptr);
|
||||
r = Commit3(epdComsHandle); SetCommitReturnValue(r);
|
||||
r = EndReadWearerId(epdComsHandle, token, &mk3WearerID);
|
||||
r = SetEndReturnValue(r);
|
||||
if (r != 0) goto error;
|
||||
|
||||
if (mk3WearerID.Length > WearerNameLength) mk3WearerID.Length = WearerNameLength;
|
||||
memcpy(WearerName, mk3WearerID.Utf8String, mk3WearerID.Length); WearerName[mk3WearerID.Length] = 0;
|
||||
|
||||
step = 5;
|
||||
SetFunctionReturnValue(ReadWearerId,0);
|
||||
token = BeginReadWearerId(epdComsHandle, static_cast<uint16_t>(WearerIdType::WearerId_Primary), nullptr);
|
||||
r = Commit3(epdComsHandle); SetCommitReturnValue(r);
|
||||
if (!r) r = EndReadWearerId(epdComsHandle, token, &mk3WearerID);
|
||||
r = SetEndReturnValue(r);
|
||||
if (r != 0) goto error;
|
||||
|
||||
|
||||
if (mk3WearerID.Length > WearerIDLength) mk3WearerID.Length = WearerIDLength;
|
||||
memcpy(this->WearerID, mk3WearerID.Utf8String, mk3WearerID.Length); WearerName[mk3WearerID.Length] = 0;
|
||||
for (int i = 0; i < mk3WearerID.Length; i++)
|
||||
if (WearerID[i] == 0xb) WearerID[i] = '0'; else WearerID[i] |= 0x30;
|
||||
}
|
||||
|
||||
//Times
|
||||
//1601-01-01T00:00:00Z.
|
||||
//MK2 .. some utc... but no real time clock
|
||||
step = 6;
|
||||
//batchstep = 3;
|
||||
if (utc == 0) {
|
||||
SetFunctionReturnValue(ReadRTC,0);
|
||||
token = BeginReadRTC(epdComsHandle, nullptr);
|
||||
r = CommitAndSetRV();
|
||||
if (!r) r = EndReadRTC(epdComsHandle, token, &utc); //EpdClock for MK2
|
||||
r= SetEndReturnValue(r);
|
||||
if (r) goto error;
|
||||
rv = CommitAndSetRV();
|
||||
if (!rv) rv = EndReadRTC(epdComsHandle, token, &utc); //EpdClock for MK2
|
||||
rv= SetEndReturnValue(rv);
|
||||
if (rv) goto error;
|
||||
EpdClock = utc;
|
||||
utc = TimeFunctions::NowToEpdTime(true);
|
||||
}
|
||||
|
|
@ -628,12 +627,55 @@ int Epd3Base::Epd3U::ReadStatus()
|
|||
TimeFunctions::EpdTimeToFileTime(utc, &fUTC, Epd.Gen == EpdGeneration::Mk2);
|
||||
FileTimeToSystemTime(&fUTC, &tRealTime);
|
||||
|
||||
return r;
|
||||
step = 4;
|
||||
if (EPDIssued) {
|
||||
IdString_t mk3WearerID;
|
||||
//Mk2 EPDs only support Name and Primary ID
|
||||
//batchstep = 0;
|
||||
//s[batchstep]=SetFunctionReturnValue(ReadWearerId, 0);
|
||||
//btoken[batchstep] = BeginReadWearerId(epdComsHandle, static_cast<uint16_t>(WearerIdType::WearerId_Name), nullptr);
|
||||
|
||||
//batchstep = 1;
|
||||
//s[batchstep] = SetFunctionReturnValue(ReadWearerId, 0);
|
||||
//btoken[batchstep] = BeginReadWearerId(epdComsHandle, static_cast<uint16_t>(WearerIdType::WearerId_Primary), nullptr);
|
||||
|
||||
//rv = CommitAndSetRV(s, 2);
|
||||
|
||||
//batchstep = 0;
|
||||
SetFunctionReturnValue(ReadWearerId, 0);
|
||||
token= BeginReadWearerId(epdComsHandle, static_cast<uint16_t>(WearerIdType::WearerId_Name), nullptr);
|
||||
rv = CommitAndSetRV();
|
||||
|
||||
if (!rv) rv = EndReadWearerId(epdComsHandle, token, &mk3WearerID);
|
||||
rv = SetEndReturnValue(rv);
|
||||
if (rv != 0) goto error;
|
||||
|
||||
if (mk3WearerID.Length > WearerNameLength) mk3WearerID.Length = WearerNameLength;
|
||||
memcpy(WearerName, mk3WearerID.Utf8String, mk3WearerID.Length); WearerName[mk3WearerID.Length] = 0;
|
||||
|
||||
step = 5;
|
||||
//batchstep = 1;
|
||||
SetFunctionReturnValue(ReadWearerId, 0);
|
||||
token = BeginReadWearerId(epdComsHandle, static_cast<uint16_t>(WearerIdType::WearerId_Primary), nullptr);
|
||||
rv = CommitAndSetRV();
|
||||
if (!rv) rv = EndReadWearerId(epdComsHandle, token, &mk3WearerID);
|
||||
rv = SetEndReturnValue(rv);
|
||||
if (rv != 0) goto error;
|
||||
|
||||
|
||||
if (mk3WearerID.Length > WearerIDLength) mk3WearerID.Length = WearerIDLength;
|
||||
memcpy(this->WearerID, mk3WearerID.Utf8String, mk3WearerID.Length); WearerName[mk3WearerID.Length] = 0;
|
||||
for (int i = 0; i < mk3WearerID.Length; i++)
|
||||
if (WearerID[i] == 0xb) WearerID[i] = '0'; else WearerID[i] |= 0x30;
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
||||
error:
|
||||
Error = r;
|
||||
//Cancel(epdComsHandle);
|
||||
Error = rv;
|
||||
ErrorStep = step;
|
||||
return r;
|
||||
return rv;
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
|
|
@ -1030,30 +1072,37 @@ error:
|
|||
/// <returns>0 success</returns>
|
||||
int Epd3Base::Epd3U::ClearDoses()
|
||||
{
|
||||
constexpr int maxbatch = 3;
|
||||
//constexpr int maxbatch = 3;
|
||||
int rv;
|
||||
int r[maxbatch];
|
||||
int s[maxbatch];
|
||||
int batchstep = 0;
|
||||
s[batchstep]= SetFunctionReturnValue(eFunctions::ClearTotalDose,0);
|
||||
btoken[batchstep] = BeginClearTotalDose(epdComsHandle, nullptr);
|
||||
batchstep = 1;
|
||||
s[batchstep] =SetFunctionReturnValue(eFunctions::ClearDose,0);
|
||||
btoken[batchstep] = BeginClearDose(epdComsHandle, nullptr);
|
||||
batchstep = 2;
|
||||
s[batchstep]= SetFunctionReturnValue(eFunctions::ClearPeakRates,0);
|
||||
btoken[batchstep] = BeginClearPeakRates(epdComsHandle, nullptr);
|
||||
//int r[maxbatch];
|
||||
//int s[maxbatch];
|
||||
//int batchstep = 0;
|
||||
SetFunctionReturnValue(eFunctions::ClearTotalDose,0);
|
||||
token = BeginClearTotalDose(epdComsHandle, nullptr);
|
||||
rv = CommitAndEnd2RV(EndClearTotalDose, token);
|
||||
if (rv) goto error;
|
||||
//batchstep = 1;
|
||||
SetFunctionReturnValue(eFunctions::ClearDose,0);
|
||||
token= BeginClearDose(epdComsHandle, nullptr);
|
||||
rv = CommitAndEnd2RV(EndClearDose, token);
|
||||
if (rv) goto error;
|
||||
//batchstep = 2;
|
||||
SetFunctionReturnValue(eFunctions::ClearPeakRates,0);
|
||||
token= BeginClearPeakRates(epdComsHandle, nullptr);
|
||||
rv = CommitAndEnd2RV(EndClearPeakRates, token);
|
||||
if (rv) goto error;
|
||||
|
||||
rv = CommitAndSetRV(s, maxbatch);
|
||||
batchstep = 0;
|
||||
r[batchstep] = End2RV(s[batchstep], EndClearTotalDose, btoken[batchstep]);
|
||||
batchstep = 1;
|
||||
r[batchstep] = End2RV(s[batchstep], EndClearDose, btoken[batchstep]);
|
||||
batchstep = 2;
|
||||
r[batchstep] = End2RV(s[batchstep], EndClearPeakRates, btoken[batchstep]);
|
||||
//rv = CommitAndSetRV(s, maxbatch);
|
||||
//batchstep = 0;
|
||||
//r[batchstep] = End2RV(s[batchstep], EndClearTotalDose, btoken[batchstep]);
|
||||
//batchstep = 1;
|
||||
//r[batchstep] = End2RV(s[batchstep], EndClearDose, btoken[batchstep]);
|
||||
//batchstep = 2;
|
||||
//r[batchstep] = End2RV(s[batchstep], EndClearPeakRates, btoken[batchstep]);
|
||||
|
||||
rv = r[0];
|
||||
for (int b = 1; !rv && b < maxbatch;++b) if (r[b]) rv = r[b];
|
||||
//rv = r[0];
|
||||
//for (int b = 1; !rv && b < maxbatch;++b) if (r[b]) rv = r[b];
|
||||
error:
|
||||
Error = rv;
|
||||
return rv;
|
||||
|
||||
|
|
@ -1154,7 +1203,7 @@ WORD Epd3Base::Epd3U::ReadAlarmTresholds() {
|
|||
uint8_t measID;
|
||||
uint32_t r;
|
||||
|
||||
SetResponseTimeout(epdComsHandle, 2000);
|
||||
SetResponseTimeout(epdComsHandle, ResponseTimeout);
|
||||
|
||||
if (isNeutron) measID = (uint8_t)MeasurementId::Meas_Hp10N; else measID = (uint8_t)MeasurementId::Meas_Hp07;
|
||||
hp07tresholds.MeasId = measID;
|
||||
|
|
@ -1524,6 +1573,7 @@ int Epd3Base::Epd3U::IssueAndCheck(float gain, float ChirpRate)
|
|||
|
||||
|
||||
step = 3;
|
||||
if (!isConnected) rv = ReOpenDev();
|
||||
rv = SetChirp(ChirpRate);
|
||||
if (rv == r_ErrorNotConnected)
|
||||
{
|
||||
|
|
@ -1634,34 +1684,30 @@ int Epd3Base::Epd3U::WriteConfig(void)
|
|||
r = CommitAndEnd2RV(EndWriteAlarmConfiguration_R3, token);
|
||||
}
|
||||
|
||||
constexpr int maxbatch= 2;
|
||||
int s[maxbatch];
|
||||
int rv[maxbatch];
|
||||
int batchstep;
|
||||
//constexpr int maxbatch= 2;
|
||||
//int s[maxbatch];
|
||||
//int rv[maxbatch];
|
||||
//int batchstep;
|
||||
|
||||
if (!r) {
|
||||
//OffModeDisplay
|
||||
batchstep = 0;
|
||||
//batchstep = 0;
|
||||
dutyCycle = (OffModeDutyCycle)0;
|
||||
offModeDispId = (OffModeDisplayId_t)1;
|
||||
s[batchstep] =SetFunctionReturnValue(eFunctions::WriteOffModeDisplay_R3,1);
|
||||
btoken[batchstep] = BeginWriteOffModeDisplay_R3(epdComsHandle, dutyCycle, offModeDispId, nullptr);
|
||||
|
||||
SetFunctionReturnValue(eFunctions::WriteOffModeDisplay_R3,1);
|
||||
token = BeginWriteOffModeDisplay_R3(epdComsHandle, dutyCycle, offModeDispId, nullptr);
|
||||
r = CommitAndEnd2RV(EndWriteOffModeDisplay_R3, token);
|
||||
|
||||
//SwitchOnFromButton
|
||||
batchstep = 1;
|
||||
//batchstep = 1;
|
||||
uint8_t OnOfenabled = 0;
|
||||
s[batchstep] = SetFunctionReturnValue(eFunctions::WriteSwitchOnFromButton_R3, 0);
|
||||
btoken[batchstep] = BeginWriteSwitchOnFromButton_R3(epdComsHandle, OnOfenabled, nullptr);
|
||||
|
||||
r = CommitAndSetRV(s, maxbatch);
|
||||
|
||||
batchstep = 0;
|
||||
rv[batchstep] = End2RV(batchstep,EndWriteOffModeDisplay_R3, btoken[batchstep]);
|
||||
batchstep = 1;
|
||||
rv[batchstep] = End2RV(batchstep, EndWriteSwitchOnFromButton_R3, btoken[batchstep]);
|
||||
//s[batchstep] = SetFunctionReturnValue(eFunctions::WriteSwitchOnFromButton_R3, 0);
|
||||
//btoken[batchstep] = BeginWriteSwitchOnFromButton_R3(epdComsHandle, OnOfenabled, nullptr);
|
||||
|
||||
SetFunctionReturnValue(eFunctions::WriteSwitchOnFromButton_R3, 0);
|
||||
token = BeginWriteSwitchOnFromButton_R3(epdComsHandle, OnOfenabled, nullptr);
|
||||
r = CommitAndEnd2RV(EndWriteSwitchOnFromButton_R3, token);
|
||||
|
||||
r = rv[0];
|
||||
for (int b = 1; !r && b < maxbatch; ++b) if (rv[b]) r = rv[b];
|
||||
Error = r;
|
||||
}
|
||||
|
||||
|
|
@ -1678,7 +1724,6 @@ int Epd3Base::Epd3U::SetChirp(float Sensitivity)
|
|||
SetFunctionReturnValue(eFunctions::WriteChirpSensitivity,0);
|
||||
token = BeginWriteChirpSensitivity(epdComsHandle, Sensitivity, nullptr);
|
||||
r = CommitAndEnd2RV(EndWriteChirpSensitivity , token);
|
||||
/*r = Commit3(epdComsHandle); SetCommitReturnValue(r); if (!r) r = EndWriteChirpSensitivity(epdComsHandle, token); SetEndReturnValue(r);*/
|
||||
}
|
||||
if (r) goto error;
|
||||
|
||||
|
|
@ -1686,8 +1731,6 @@ int Epd3Base::Epd3U::SetChirp(float Sensitivity)
|
|||
SetFunctionReturnValue(eFunctions::WriteChirpEnable_R3,0);
|
||||
token = BeginWriteChirpEnable_R3(epdComsHandle, enable, nullptr);
|
||||
r = CommitAndEnd2RV(EndWriteChirpEnable_R3, token);
|
||||
/*r = Commit3(epdComsHandle); SetCommitReturnValue(r);
|
||||
if (!r) r = EndWriteChirpEnable_R3(epdComsHandle, token); SetEndReturnValue(r);*/
|
||||
}
|
||||
if (r) goto error;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@
|
|||
#define MaxAlarmConfig 10
|
||||
#define MaxTresholds 10
|
||||
#define MaxSteps 50
|
||||
#define MaxBatch 3
|
||||
#define MaxBatch 4
|
||||
#define ResponseTimeout 2500
|
||||
|
||||
namespace Epd3Base {
|
||||
enum eFunctions {
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ extern "C"
|
|||
int32_t EPDDLL_API Commit3(CommsHandle hComms);
|
||||
int32_t EPDDLL_API CommitAndWait(CommsHandle hComms);
|
||||
int32_t EPDDLL_API Cancel(CommsHandle hComms);
|
||||
int32_t EPDDLL_API StartDiscovery(CommsHandle hComms, DiscoveryCallback callback);
|
||||
int32_t EPDDLL_API StartDiscovery(CommsHandle hComms, DiscoveryCallback callback);
|
||||
int32_t EPDDLL_API StopDiscovery(CommsHandle hComms);
|
||||
int32_t EPDDLL_API GetDiscoveredEpds(CommsHandle hComms, DiscoveryId discovered[], uint32_t size, uint32_t* count);
|
||||
int32_t EPDDLL_API Connect3(CommsHandle hComms, DiscoveryId epd, bool wait = false);
|
||||
|
|
|
|||
|
|
@ -389,4 +389,42 @@ as
|
|||
UPDATE [dbo].[Visit] SET InitError=@InitError WHERE ID_Station=@ID_Station AND ID_Visit=@ID_Visit;
|
||||
go
|
||||
GRANT EXECUTE ON [dbo].[VisitInitConfirm] TO [eDosStation];
|
||||
go
|
||||
GO
|
||||
ALTER PROCEDURE [dbo].[VisitInit] @PersID INT,
|
||||
@ID_Task INT,
|
||||
@Inst_CODE INT,
|
||||
@EPD_InternalID INT,
|
||||
@isBG BIT,
|
||||
@EPDVisitID INT = NULL OUTPUT,
|
||||
@ID_Station INT NULL,
|
||||
@ID_Visit INT,
|
||||
@ENTRY_EPD_CLOCK DECIMAL(10, 0) NULL,
|
||||
@epdType TINYINT = NULL
|
||||
AS
|
||||
--Local !!
|
||||
DECLARE @ID_EPD INT;
|
||||
|
||||
IF @ID_Station IS NULL
|
||||
SELECT
|
||||
@ID_Station = [ID_Station]
|
||||
FROM [dbo].[StationSettings]
|
||||
WHERE [PCNr] = HOST_NAME();
|
||||
|
||||
SELECT
|
||||
@ID_EPD = [ID_EPD]
|
||||
FROM [dbo].[EPD]
|
||||
WHERE [EPD_InternalID] = @EPD_InternalID;
|
||||
|
||||
IF @ID_EPD IS NULL BEGIN
|
||||
INSERT [dbo].[EPD]([EPD_InternalID], [EPD_sn], [EPDType])
|
||||
VALUES(@EPD_InternalID, CONVERT(VARCHAR(8), @EPD_InternalID), CASE WHEN @epdType IS NOT NULL THEN @epdType
|
||||
WHEN @isBG = 0 THEN 2 ELSE 0 END);
|
||||
|
||||
SET @ID_EPD = SCOPE_IDENTITY();
|
||||
END;
|
||||
|
||||
INSERT [dbo].[Visit]([ID_Station], [PersID], [Inst_CODE], [ID_Visit], [ID_Task], [EntryTime], [ID_EPD], [isBG], [isComplete], [isDeleted], [isAlarmCleared], [isAlarm], [isManualExit], [ENTRY_EPD_CLOCK], [EXIT_EPD_CLOCK], [epdType], [epdID],InitError)
|
||||
VALUES(@ID_Station, @PersID, @Inst_CODE, @ID_Visit, @ID_Task, GETDATE(), @ID_EPD, @isBG, 0, 0, 0, 0, 0, @ENTRY_EPD_CLOCK, @ENTRY_EPD_CLOCK, @epdType, @EPD_InternalID,0);
|
||||
|
||||
SET @EPDVisitID = @ID_Visit * 100 + @ID_Station;
|
||||
GO
|
||||
|
|
|
|||
BIN
eDosStation.zip
Normal file
BIN
eDosStation.zip
Normal file
Binary file not shown.
|
|
@ -65,12 +65,22 @@ namespace eDosStation
|
|||
Dispatcher.InvokeAsync(() => { SetTimedOutAndEnd(); });
|
||||
});
|
||||
}
|
||||
|
||||
private void StopProgress(string newmessage)
|
||||
{
|
||||
dispatcherTimer?.Stop();
|
||||
statusEPD.Text = newmessage;
|
||||
pWaitEpd.Visibility = Visibility.Collapsed;
|
||||
|
||||
}
|
||||
private void Ep_EpdRead(EpdBaseClr.Epd2 Sender, EpdBaseClr.EpdEventArgs e)
|
||||
{
|
||||
EntryState = eEntryState.epdOK;
|
||||
EpdReading = false;
|
||||
dispatcherTimer?.Stop();
|
||||
Dispatcher.InvokeAsync(() => pWaitEpd.Visibility = Visibility.Collapsed );
|
||||
//dispatcherTimer?.Stop();
|
||||
Dispatcher.InvokeAsync(() => StopProgress("Writing config"));
|
||||
DoEvents();
|
||||
System.Threading.Thread.Sleep(100);
|
||||
Dispatcher.InvokeAsync(() => GetEPD());
|
||||
}
|
||||
private bool LoadDoses()
|
||||
|
|
@ -240,7 +250,7 @@ namespace eDosStation
|
|||
l.LogCommand(ex.Message);
|
||||
MessageBox.Show(ex.Message);
|
||||
}
|
||||
StationVisitID = (int?)dataInterface.VisitInitCommand.Parameters["EPDVisitID"].Value;
|
||||
//StationVisitID = (int?)dataInterface.VisitInitCommand.Parameters["EPDVisitID"].Value;
|
||||
StationVisitID = ID_Visit * 100 + thisStation.ID_Station;
|
||||
//co.Close();
|
||||
step = "EPD writing";
|
||||
|
|
@ -248,9 +258,9 @@ namespace eDosStation
|
|||
ep.WearerName = _User.PersID.ToString();
|
||||
|
||||
#if SimulateEPD
|
||||
simulData.EdpType = ep.epdType;
|
||||
simulData.WearerID = ep.WearerID;
|
||||
simulData.WearerName = ep.WearerName;
|
||||
simulData.EdpType = ep.epdType;
|
||||
simulData.WearerID = ep.WearerID;
|
||||
simulData.WearerName = ep.WearerName;
|
||||
#endif
|
||||
|
||||
ep.Hp07RateOn = CurTaskRow.HP07RateON;
|
||||
|
|
@ -317,29 +327,28 @@ namespace eDosStation
|
|||
if (rv != 0) MessageBox.Show(DecodeResults.decodesteps(ep.StepReturnValues));
|
||||
DecodeResults.logsteps(module, ep.StepReturnValues, thisStation.splunkLog);
|
||||
}
|
||||
if (rv != 0)
|
||||
{
|
||||
MessageBox.Show($"SetIssued error {rv}");
|
||||
}
|
||||
|
||||
lbHP07.Text = ep.Hp07Name;
|
||||
lbHP10.Text = ep.Hp10Name;
|
||||
|
||||
step = "SqlConfirmVisit";
|
||||
dataInterface.VisitInitConfirmCommand.Connection = co;
|
||||
dataInterface.VisitInitConfirmCommand.Parameters["ID_Station"].Value = thisStation.ID_Station;
|
||||
dataInterface.VisitInitConfirmCommand.Parameters["ID_Visit"].Value = ID_Visit;
|
||||
dataInterface.VisitInitConfirmCommand.Parameters["InitError"].Value = rv;
|
||||
try
|
||||
if (rv != 0)
|
||||
{
|
||||
dataInterface.VisitInitConfirmCommand.ExecuteNonQuery();
|
||||
//l.LogCommand(dataInterface.VisitInitCommand);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
//l.LogCommand(ex.Message);
|
||||
MessageBox.Show(ex.Message);
|
||||
thisStation.splunkLog.WriteException(module, step, ex);
|
||||
MessageBox.Show($"SetIssued error {rv}");
|
||||
step = "SqlConfirmVisit";
|
||||
dataInterface.VisitInitConfirmCommand.Connection = co;
|
||||
dataInterface.VisitInitConfirmCommand.Parameters["ID_Station"].Value = thisStation.ID_Station;
|
||||
dataInterface.VisitInitConfirmCommand.Parameters["ID_Visit"].Value = ID_Visit;
|
||||
dataInterface.VisitInitConfirmCommand.Parameters["InitError"].Value = rv;
|
||||
try
|
||||
{
|
||||
dataInterface.VisitInitConfirmCommand.ExecuteNonQuery();
|
||||
//l.LogCommand(dataInterface.VisitInitCommand);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
//l.LogCommand(ex.Message);
|
||||
MessageBox.Show(ex.Message);
|
||||
thisStation.splunkLog.WriteException(module, step, ex);
|
||||
}
|
||||
}
|
||||
co.Close();
|
||||
ShowFinal();
|
||||
|
|
@ -388,7 +397,6 @@ namespace eDosStation
|
|||
if (ep.DeviceCount == 1 && ep.EpdID > 0)
|
||||
{
|
||||
statusEPD.Text = "Found Device : writing config";
|
||||
DoEvents();
|
||||
Dispatcher.InvokeAsync(() => { DoEPD(); });
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -57,5 +57,6 @@ using System.Windows;
|
|||
//2.20 Thermo : workflow bij issue ( en toevoegen time set)
|
||||
//2.22 No clear bij deissue.
|
||||
//2.27 Display wait while issuing
|
||||
[assembly: AssemblyVersion("2.27.0.0")]
|
||||
[assembly: AssemblyFileVersion("2.27.0.0")]
|
||||
//2.28 After testing
|
||||
[assembly: AssemblyVersion("2.28.0.0")]
|
||||
[assembly: AssemblyFileVersion("2.28.0.0")]
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Fri 09/06/2024 15:29:44.75
|
||||
Mon 09/09/2024 10:26:16.80
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
|
||||
xmlns:local="clr-namespace:eDosStation"
|
||||
mc:Ignorable="d"
|
||||
Title="ShowEPDDose" Height="609.665" Width="858.8"
|
||||
Title="ShowEPDDose" Height="620" Width="785.554"
|
||||
Loaded="Window_Loaded"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
FontFamily="Segoe UI"
|
||||
|
|
|
|||
|
|
@ -213,17 +213,17 @@ exit
|
|||
# aWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0
|
||||
# MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0ECEAVEr/OUnQg5pr/bP1/lYRYwDQYJ
|
||||
# YIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3
|
||||
# DQEJBTEPFw0yNDA1MjkxMzU4MzFaMC8GCSqGSIb3DQEJBDEiBCDbjZuxJgcSDufz
|
||||
# +ekiprJJKPMdOid8HFavnX4C8hgeWzANBgkqhkiG9w0BAQEFAASCAgBGjdQr8S+I
|
||||
# nwuGA0gDFbifrx8gb9772uSbSfgF4GM3zmVlNC21F2ZVJruG6N8MN/W3uZxsRjVD
|
||||
# /pY0v7kXTJ3ygrvmcKt0reuUkj+qv0HMLa7gd3yTLealUT7+JtzraalEzEsVCGiI
|
||||
# OzM/7S2N1Z5YgsjfudW0v5sP4sDjUAUGYIgs2lH+qBFBSH2l/I9pV7gi/obxC7+4
|
||||
# EYKLcGWsuXf+q2KRoEPnr5p3fYOrNuNXaVRJkn8NPxRArupcMUddIDV6eMBQ85Xn
|
||||
# wPPdap/jjTV839y89km8h/zf70XYrGJDBeevl2VCa2TmlmMJYmQF+6T+zVzSTPyU
|
||||
# dnGAoC1ing+ky9U9WZ14K5DNRgbxkAnIgV723BEsI6Vkj55WYQ3a4OKwx080a+rV
|
||||
# GeeMKYjhbgnTyD9exX8TkFYdklKY+A1Vurhxjq5BiektiXriw93w5Dsrwq8TnT0o
|
||||
# GvaDt3FO+kXRWYBXUMvFBu3ID5wYw/q688g9IF7G0VAxDa73lBF4GC15TkSALVLR
|
||||
# eliiwBfdRnoLfxMYurGne4Iux7G4iSxBDlonsHur7Lcc/6jrtIIM8mHn11GWZwXv
|
||||
# Dk+CJBvtno+UU2VCCelL+7mZEFQ1cwQLaCM3A8MY+3tgenFke+4HnYLN1AG+D68o
|
||||
# h4eZTK9m9nojRGxKVYFVZJc+VhsdkQhHyQ==
|
||||
# DQEJBTEPFw0yNDA5MDkwOTA4NDJaMC8GCSqGSIb3DQEJBDEiBCDbjZuxJgcSDufz
|
||||
# +ekiprJJKPMdOid8HFavnX4C8hgeWzANBgkqhkiG9w0BAQEFAASCAgAvDFz5Vo34
|
||||
# 2MO+GnnnzbqXIY3Lsho9iLPCjIl6OkJbH4HbzvU5UUEo2fGVsnINfIfOVN+slEal
|
||||
# 9dpPaFdpczYf9zEGxPYpOumWqRdIY8Xl550IF5S834PiAMzlMAu7iwjDjEspk7bG
|
||||
# wcxKI+DdSdru4Uj88gbJWWYbt0967R7bi6TmFzuYC38g4sknmq9AklgykrtypG+I
|
||||
# inlzP3iorB9m3IfD3PmG7Rqp1qAsai4aXvyzEpM8SD/HNYlXyWa5/2GbqX3Qjhd6
|
||||
# XtSqFsRfZcDThGpbi53I0LxbRYc5mWUpOgCbFq3u/fWmqJ2MYQXbmP2p0zkGu4jL
|
||||
# w3l7ENgL1gGJfralDftUr+UN6tjAuUtPoV3h5tvnr22EjX+Hs8g44dXtL4FN/pfL
|
||||
# wkDvPLSBjhxoaND0/i4IzgAwWPaVuLWTSUDaZaBnxPskpfavhyT+a0V7RUutv2NZ
|
||||
# FULkI2AnX0fs8kF5XIy1K0WEAM5cyMvhD4PlZm6orNlFZI79WQ2BzDrBqUrtWQs7
|
||||
# PddaEKi+fckABsYeV9AaGsfpbt5WsUHTG8fBK4ZL3Z5saCFgc90ZxdRf+XKwwtTL
|
||||
# FqMom33K3eSpMKabSMYAI2kNGVvMWP3HnfSpqAcKsZy7dNYG25ljZkVZKmF5JV9G
|
||||
# 2951cTy1Qfx/bm2EKcXM3J2uFM5DfpPalA==
|
||||
# SIG # End signature block
|
||||
|
|
|
|||
|
|
@ -328,17 +328,17 @@ exit
|
|||
# aWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0
|
||||
# MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0ECEAVEr/OUnQg5pr/bP1/lYRYwDQYJ
|
||||
# YIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3
|
||||
# DQEJBTEPFw0yNDA1MjkxMzU4MzFaMC8GCSqGSIb3DQEJBDEiBCAcllG2mSPxCJ8u
|
||||
# oQsIqOunNyELPZuVN2PuUwDZLmIbpTANBgkqhkiG9w0BAQEFAASCAgBnR/5a25Cy
|
||||
# oS6Ylo3RZzQJZkih7pEQYAzzhnhueErTJjKQ/xxdvN+IUn/RvUPkas7QRboqfrJm
|
||||
# 4xGwmBbEsZuQyt7XBXz7ZS2sVuzpBwN96JhRmIuTZk5uIGbQ0EI9cy1m84MCjOaC
|
||||
# dF0+XITTunQBIZs91fQWdhQhi0oDES6yrmi4ziTd2auFoMCD0l4xDQm0AXZ0aGGZ
|
||||
# H9mGwuYA5kP8GWj/2Q90wG7/ivnqE7vVQ2ogRuqTQSfYJhy45n1yZh3MC2lHiA83
|
||||
# yOiWlr2CZP1vn7kTiPHwDaWJn8YuEhG45Xg9DYSd+yhwmIG+Cy7h3BDE2XTVdhwi
|
||||
# CvzLpfCPTJq5xS9G2wMGpxrQYff+EKlXNrVYZCYvlvSm+p5cLGfitgJvUy9Neyuq
|
||||
# FMAqzdTcBgf+TBmOP4hwryQKeE1/ZghZ+DnOb3g5JMPyOjqqeMf37aLObl+jiQrN
|
||||
# 6apWTPysMla2x1f7QCTqv5a0kElKqdVt/zF/lJekCtWpK//tznXPHDtnyPnb3w0c
|
||||
# 9/1j2oClQc0+pVWUnoq8mBb61bvi/9E6EemMSRJ9qHio4+H6J+SHqNKPgiOu4VFT
|
||||
# sfHBV6h649yroU8bHMlYkc+52YNoBbJANgeA5ihS02+C2N74mdlmkUEE52unk+2J
|
||||
# oQ2vybH262KiIJSPgIQb91KPw4+FjaCtQg==
|
||||
# DQEJBTEPFw0yNDA5MDkwOTA4NDJaMC8GCSqGSIb3DQEJBDEiBCAcllG2mSPxCJ8u
|
||||
# oQsIqOunNyELPZuVN2PuUwDZLmIbpTANBgkqhkiG9w0BAQEFAASCAgANDH5u1OSV
|
||||
# cJXiELrSQ0jqn+XQjgAPQMtzrKQA3ukod36kbfHudvnp1YlOTffz3LsAayEXf9Wv
|
||||
# HxyAF+RDHBFjcQuQRgye5HhOWNphB7xfFbMFgjQtC7pgH7vSCqqS42Zh4h9PlQCx
|
||||
# i4AfLS78d6W40Thf5ZS5TCtPE9+FjMxwOE6/4rVp0xMT1EVa6KCKczP6z9mLOVA9
|
||||
# O9CYau+9l2s3dbOHPMRYU9HPGkn6ilziy2K2skVeUuRB8bbxEFoKpcIWt7720mQ5
|
||||
# Irsw8ByyYLjNSJkCnO0nZc2xaNrHgScimeCfpQY3wIUwVV/62LMIAYLID47Xvm4h
|
||||
# kBjlhgO6fKcsrowiTbtCZLZtlZNBpjX7KBrFYLsFPCKWRS3mx7/jgdgoIs5Jr0dD
|
||||
# BGt6GYOIaapVqKvEk7p0YSpJ+tuNuz1V9jM6Yd1LmhqqeY1sJTTW058pU3DhMa9J
|
||||
# g/s9VCUaT/L51NPwnghM54l7flsjMG3RWhySONatjnQeLIwAt50iVpKrrQpGuZIR
|
||||
# WAacqX7HuGuPUWWZbKgwfaRtwUB6n6ArTqMh45AqZDzBAgSVU1UZUd52khO+GwR0
|
||||
# yucq9tFyys+iKQc4aXcHOaCvuAdbIxoQbv+3FGW0wUL2syI0/03TV/+sxOe9OlW0
|
||||
# gIyTzYLvf/X1/sTlkFHCtPZmnIrTyVRxbA==
|
||||
# SIG # End signature block
|
||||
|
|
|
|||
|
|
@ -192,17 +192,17 @@ exit
|
|||
# aWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0
|
||||
# MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0ECEAVEr/OUnQg5pr/bP1/lYRYwDQYJ
|
||||
# YIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3
|
||||
# DQEJBTEPFw0yNDA1MjkxMzU4MzFaMC8GCSqGSIb3DQEJBDEiBCDpOCR32+BElOsp
|
||||
# pr9o2qvS6Cq0zGXXv8N/urfnLBwlITANBgkqhkiG9w0BAQEFAASCAgALWrY16T9Q
|
||||
# jGcDVEEOobysVU7id8rnqKMXfCLAIlVyI44uEwXMk854ZoUmv7lItRGpLto03sTs
|
||||
# 9NI4LOp2rJA90bN1EZZbL05a10elnxbGarZNnHUEA5LKyIFrcTrnASLJ2Hz7PCmW
|
||||
# /QBO2lb0AtBtyxmXfzjxAJj+RLbD+lJxWkgEaTidT36foaCbNQvb0qap3B8g+r0K
|
||||
# SG9THPmYivEmme2gThHZSJ5emre6cUdZ3cpvKoCuqCMErXKik1az4KDMX6Ym/3AU
|
||||
# EW5/WmZkCAiYCEOHlaOLoW3X/XiPW5p72viy5qwaO0f9NfleXU0FkChAvYUgL2jq
|
||||
# UjKszVphMrqYJFwc9zLU5zVP+WyA/kOxW7uNs2HzYxMZribDsOaJQQro8T+5iO13
|
||||
# 2Ws5tH/hHxPvVH4NHOFctdUg/j2ntJfoAcGYo4j+o6zJQOmInNA3vi0IM8BNSfar
|
||||
# BogdNzBVYW5f4giwGLfCN0SEjL8l1m/Rmf7DWhyLpK9T6Lr+t9Fuh6PAE1Icr3Wv
|
||||
# PXeS237UKqfEr25i6mDfIEOCiltJfZa88ooJE5eruv6ZD/2nc4U+UZDLYPB/inlZ
|
||||
# b1bU17qxfue5MhOA7UQY8xNifuPaf21tgTUAHW71ub3dY4r1FE/7k9uQbU0BxsGA
|
||||
# PAD79tEAEFh6FCBKOQtKG0lE2ntikNRQ5Q==
|
||||
# DQEJBTEPFw0yNDA5MDkwOTA4NDJaMC8GCSqGSIb3DQEJBDEiBCDpOCR32+BElOsp
|
||||
# pr9o2qvS6Cq0zGXXv8N/urfnLBwlITANBgkqhkiG9w0BAQEFAASCAgCNlSoY6fdc
|
||||
# g6JHWpkvaNL5I5tHlHg5mXiy9aWHLNT6vWVke6fBNDLpfiRp7JjoPiBA0sWXh563
|
||||
# Vb0xjsJbW3ubDegN6jG+TbD5AH0vFXyANmVGjw8Mi4ylMMCw4QXvNo83QSQDttk7
|
||||
# ykJaYnk+DPAbU0h2/NWvkRK4y2kBGdOjTjkp4ZKubc/0rsiJg4EOnsvMz12+GNiT
|
||||
# frMAGcuix6kUe6IqdS0PjnNp8ne7oN2Nb2AuyJt944VBfVh518xPPDEtbeT2pR7X
|
||||
# 6P521k2fkOQZZpuZE/PzPSXyZ/1qB8UDbteTOpNEMKuEKy0wrIyxQf3C/mldAerW
|
||||
# 39YVgAjSCCcNW0IKF9ndLq+0xH3Ie9WppP3rvx4t9Xu1Ypq8HsrfwAMG+W1lern4
|
||||
# zVCDsGPvl0HHeHHX7ZAKqNpMmkl0oAvO+KXs1VMK7EcM80MSUwzNRfHZURAlcC08
|
||||
# j4QIt1kPqGnsKrWeMk0I6Wk81FgOJY27QG+ms4utIbbKVAFiPGXS7QcIXfFKDdu+
|
||||
# VsaBfr9SSGQj/LYBupJIbhfRHyTt8A9M2svNYvliiG+sJGtxYGhLLjMRwDCIBAAV
|
||||
# DiXSiys+jpF9yKNl7jSMjQM18u2lnKa9ZU0KB24Q244Fkjli3suRoVHU14UltG2q
|
||||
# gmuXlJyR/K7fBS1/gQ7nBuDu6WyTdKNVmg==
|
||||
# SIG # End signature block
|
||||
|
|
|
|||
38
sync.cmd
38
sync.cmd
|
|
@ -1,4 +1,34 @@
|
|||
set src=D:\l\src\cs\eDosStation\SetupProject1\bin\Release
|
||||
set dst=\\sqlsrv7\c$\temp\edos
|
||||
xcopy %src%\edos.msi %dst%
|
||||
pause
|
||||
pause "eDosStation to Sqlsrv7 "
|
||||
|
||||
|
||||
set src="D:\l\src\cs2024\eDosStation\eDosStation\bin\Release"
|
||||
set C="%cd:"=%\eDosStation\bin\release"
|
||||
if /I %src%==%C% (echo "Path OK ") else (echo "Path issue !")
|
||||
Pause was ok ?
|
||||
|
||||
set dst="\\sqlsrv7\c$\Soft\eDos2023"
|
||||
|
||||
::set zip="eDosStation.tar"
|
||||
::tar -cf %zip% -C %src% --exclude *.zip *.*
|
||||
|
||||
set zip="eDosStation.zip"
|
||||
"c:\program files\7-zip\7z.exe" a -r %zip% .\edosstation\bin\release\*.*
|
||||
|
||||
xcopy %zip% %dst% /i /h /R /y
|
||||
|
||||
set src="D:\l\src\cs2024\eDosStation\eDosLocal"
|
||||
xcopy "%src:"=%\UpdateLocal.sql" %dst% /i /h /R /y
|
||||
|
||||
|
||||
:: %src:"=% remove quotes
|
||||
:: %src:"=%\*.*9 remove quotes and add \*.*
|
||||
:: /i If destination does not exist and copying more than one file, assumes that destination must be a directory.
|
||||
:: /h Copies hidden and system files also.
|
||||
:: /r Overwrites read-only files
|
||||
:: /y uppresses prompting to confirm you want to overwrite an existing destination file.
|
||||
:: /s Copies directories and subdirectories except empty ones
|
||||
|
||||
pause
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue