-remove hack for 0 terminating string in groupobjects

-fix logging on linux
-add parameters to python bindings
This commit is contained in:
Thomas Kunze 2024-09-12 00:14:25 +02:00
parent b687cd24d9
commit d1bdc6ef51
17 changed files with 77 additions and 54 deletions

View File

@ -91,13 +91,13 @@ void setup()
goMin.dataPointType(DPT_Value_Temp); goMin.dataPointType(DPT_Value_Temp);
goMax.dataPointType(DPT_Value_Temp); goMax.dataPointType(DPT_Value_Temp);
Serial.print("Timeout: "); Serial.print("Startverzögerung s: ");
Serial.println(knx.paramByte(0)); Serial.println(knx.paramByte(0));
Serial.print("Zykl. senden: "); Serial.print("Aenderung senden (*0.1K): ");
Serial.println(knx.paramByte(1)); Serial.println(knx.paramByte(1));
Serial.print("Min/Max senden: "); Serial.print("Zykl. senden min: ");
Serial.println(knx.paramByte(2)); Serial.println(knx.paramByte(2));
Serial.print("Aenderung senden: "); Serial.print("Min/Max senden: ");
Serial.println(knx.paramByte(3)); Serial.println(knx.paramByte(3));
Serial.print("Abgleich: "); Serial.print("Abgleich: ");
Serial.println(knx.paramByte(4)); Serial.println(knx.paramByte(4));

View File

@ -99,7 +99,8 @@ void setup()
srand((unsigned int)time(NULL)); srand((unsigned int)time(NULL));
Logger::logLevel("App", Logger::Info); Logger::logLevel("App", Logger::Info);
Logger::logLevel("ApplicationLayer", Logger::Info); Logger::logLevel("TableObject", Logger::Info);
Logger::logLevel("Memory", Logger::Info);
knx.readMemory(); knx.readMemory();
if (knx.individualAddress() == 0xFFFF) if (knx.individualAddress() == 0xFFFF)
@ -115,11 +116,11 @@ void setup()
GO_MAX.dataPointType(Dpt(9, 1)); GO_MAX.dataPointType(Dpt(9, 1));
GO_MAX.valueNoSend(-273.0); GO_MAX.valueNoSend(-273.0);
GO_RESET.dataPointType(Dpt(1, 15)); GO_RESET.dataPointType(Dpt(1, 15));
LOGGER.info("Timeout: %d", knx.paramWord(0)); LOGGER.info("Startverzögerung s: %d", knx.paramByte(0));
LOGGER.info("Zykl. senden: %d", knx.paramByte(2)); LOGGER.info("Aenderung senden (*0.1K): %d", knx.paramByte(1));
LOGGER.info("Zykl. senden min: %d", knx.paramByte(2));
LOGGER.info("Min/Max senden: %d", knx.paramByte(3)); LOGGER.info("Min/Max senden: %d", knx.paramByte(3));
LOGGER.info("Aenderung senden: %d", knx.paramByte(4)); LOGGER.info("Abgleich %d", knx.paramInt(4));
LOGGER.info("Abgleich %d", knx.paramByte(5));
} }
else else
LOGGER.info("not configured"); LOGGER.info("not configured");

View File

@ -14,11 +14,11 @@ namespace py = pybind11;
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include "knx/bits.h" #include <knx/bits.h>
#include "knx/platform/linux_platform.h" #include <knx/platform/linux_platform.h>
#include "knx/ip/bau57B0.h" #include <knx/ip/bau57B0.h>
#include "knx/interface_object/group_object_table_object.h" #include <knx/interface_object/group_object_table_object.h>
#include "knx/util/logger.h" #include <knx/util/logger.h>
#define LOGGER Logger::logger("knxmodule") #define LOGGER Logger::logger("knxmodule")
@ -56,6 +56,8 @@ static void init()
Logger::logLevel("ApplicationLayer", Logger::Info); Logger::logLevel("ApplicationLayer", Logger::Info);
Logger::logLevel("BauSystemBDevice", Logger::Info); Logger::logLevel("BauSystemBDevice", Logger::Info);
Logger::logLevel("GroupObject", Logger::Info); Logger::logLevel("GroupObject", Logger::Info);
Logger::logLevel("TableObject", Logger::Info);
Logger::logLevel("Memory", Logger::Info);
/* /*
// copy args so we control the livetime of the char* // copy args so we control the livetime of the char*
@ -186,6 +188,14 @@ PYBIND11_MODULE(knx, m)
{ {
GroupObject::classCallback(handler); GroupObject::classCallback(handler);
}); });
m.def("Parameters", []()
{
uint8_t* data = bau->parameters().data();
if (data == nullptr)
return py::bytes();
return py::bytes((const char*)data, bau->parameters().dataSize());
});
py::class_<GroupObject>(m, "GroupObject", py::dynamic_attr()) py::class_<GroupObject>(m, "GroupObject", py::dynamic_attr())
.def(py::init()) .def(py::init())

View File

@ -4,4 +4,4 @@ build-backend = "scikit_build_core.build"
[project] [project]
name = "knxPython" name = "knxPython"
version = "0.1.5" version = "1.5.0"

View File

@ -187,7 +187,7 @@ set(SOURCES
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -Wno-unknown-pragmas -g -O0") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -Wno-unknown-pragmas -g -O0")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wno-unknown-pragmas -g -O0") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wno-unknown-pragmas -g -O0")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -g -O0") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -DKNX_FLASH_SIZE=0x20000")
add_library(knx ${SOURCES}) add_library(knx ${SOURCES})
target_include_directories(knx PUBLIC .) target_include_directories(knx PUBLIC .)

View File

@ -27,6 +27,7 @@ namespace Knx
void loop() override; void loop() override;
bool configured() override; bool configured() override;
GroupObjectTableObject& groupObjectTable(); GroupObjectTableObject& groupObjectTable();
protected: protected:
ApplicationLayer& applicationLayer() override; ApplicationLayer& applicationLayer() override;

View File

@ -372,5 +372,7 @@ namespace Knx
unsigned short index; unsigned short index;
bool operator==(const Dpt& other) const; bool operator==(const Dpt& other) const;
bool operator!=(const Dpt& other) const; bool operator!=(const Dpt& other) const;
}; };
} }

View File

@ -629,16 +629,16 @@ namespace Knx
int busValueToString(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value) int busValueToString(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
{ {
ASSERT_PAYLOAD(14); ASSERT_PAYLOAD(14);
char strValue[15];
strValue[14] = '\0';
for (int n = 0; n < 14; ++n) for (int n = 0; n < 14; ++n)
{ {
auto value = signed8FromPayload(payload, n); strValue[n] = signed8FromPayload(payload, n);
if (!datatype.subGroup && (strValue[n] & 0x80))
if (!datatype.subGroup && (value & 0x80))
return false; return false;
} }
value = (const char*) payload; value = strValue;
return true; return true;
} }

View File

@ -202,20 +202,6 @@ namespace Knx
return asapValueSize(code); return asapValueSize(code);
} }
size_t GroupObject::sizeInMemory() const
{
uint8_t code = lowByte(ntohs(_table->_tableData[_asap]));
size_t result = asapValueSize(code);
if (code == 0)
return 1;
if (code == 14)
return 14 + 1;
return result;
}
GroupObjectUpdatedHandler GroupObject::classCallback() GroupObjectUpdatedHandler GroupObject::classCallback()
{ {
return _updateHandlerStatic; return _updateHandlerStatic;

View File

@ -128,11 +128,6 @@ namespace Knx
* will return 0. * will return 0.
*/ */
size_t sizeInTelegram(); size_t sizeInTelegram();
/**
* returns the size of the group object in the heap memory of the group object. The function returns the same value as goSize(),
* exept fot the 14 byte string type to reserve one byte of a \0 terminator character.
*/
size_t sizeInMemory() const;
/** /**
* returns the pointer to the value of the group object. This can be used if a datapoint type is not supported or if you want do * returns the pointer to the value of the group object. This can be used if a datapoint type is not supported or if you want do
* your own conversion. * your own conversion.

View File

@ -22,6 +22,8 @@ namespace Knx
uint16_t getWord(uint32_t addr); uint16_t getWord(uint32_t addr);
uint32_t getInt(uint32_t addr); uint32_t getInt(uint32_t addr);
double getFloat(uint32_t addr, ParameterFloatEncodings encoding); double getFloat(uint32_t addr, ParameterFloatEncodings encoding);
using TableObject::data;
using TableObject::dataSize;
const char* name() override const char* name() override
{ {
return "ApplicationProgram"; return "ApplicationProgram";

View File

@ -35,7 +35,7 @@ namespace Knx
GroupObject& GroupObjectTableObject::get(uint16_t asap) GroupObject& GroupObjectTableObject::get(uint16_t asap)
{ {
if(asap == 0 || asap > entryCount()) if (asap == 0 || asap > entryCount())
LOGGER.warning("get: %d is no valid GroupObject. Asap must be > 0 and <= %d", asap, entryCount()); LOGGER.warning("get: %d is no valid GroupObject. Asap must be > 0 and <= %d", asap, entryCount());
return _groupObjects[asap - 1]; return _groupObjects[asap - 1];
@ -122,9 +122,8 @@ namespace Knx
go._table = this; go._table = this;
go._dataLength = go.goSize(); go._dataLength = go.goSize();
size_t sizeInMemory = go.sizeInMemory(); go._data = new uint8_t[go._dataLength];
go._data = new uint8_t[sizeInMemory]; memset(go._data, 0, go._dataLength);
memset(go._data, 0, sizeInMemory);
if (go.valueReadOnInit()) if (go.valueReadOnInit())
go.requestObjectRead(); go.requestObjectRead();

View File

@ -317,6 +317,11 @@ namespace Knx
return _data; return _data;
} }
uint32_t TableObject::dataSize()
{
return _size;
}
void TableObject::errorCode(ErrorCode errorCode) void TableObject::errorCode(ErrorCode errorCode)
{ {
uint8_t data = errorCode; uint8_t data = errorCode;

View File

@ -50,6 +50,12 @@ namespace Knx
* must not be written at nor freed. * must not be written at nor freed.
*/ */
uint8_t* data(); uint8_t* data();
/**
* returns the size in bytes of the internal data of the interface object.
*/
uint32_t dataSize();
/** /**
* Set the reason for a state change failure. * Set the reason for a state change failure.
*/ */

View File

@ -293,7 +293,7 @@ namespace Knx
fsync(_fd); fsync(_fd);
} }
#define FLASHSIZE 0x10000 #define FLASHSIZE 0x20000
void LinuxPlatform::doMemoryMapping() void LinuxPlatform::doMemoryMapping()
{ {
fs::path filePath = _flashFilePath; fs::path filePath = _flashFilePath;

View File

@ -4,16 +4,16 @@
namespace Knx namespace Knx
{ {
Map<const char*, Logger::LogType, 64> Logger::_loggers; Map<loggername_t, Logger::LogType, 64> Logger::_loggers;
Logger Logger::_logger; Logger Logger::_logger;
Logger& Logger::logger(const char* name) Logger& Logger::logger(loggername_t name)
{ {
_logger.name(name); _logger.name(name);
return _logger; return _logger;
} }
void Logger::logLevel(const char* name, LogType level) void Logger::logLevel(loggername_t name, LogType level)
{ {
_loggers.insertOrAssign(name, level); _loggers.insertOrAssign(name, level);
} }
@ -67,6 +67,12 @@ namespace Knx
va_end(objects); va_end(objects);
#endif #endif
} }
#ifdef __linux__
void print(std::string msg)
{
print(msg.c_str());
}
#endif
bool Logger::log(LogType type) bool Logger::log(LogType type)
{ {
@ -86,7 +92,7 @@ namespace Knx
if (*level > type) if (*level > type)
return false; return false;
print(millis()); print(millis());
print(" "); print(" ");
print(_name); print(_name);

View File

@ -3,8 +3,18 @@
#include <stdarg.h> #include <stdarg.h>
#include "simple_map.h" #include "simple_map.h"
#ifdef __linux
#include <string>
#define loggername_t std::string
#else
#define loggername_t const char*
#endif
namespace Knx namespace Knx
{ {
class IPrintable class IPrintable
{ {
public: public:
@ -23,8 +33,8 @@ namespace Knx
{ {
public: public:
enum LogType { Info, Warning, Error, Critical, Exception, Disabled}; enum LogType { Info, Warning, Error, Critical, Exception, Disabled};
static Logger& logger(const char* name); static Logger& logger(const loggername_t name);
static void logLevel(const char* name, LogType level); static void logLevel(const loggername_t name, LogType level);
void info(const char* message, IPrintable& object) void info(const char* message, IPrintable& object)
{ {
if (!log(LogType::Info)) if (!log(LogType::Info))
@ -79,14 +89,14 @@ namespace Knx
Logger() {} Logger() {}
bool log(LogType type); bool log(LogType type);
void log(LogType type, const char* format, va_list args); void log(LogType type, const char* format, va_list args);
void name(const char* value) void name(loggername_t value)
{ {
_name = value; _name = value;
} }
private: private:
const char* enum_name(LogType type); const char* enum_name(LogType type);
const char* _name = ""; loggername_t _name = "";
static Map<const char*, LogType, 64> _loggers; static Map<loggername_t, LogType, 64> _loggers;
static Logger _logger; static Logger _logger;
}; };
} }