Застрял на коде ошибки 21 с использованием Dahua Java NetSDKJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Застрял на коде ошибки 21 с использованием Dahua Java NetSDK

Сообщение Anonymous »

Итак, я пытаюсь считать тепловые данные с IP-камеры Dahua модели TPC-BF5401. Мне не удалось найти каких-либо подробных документов, поэтому я просто прочитал руководство и попытался следовать примерам, включенным в SDK, по адресу https://depp.dahuasecurity.com/integrat ... wnload/SDK (я использую версию Java x64 в Linux). Мне удалось прочитать температуру по точкам с помощью этого скрипта

Код: Выделить всё

package com.netsdk.demo.frame;

import java.io.File;
import java.util.Scanner;

import com.netsdk.lib.NetSDKLib;
import com.netsdk.lib.NetSDKLib.*;
import com.netsdk.lib.ToolKits;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;

/**
* Console demo:
*  - Init SDK
*  - Login to camera
*  - Query temperature at a given (x,y) pixel coordinate on a channel
*  - Print the result
*/
public class QueryTempEx {

public static final NetSDKLib netSdk = NetSDKLib.NETSDK_INSTANCE;

private LLong loginHandle = new LLong(0);

private NET_DEVICEINFO_Ex deviceInfo = new NET_DEVICEINFO_Ex();

/**
* SDK init + log settings (similar to RealplayEx.InitTest)
*/
public void initSdk() {
netSdk.CLIENT_Init(DisConnectCallBack.getInstance(), null);
netSdk.CLIENT_SetAutoReconnect(HaveReConnectCallBack.getInstance(), null);

NetSDKLib.LOG_SET_PRINT_INFO setLog = new NetSDKLib.LOG_SET_PRINT_INFO();
String logPath = new File(".").getAbsoluteFile().getParent()
+ File.separator + "sdk_log" + File.separator + "sdk.log";
setLog.bSetFilePath = 1;
System.arraycopy(logPath.getBytes(), 0, setLog.szLogFilePath, 0, logPath.getBytes().length);
setLog.bSetPrintStrategy = 1;
setLog.nPrintStrategy = 0;

if (!netSdk.CLIENT_LogOpen(setLog)) {
System.err.println("Open SDK Log Failed!!!");
}
}

/**
* Login to device (similar style to RealplayEx.Login)
*/
public void login(String ip, int port, String user, String password) {

int nSpecCap = NetSDKLib.EM_LOGIN_SPAC_CAP_TYPE.EM_LOGIN_SPEC_CAP_TCP; // TCP login
IntByReference nError = new IntByReference(0);

loginHandle = netSdk.CLIENT_LoginEx2(
ip,
port,
user,
password,
nSpecCap,
null,
deviceInfo,
nError);

if (loginHandle.longValue() != 0) {
System.out.printf("Login Device[%s] Success!\n", ip);
} else {
System.err.printf("Login Device[%s] Fail.  Error[0x%x]\n",
ip, netSdk.CLIENT_GetLastError());
logoutAndCleanup();
}
}

/**
* Query temperature at a single (x,y) pixel on a channel..
*/
public NET_RADIOMETRYINFO queryPointTemper(int channel, short x, short y) {
int nQueryType = NetSDKLib.NET_QUERY_DEV_RADIOMETRY_POINT_TEMPER;

NET_IN_RADIOMETRY_GETPOINTTEMPER stIn = new NET_IN_RADIOMETRY_GETPOINTTEMPER();
stIn.nChannel = channel;
stIn.stCoordinate.nx = x;
stIn.stCoordinate.ny = y;

NET_OUT_RADIOMETRY_GETPOINTTEMPER stOut = new NET_OUT_RADIOMETRY_GETPOINTTEMPER();

stIn.write();
stOut.write();

boolean bRet = netSdk.CLIENT_QueryDevInfo(
loginHandle,
nQueryType,
stIn.getPointer(),
stOut.getPointer(),
null,
3000);

if (!bRet) {
System.err.printf("QueryPointTemper Failed! %s\n", ToolKits.getErrorCodePrint());
return null;
}

stOut.read();
return stOut.stPointTempInfo;    // This struct holds the temperature info
}

/**
* Logout + cleanup (similar to RealplayEx.LoginOut but without System.exit)
*/
public void logoutAndCleanup() {
System.out.println("End Test");

if (loginHandle.longValue() != 0) {
netSdk.CLIENT_Logout(loginHandle);
loginHandle.setValue(0);
}

System.out.println("See You...");
netSdk.CLIENT_Cleanup();
}

/**
* Disconnect callback (copied from RealplayEx)
*/
private static class DisConnectCallBack implements NetSDKLib.fDisConnect {

private DisConnectCallBack() {}

private static class CallBackHolder {
private static final DisConnectCallBack instance = new DisConnectCallBack();
}

public static DisConnectCallBack getInstance() {
return CallBackHolder.instance;
}

@Override
public void invoke(NetSDKLib.LLong lLoginID, String pchDVRIP, int nDVRPort, Pointer dwUser) {
System.out.printf("Device[%s] Port[%d] DisConnect!\n", pchDVRIP, nDVRPort);
}
}

/**
* Reconnect callback (copied from RealplayEx)
*/
private static class HaveReConnectCallBack implements NetSDKLib.fHaveReConnect {

private HaveReConnectCallBack() {}

private static class CallBackHolder {
private static final HaveReConnectCallBack instance = new HaveReConnectCallBack();
}

public static HaveReConnectCallBack getInstance() {
return CallBackHolder.instance;
}

@Override
public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {
System.out.printf("ReConnect Device[%s] Port[%d]\n", pchDVRIP, nDVRPort);
}
}

/**
* Main – console app:
*/
public static void main(String[] args) {
QueryTempEx app = new QueryTempEx();
Scanner scanner = new Scanner(System.in);

// --- Default login config (you can edit these) ---
String ip = "0.0.0.0";
int port = 37777;
String username = "admin";
String password = "password";

String defaultConfig = String.format(
"ip:%s, port:%d, username:%s, password:%s, 需要修改吗?(y/n)",
ip, port, username, password);
System.out.println(defaultConfig);

String answer = "";
do {
answer = scanner.nextLine();
if ("y".equalsIgnoreCase(answer) || "yes".equalsIgnoreCase(answer)) {
System.out.println("please input ip:");
ip = scanner.nextLine().trim();

System.out.println("please input port:");
port = Integer.parseInt(scanner.nextLine().trim());

System.out.println("please input username:");
username = scanner.nextLine().trim();

System.out.println("please input password:");
password = scanner.nextLine().trim();
break;
} else if ("n".equalsIgnoreCase(answer) || "no".equalsIgnoreCase(answer)) {
break;
}
System.out.println("please input the right word.  y/yes/n/no, try again.");
} while (!(answer.equalsIgnoreCase("y")
|| answer.equalsIgnoreCase("yes")
|| answer.equalsIgnoreCase("no")
|| answer.equalsIgnoreCase("n")));

// --- Init + Login ---
app.initSdk();
app.login(ip, port, username, password);

// --- Ask for channel + pixel coordinates ---
try {
System.out.println("please input channel (default 0):");
String chStr = scanner.nextLine().trim();
int channel = chStr.isEmpty() ? 0 : Integer.parseInt(chStr);

System.out.println("please input x coordinate (pixel, short):");
short x = Short.parseShort(scanner.nextLine().trim());

System.out.println("please input y coordinate (pixel, short):");
short y = Short.parseShort(scanner.nextLine().trim());

// --- Query temperature ---
NET_RADIOMETRYINFO info = app.queryPointTemper(channel, x, y);

if (info == null) {
System.err.println("Failed to get temperature info.");
} else {
System.out.println("Got radiometry info for point (" + x + ", " + y + ") on channel " + channel);

// Basic dump (at least this always compiles)
System.out.println("Radiometry info struct: " + info.toString());

}

} catch (Exception e) {
e.printStackTrace();
} finally {
app.logoutAndCleanup();
scanner.close();
}
}
}

(этот сценарий очень похож на пример RealplayEx, который поставляется вместе с SDK, если вы знакомы. Просто заполняет структуру информации о точке значениями пикселей x и y, и она возвращает временные данные)
Теперь проблема в том, что я хочу читать тепловые данные по регионам, а не по точкам. Я добавляю в приведенный выше скрипт следующую функцию:

Код: Выделить всё

    public NET_RADIOMETRYINFO queryTemper(int channel, int presetID, int ruleID, int nMeterType) {
int nQueryType = NetSDKLib.NET_QUERY_DEV_RADIOMETRY_TEMPER;

NET_IN_RADIOMETRY_GETTEMPER stIn = new NET_IN_RADIOMETRY_GETTEMPER();
stIn.stCondition.nChannel = channel;
stIn.stCondition.nMeterType = nMeterType;
stIn.stCondition.nPresetId = presetID;
stIn.stCondition.nRuleId = ruleID;

NET_OUT_RADIOMETRY_GETTEMPER stOut = new NET_OUT_RADIOMETRY_GETTEMPER();

stIn.write();
stOut.write();

boolean bRet = netSdk.CLIENT_QueryDevInfo(
loginHandle,
nQueryType,
stIn.getPointer(),
stOut.getPointer(),
null,
3000);

if (!bRet) {
System.err.printf("QueryTemper Failed! %s\n", ToolKits.getErrorCodePrint());
return null;
}

stOut.read();
return stOut.stTempInfo;
}
и вызвать его с помощью

Код: Выделить всё

 NET_RADIOMETRYINFO info = app.queryTemper(channel, presetID, ruleID, meterType);
Все комбинации (канал, PresetID, RuleID, MeterType), которые я пробовал, возвращают это:

Код: Выделить всё

Login Device[192.168.127.108] Success!
please input channel (default 0):
0
please input presetID (default 0):
1
please input ruleID (default 0):
1
please input meterType (default 0):
1
QueryTemper Failed!
{error code: (0x80000000|21).参考  NetSDKLib.java } - {error info:对返回数据的校验出错}
Согласно интернет-источникам, эта строка на китайском языке вместе с кодом ошибки 21 может указывать на то, что проблема либо:
  • камера настроена неправильно
  • неправильная структура ответа
Здесь я застрял. Ошибка возникает внутри динамически связанной библиотеки, поэтому я не знаю, что делать. Кроме того, мне еще предстоит точно определить, какой идентификатор правила и идентификатор предварительной настройки для настройки на камеру и обратно, идентификатор правила региона/прямоугольника/многоугольника и идентификатор предварительной настройки PTZ, я полагаю? И канал, кажется, всегда 0, а счетчик типа 1, поправьте меня, если я ошибаюсь? У кого-нибудь была такая же проблема, поделитесь чем-нибудь?

Подробнее здесь: https://stackoverflow.com/questions/798 ... ava-netsdk
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»