#include <dlt698/app.hpp>
#include <dlt698/standard/catalog.hpp>
#include <iomanip>
#include <iostream>
#include <sstream>
namespace {
// OctetString 是原始字节,编成十六进制便于和设备配置对照。
std::string to_hex(const model::OctetString& value) {
std::ostringstream out;
out << std::hex << std::setfill('0');
for (std::uint8_t byte : value.value) out << std::setw(2) << unsigned(byte);
return out.str();
}
} // namespace
int main() {
using namespace dlt698;
namespace oi = standard::oi;
const standard::DeviceLayout layout{standard::Wiring::three_phase, 4, 21};
app::ClientOptions options;
options.protocol.server.bytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
app::Client client(options);
auto connected = client.connect_tcp("127.0.0.1", 6980);
if (!connected) {
std::cerr << connected.error().context << '\n';
return 1;
}
struct Field { std::uint16_t oi; const char* label; };
const Field fields[] = {
{oi::communication_address, "communication address"},
{oi::meter_number, "meter number"},
{oi::customer_number, "customer number"},
{oi::asset_code, "asset code"},
{oi::rated_voltage, "rated voltage"},
{oi::rated_current, "rated current"},
{oi::maximum_current, "maximum current"},
{oi::active_accuracy_class, "active accuracy class"},
{oi::reactive_accuracy_class, "reactive accuracy class"},
{oi::meter_model, "meter model"},
};
for (const auto& field : fields) {
auto oad = standard::make_oad(field.oi, 2, 0, layout);
if (!oad) {
std::cerr << field.label << ": " << oad.error().context << '\n';
continue;
}
auto value = client.get(oad.value());
if (!value) {
std::cerr << field.label << ": " << value.error().context << '\n';
continue;
}
if (const auto dar = std::get_if<std::uint8_t>(&value.value())) {
std::cerr << field.label << ": unsupported, DAR=" << unsigned(*dar) << '\n';
continue;
}
const auto& data = std::get<model::Data>(value.value());
// 必须按实际类型分支,OctetString 和 VisibleString 都要处理。
if (data.type() == model::DataType::octet_string) {
std::cout << field.label << " = " << to_hex(data.as<model::OctetString>()) << '\n';
} else if (data.type() == model::DataType::visible_string) {
std::cout << field.label << " = "
<< data.as<model::VisibleString>().value << '\n';
} else {
std::cerr << field.label << ": unexpected type\n";
}
}
// 输出示例:
// communication address = 123456789012
// meter number = 1234
// customer number = abcd
// asset code = GDZM-2026-000123
// rated voltage = 220V
// rated current = 5(60)A
// maximum current = 60A
// active accuracy class = 1.0S
// reactive accuracy class = 2.0L
// meter model = DTZY-200
client.disconnect();
return 0;
}