diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index c1d6c585a..8f9812011 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -327,8 +327,6 @@ static void luaPushLatLon(lua_State* L, TelemetrySensor & telemetrySensor, Telem int8_t delay = telemetryItem.getDelaySinceLastValue(); if (delay >= 0) lua_pushtableinteger(L, "delay", delay); - else - lua_pushtablenil(L, "delay"); } static void luaPushTelemetryDateTime(lua_State* L, TelemetrySensor & telemetrySensor, TelemetryItem & telemetryItem) @@ -551,6 +549,256 @@ bool luaFindFieldById(int id, LuaField & field, unsigned int flags) return false; // not found } +/*luadoc +@function getFieldInfo(source) + +Return detailed information about field (source) + +The list of valid sources is available: + +| OpenTX Version | Radio | +|----------------|-------| +| 2.0 | [all](http://downloads-20.open-tx.org/firmware/lua_fields.txt) | +| 2.1 | [X9D and X9D+](http://downloads-21.open-tx.org/firmware/lua_fields_taranis.txt), [X9E](http://downloads-21.open-tx.org/firmware/lua_fields_taranis_x9e.txt) | +| 2.2 | [X9D and X9D+](http://downloads.open-tx.org/2.2/release/firmware/lua_fields_x9d.txt), [X9E](http://downloads.open-tx.org/2.2/release/firmware/lua_fields_x9e.txt), [Horus](http://downloads.open-tx.org/2.2/release/firmware/lua_fields_x12s.txt) | +| 2.3 | [X9D and X9D+](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x9d.txt), [X9E](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x9e.txt), [X7](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x7.txt), [Horus](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x12s.txt) | + +@param source can be an index (number) (which was obtained by `getFieldInfo` or `getSourceIndex`) or a name (string) of the source. + +@retval table information about requested field, table elements: + * `id` (number) field identifier + * `name` (string) field name + * `desc` (string) field description + * 'unit' (number) unit identifier [Full list](../appendix/units.html) + +@retval nil the requested field was not found + +@status current Introduced in 2.0.8, 'unit' field added in 2.2.0, and argument also can be an index number as of 2.6.0 +*/ +static int luaGetFieldInfo(lua_State * L) +{ + bool found; + LuaField field; + + if (lua_type(L, 1) == LUA_TNUMBER) + found = luaFindFieldById(luaL_checkinteger(L, 1), field, FIND_FIELD_DESC); + else + found = luaFindFieldByName(luaL_checkstring(L, 1), field, FIND_FIELD_DESC); + + if (found) { + lua_newtable(L); + lua_pushtableinteger(L, "id", field.id); + lua_pushtablestring(L, "name", field.name); + lua_pushtablestring(L, "desc", field.desc); + if (field.id >= MIXSRC_FIRST_TELEM && field.id <= MIXSRC_LAST_TELEM) { + TelemetrySensor & telemetrySensor = g_model.telemetrySensors[(int)((field.id-MIXSRC_FIRST_TELEM)/3)]; + lua_pushtableinteger(L, "unit", telemetrySensor.unit); + } + return 1; + } + return 0; +} + +/*luadoc +@function getValue(source) + +Returns the value of a source. + +The list of fixed sources: + +| OpenTX Version | Radio | +|----------------|-------| +| 2.0 | [all](http://downloads-20.open-tx.org/firmware/lua_fields.txt) | +| 2.1 | [X9D and X9D+](http://downloads-21.open-tx.org/firmware/lua_fields_taranis.txt), [X9E](http://downloads-21.open-tx.org/firmware/lua_fields_taranis_x9e.txt) | +| 2.2 | [X9D and X9D+](http://downloads.open-tx.org/2.2/release/firmware/lua_fields_x9d.txt), [X9E](http://downloads.open-tx.org/2.2/release/firmware/lua_fields_x9e.txt), [Horus](http://downloads.open-tx.org/2.2/release/firmware/lua_fields_x12s.txt) | +| 2.3 | [X9D and X9D+](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x9d.txt), [X9E](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x9e.txt), [X7](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x7.txt), [Horus](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x12s.txt) | + +In OpenTX 2.1.x the telemetry sources no longer have a predefined name. +To get a telemetry value simply use it's sensor name. For example: + * Altitude sensor has a name "Alt" + * to get the current altitude use the source "Alt" + * to get the minimum altitude use the source "Alt-", to get the maximum use "Alt+" + +@param source can be an index (number) (which was obtained by `getFieldInfo` or `getSourceIndex`) or a name (string) of the source. + +@retval value current source value (number). Zero is returned for: + * non-existing sources + * for all telemetry source when the telemetry stream is not received + * far all non allowed sensors while FAI MODE is active + +@retval table GPS position is returned in a table: + * `lat` (number) latitude, positive is North + * `lon` (number) longitude, positive is East + * `pilot-lat` (number) pilot latitude, positive is North + * `pilot-lon` (number) pilot longitude, positive is East + +@retval table GPS date/time, see getDateTime() + +@retval table Cells are returned in a table +(except where no cells were detected in which +case the returned value is 0): + * table has one item for each detected cell: + * key (number) cell number (1 to number of cells) + * value (number) current cell voltage + +@status current Introduced in 2.0.0, changed in 2.1.0, `Cels+` and +`Cels-` added in 2.1.9 + +@notice Getting a value by its numerical identifier is faster then by its name. +While `Cels` sensor returns current values of all cells in a table, a `Cels+` or +`Cels-` will return a single value - the maximum or minimum Cels value. +*/ +static int luaGetValue(lua_State * L) +{ + int src = MIXSRC_NONE; + if (lua_isnumber(L, 1)) { + src = luaL_checkinteger(L, 1); + } + else { + // convert from field name to its id + const char *name = luaL_checkstring(L, 1); + LuaField field; + bool found = luaFindFieldByName(name, field); + if (found) { + src = field.id; + } + } + luaGetValueAndPush(L, src); + return 1; +} + +/*luadoc +@function getSourceValue(source) + +Returns the value of a source. Superseeds getValue. + +The list of fixed sources: + +| OpenTX Version | Radio | +|----------------|-------| +| 2.0 | [all](http://downloads-20.open-tx.org/firmware/lua_fields.txt) | +| 2.1 | [X9D and X9D+](http://downloads-21.open-tx.org/firmware/lua_fields_taranis.txt), [X9E](http://downloads-21.open-tx.org/firmware/lua_fields_taranis_x9e.txt) | +| 2.2 | [X9D and X9D+](http://downloads.open-tx.org/2.2/release/firmware/lua_fields_x9d.txt), [X9E](http://downloads.open-tx.org/2.2/release/firmware/lua_fields_x9e.txt), [Horus](http://downloads.open-tx.org/2.2/release/firmware/lua_fields_x12s.txt) | +| 2.3 | [X9D and X9D+](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x9d.txt), [X9E](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x9e.txt), [X7](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x7.txt), [Horus](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x12s.txt) | + +In OpenTX 2.1.x the telemetry sources no longer have a predefined name. +To get a telemetry value simply use it's sensor name. For example: + * Altitude sensor has a name "Alt" + * to get the current altitude use the source "Alt" + * to get the minimum altitude use the source "Alt-", to get the maximum use "Alt+" + +@param source can be an index (number) (which was obtained by `getFieldInfo` or `getSourceIndex`) or a name (string) of the source. + +@retval value current source value (number), or last known telemetry item value. + +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 + +value is a table for GPS position: + + * `lat` (number) latitude, positive is North + * `lon` (number) longitude, positive is East + * `pilot-lat` (number) pilot latitude, positive is North + * `pilot-lon` (number) pilot longitude, positive is East + +value is a table for date/time, see getDateTime() + +value is a table for battery cells(except where no cells were detected in which case the returned value is 0): + * table has one item for each detected cell: + * key (number) cell number (1 to number of cells) + * value (number) current cell voltage + +@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. + +@status current Introduced in 2.0.0, changed in 2.1.0, `Cels+` and `Cels-` added in 2.1.9 + +@notice Getting a value by its numerical identifier is much faster than by its name. +While `Cels` sensor returns current values of all cells in a table, a `Cels+` or +`Cels-` will return a single value - the maximum or minimum Cels value. +*/ + +static int luaGetSourceValue(lua_State * L) +{ + // Get source id + int src = MIXSRC_NONE; + if (lua_isnumber(L, 1)) { + src = luaL_checkinteger(L, 1); + } + else { + // convert from field name to its id + const char *name = luaL_checkstring(L, 1); + LuaField field; + bool found = luaFindFieldByName(name, field); + if (found) { + src = field.id; + } + } + + // Get source value. Ignored for GPS, DATETIME, and CELLS + bool valid = true; + getvalue_t value = getValue(src, &valid); + + if (!valid) + { + return 0; + } + + if (src >= MIXSRC_FIRST_TELEM && src <= MIXSRC_LAST_TELEM) { + div_t qr = div(src-MIXSRC_FIRST_TELEM, 3); + // telemetry values + if (telemetryItems[qr.quot].isAvailable()) { + TelemetrySensor & telemetrySensor = g_model.telemetrySensors[qr.quot]; + switch (telemetrySensor.unit) { + case UNIT_GPS: + luaPushLatLon(L, telemetrySensor, telemetryItems[qr.quot]); + break; + case UNIT_DATETIME: + luaPushTelemetryDateTime(L, telemetrySensor, telemetryItems[qr.quot]); + break; + case UNIT_TEXT: + lua_pushstring(L, telemetryItems[qr.quot].text); + break; + case UNIT_CELLS: + if (qr.rem == 0) { + // Return nil if there are no cells + if (telemetryItems[qr.quot].cells.count == 0) { + lua_pushnil(L); + lua_pushboolean(L, false); + lua_pushboolean(L, false); + return 3; + } + luaPushCells(L, telemetrySensor, telemetryItems[qr.quot]); + break; + } + // deliberate no break here to properly return `Cels-` and `Cels+` + default: + if (telemetrySensor.prec > 0) + lua_pushnumber(L, float(value)/telemetrySensor.getPrecDivisor()); + else + lua_pushinteger(L, value); + break; + } + lua_pushboolean(L, !telemetryItems[qr.quot].isOld()); + lua_pushboolean(L, telemetryItems[qr.quot].isFresh()); + } + else { // telemetry is not available + return 0; + } + } + else if (src == MIXSRC_TX_VOLTAGE) { + lua_pushnumber(L, float(value) * 0.1f); + lua_pushboolean(L, true); + lua_pushboolean(L, true); + } + else { + lua_pushinteger(L, value); + lua_pushboolean(L, true); + lua_pushboolean(L, true); + } + return 3; +} + /*luadoc @function getRotEncSpeed() @@ -1014,127 +1262,6 @@ static int luaGhostTelemetryPush(lua_State * L) } #endif -/*luadoc -@function getFieldInfo(source) - -Return detailed information about field (source) - -The list of valid sources is available: - -| OpenTX Version | Radio | -|----------------|-------| -| 2.0 | [all](http://downloads-20.open-tx.org/firmware/lua_fields.txt) | -| 2.1 | [X9D and X9D+](http://downloads-21.open-tx.org/firmware/lua_fields_taranis.txt), [X9E](http://downloads-21.open-tx.org/firmware/lua_fields_taranis_x9e.txt) | -| 2.2 | [X9D and X9D+](http://downloads.open-tx.org/2.2/release/firmware/lua_fields_x9d.txt), [X9E](http://downloads.open-tx.org/2.2/release/firmware/lua_fields_x9e.txt), [Horus](http://downloads.open-tx.org/2.2/release/firmware/lua_fields_x12s.txt) | -| 2.3 | [X9D and X9D+](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x9d.txt), [X9E](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x9e.txt), [X7](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x7.txt), [Horus](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x12s.txt) | - -@param source can be an index (number) (which was obtained by `getFieldInfo` or `getSourceIndex`) or a name (string) of the source. - -@retval table information about requested field, table elements: - * `id` (number) field identifier - * `name` (string) field name - * `desc` (string) field description - * 'unit' (number) unit identifier [Full list](../appendix/units.html) - -@retval nil the requested field was not found - -@status current Introduced in 2.0.8, 'unit' field added in 2.2.0, and argument also can be an index number as of 2.6.0 -*/ -static int luaGetFieldInfo(lua_State * L) -{ - bool found; - LuaField field; - - if (lua_type(L, 1) == LUA_TNUMBER) - found = luaFindFieldById(luaL_checkinteger(L, 1), field, FIND_FIELD_DESC); - else - found = luaFindFieldByName(luaL_checkstring(L, 1), field, FIND_FIELD_DESC); - - if (found) { - lua_newtable(L); - lua_pushtableinteger(L, "id", field.id); - lua_pushtablestring(L, "name", field.name); - lua_pushtablestring(L, "desc", field.desc); - if (field.id >= MIXSRC_FIRST_TELEM && field.id <= MIXSRC_LAST_TELEM) { - TelemetrySensor & telemetrySensor = g_model.telemetrySensors[(int)((field.id-MIXSRC_FIRST_TELEM)/3)]; - lua_pushtableinteger(L, "unit", telemetrySensor.unit); - } - else { - lua_pushtablenil(L, "unit"); - } - return 1; - } - return 0; -} - -/*luadoc -@function getValue(source) - -Returns the value of a source. - -The list of fixed sources: - -| OpenTX Version | Radio | -|----------------|-------| -| 2.0 | [all](http://downloads-20.open-tx.org/firmware/lua_fields.txt) | -| 2.1 | [X9D and X9D+](http://downloads-21.open-tx.org/firmware/lua_fields_taranis.txt), [X9E](http://downloads-21.open-tx.org/firmware/lua_fields_taranis_x9e.txt) | -| 2.2 | [X9D and X9D+](http://downloads.open-tx.org/2.2/release/firmware/lua_fields_x9d.txt), [X9E](http://downloads.open-tx.org/2.2/release/firmware/lua_fields_x9e.txt), [Horus](http://downloads.open-tx.org/2.2/release/firmware/lua_fields_x12s.txt) | -| 2.3 | [X9D and X9D+](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x9d.txt), [X9E](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x9e.txt), [X7](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x7.txt), [Horus](http://downloads.open-tx.org/2.3/release/firmware/lua_fields_x12s.txt) | - -In OpenTX 2.1.x the telemetry sources no longer have a predefined name. -To get a telemetry value simply use it's sensor name. For example: - * Altitude sensor has a name "Alt" - * to get the current altitude use the source "Alt" - * to get the minimum altitude use the source "Alt-", to get the maximum use "Alt+" - -@param source can be an index (number) (which was obtained by `getFieldInfo` or `getSourceIndex`) or a name (string) of the source. - -@retval value current source value (number). Zero is returned for: - * non-existing sources - * for all telemetry source when the telemetry stream is not received - * far all non allowed sensors while FAI MODE is active - -@retval table GPS position is returned in a table: - * `lat` (number) latitude, positive is North - * `lon` (number) longitude, positive is East - * `pilot-lat` (number) pilot latitude, positive is North - * `pilot-lon` (number) pilot longitude, positive is East - -@retval table GPS date/time, see getDateTime() - -@retval table Cells are returned in a table -(except where no cells were detected in which -case the returned value is 0): - * table has one item for each detected cell: - * key (number) cell number (1 to number of cells) - * value (number) current cell voltage - -@status current Introduced in 2.0.0, changed in 2.1.0, `Cels+` and -`Cels-` added in 2.1.9 - -@notice Getting a value by its numerical identifier is faster then by its name. -While `Cels` sensor returns current values of all cells in a table, a `Cels+` or -`Cels-` will return a single value - the maximum or minimum Cels value. -*/ -static int luaGetValue(lua_State * L) -{ - int src = 0; - if (lua_isnumber(L, 1)) { - src = luaL_checkinteger(L, 1); - } - else { - // convert from field name to its id - const char *name = luaL_checkstring(L, 1); - LuaField field; - bool found = luaFindFieldByName(name, field); - if (found) { - src = field.id; - } - } - luaGetValueAndPush(L, src); - return 1; -} - /*luadoc @function getRAS() @@ -2481,9 +2608,11 @@ const luaL_Reg opentxLib[] = { { "getRotEncMode", luaGetRotEncMode }, { "getValue", luaGetValue }, { "getOutputValue", luaGetOutputValue }, + { "getSourceValue", luaGetSourceValue }, { "getRAS", luaGetRAS }, { "getTxGPS", luaGetTxGPS }, { "getFieldInfo", luaGetFieldInfo }, + { "getSourceInfo", luaGetFieldInfo }, { "getFlightMode", luaGetFlightMode }, { "playFile", luaPlayFile }, { "playNumber", luaPlayNumber }, diff --git a/radio/src/lua/lua_api.h b/radio/src/lua/lua_api.h index 77d05f6f2..632228ee5 100644 --- a/radio/src/lua/lua_api.h +++ b/radio/src/lua/lua_api.h @@ -73,7 +73,6 @@ void luaEmptyEventBuffer(); #define LUA_INIT_THEMES_AND_WIDGETS() luaInitThemesAndWidgets() #define lua_registernumber(L, n, i) (lua_pushnumber(L, (i)), lua_setglobal(L, (n))) #define lua_registerint(L, n, i) (lua_pushinteger(L, (i)), lua_setglobal(L, (n))) -#define lua_pushtablenil(L, k) (lua_pushstring(L, (k)), lua_pushnil(L), lua_settable(L, -3)) #define lua_pushtableboolean(L, k, v) (lua_pushstring(L, (k)), lua_pushboolean(L, (v)), lua_settable(L, -3)) #define lua_pushtableinteger(L, k, v) (lua_pushstring(L, (k)), lua_pushinteger(L, (v)), lua_settable(L, -3)) #define lua_pushtablenumber(L, k, v) (lua_pushstring(L, (k)), lua_pushnumber(L, (v)), lua_settable(L, -3)) diff --git a/radio/src/mixer.cpp b/radio/src/mixer.cpp index 9731a39fb..70b188a57 100644 --- a/radio/src/mixer.cpp +++ b/radio/src/mixer.cpp @@ -297,10 +297,11 @@ int16_t applyLimits(uint8_t channel, int32_t value) } // TODO same naming convention than the drawSource - -getvalue_t getValue(mixsrc_t i) +// *valid added to return status to Lua for invalid sources +getvalue_t getValue(mixsrc_t i, bool* valid) { if (i == MIXSRC_NONE) { + if (valid != nullptr) *valid = false; return 0; } else if (i <= MIXSRC_LAST_INPUT) { @@ -312,6 +313,7 @@ getvalue_t getValue(mixsrc_t i) div_t qr = div(i-MIXSRC_FIRST_LUA, MAX_SCRIPT_OUTPUTS); return scriptInputsOutputs[qr.quot].outputs[qr.rem].value; #else + if (valid != nullptr) *valid = false; return 0; #endif } @@ -344,6 +346,7 @@ getvalue_t getValue(mixsrc_t i) #if defined(HELI) return cyc_anas[i - MIXSRC_CYC1]; #else + if (valid != nullptr) *valid = false; return 0; #endif } @@ -361,6 +364,7 @@ getvalue_t getValue(mixsrc_t i) return (switchState(3*sw) ? -1024 : (IS_CONFIG_3POS(sw) && switchState(3*sw+1) ? 0 : 1024)); } else { + if (valid != nullptr) *valid = false; return 0; } } @@ -374,6 +378,7 @@ getvalue_t getValue(mixsrc_t i) return (switchState(3*sw) ? -1024 : (IS_CONFIG_3POS(sw) && switchState(3*sw+1) ? 0 : 1024)); } else { + if (valid != nullptr) *valid = false; return 0; } } @@ -406,6 +411,7 @@ getvalue_t getValue(mixsrc_t i) #if defined(GVARS) return GVAR_VALUE(i - MIXSRC_GVAR1, getGVarFlightMode(mixerCurrentFlightMode, i - MIXSRC_GVAR1)); #else + if (valid != nullptr) *valid = false; return 0; #endif } @@ -418,6 +424,7 @@ getvalue_t getValue(mixsrc_t i) #if defined(RTCLOCK) return (g_rtcTime % SECS_PER_DAY) / 60; // number of minutes from midnight #else + if (valid != nullptr) *valid = false; return 0; #endif } @@ -427,6 +434,7 @@ getvalue_t getValue(mixsrc_t i) else if (i <= MIXSRC_LAST_TELEM) { if (IS_FAI_FORBIDDEN(i)) { + if (valid != nullptr) *valid = false; return 0; } i -= MIXSRC_FIRST_TELEM; @@ -441,7 +449,10 @@ getvalue_t getValue(mixsrc_t i) return telemetryItem.value; } } - else return 0; + else { + if (valid != nullptr) *valid = false; + return 0; + } } void evalInputs(uint8_t mode) diff --git a/radio/src/opentx.h b/radio/src/opentx.h index b90a131dc..b86dfdad2 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -489,7 +489,7 @@ extern uint8_t currentBacklightBright; void perMain(); void per10ms(); -getvalue_t getValue(mixsrc_t i); +getvalue_t getValue(mixsrc_t i, bool* valid = nullptr); #define GETSWITCH_MIDPOS_DELAY 1 bool getSwitch(swsrc_t swtch, uint8_t flags=0);