mirror of
https://github.com/meshtastic/firmware.git
synced 2025-06-08 22:22:05 +00:00
update to handle ws80 as well (#6440)
Small change to make the string parsing of Name = value less brittle. Adds a function to parse a line without knowing how many spaces are after the = sign. This allows it to also work with the ws80 serial output.
This commit is contained in:
parent
b52c355f2f
commit
e08177ba98
@ -408,6 +408,49 @@ uint32_t SerialModule::getBaudRate()
|
|||||||
return BAUD;
|
return BAUD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add this structure to help with parsing WindGust = 24.4 serial lines.
|
||||||
|
struct ParsedLine {
|
||||||
|
String name;
|
||||||
|
String value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a line of format "Name = Value" into name/value pair
|
||||||
|
* @param line Input line to parse
|
||||||
|
* @return ParsedLine containing name and value, or empty strings if parse failed
|
||||||
|
*/
|
||||||
|
ParsedLine parseLine(const char *line)
|
||||||
|
{
|
||||||
|
ParsedLine result = {"", ""};
|
||||||
|
|
||||||
|
// Find equals sign
|
||||||
|
const char *equals = strchr(line, '=');
|
||||||
|
if (!equals) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract name by copying substring
|
||||||
|
char nameBuf[64]; // Temporary buffer
|
||||||
|
size_t nameLen = equals - line;
|
||||||
|
if (nameLen >= sizeof(nameBuf)) {
|
||||||
|
nameLen = sizeof(nameBuf) - 1;
|
||||||
|
}
|
||||||
|
strncpy(nameBuf, line, nameLen);
|
||||||
|
nameBuf[nameLen] = '\0';
|
||||||
|
|
||||||
|
// Create trimmed name string
|
||||||
|
String name = String(nameBuf);
|
||||||
|
name.trim();
|
||||||
|
|
||||||
|
// Extract value after equals sign
|
||||||
|
String value = String(equals + 1);
|
||||||
|
value.trim();
|
||||||
|
|
||||||
|
result.name = name;
|
||||||
|
result.value = value;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the received weather station serial data, extract wind, voltage, and temperature information,
|
* Process the received weather station serial data, extract wind, voltage, and temperature information,
|
||||||
* calculate averages and send telemetry data over the mesh network.
|
* calculate averages and send telemetry data over the mesh network.
|
||||||
@ -453,6 +496,7 @@ void SerialModule::processWXSerial()
|
|||||||
// WindSpeed = 0.5
|
// WindSpeed = 0.5
|
||||||
// WindGust = 0.6
|
// WindGust = 0.6
|
||||||
// GXTS04Temp = 24.4
|
// GXTS04Temp = 24.4
|
||||||
|
// Temperature = 23.4 // WS80
|
||||||
|
|
||||||
// RainIntSum = 0
|
// RainIntSum = 0
|
||||||
// Rain = 0.0
|
// Rain = 0.0
|
||||||
@ -471,77 +515,50 @@ void SerialModule::processWXSerial()
|
|||||||
memset(line, '\0', sizeof(line));
|
memset(line, '\0', sizeof(line));
|
||||||
if (lineEnd - lineStart < sizeof(line) - 1) {
|
if (lineEnd - lineStart < sizeof(line) - 1) {
|
||||||
memcpy(line, &serialBytes[lineStart], lineEnd - lineStart);
|
memcpy(line, &serialBytes[lineStart], lineEnd - lineStart);
|
||||||
if (strstr(line, "Wind") != NULL) // we have a wind line
|
|
||||||
{
|
|
||||||
gotwind = true;
|
|
||||||
// Find the positions of "=" signs in the line
|
|
||||||
char *windDirPos = strstr(line, "WindDir = ");
|
|
||||||
char *windSpeedPos = strstr(line, "WindSpeed = ");
|
|
||||||
char *windGustPos = strstr(line, "WindGust = ");
|
|
||||||
|
|
||||||
if (windDirPos != NULL) {
|
ParsedLine parsed = parseLine(line);
|
||||||
// Extract data after "=" for WindDir
|
if (parsed.name.length() > 0) {
|
||||||
strlcpy(windDir, windDirPos + 15, sizeof(windDir)); // Add 15 to skip "WindDir = "
|
if (parsed.name == "WindDir") {
|
||||||
|
strlcpy(windDir, parsed.value.c_str(), sizeof(windDir));
|
||||||
double radians = GeoCoord::toRadians(strtof(windDir, nullptr));
|
double radians = GeoCoord::toRadians(strtof(windDir, nullptr));
|
||||||
dir_sum_sin += sin(radians);
|
dir_sum_sin += sin(radians);
|
||||||
dir_sum_cos += cos(radians);
|
dir_sum_cos += cos(radians);
|
||||||
dirCount++;
|
dirCount++;
|
||||||
} else if (windSpeedPos != NULL) {
|
gotwind = true;
|
||||||
// Extract data after "=" for WindSpeed
|
} else if (parsed.name == "WindSpeed") {
|
||||||
strlcpy(windVel, windSpeedPos + 15, sizeof(windVel)); // Add 15 to skip "WindSpeed = "
|
strlcpy(windVel, parsed.value.c_str(), sizeof(windVel));
|
||||||
float newv = strtof(windVel, nullptr);
|
float newv = strtof(windVel, nullptr);
|
||||||
velSum += newv;
|
velSum += newv;
|
||||||
velCount++;
|
velCount++;
|
||||||
if (newv < lull || lull == -1)
|
if (newv < lull || lull == -1) {
|
||||||
lull = newv;
|
lull = newv;
|
||||||
|
}
|
||||||
} else if (windGustPos != NULL) {
|
gotwind = true;
|
||||||
strlcpy(windGust, windGustPos + 15, sizeof(windGust)); // Add 15 to skip "WindSpeed = "
|
} else if (parsed.name == "WindGust") {
|
||||||
|
strlcpy(windGust, parsed.value.c_str(), sizeof(windGust));
|
||||||
float newg = strtof(windGust, nullptr);
|
float newg = strtof(windGust, nullptr);
|
||||||
if (newg > gust)
|
if (newg > gust) {
|
||||||
gust = newg;
|
gust = newg;
|
||||||
}
|
}
|
||||||
|
gotwind = true;
|
||||||
// these are also voltage data we care about possibly
|
} else if (parsed.name == "BatVoltage") {
|
||||||
} else if (strstr(line, "BatVoltage") != NULL) { // we have a battVoltage line
|
strlcpy(batVoltage, parsed.value.c_str(), sizeof(batVoltage));
|
||||||
char *batVoltagePos = strstr(line, "BatVoltage = ");
|
|
||||||
if (batVoltagePos != NULL) {
|
|
||||||
strlcpy(batVoltage, batVoltagePos + 17, sizeof(batVoltage)); // 18 for ws 80, 17 for ws85
|
|
||||||
batVoltageF = strtof(batVoltage, nullptr);
|
batVoltageF = strtof(batVoltage, nullptr);
|
||||||
break; // last possible data we want so break
|
break; // last possible data we want so break
|
||||||
}
|
} else if (parsed.name == "CapVoltage") {
|
||||||
} else if (strstr(line, "CapVoltage") != NULL) { // we have a cappVoltage line
|
strlcpy(capVoltage, parsed.value.c_str(), sizeof(capVoltage));
|
||||||
char *capVoltagePos = strstr(line, "CapVoltage = ");
|
|
||||||
if (capVoltagePos != NULL) {
|
|
||||||
strlcpy(capVoltage, capVoltagePos + 17, sizeof(capVoltage)); // 18 for ws 80, 17 for ws85
|
|
||||||
capVoltageF = strtof(capVoltage, nullptr);
|
capVoltageF = strtof(capVoltage, nullptr);
|
||||||
}
|
} else if (parsed.name == "GXTS04Temp" || parsed.name == "Temperature") {
|
||||||
// GXTS04Temp = 24.4
|
strlcpy(temperature, parsed.value.c_str(), sizeof(temperature));
|
||||||
} else if (strstr(line, "GXTS04Temp") != NULL) { // we have a temperature line
|
|
||||||
char *tempPos = strstr(line, "GXTS04Temp = ");
|
|
||||||
if (tempPos != NULL) {
|
|
||||||
strlcpy(temperature, tempPos + 15, sizeof(temperature)); // 15 spaces for ws85
|
|
||||||
temperatureF = strtof(temperature, nullptr);
|
temperatureF = strtof(temperature, nullptr);
|
||||||
}
|
} else if (parsed.name == "RainIntSum") {
|
||||||
|
strlcpy(rainStr, parsed.value.c_str(), sizeof(rainStr));
|
||||||
} else if (strstr(line, "RainIntSum") != NULL) { // we have a rainsum line
|
|
||||||
// LOG_INFO(line);
|
|
||||||
char *pos = strstr(line, "RainIntSum = ");
|
|
||||||
if (pos != NULL) {
|
|
||||||
strlcpy(rainStr, pos + 17, sizeof(rainStr)); // 17 spaces for ws85
|
|
||||||
rainSum = int(strtof(rainStr, nullptr));
|
rainSum = int(strtof(rainStr, nullptr));
|
||||||
}
|
} else if (parsed.name == "Rain") {
|
||||||
|
strlcpy(rainStr, parsed.value.c_str(), sizeof(rainStr));
|
||||||
} else if (strstr(line, "Rain") != NULL) { // we have a rain line
|
|
||||||
if (strstr(line, "WaveRain") == NULL) { // skip WaveRain lines though.
|
|
||||||
// LOG_INFO(line);
|
|
||||||
char *pos = strstr(line, "Rain = ");
|
|
||||||
if (pos != NULL) {
|
|
||||||
strlcpy(rainStr, pos + 17, sizeof(rainStr)); // 17 spaces for ws85
|
|
||||||
rain = strtof(rainStr, nullptr);
|
rain = strtof(rainStr, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Update lineStart for the next line
|
// Update lineStart for the next line
|
||||||
lineStart = lineEnd + 1;
|
lineStart = lineEnd + 1;
|
||||||
@ -557,7 +574,7 @@ void SerialModule::processWXSerial()
|
|||||||
}
|
}
|
||||||
if (gotwind) {
|
if (gotwind) {
|
||||||
|
|
||||||
LOG_INFO("WS85 : %i %.1fg%.1f %.1fv %.1fv %.1fC rain: %.1f, %i sum", atoi(windDir), strtof(windVel, nullptr),
|
LOG_INFO("WS8X : %i %.1fg%.1f %.1fv %.1fv %.1fC rain: %.1f, %i sum", atoi(windDir), strtof(windVel, nullptr),
|
||||||
strtof(windGust, nullptr), batVoltageF, capVoltageF, temperatureF, rain, rainSum);
|
strtof(windGust, nullptr), batVoltageF, capVoltageF, temperatureF, rain, rainSum);
|
||||||
}
|
}
|
||||||
if (gotwind && !Throttle::isWithinTimespanMs(lastAveraged, averageIntervalMillis)) {
|
if (gotwind && !Throttle::isWithinTimespanMs(lastAveraged, averageIntervalMillis)) {
|
||||||
@ -607,7 +624,7 @@ void SerialModule::processWXSerial()
|
|||||||
m.variant.environment_metrics.wind_lull = lull;
|
m.variant.environment_metrics.wind_lull = lull;
|
||||||
m.variant.environment_metrics.has_wind_lull = true;
|
m.variant.environment_metrics.has_wind_lull = true;
|
||||||
|
|
||||||
LOG_INFO("WS85 Transmit speed=%fm/s, direction=%d , lull=%f, gust=%f, voltage=%f temperature=%f",
|
LOG_INFO("WS8X Transmit speed=%fm/s, direction=%d , lull=%f, gust=%f, voltage=%f temperature=%f",
|
||||||
m.variant.environment_metrics.wind_speed, m.variant.environment_metrics.wind_direction,
|
m.variant.environment_metrics.wind_speed, m.variant.environment_metrics.wind_direction,
|
||||||
m.variant.environment_metrics.wind_lull, m.variant.environment_metrics.wind_gust,
|
m.variant.environment_metrics.wind_lull, m.variant.environment_metrics.wind_gust,
|
||||||
m.variant.environment_metrics.voltage, m.variant.environment_metrics.temperature);
|
m.variant.environment_metrics.voltage, m.variant.environment_metrics.temperature);
|
||||||
|
Loading…
Reference in New Issue
Block a user