Compare commits

..

5 Commits

Author SHA1 Message Date
norbert-walter 4a273d2c93 Add hibernate in full page refresh 2025-08-12 15:37:22 +02:00
Norbert Walter 9be1b864f4
Merge pull request #192 from thooge/scripts
Automate gen_set.py with page detection and command line parameters
2025-08-12 15:32:51 +02:00
Norbert Walter bfc4337417
Merge pull request #191 from thooge/precision
Added config option for display precision and formatter code improvement
2025-08-12 15:31:28 +02:00
Thomas Hooge 28a7e58e27 Automate gen_set.py with page detection and command line parameters 2025-08-01 11:01:23 +02:00
Thomas Hooge eb51092b23 Added config option for display precision and formatter code improvements 2025-07-31 12:31:57 +02:00
5 changed files with 436 additions and 339 deletions

View File

@ -65,13 +65,27 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
String tempFormat = commondata.config->getString(commondata.config->tempFormat); // [K|°C|°F]
String dateFormat = commondata.config->getString(commondata.config->dateFormat); // [DE|GB|US]
bool usesimudata = commondata.config->getBool(commondata.config->useSimuData); // [on|off]
String precision = commondata.config->getString(commondata.config->valueprecision); // [1|2]
// If boat value not valid
if (! value->valid && !usesimudata){
result.svalue = "---";
return result;
}
const char* fmt_dec_1;
const char* fmt_dec_10;
const char* fmt_dec_100;
if (precision == "1") {
fmt_dec_1 = "%3.1f";
fmt_dec_10 = "%3.0f";
fmt_dec_100 = "%3.0f";
} else {
fmt_dec_1 = "%3.2f";
fmt_dec_10 = "%3.1f";
fmt_dec_100 = "%3.0f";
}
// LOG_DEBUG(GwLog::DEBUG,"formatValue init: getFormat: %s date->value: %f time->value: %f", value->getFormat(), commondata.date->value, commondata.time->value);
static const int bsize = 30;
char buffer[bsize+1];
@ -91,25 +105,25 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
tmElements_t parts;
time_t tv=tNMEA0183Msg::daysToTime_t(value->value + dayoffset);
tNMEA0183Msg::breakTime(tv,parts);
if(usesimudata == false) {
if(String(dateFormat) == "DE"){
snprintf(buffer,bsize,"%02d.%02d.%04d",parts.tm_mday,parts.tm_mon+1,parts.tm_year+1900);
if (usesimudata == false) {
if (String(dateFormat) == "DE") {
snprintf(buffer,bsize, "%02d.%02d.%04d", parts.tm_mday, parts.tm_mon+1, parts.tm_year+1900);
}
else if(String(dateFormat) == "GB"){
snprintf(buffer,bsize,"%02d/%02d/%04d",parts.tm_mday,parts.tm_mon+1,parts.tm_year+1900);
else if(String(dateFormat) == "GB") {
snprintf(buffer, bsize, "%02d/%02d/%04d", parts.tm_mday, parts.tm_mon+1, parts.tm_year+1900);
}
else if(String(dateFormat) == "US"){
snprintf(buffer,bsize,"%02d/%02d/%04d",parts.tm_mon+1,parts.tm_mday,parts.tm_year+1900);
else if(String(dateFormat) == "US") {
snprintf(buffer, bsize, "%02d/%02d/%04d", parts.tm_mon+1, parts.tm_mday, parts.tm_year+1900);
}
else if(String(dateFormat) == "ISO"){
snprintf(buffer,bsize,"%04d-%02d-%02d",parts.tm_year+1900,parts.tm_mon+1,parts.tm_mday);
else if(String(dateFormat) == "ISO") {
snprintf(buffer, bsize, "%04d-%02d-%02d", parts.tm_year+1900, parts.tm_mon+1, parts.tm_mday);
}
else{
snprintf(buffer,bsize,"%02d.%02d.%04d",parts.tm_mday,parts.tm_mon+1,parts.tm_year+1900);
else {
snprintf(buffer, bsize, "%02d.%02d.%04d", parts.tm_mday, parts.tm_mon+1, parts.tm_year+1900);
}
}
else{
snprintf(buffer,bsize,"01.01.2022");
snprintf(buffer, bsize, "01.01.2022");
}
if(timeZone == 0){
result.unit = "UTC";
@ -130,11 +144,11 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
if (timeInSeconds > 86400) {timeInSeconds = timeInSeconds - 86400;}
if (timeInSeconds < 0) {timeInSeconds = timeInSeconds + 86400;}
// LOG_DEBUG(GwLog::DEBUG,"... formatTime value: %f tz: %f corrected timeInSeconds: %f ", value->value, timeZone, timeInSeconds);
if(usesimudata == false) {
val=modf(timeInSeconds/3600.0,&inthr);
val=modf(val*3600.0/60.0,&intmin);
if (usesimudata == false) {
val = modf(timeInSeconds/3600.0, &inthr);
val = modf(val*3600.0/60.0, &intmin);
modf(val*60.0,&intsec);
snprintf(buffer,bsize,"%02.0f:%02.0f:%02.0f",inthr,intmin,intsec);
snprintf(buffer, bsize, "%02.0f:%02.0f:%02.0f", inthr, intmin, intsec);
}
else{
static long sec;
@ -143,7 +157,7 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
sec ++;
}
sec = sec % 60;
snprintf(buffer,bsize,"11:36:%02i", int(sec));
snprintf(buffer, bsize, "11:36:%02i", int(sec));
lasttime = millis();
}
if(timeZone == 0){
@ -156,26 +170,26 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
//########################################################
else if (value->getFormat() == "formatFixed0"){
if(usesimudata == false) {
snprintf(buffer,bsize,"%3.0f",value->value);
snprintf(buffer, bsize, "%3.0f", value->value);
rawvalue = value->value;
}
else{
rawvalue = 8.0 + float(random(0, 10)) / 10.0;
snprintf(buffer,bsize,"%3.0f", rawvalue);
snprintf(buffer, bsize, "%3.0f", rawvalue);
}
result.unit = "";
}
//########################################################
else if (value->getFormat() == "formatCourse" || value->getFormat() == "formatWind"){
double course = 0;
if(usesimudata == false) {
if (usesimudata == false) {
course = value->value;
rawvalue = value->value;
}
else{
else {
course = 2.53 + float(random(0, 10) / 100.0);
rawvalue = course;
}
}
course = course * 57.2958; // Unit conversion form rad to deg
// Format 3 numbers with prefix zero
@ -185,7 +199,7 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
//########################################################
else if (value->getFormat() == "formatKnots" && (value->getName() == "SOG" || value->getName() == "STW")){
double speed = 0;
if(usesimudata == false) {
if (usesimudata == false) {
speed = value->value;
rawvalue = value->value;
}
@ -193,85 +207,85 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
rawvalue = 4.0 + float(random(0, 40));
speed = rawvalue;
}
if(String(speedFormat) == "km/h"){
if (String(speedFormat) == "km/h"){
speed = speed * 3.6; // Unit conversion form m/s to km/h
result.unit = "km/h";
}
else if(String(speedFormat) == "kn"){
else if (String(speedFormat) == "kn"){
speed = speed * 1.94384; // Unit conversion form m/s to kn
result.unit = "kn";
}
else{
else {
speed = speed; // Unit conversion form m/s to m/s
result.unit = "m/s";
}
if(speed < 10){
snprintf(buffer,bsize,"%3.2f",speed);
if(speed < 10) {
snprintf(buffer, bsize, fmt_dec_1, speed);
}
if(speed >= 10 && speed < 100){
snprintf(buffer,bsize,"%3.1f",speed);
else if (speed < 100) {
snprintf(buffer, bsize, fmt_dec_10, speed);
}
if(speed >= 100){
snprintf(buffer,bsize,"%3.0f",speed);
else {
snprintf(buffer, bsize, fmt_dec_100, speed);
}
}
//########################################################
else if (value->getFormat() == "formatKnots" && (value->getName() == "AWS" || value->getName() == "TWS" || value->getName() == "MaxAws" || value->getName() == "MaxTws")){
double speed = 0;
if(usesimudata == false) {
if (usesimudata == false) {
speed = value->value;
rawvalue = value->value;
}
else{
else {
rawvalue = 4.0 + float(random(0, 40));
speed = rawvalue;
}
if(String(windspeedFormat) == "km/h"){
speed = speed * 3.6; // Unit conversion form m/s to km/h
if (String(windspeedFormat) == "km/h"){
speed = speed * 3.6; // Unit conversion form m/s to km/h
result.unit = "km/h";
}
else if(String(windspeedFormat) == "kn"){
else if (String(windspeedFormat) == "kn"){
speed = speed * 1.94384; // Unit conversion form m/s to kn
result.unit = "kn";
}
else if(String(windspeedFormat) == "bft"){
if(speed < 0.3){
if (speed < 0.3) {
speed = 0;
}
if(speed >=0.3 && speed < 1.5){
else if (speed < 1.5) {
speed = 1;
}
if(speed >=1.5 && speed < 3.3){
else if (speed < 3.3) {
speed = 2;
}
if(speed >=3.3 && speed < 5.4){
else if (speed < 5.4) {
speed = 3;
}
if(speed >=5.4 && speed < 7.9){
else if (speed < 7.9) {
speed = 4;
}
if(speed >=7.9 && speed < 10.7){
else if (speed < 10.7) {
speed = 5;
}
if(speed >=10.7 && speed < 13.8){
else if (speed < 13.8) {
speed = 6;
}
if(speed >=13.8 && speed < 17.1){
else if (speed < 17.1) {
speed = 7;
}
if(speed >=17.1 && speed < 20.7){
else if (speed < 20.7) {
speed = 8;
}
if(speed >=20.7 && speed < 24.4){
else if (speed < 24.4) {
speed = 9;
}
if(speed >=24.4 && speed < 28.4){
else if (speed < 28.4) {
speed = 10;
}
if(speed >=28.4 && speed < 32.6){
else if (speed < 32.6) {
speed = 11;
}
if(speed >=32.6){
else {
speed = 12;
}
result.unit = "bft";
@ -280,82 +294,85 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
speed = speed; // Unit conversion form m/s to m/s
result.unit = "m/s";
}
if(String(windspeedFormat) == "bft"){
snprintf(buffer,bsize,"%2.0f",speed);
if (String(windspeedFormat) == "bft"){
snprintf(buffer, bsize, "%2.0f", speed);
}
else{
if(speed < 10){
snprintf(buffer,bsize,"%3.2f",speed);
if (speed < 10){
snprintf(buffer, bsize, fmt_dec_1, speed);
}
if(speed >= 10 && speed < 100){
snprintf(buffer,bsize,"%3.1f",speed);
else if (speed < 100){
snprintf(buffer, bsize, fmt_dec_10, speed);
}
if(speed >= 100){
snprintf(buffer,bsize,"%3.0f",speed);
else {
snprintf(buffer, bsize, fmt_dec_100, speed);
}
}
}
//########################################################
else if (value->getFormat() == "formatRot"){
double rotation = 0;
if(usesimudata == false) {
if (usesimudata == false) {
rotation = value->value;
rawvalue = value->value;
}
else{
else {
rawvalue = 0.04 + float(random(0, 10)) / 100.0;
rotation = rawvalue;
}
rotation = rotation * 57.2958; // Unit conversion form rad/s to deg/s
result.unit = "Deg/s";
if(rotation < -100){
if (rotation < -100){
rotation = -99;
}
if(rotation > 100){
if (rotation > 100){
rotation = 99;
}
if(rotation > -10 && rotation < 10){
snprintf(buffer,bsize,"%3.2f",rotation);
if (rotation > -10 && rotation < 10){
snprintf(buffer, bsize, "%3.2f", rotation);
}
if(rotation <= -10 || rotation >= 10){
snprintf(buffer,bsize,"%3.0f",rotation);
if (rotation <= -10 || rotation >= 10){
snprintf(buffer, bsize, "%3.0f", rotation);
}
}
//########################################################
else if (value->getFormat() == "formatDop"){
double dop = 0;
if(usesimudata == false) {
if (usesimudata == false) {
dop = value->value;
rawvalue = value->value;
}
else{
else {
rawvalue = 2.0 + float(random(0, 40)) / 10.0;
dop = rawvalue;
}
result.unit = "m";
if(dop > 99.9){
if (dop > 99.9){
dop = 99.9;
}
if(dop < 10){
snprintf(buffer,bsize,"%3.2f",dop);
if (dop < 10){
snprintf(buffer, bsize, fmt_dec_1, dop);
}
if(dop >= 10 && dop < 100){
snprintf(buffer,bsize,"%3.1f",dop);
else if(dop < 100){
snprintf(buffer, bsize, fmt_dec_10, dop);
}
else {
snprintf(buffer, bsize, fmt_dec_100, dop);
}
}
//########################################################
else if (value->getFormat() == "formatLatitude"){
if(usesimudata == false) {
if (usesimudata == false) {
double lat = value->value;
rawvalue = value->value;
String latitude = "";
String latdir = "";
float degree = abs(int(lat));
float minute = abs((lat - int(lat)) * 60);
if(lat > 0){
if (lat > 0){
latdir = "N";
}
else{
else {
latdir = "S";
}
latitude = String(degree,0) + "\x90 " + String(minute,4) + "' " + latdir;
@ -364,41 +381,41 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
}
else{
rawvalue = 35.0 + float(random(0, 10)) / 10000.0;
snprintf(buffer,bsize," 51\" %2.4f' N", rawvalue);
snprintf(buffer, bsize, " 51\" %2.4f' N", rawvalue);
}
}
//########################################################
else if (value->getFormat() == "formatLongitude"){
if(usesimudata == false) {
if (usesimudata == false) {
double lon = value->value;
rawvalue = value->value;
String longitude = "";
String londir = "";
float degree = abs(int(lon));
float minute = abs((lon - int(lon)) * 60);
if(lon > 0){
if (lon > 0){
londir = "E";
}
else{
else {
londir = "W";
}
longitude = String(degree,0) + "\x90 " + String(minute,4) + "' " + londir;
result.unit = "";
strcpy(buffer, longitude.c_str());
}
else{
else {
rawvalue = 6.0 + float(random(0, 10)) / 100000.0;
snprintf(buffer,bsize," 15\" %2.4f'", rawvalue);
snprintf(buffer, bsize, " 15\" %2.4f'", rawvalue);
}
}
//########################################################
else if (value->getFormat() == "formatDepth"){
double depth = 0;
if(usesimudata == false) {
if (usesimudata == false) {
depth = value->value;
rawvalue = value->value;
}
else{
else {
rawvalue = 18.0 + float(random(0, 100)) / 10.0;
depth = rawvalue;
}
@ -409,14 +426,14 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
else{
result.unit = "m";
}
if(depth < 10){
snprintf(buffer,bsize,"%3.2f",depth);
if (depth < 10) {
snprintf(buffer, bsize, fmt_dec_1, depth);
}
if(depth >= 10 && depth < 100){
snprintf(buffer,bsize,"%3.1f",depth);
else if (depth < 100){
snprintf(buffer, bsize, fmt_dec_10, depth);
}
if(depth >= 100){
snprintf(buffer,bsize,"%3.0f",depth);
else {
snprintf(buffer, bsize, fmt_dec_100, depth);
}
}
//########################################################
@ -430,50 +447,50 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
xte = rawvalue;
}
if (xte >= 100) {
snprintf(buffer,bsize,"%3.0f",value->value);
snprintf(buffer, bsize, fmt_dec_100, value->value);
} else if (xte >= 10) {
snprintf(buffer,bsize,"%3.1f",value->value);
snprintf(buffer, bsize, fmt_dec_10, value->value);
} else {
snprintf(buffer,bsize,"%3.2f",value->value);
snprintf(buffer, bsize, fmt_dec_1, value->value);
}
result.unit = "nm";
}
//########################################################
else if (value->getFormat() == "kelvinToC"){
double temp = 0;
if(usesimudata == false) {
if (usesimudata == false) {
temp = value->value;
rawvalue = value->value;
}
else{
else {
rawvalue = 296.0 + float(random(0, 10)) / 10.0;
temp = rawvalue;
}
if(String(tempFormat) == "C"){
if (String(tempFormat) == "C") {
temp = temp - 273.15;
result.unit = "C";
}
else if(String(tempFormat) == "F"){
else if (String(tempFormat) == "F") {
temp = (temp - 273.15) * 9 / 5 + 32;
result.unit = "F";
}
else{
result.unit = "K";
}
if(temp < 10){
snprintf(buffer,bsize,"%3.2f",temp);
if(temp < 10) {
snprintf(buffer, bsize, fmt_dec_1, temp);
}
if(temp >= 10 && temp < 100){
snprintf(buffer,bsize,"%3.1f",temp);
else if (temp < 100) {
snprintf(buffer, bsize, fmt_dec_10, temp);
}
if(temp >= 100){
snprintf(buffer,bsize,"%3.0f",temp);
else {
snprintf(buffer, bsize, fmt_dec_100, temp);
}
}
//########################################################
else if (value->getFormat() == "mtr2nm"){
double distance = 0;
if(usesimudata == false) {
if (usesimudata == false) {
distance = value->value;
rawvalue = value->value;
}
@ -481,25 +498,25 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
rawvalue = 2960.0 + float(random(0, 10));
distance = rawvalue;
}
if(String(distanceFormat) == "km"){
if (String(distanceFormat) == "km") {
distance = distance * 0.001;
result.unit = "km";
}
else if(String(distanceFormat) == "nm"){
else if (String(distanceFormat) == "nm") {
distance = distance * 0.000539957;
result.unit = "nm";
}
else{;
else {
result.unit = "m";
}
if(distance < 10){
snprintf(buffer,bsize,"%3.2f",distance);
if (distance < 10){
snprintf(buffer, bsize, fmt_dec_1, distance);
}
if(distance >= 10 && distance < 100){
snprintf(buffer,bsize,"%3.1f",distance);
else if (distance < 100){
snprintf(buffer, bsize, fmt_dec_10, distance);
}
if(distance >= 100){
snprintf(buffer,bsize,"%3.0f",distance);
else {
snprintf(buffer, bsize, fmt_dec_100, distance);
}
}
//########################################################
@ -508,122 +525,122 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
//########################################################
else if (value->getFormat() == "formatXdr:P:P"){
double pressure = 0;
if(usesimudata == false) {
if (usesimudata == false) {
pressure = value->value;
rawvalue = value->value;
pressure = pressure / 100.0; // Unit conversion form Pa to hPa
}
else{
else {
rawvalue = 968 + float(random(0, 10));
pressure = rawvalue;
}
snprintf(buffer,bsize,"%4.0f",pressure);
snprintf(buffer, bsize, "%4.0f", pressure);
result.unit = "hPa";
}
//########################################################
else if (value->getFormat() == "formatXdr:P:B"){
double pressure = 0;
if(usesimudata == false) {
if (usesimudata == false) {
pressure = value->value;
rawvalue = value->value;
pressure = pressure / 100.0; // Unit conversion form Pa to mBar
}
else{
else {
rawvalue = value->value;
pressure = 968 + float(random(0, 10));
}
snprintf(buffer,bsize,"%4.0f",pressure);
snprintf(buffer, bsize, "%4.0f", pressure);
result.unit = "mBar";
}
//########################################################
else if (value->getFormat() == "formatXdr:U:V"){
double voltage = 0;
if(usesimudata == false) {
if (usesimudata == false) {
voltage = value->value;
rawvalue = value->value;
}
else{
else {
rawvalue = 12 + float(random(0, 30)) / 10.0;
voltage = rawvalue;
}
if(voltage < 10){
snprintf(buffer,bsize,"%3.2f",voltage);
if (voltage < 10) {
snprintf(buffer, bsize, fmt_dec_1, voltage);
}
else{
snprintf(buffer,bsize,"%3.1f",voltage);
else {
snprintf(buffer, bsize, fmt_dec_10, voltage);
}
result.unit = "V";
}
//########################################################
else if (value->getFormat() == "formatXdr:I:A"){
double current = 0;
if(usesimudata == false) {
if (usesimudata == false) {
current = value->value;
rawvalue = value->value;
}
else{
else {
rawvalue = 8.2 + float(random(0, 50)) / 10.0;
current = rawvalue;
}
if(current < 10){
snprintf(buffer,bsize,"%3.2f",current);
if (current < 10) {
snprintf(buffer, bsize, fmt_dec_1, current);
}
if(current >= 10 && current < 100){
snprintf(buffer,bsize,"%3.1f",current);
else if(current < 100) {
snprintf(buffer, bsize, fmt_dec_10, current);
}
if(current >= 100){
snprintf(buffer,bsize,"%3.0f",current);
else {
snprintf(buffer, bsize, fmt_dec_100, current);
}
result.unit = "A";
}
//########################################################
else if (value->getFormat() == "formatXdr:C:K"){
double temperature = 0;
if(usesimudata == false) {
if (usesimudata == false) {
temperature = value->value - 273.15; // Convert K to C
rawvalue = value->value - 273.15;
}
else{
else {
rawvalue = 21.8 + float(random(0, 50)) / 10.0;
temperature = rawvalue;
}
if(temperature < 10){
snprintf(buffer,bsize,"%3.2f",temperature);
if (temperature < 10) {
snprintf(buffer, bsize, fmt_dec_1, temperature);
}
if(temperature >= 10 && temperature < 100){
snprintf(buffer,bsize,"%3.1f",temperature);
else if (temperature < 100) {
snprintf(buffer, bsize, fmt_dec_10, temperature);
}
if(temperature >= 100){
snprintf(buffer,bsize,"%3.0f",temperature);
else {
snprintf(buffer, bsize, fmt_dec_100, temperature);
}
result.unit = "Deg C";
}
//########################################################
else if (value->getFormat() == "formatXdr:C:C"){
double temperature = 0;
if(usesimudata == false) {
if (usesimudata == false) {
temperature = value->value; // Value in C
rawvalue = value->value;
}
else{
else {
rawvalue = 21.8 + float(random(0, 50)) / 10.0;
temperature = rawvalue;
}
if(temperature < 10){
snprintf(buffer,bsize,"%3.2f",temperature);
if (temperature < 10) {
snprintf(buffer, bsize, fmt_dec_1, temperature);
}
if(temperature >= 10 && temperature < 100){
snprintf(buffer,bsize,"%3.1f",temperature);
else if(temperature < 100) {
snprintf(buffer, bsize, fmt_dec_10, temperature);
}
if(temperature >= 100){
snprintf(buffer,bsize,"%3.0f",temperature);
else {
snprintf(buffer, bsize, fmt_dec_100, temperature);
}
result.unit = "Deg C";
}
//########################################################
else if (value->getFormat() == "formatXdr:H:P"){
double humidity = 0;
if(usesimudata == false) {
if (usesimudata == false) {
humidity = value->value; // Value in %
rawvalue = value->value;
}
@ -631,143 +648,143 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
rawvalue = 41.3 + float(random(0, 50)) / 10.0;
humidity = rawvalue;
}
if(humidity < 10){
snprintf(buffer,bsize,"%3.2f",humidity);
if (humidity < 10) {
snprintf(buffer, bsize, fmt_dec_1, humidity);
}
if(humidity >= 10 && humidity < 100){
snprintf(buffer,bsize,"%3.1f",humidity);
else if(humidity < 100) {
snprintf(buffer, bsize, fmt_dec_10, humidity);
}
if(humidity >= 100){
snprintf(buffer,bsize,"%3.0f",humidity);
else {
snprintf(buffer, bsize, fmt_dec_100, humidity);
}
result.unit = "%";
}
//########################################################
else if (value->getFormat() == "formatXdr:V:P"){
double volume = 0;
if(usesimudata == false) {
if (usesimudata == false) {
volume = value->value; // Value in %
rawvalue = value->value;
}
else{
else {
rawvalue = 85.8 + float(random(0, 50)) / 10.0;
volume = rawvalue;
}
if(volume < 10){
snprintf(buffer,bsize,"%3.2f",volume);
if (volume < 10) {
snprintf(buffer, bsize, fmt_dec_1, volume);
}
if(volume >= 10 && volume < 100){
snprintf(buffer,bsize,"%3.1f",volume);
else if (volume < 100) {
snprintf(buffer, bsize, fmt_dec_10, volume);
}
if(volume >= 100){
snprintf(buffer,bsize,"%3.0f",volume);
else if (volume >= 100) {
snprintf(buffer, bsize, fmt_dec_100, volume);
}
result.unit = "%";
}
//########################################################
else if (value->getFormat() == "formatXdr:V:M"){
double volume = 0;
if(usesimudata == false) {
if (usesimudata == false) {
volume = value->value; // Value in l
rawvalue = value->value;
}
else{
else {
rawvalue = 75.2 + float(random(0, 50)) / 10.0;
volume = rawvalue;
}
if(volume < 10){
snprintf(buffer,bsize,"%3.2f",volume);
if (volume < 10) {
snprintf(buffer, bsize, fmt_dec_1, volume);
}
if(volume >= 10 && volume < 100){
snprintf(buffer,bsize,"%3.1f",volume);
else if (volume < 100) {
snprintf(buffer, bsize, fmt_dec_10, volume);
}
if(volume >= 100){
snprintf(buffer,bsize,"%3.0f",volume);
else {
snprintf(buffer, bsize, fmt_dec_100, volume);
}
result.unit = "l";
}
//########################################################
else if (value->getFormat() == "formatXdr:R:I"){
double flow = 0;
if(usesimudata == false) {
if (usesimudata == false) {
flow = value->value; // Value in l/min
rawvalue = value->value;
}
else{
else {
rawvalue = 7.5 + float(random(0, 20)) / 10.0;
flow = rawvalue;
}
if(flow < 10){
snprintf(buffer,bsize,"%3.2f",flow);
if (flow < 10) {
snprintf(buffer, bsize, fmt_dec_1, flow);
}
if(flow >= 10 && flow < 100){
snprintf(buffer,bsize,"%3.1f",flow);
else if (flow < 100) {
snprintf(buffer, bsize, fmt_dec_10, flow);
}
if(flow >= 100){
snprintf(buffer,bsize,"%3.0f",flow);
else {
snprintf(buffer, bsize, fmt_dec_100, flow);
}
result.unit = "l/min";
}
//########################################################
else if (value->getFormat() == "formatXdr:G:"){
double generic = 0;
if(usesimudata == false) {
generic = value->value; // Value in l/min
if (usesimudata == false) {
generic = value->value;
rawvalue = value->value;
}
else{
else {
rawvalue = 18.5 + float(random(0, 20)) / 10.0;
generic = rawvalue;
}
if(generic < 10){
snprintf(buffer,bsize,"%3.2f",generic);
if (generic < 10) {
snprintf(buffer, bsize, fmt_dec_1, generic);
}
if(generic >= 10 && generic < 100){
snprintf(buffer,bsize,"%3.1f",generic);
else if (generic < 100) {
snprintf(buffer, bsize, fmt_dec_10, generic);
}
if(generic >= 100){
snprintf(buffer,bsize,"%3.0f",generic);
else {
snprintf(buffer, bsize, fmt_dec_100, generic);
}
result.unit = "";
}
//########################################################
else if (value->getFormat() == "formatXdr:A:P"){
double dplace = 0;
if(usesimudata == false) {
if (usesimudata == false) {
dplace = value->value; // Value in %
rawvalue = value->value;
}
else{
else {
rawvalue = 55.3 + float(random(0, 20)) / 10.0;
dplace = rawvalue;
}
if(dplace < 10){
snprintf(buffer,bsize,"%3.2f",dplace);
if (dplace < 10) {
snprintf(buffer, bsize, fmt_dec_1, dplace);
}
if(dplace >= 10 && dplace < 100){
snprintf(buffer,bsize,"%3.1f",dplace);
else if (dplace < 100) {
snprintf(buffer, bsize, fmt_dec_10, dplace);
}
if(dplace >= 100){
snprintf(buffer,bsize,"%3.0f",dplace);
else {
snprintf(buffer, bsize, fmt_dec_100, dplace);
}
result.unit = "%";
}
//########################################################
else if (value->getFormat() == "formatXdr:A:D"){
double angle = 0;
if(usesimudata == false) {
if (usesimudata == false) {
angle = value->value;
angle = angle * 57.2958; // Unit conversion form rad to deg
rawvalue = value->value;
}
else{
else {
rawvalue = PI / 100 + (random(-5, 5) / 360 * 2* PI);
angle = rawvalue * 57.2958;
}
if(angle > -10 && angle < 10){
if (angle > -10 && angle < 10) {
snprintf(buffer,bsize,"%3.1f",angle);
}
else{
else {
snprintf(buffer,bsize,"%3.0f",angle);
}
result.unit = "Deg";
@ -775,41 +792,41 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata){
//########################################################
else if (value->getFormat() == "formatXdr:T:R"){
double rpm = 0;
if(usesimudata == false) {
if (usesimudata == false) {
rpm = value->value; // Value in rpm
rawvalue = value->value;
}
else{
else {
rawvalue = 2505 + random(0, 20);
rpm = rawvalue;
}
if(rpm < 10){
snprintf(buffer,bsize,"%3.2f",rpm);
if (rpm < 10) {
snprintf(buffer, bsize, fmt_dec_1, rpm);
}
if(rpm >= 10 && rpm < 100){
snprintf(buffer,bsize,"%3.1f",rpm);
else if (rpm < 100) {
snprintf(buffer, bsize, fmt_dec_10, rpm);
}
if(rpm >= 100){
snprintf(buffer,bsize,"%3.0f",rpm);
else {
snprintf(buffer, bsize, fmt_dec_100, rpm);
}
result.unit = "rpm";
}
//########################################################
// Default format
//########################################################
else{
if(value->value < 10){
snprintf(buffer,bsize,"%3.2f",value->value);
else {
if (value->value < 10) {
snprintf(buffer, bsize, fmt_dec_1, value->value);
}
if(value->value >= 10 && value->value < 100){
snprintf(buffer,bsize,"%3.1f",value->value);
else if (value->value < 100) {
snprintf(buffer, bsize, fmt_dec_10, value->value);
}
if(value->value >= 100){
snprintf(buffer,bsize,"%3.0f",value->value);
else {
snprintf(buffer, bsize, fmt_dec_100, value->value);
}
result.unit = "";
}
buffer[bsize]=0;
buffer[bsize] = 0;
result.value = rawvalue; // Return value is only necessary in case of simulation of graphic pointer
result.svalue = String(buffer);
return result;

View File

@ -1117,6 +1117,21 @@
"obp60":"true"
}
},
{
"name": "valueprecision",
"label": "Display value precision",
"type": "list",
"default": "2",
"description": "Maximum number of decimal places to display [1|2]",
"list": [
"1",
"2"
],
"category": "OBP60 Display",
"capabilities": {
"obp60":"true"
}
},
{
"name": "backlight",
"label": "Backlight Mode",

View File

@ -1129,6 +1129,21 @@
"obp40": "true"
}
},
{
"name": "valueprecision",
"label": "Display value precision",
"type": "list",
"default": "2",
"description": "Maximum number of decimal places to display [1|2]",
"list": [
"1",
"2"
],
"category": "OBP40 Display",
"capabilities": {
"obp40":"true"
}
},
{
"name": "backlight",
"label": "Backlight Mode",

View File

@ -1,132 +1,179 @@
#!/usr/bin/env python3
# A tool to generate that part of config.json that deals with pages and fields.
#
#Usage: 1. modify this script (e.g.add a page, change number of fields, etc.)
# 2. Delete all lines from config.json from the curly backet before "name": "page1type" to o the end of the file (as of today, delete from line 917 to the end of the File)
# 3. run ./gen_set.py >> config.json
"""
A tool to generate that part of config.json that deals with pages and fields.
Usage example:
1. Delete all lines from config.json from the curly backet before
"name": "page1type" to the end of the file
2. run ./gen_set.py -d obp60 -p 10 >> config.json
TODO Better handling of default pages
"""
import os
import sys
import getopt
import re
import json
# List of all pages and the number of parameters they expect.
no_of_fields_per_page = {
"Wind": 0,
"XTETrack": 0,
"Battery2": 0,
"Battery": 0,
"BME280": 0,
"Clock": 0,
"Compass" : 0,
"DST810": 0,
"Fluid": 1,
"FourValues2": 4,
"FourValues": 4,
"Generator": 0,
"KeelPosition": 0,
"OneValue": 1,
"RollPitch": 2,
"RudderPosition": 0,
"SixValues" : 6,
"Solar": 0,
"ThreeValues": 3,
"TwoValues": 2,
"Voltage": 0,
"WhitePage": 0,
"WindPlot": 0,
"WindRose": 0,
"WindRoseFlex": 6,
}
__version__ = "0.2"
# No changes needed beyond this point
# max number of pages supported by OBP60
no_of_pages = 10
# Default selection for each page
default_pages = [
"Voltage",
"WindRose",
"OneValue",
"TwoValues",
"ThreeValues",
"FourValues",
"FourValues2",
"Clock",
"RollPitch",
"Battery2",
]
numbers = [
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"ten",
]
pages = sorted(no_of_fields_per_page.keys())
max_no_of_fields_per_page = max(no_of_fields_per_page.values())
def detect_pages(filename):
# returns a dictionary with page name and the number of gui fields
pagefiles = []
with open(filename, 'r') as fh:
pattern = r'extern PageDescription\s*register(Page[^;\s]*)'
for line in fh:
if "extern PageDescription" in line:
match = re.search(pattern, line)
if match:
pagefiles.append(match.group(1))
try:
pagefiles.remove('PageSystem')
except ValueError:
pass
pagedata = {}
for pf in pagefiles:
filename = pf + ".cpp"
with open(filename, 'r') as fh:
content = fh.read()
pattern = r'PageDescription\s*?register' + pf + r'\s*\(\s*"([^"]+)".*?\n\s*(\d+)'
match = re.search(pattern, content, re.DOTALL)
if match:
pagedata[match.group(1)] = int(match.group(2))
return pagedata
output = []
def get_default_page(pageno):
# Default selection for each page
default_pages = (
"Voltage",
"WindRose",
"OneValue",
"TwoValues",
"ThreeValues",
"FourValues",
"FourValues2",
"Clock",
"RollPitch",
"Battery2"
)
if pageno > len(default_pages):
return "OneValue"
return default_pages[pageno - 1]
for page_no in range(1, no_of_pages + 1):
page_data = {
"name": f"page{page_no}type",
"label": "Type",
"type": "list",
"default": default_pages[page_no - 1],
"description": f"Type of page for page {page_no}",
"list": pages,
"category": f"OBP60 Page {page_no}",
"capabilities": {"obp60": "true"},
"condition": [{"visiblePages": vp} for vp in range(page_no, no_of_pages + 1)],
#"fields": [],
}
output.append(page_data)
def number_to_text(number):
if number < 0 or number > 99:
raise ValueError("Only numbers from 0 to 99 are allowed.")
numbers = ("zero", "one", "two", "three", "four", "five", "six", "seven",
"eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen")
tens = ("", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy",
"eighty", "ninety")
if number < 20:
return numbers[number]
else:
q, r = divmod(number, 10)
return tens[q] + numbers[r]
for field_no in range(1, max_no_of_fields_per_page + 1):
field_data = {
"name": f"page{page_no}value{field_no}",
"label": f"Field {field_no}",
"type": "boatData",
"default": "",
"description": f"The display for field {numbers[field_no - 1]}",
"category": f"OBP60 Page {page_no}",
"capabilities": {"obp60": "true"},
"condition": [
{f"page{page_no}type": page}
for page in pages
if no_of_fields_per_page[page] >= field_no
],
def create_json(device, no_of_pages, pagedata):
pages = sorted(pagedata.keys())
max_no_of_fields_per_page = max(pagedata.values())
output = []
for page_no in range(1, no_of_pages + 1):
page_data = {
"name": f"page{page_no}type",
"label": "Type",
"type": "list",
"default": get_default_page(page_no),
"description": f"Type of page for page {page_no}",
"list": pages,
"category": f"{device.upper()} Page {page_no}",
"capabilities": {device.lower(): "true"},
"condition": [{"visiblePages": vp} for vp in range(page_no, no_of_pages + 1)],
#"fields": [],
}
output.append(field_data)
output.append(page_data)
fluid_data ={
"name": f"page{page_no}fluid",
"label": "Fluid type",
"type": "list",
"default": "0",
"list": [
{"l":"Fuel (0)","v":"0"},
{"l":"Water (1)","v":"1"},
{"l":"Gray Water (2)","v":"2"},
{"l":"Live Well (3)","v":"3"},
{"l":"Oil (4)","v":"4"},
{"l":"Black Water (5)","v":"5"},
{"l":"Fuel Gasoline (6)","v":"6"}
],
"description": "Fluid type in tank",
"category": f"OBP60 Page {page_no}",
"capabilities": {
"obp60":"true"
},
"condition":[{f"page{page_no}type":"Fluid"}]
}
output.append(fluid_data)
for field_no in range(1, max_no_of_fields_per_page + 1):
field_data = {
"name": f"page{page_no}value{field_no}",
"label": f"Field {field_no}",
"type": "boatData",
"default": "",
"description": "The display for field {}".format(number_to_text(field_no)),
"category": f"{device.upper()} Page {page_no}",
"capabilities": {device.lower(): "true"},
"condition": [
{f"page{page_no}type": page}
for page in pages
if pagedata[page] >= field_no
],
}
output.append(field_data)
json_output = json.dumps(output, indent=4)
# print omitting first and last line containing [ ] of JSON array
#print(json_output[1:-1])
# print omitting first line containing [ of JSON array
print(json_output[1:])
# print(",")
fluid_data ={
"name": f"page{page_no}fluid",
"label": "Fluid type",
"type": "list",
"default": "0",
"list": [
{"l":"Fuel (0)","v":"0"},
{"l":"Water (1)","v":"1"},
{"l":"Gray Water (2)","v":"2"},
{"l":"Live Well (3)","v":"3"},
{"l":"Oil (4)","v":"4"},
{"l":"Black Water (5)","v":"5"},
{"l":"Fuel Gasoline (6)","v":"6"}
],
"description": "Fluid type in tank",
"category": f"{device.upper()} Page {page_no}",
"capabilities": {
device.lower(): "true"
},
"condition":[{f"page{page_no}type":"Fluid"}]
}
output.append(fluid_data)
return json.dumps(output, indent=4)
def usage():
print("{} v{}".format(os.path.basename(__file__), __version__))
print()
print("Command line options")
print(" -d --device device name to use e.g. obp60")
print(" -p --pages number of pages to create")
print(" -h show this help")
print()
if __name__ == '__main__':
try:
options, remainder = getopt.getopt(sys.argv[1:], 'd:p:', ['device=','--pages='])
except getopt.GetoptError as err:
print(err)
usage()
sys.exit(2)
device = "obp60"
no_of_pages = 10
for opt, arg in options:
if opt in ('-d', '--device'):
device = arg
elif opt in ('-p', '--pages'):
no_of_pages = int(arg)
elif opt == '-h':
usage()
sys.exit(0)
# automatic detect pages and number of fields from sourcecode
pagedata = detect_pages("obp60task.cpp")
json_output = create_json(device, no_of_pages, pagedata)
# print omitting first line containing [ of JSON array
print(json_output[1:])

View File

@ -891,6 +891,7 @@ void OBP60Task(GwApi *api){
else{
getdisplay().fillScreen(commonData.fgcolor); // Clear display
#ifdef DISPLAY_GDEY042T81
getdisplay().hibernate(); // Set display in hybenate mode
getdisplay().init(115200, true, 2, false); // Init for Waveshare boards with "clever" reset circuit, 2ms reset pulse
#else
getdisplay().init(115200); // Init for normal displays
@ -918,6 +919,7 @@ void OBP60Task(GwApi *api){
else{
getdisplay().fillScreen(commonData.fgcolor); // Clear display
#ifdef DISPLAY_GDEY042T81
getdisplay().hibernate(); // Set display in hybenate mode
getdisplay().init(115200, true, 2, false); // Init for Waveshare boards with "clever" reset circuit, 2ms reset pulse
#else
getdisplay().init(115200); // Init for normal displays
@ -942,6 +944,7 @@ void OBP60Task(GwApi *api){
else{
getdisplay().fillScreen(commonData.fgcolor); // Clear display
#ifdef DISPLAY_GDEY042T81
getdisplay().hibernate(); // Set display in hybenate mode
getdisplay().init(115200, true, 2, false); // Init for Waveshare boards with "clever" reset circuit, 2ms reset pulse
#else
getdisplay().init(115200); // Init for normal displays