Bindings: Add LiveData and LiveDataMessage support in Python bindings

This commit is contained in:
Thomas Stoddard
2026-01-05 10:40:14 -05:00
committed by Kyle Schwarz
parent 000036f745
commit 977677e3af
10 changed files with 318 additions and 20 deletions
+2
View File
@@ -22,6 +22,7 @@ pybind11_add_module(icsneopy
icsneopy/device/devicetype.cpp
icsneopy/communication/network.cpp
icsneopy/communication/io.cpp
icsneopy/communication/livedata.cpp
icsneopy/communication/message/message.cpp
icsneopy/communication/message/canmessage.cpp
icsneopy/communication/message/canerrormessage.cpp
@@ -34,6 +35,7 @@ pybind11_add_module(icsneopy
icsneopy/communication/message/spimessage.cpp
icsneopy/communication/message/scriptstatusmessage.cpp
icsneopy/communication/message/ethphymessage.cpp
icsneopy/communication/message/livedatamessage.cpp
icsneopy/communication/message/callback/messagecallback.cpp
icsneopy/communication/message/filter/messagefilter.cpp
icsneopy/core/macseccfg.cpp
@@ -0,0 +1,79 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include <pybind11/native_enum.h>
#include "icsneo/communication/livedata.h"
namespace icsneo {
void init_livedata(pybind11::module_& m) {
// LiveDataValue struct
pybind11::classh<LiveDataValue>(m, "LiveDataValue")
.def(pybind11::init<>())
.def_readwrite("value", &LiveDataValue::value);
// LiveDataArgument struct
pybind11::classh<LiveDataArgument>(m, "LiveDataArgument")
.def(pybind11::init<>())
.def_readwrite("object_type", &LiveDataArgument::objectType)
.def_readwrite("object_index", &LiveDataArgument::objectIndex)
.def_readwrite("signal_index", &LiveDataArgument::signalIndex)
.def_readwrite("value_type", &LiveDataArgument::valueType);
// LiveDataCommand enum
pybind11::native_enum<LiveDataCommand>(m, "LiveDataCommand", "enum.IntEnum")
.value("STATUS", LiveDataCommand::STATUS)
.value("SUBSCRIBE", LiveDataCommand::SUBSCRIBE)
.value("UNSUBSCRIBE", LiveDataCommand::UNSUBSCRIBE)
.value("RESPONSE", LiveDataCommand::RESPONSE)
.value("CLEAR_ALL", LiveDataCommand::CLEAR_ALL)
.value("SET_VALUE", LiveDataCommand::SET_VALUE)
.finalize();
// LiveDataStatus enum
pybind11::native_enum<LiveDataStatus>(m, "LiveDataStatus", "enum.IntEnum")
.value("SUCCESS", LiveDataStatus::SUCCESS)
.value("ERR_UNKNOWN_COMMAND", LiveDataStatus::ERR_UNKNOWN_COMMAND)
.value("ERR_HANDLE", LiveDataStatus::ERR_HANDLE)
.value("ERR_DUPLICATE", LiveDataStatus::ERR_DUPLICATE)
.value("ERR_FULL", LiveDataStatus::ERR_FULL)
.finalize();
// LiveDataObjectType enum
pybind11::enum_<LiveDataObjectType>(m, "LiveDataObjectType")
.value("MISC", LiveDataObjectType::MISC)
.value("SNA", LiveDataObjectType::SNA)
.export_values();
// LiveDataValueType enum
pybind11::native_enum<LiveDataValueType>(m, "LiveDataValueType", "enum.IntEnum")
.value("GPS_LATITUDE", LiveDataValueType::GPS_LATITUDE)
.value("GPS_LONGITUDE", LiveDataValueType::GPS_LONGITUDE)
.value("GPS_ALTITUDE", LiveDataValueType::GPS_ALTITUDE)
.value("GPS_SPEED", LiveDataValueType::GPS_SPEED)
.value("GPS_VALID", LiveDataValueType::GPS_VALID)
.value("GPS_ENABLE", LiveDataValueType::GPS_ENABLE)
.value("MANUAL_TRIGGER", LiveDataValueType::MANUAL_TRIGGER)
.value("TIME_SINCE_MSG", LiveDataValueType::TIME_SINCE_MSG)
.value("GPS_ACCURACY", LiveDataValueType::GPS_ACCURACY)
.value("GPS_BEARING", LiveDataValueType::GPS_BEARING)
.value("GPS_TIME", LiveDataValueType::GPS_TIME)
.value("GPS_TIME_VALID", LiveDataValueType::GPS_TIME_VALID)
.value("DAQ_ENABLE", LiveDataValueType::DAQ_ENABLE)
.finalize();
// LiveDataUtil namespace functions
m.def("get_new_handle", &LiveDataUtil::getNewHandle,
"Generate a new unique LiveData handle");
m.def("livedata_value_to_double", &LiveDataUtil::liveDataValueToDouble,
pybind11::arg("val"),
"Convert LiveDataValue to double (32.32 fixed-point to floating-point)");
m.def("livedata_double_to_value", &LiveDataUtil::liveDataDoubleToValue,
pybind11::arg("d"),
"Convert double to LiveDataValue (32.32 fixed-point format). Returns LiveDataValue or None on failure.");
}
} // namespace icsneo
@@ -0,0 +1,50 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include <pybind11/chrono.h>
#include "icsneo/communication/message/livedatamessage.h"
namespace icsneo {
void init_livedatamessage(pybind11::module_& m) {
// LiveDataMessage base class
pybind11::classh<LiveDataMessage, RawMessage>(m, "LiveDataMessage")
.def(pybind11::init<>())
.def_readwrite("handle", &LiveDataMessage::handle)
.def_readwrite("cmd", &LiveDataMessage::cmd);
// LiveDataCommandMessage (for subscribe/unsubscribe)
pybind11::classh<LiveDataCommandMessage, LiveDataMessage>(m, "LiveDataCommandMessage")
.def(pybind11::init<>())
.def_readwrite("update_period", &LiveDataCommandMessage::updatePeriod)
.def_readwrite("expiration_time", &LiveDataCommandMessage::expirationTime)
.def_readwrite("args", &LiveDataCommandMessage::args)
.def("append_signal_arg", &LiveDataCommandMessage::appendSignalArg,
pybind11::arg("value_type"),
"Append a signal argument to the command message");
// LiveDataValueMessage (received values)
pybind11::classh<LiveDataValueMessage, LiveDataMessage>(m, "LiveDataValueMessage")
.def(pybind11::init<>())
.def_readwrite("num_args", &LiveDataValueMessage::numArgs)
.def_readwrite("values", &LiveDataValueMessage::values);
// LiveDataStatusMessage (status responses)
pybind11::classh<LiveDataStatusMessage, LiveDataMessage>(m, "LiveDataStatusMessage")
.def(pybind11::init<>())
.def_readwrite("requested_command", &LiveDataStatusMessage::requestedCommand)
.def_readwrite("status", &LiveDataStatusMessage::status);
// LiveDataSetValueMessage (for setting values)
pybind11::classh<LiveDataSetValueMessage, LiveDataMessage>(m, "LiveDataSetValueMessage")
.def(pybind11::init<>())
.def_readwrite("args", &LiveDataSetValueMessage::args)
.def_readwrite("values", &LiveDataSetValueMessage::values)
.def("append_set_value", &LiveDataSetValueMessage::appendSetValue,
pybind11::arg("value_type"),
pybind11::arg("value"),
"Append a value to set in the message");
}
} // namespace icsneo
@@ -52,6 +52,11 @@ void init_device(pybind11::module_& m) {
.def("start_script", &Device::startScript, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("stop_script", &Device::stopScript, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("supports_tc10", &Device::supportsTC10)
.def("supports_live_data", &Device::supportsLiveData)
.def("subscribe_live_data", &Device::subscribeLiveData, pybind11::arg("message"), pybind11::call_guard<pybind11::gil_scoped_release>())
.def("unsubscribe_live_data", &Device::unsubscribeLiveData, pybind11::arg("handle"), pybind11::call_guard<pybind11::gil_scoped_release>())
.def("clear_all_live_data", &Device::clearAllLiveData, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_value_live_data", &Device::setValueLiveData, pybind11::arg("message"), pybind11::call_guard<pybind11::gil_scoped_release>())
.def("transmit", pybind11::overload_cast<std::shared_ptr<Frame>>(&Device::transmit), pybind11::call_guard<pybind11::gil_scoped_release>())
.def("upload_coremini", [](Device& device, std::string& path, Disk::MemoryType memType) { std::ifstream ifs(path, std::ios::binary); return device.uploadCoremini(ifs, memType); }, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("write_macsec_config", &Device::writeMACsecConfig, pybind11::call_guard<pybind11::gil_scoped_release>())
+4
View File
@@ -35,6 +35,8 @@ void init_version(pybind11::module_&);
void init_flexray(pybind11::module_& m);
void init_idevicesettings(pybind11::module_&);
void init_ethphymessage(pybind11::module_&);
void init_livedata(pybind11::module_&);
void init_livedatamessage(pybind11::module_&);
PYBIND11_MODULE(icsneopy, m) {
pybind11::options options;
@@ -48,6 +50,7 @@ PYBIND11_MODULE(icsneopy, m) {
init_devicetype(m);
init_network(m);
init_io(m);
init_livedata(m);
init_message(m);
init_canmessage(m);
init_canerrormessage(m);
@@ -60,6 +63,7 @@ PYBIND11_MODULE(icsneopy, m) {
init_macsecconfig(m);
init_scriptstatusmessage(m);
init_spimessage(m);
init_livedatamessage(m);
init_messagefilter(m);
init_messagecallback(m);
init_diskdriver(m);