Conversation
…zero because of invalid source id
Also added alias getSourceInfo for getFieldInfo
|
Argh, I appologize! I didn't follow through on actually looking up and trying to understand the code for isFresh() and just assumed it was the condition I wanted. Today I learned...
So I believe what we actually want is diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp
index 85322cff7..4647118db 100644
--- a/radio/src/lua/api_general.cpp
+++ b/radio/src/lua/api_general.cpp
@@ -784,7 +784,7 @@ static int luaGetSourceValue(lua_State * L)
lua_pushinteger(L, value);
break;
}
- lua_pushboolean(L, telemetryItems[qr.quot].isFresh());
+ lua_pushboolean(L, !telemetryItems[qr.quot].isOld());
}
else { // telemetry is not available
lua_pushnil(L);Tested I know it was brought up in the discussion about returning more than a simple true / false for this value, since isFresh and isOld are both useful bits of information. One could not reproduce the Model -> Telemetry list without knowing what the state is, and for ExpressLRS testing it would be beneficial to be able to programmatically time the update rates. I admit that's a bit of a specialized use case though. I just thought I'd bring it up for consideration one last time before this becomes the new API.
I'm leaning against this change just because it makes working with it possibly more complicated. Compiler WarningThere's a compiler warning in the unit as well, which wasn't added by this but I thought I'd bring that up as well so maybe it can get fixed for 2.8 (as this was added for 2.8 #2279) |
Thanks...
I think this is the key aspect - since this is something we are trying to achieve with extending the Lua APIs... so I have nothing against this if it makes sense to Jesper, et al. It is probably better to be added here, then as part of yet another function? Since as I understand it now the second parameter essentially only tells you if telemetry is active or not at the moment, and you don't know what the health state of the data/link is. |
|
I have now replaced |
|
I don't think there's any need for another return value. If you look at the list I have above, both nil and false evaluate to false in a comparison, and the others are status numbers. If you go by the way the code is currently in this PR, there's nothing to gain from adding another return parameter to juggle. There's nothing that says the The immediate response might be "Well what happens when we add other statuses at some point that could be consistent with the old/fresh/nominal/non-existent status?!". I mean these are the same statuses that telemetry items have had for like 5 years now so let's not get crazy thinking suddenly items will have all sorts of new properties that will be able to be expressed as part of this proposed new integer returned. 😄 The code is insanely simple with just the two return values, both on the Lua side and the C side (although it would probably be good to refactor all the diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp
index 85322cff7..f510a78d6 100644
--- a/radio/src/lua/api_general.cpp
+++ b/radio/src/lua/api_general.cpp
@@ -745,9 +745,8 @@ static int luaGetSourceValue(lua_State * L)
if (!valid)
{
- lua_pushnil(L);
- lua_pushboolean(L, false);
- return 2;
+ // Return nil, nil (SOURCE_STATUS_ERROR) implicitly
+ return 0;
}
if (src >= MIXSRC_FIRST_TELEM && src <= MIXSRC_LAST_TELEM) {
@@ -770,7 +769,7 @@ static int luaGetSourceValue(lua_State * L)
// Return nil if there are no cells
if (telemetryItems[qr.quot].cells.count == 0) {
lua_pushnil(L);
- lua_pushboolean(L, false);
+ lua_pushboolean(L, SOURCE_STATUS_OLD);
return 2;
}
luaPushCells(L, telemetrySensor, telemetryItems[qr.quot]);
@@ -784,20 +783,25 @@ static int luaGetSourceValue(lua_State * L)
lua_pushinteger(L, value);
break;
}
- lua_pushboolean(L, telemetryItems[qr.quot].isFresh());
+ if (telemetryItems[qr.quot].isFresh())
+ lua_pushinteger(L, SOURCE_STATUS_FRESH);
+ else if (telemetryItems[qr.quot].isOld())
+ lua_pushboolean(L, SOURCE_STATUS_OLD);
+ else
+ lua_pushinteger(L, SOURCE_STATUS_NOMINAL);
}
else { // telemetry is not available
lua_pushnil(L);
- lua_pushboolean(L, false);
+ lua_pushboolean(L, SOURCE_STATUS_OLD);
}
}
else if (src == MIXSRC_TX_VOLTAGE) {
lua_pushnumber(L, float(value) * 0.1f);
- lua_pushboolean(L, true);
+ lua_pushinteger(L, SOURCE_STATUS_NOMINAL);
}
else {
lua_pushinteger(L, value);
- lua_pushboolean(L, true);
+ lua_pushinteger(L, SOURCE_STATUS_NOMINAL);
}
return 2;
} |
|
With all due respect, this is not a simple solution. First of all, you have to add these new constants to the C++ code, and then you also have to export the constant values and names to Lua. This means that you are now creating constants and name spaces just for Lua that do not get used in the underlying EdgeTX system. This is directly contrary to how I believe that things should be done, which is to have the Lua API be based on the underlying API w/o adding new things to it. |
|
Oh no offense taken at all, your point makes a lot of sense. I didn't include the C or Lua defines in my diff to just keep it clear about how they would work, but I had them in my local repo. You're right about it not being a great idea to create new definitions that would only be used for the Lua interface, so I think just leave it what you've got currently. It solves the current issue of the values "disappearing" when telemetry is lost and requiring the Lua cache all the last values if it doesn't want its display to turn into a bunch of zeros suddenly, and resolves the ambiguity of the EDIT: One minor thing, when pushing the table for |
|
Great! I have never been accused of being diplomatic; I find it easier to just lay it out as I see it - thanks for understanding 🍻 Since the underlying API has several different functions Good catch with the redundant code in |
|
So I take it this is ready as it is, and access to |
I think this decision should be made before merging this so that the API of this function is not continuously changing and requiring the Lua code to figure out and work around what capabilities are available. You could just slap another boolean return value on there, but that seems like a waste considering only Telemetry items have this property so there's a sprinkling of adding a fixed "true" to every other item. I do not have any further opinions on the subject though, since I just seem to be holding everything up with my analysis. |
|
Indeed you are, but it is an entirely worthy analysis, so you are forgiven for that ;) API changes need discussion so all possible variations and situations are considered, rather than just the original intended and potentially single use case. It does seem like a waste, but it also gives access to that last bit of info, so IMO is an acceptable evil. |
|
How about we make the second return value into a table, and then we can return |
|
Returning a table has more of a performance hit to both Lua memory and script size than just returning an additional boolean and is a slightly more cumbersome to work with (having to remember the exact string name of the value in the table). My opinion is that it should just return If the requested item is not found I think you can just return nil for all 3? That is, have the |
|
OK, you got it! |
|
Tested, all pass except the one I'm not sure you're going to do -- getSourceValue returns nil for all values if the item does not exist: FAIL ASTERISK Just to note the first time a telemetry item is receiver, the third parameter (isFresh) returns true for a long time (5 seconds?). This matches the EdgeTX display on Model -> Telemetry. This only seems to happen if it has been longer than a certain amount of time since telemetry was lost? As if I unplug and replug the flight controller in just a couple of seconds it behaves as expected (isFresh = true for just an instant) but somewhere around 20s of lost power isFresh = true for ~5s when telemetry_streaming goes true (regardless of if the queried value was actually updated). This is the code I have been using, but sort of hacking it as needed to test everything above. local LH = 14
local xoff
local Y
local function echo(msg)
lcd.drawText(xoff, Y, msg)
Y = Y + LH
end
local function run(event, ts)
lcd.clear()
if ts then
lcd.drawText(0, 0, string.format("%ux%u", ts.x, ts.y))
elseif event ~= 0 then
lcd.drawText(0, 0, tostring(event))
end
local strTItem = 'RxBt'
Y = LH
xoff = 0
local info = getSourceInfo(strTItem)
if info == nil then
echo(strTItem .. ' is nil')
else
for k, v in pairs(info) do
echo('(' .. k .. ')=[' .. tostring(v) .. ']')
end
if info.id then
local val = table.pack(getSourceValue(info.id))
--echo('Value table item count ' .. tostring(#val))
for k, v in pairs(val) do
echo('val(' .. k .. ') is [' .. tostring(v) .. '] ' .. type(v))
end
if val[3] then
val[1] = val[1] .. ' *'
end
lcd.drawText(LCD_W/2, 0, tostring(val[1]), val[2] and COLOR_THEME_PRIMARY1 or COLOR_THEME_WARNING)
echo('')
local info2 = getSourceInfo(info.id)
echo(info2 and 'getSourceInfo(id) PASS' or 'getSourceInfo(id) FAIL')
local val2 = table.pack(getSourceValue(strTItem))
-- echo('Value2 table item count ' .. tostring(#val))
local allMatch = true
for k, v in pairs(val2) do
if v ~= val[k] then
allMatch = false
end
end
echo(allMatch and 'getSourceValue(str) PASS' or 'getSourceValue(str) FAIL')
end
end
echo('')
echo('-- MIX SOURCE --')
info = getSourceInfo('thr')
if info == nil then
echo('Thr is nil')
else
echo ('Throttle item found, id ' .. tostring(info.id))
local val, valid, fresh = getSourceValue('thr')
echo('Throttle ' .. tostring(val) .. (valid and ' VALID' or ' NEVER') .. (valid and ' FRESH' or ' STALE'))
end
local val3 = table.pack(getSourceValue('pugh'))
for k, v in pairs(val3) do
echo('val3(' .. k .. ') is [' .. tostring(v) .. '] ' .. type(v))
end
return 0
end
return { run=run } |
|
@jfrickmann Your thoughts?
|
OK, changed that. Please test again. |
Working. However you don't need to push 3 nils, you can just return 0 without pushing anything and the caller automatically gets as many nils returned as they expect. Source docs also need updating: -@retval value current source value (number).
+@retval value current source value (number), or last known telemetry item value.
-value is nil for non-existing sources and all non-allowed sensors while FAI MODE is active
+value is nil for non-existing sources. all non-allowed sensors while FAI MODE is active, or if a telemetry item value has never been received
-@retval status is false for telemetry sources when the telemetry stream is not received, or value is nil. Otherwise, it is true
+@retval isCurrent is true for telemetry sources that are within the "Sensor Lost" duration and telemetry is streaming . Always true for non-telemetry items.
+
+@retval isFresh is true for telemetry sources which have been recently updated and telemetry is streaming. Always true for non-telemetry items. |
|
OK, you got it |
|
Thank you all! :) |
* Moved getFieldInfo and getValue up right after related functions * Modified getValue to return a valid status, so Lua can see if it got zero because of invalid source id * Added new getSourceValue Lua function per Issue #781 Also added alias getSourceInfo for getFieldInfo * Updated according to comment #2175 (comment) * Replaced isFresh() by !isOld() as requested in #2316 (comment) * Clean up `lua_pushtablenil` - tables cannot hold nil values * Changed isFresh() to !isOld() ... AGAIN * Return both `!isOld()` and `isFresh()` * Return nil for all values if the item does not exist * Return 0 instead of pushing three nil values * Update documentation
Replaces #2175 - something was messed up with the base branch