Closed markhlam closed 2 weeks ago
Was not a Priority since there was always a Workaround via Lua Scripts in FSUIPC or FlyWithLua to do any Calculation the math-Library could provide. Now not planned anymore, since 0.8.0 will have its own independent Lua-Engine.
Oh nice!
I didn't thought on that, two questions then:
1) Is there documentation on how to use the built-in lua engine already available? I have full FSUIPC, but if the plugin already has the feature I'd prefer using that. 2) How can I get a value from a lua function? That is, I provide the parameters for the calculation but, how can I retreived the transformed value? I guess it could be through the luavalue, but I never understood well how to use it
I choose to answer in the reverse Order 😉
On 2: Only by storing it to a L-Var/Offset/DataRef in the Script (which is then the Read Address in the Plugin). "The "LuaValue" Prefix is specific to FSUIPC's Lua Engine and passes the numeric Value to the given Script. In the End it's just an Alternative to mapping Numbers to Functions via "LuaToggle" - you can send more than 255 Values, but you have to do more for the Number -> Function Mapping in the Script then just "event.flag". See the Ini A300, FBW A320 or Toliss A321 Scripts which already use Scripts for Value-Display and triggering Commands. So best to forget that 😂
On 1: Well, it is currently in Development, so I didn't start with the Documentation yet and there is more to write up than just Lua 😅 But needless to say the Interactions with Scripts is now muuuuuuch easier and allows even more:
return
Keyword)SimVar(...)
) you want to use in the Script for Reading (SimRead(...)
). The available Variables and their Name/Syntax is exactly the same as used in the Property Inspector (the "GUI") - so anything the Plugin could use directly to read Values from the Sim.So for Example calling the Function "MyFunc" in the Script File "MyFile.lua":
lua:MyFile:MyFunc
And with Parameters:
lua:MyFile:MyFunc(1, 2, 3)
(For both Command- and Read-Address)
Or as an rather complex Example, my current Test/Dev Script for the Inibuilds A300 (INI-A300.lua):
SimVar("L:INI_pitch_trim1")
SimVar("L:INI_pitch_trim2")
SimVar("L:INI_MCU_PROFILE_LIGHT")
SimVar("L:INI_at_on")
SimVar("L:INI_PRESET_SETTING")
SimVar("L:INI_Airspeed_is_mach")
SimVar("L:INI_PRESET_IS_MACH")
SimVar("L:FMGS_vertical_mode")
SimVar("L:INI_PRESET_SPEED")
SimVar("L:INI_Airspeed_Dial")
SimVar("L:INI_Altitude_Dial")
SimVar("L:INI_HEADING_DIAL")
SimVar("L:INI_vvi_dial")
SimVar("L:XMLVAR_Baro1_Mode")
SimVar("(A:SIM ON GROUND, bool)")
function IsMcuOn()
return SimRead("INI_pitch_trim1") == 1 or SimRead("INI_pitch_trim2") == 1
end
function MCU_SPD_VALUE()
local isMcuOn = IsMcuOn()
local isProfile = SimRead("INI_MCU_PROFILE_LIGHT") == 1
local isAutoThr = SimRead("INI_at_on") == 1
local isPreSet = SimRead("INI_PRESET_SETTING") == 1
local isMach = SimRead("INI_Airspeed_is_mach") == 1
local isPresetMach = SimRead("INI_PRESET_IS_MACH") == 1
local verticalMode = SimRead("FMGS_vertical_mode");
local strSpd = ""
if (isMcuOn and isAutoThr and isProfile and not isPreSet) or (verticalMode == 22 or verticalMode == 23 or ((verticalMode == 10 or verticalMode == 11) and isProfile)) then
strSpd = "---"
elseif isMcuOn and isPreSet then
if not isPresetMach then
strSpd = SharpFormat("{0:000.} Pr", math.floor(SimRead("INI_PRESET_SPEED")))
else
strSpd = SharpFormat("{0:0.00} Pr", SimRead("INI_PRESET_SPEED"))
end
elseif isMcuOn then
if not isMach then
strSpd = SharpFormat("{0:000.}", math.floor(SimRead("INI_Airspeed_Dial")))
else
strSpd = SharpFormat("{0:0.00}", SimRead("INI_Airspeed_Dial"))
end
end
return strSpd
end
function MCU_ALT_VALUE()
local isMcuOn = IsMcuOn()
local strAlt = ""
if isMcuOn then
strAlt = SharpFormat("{0:0.}", SimRead("INI_Altitude_Dial"))
end
return strAlt
end
function MCU_HDG_VALUE()
local isMcuOn = IsMcuOn()
local strHdg = ""
if isMcuOn then
strHdg = SharpFormat("{0:000.}", math.floor(SimRead("INI_HEADING_DIAL")))
end
return strHdg
end
function MCU_VS_VALUE()
local isMcuOn = IsMcuOn()
local verticalMode = SimRead("FMGS_vertical_mode");
local onGround = SimRead("(A:SIM ON GROUND, bool)") == 1
local value = SimRead("INI_vvi_dial")
local strVs = "---"
if not isMcuOn then
strVs = ""
elseif verticalMode == 14 or onGround then
value = value / 100.0
if value >= 0.0 then
strVs = SharpFormat("+{0:00.}", value)
elseif value < 0.0 then
strVs = SharpFormat("{0:0.}", value)
end
end
return strVs
end
function BARO_TGL()
if SimRead("XMLVAR_Baro1_Mode") ~= 1 then
SimWrite("INI_CPT_ALTIMETER_PULL_COMMAND", 1)
else
SimWrite("INI_CPT_ALTIMETER_STD_COMMAND", 1)
end
end
So to read the MCU Speed Value, I enter that Address in the Plugin:
lua:INI-A300:MCU_SPD_VALUE
And for toggling the Barometer:
lua:INI-A300:BARO_TGL
Sorry if I missed it, but what should be the path for my .lua files using your engine?
I would also ask you not to close this issue until related documentation is released, so that I can have a place to post my questions as I commence to begin familiar with the new feature.
Thank you!!
Directly in the Plugin Folder - the Installer should have created the Directories:
<PluginDir>\Scripts
<PluginDir>\Scripts\global
<PluginDir>\Scripts\image
(and the Plugin Directory is still %appdata%\Elgato\StreamDeck\Plugins\com.extension.pilotsdeck.sdPlugin
)
Edit: The Scripts/Use-Case talked about here would go in the "normal" \Scripts Folder - not global or image)
So, let's say I'm trying to control my JU52s Magnetos, and the only way to do it is through the CALCULATOR:
x (>K:MAGNETO1_SET), where x can be 0, 1 or 2
I want to have a little bit more control so I want to put in a lua Script. I create the file JU-52-AUX.lua, and I place it in
pluginDir\Scripts (which BTW was not created by the installer you gave me)
I wrote the following code:
SimVar("K:MAGNETO1_SET")
function ToggleMagneto1()
SimWrite("MAGNETO1_SET", 2)
end
And I call it setting a SCRIPT and using: lua:JU-52-AUX:ToggleMagneto1
Which of course doesn't work , so two question: 1) What am I missing? 2) Is there a kind of console for debugging?
Edit: sorry for the format, but I'm not familiar with github formats to make it more readable
pluginDir\Scripts (which BTW was not created by the installer you gave me)
I didn't gave you anything specifically 😅 Did you use the Install-PilotsDeck-latest.exe File? Please redownload and test: Move the Scripts Folder out of the PluginDir and run the downloaded Installer. It should really create the Folders! If not, I have a really mysterious Bug to analyze oO
Which of course doesn't work , so two question:
Haha sorry, did not mention all Things yet ^^
SimCommand
and SimCalculator
- they also use the same Syntax as the GUI does and as documented. (Since the Command-Type isn't specified in Lua - like in the GUI - I had to break it up in two Commands).
So for that Use-Case you would need SimCalculator (remember: the GUI does not have an Option for "KVAR" as Command-Option) and the Calculator-Template for K-Vars would come in handy (instead of writing the full RPN Code):
SimCalculator("$K:MAGNETO1_SET:2")
Log()
Function to print Messages there (like you know from ipc.log from FSUIPC).
You can even have a dedicated Log for your Script (optionally), when you place a UseLog("filename")
at the Beginning (where your SimVar Call(s) are)One Addition: Although it is a great Example to get started with this new Feature, Lua isn't really needed for that Example 😅 That said Calculator-Template for K-Vars is something the Plugin has since it can send Calculator-Code to MSFS 😉
More questions 😅
I've tried to write and execute a quite easy script:
SimVar("L:SWITCH_Magneto_1_off")
SimVar("L:SWITCH_Magneto_1")
function ToggleMagnetoUP_1()
local isGuardOn = SimRead("SWITCH_Magneto_1_off") == 1
log(isGuardOn)
if !isGuardOn and SimRead("SWITCH_Magneto_1") == 2 then
SimCalculator("$K:MAGNETO1_SET:3")
elseif !isGuardOn and SimRead("SWITCH_Magneto_1") == 1 then
SimCalculator("$K:MAGNETO1_SET:2")
end
end
It should read the position of the switch, check the guard is off and then rotate it one position clockwise... but it doesn't...
I'm calling it with a button assigned to a LUAFUNC as follow: lua:JU-52-AUX:ToggleMagnetoUP_1
but nothing happens, and if I open the lua.log what I get is:
2024-06-17 16:02:30.209 - [ ju-52-aux.lua ] Neo.IronLua.LuaRuntimeException: Can not call nil value.
No print, no nothing :(
So two questions,
1) Can you detect my (for sure 'silly') mistake? 2) What am I doing wrong in order to obtain anything in the log? If I can't get at least that I won't be able to move forward
BTW if I write my ToggleMagnetoUP_1 function just as
function ToggleMagnetoUP_1()
SimCalculator("$K:MAGNETO1_SET:2")
end
It works as expected
Edit: The LVARs in the first code can be read (actually I'm displaying them in other buttons)
Edit2: First issue self-resolved, I was using log instead of Log, wow... sentitive lua language.....
So after the Edits, I'm not sure if and what Issue remains?
Yeah, it is case-sensitive - at least in the Calls to the Plugin. The Library I use actually implements Lua on Top of .NET's "Dynamic Language Runtime" - so you are actually calling C# Functions there (which is case-sensitive) 😉
So after the Edits, I'm not sure if and what Issue remains?
Yeah, it is case-sensitive - at least in the Calls to the Plugin. The Library I use actually implements Lua on Top of .NET's "Dynamic Language Runtime" - so you are actually calling C# Functions there (which is case-sensitive) 😉
Yes, I can now get logs but I'm still obtaining a "Can not call nil value" in the "if" check (I commented the "if" body). At least I can now log every sentence... so I will try to progress on my own.
Edit: Just one question, do I need to do anything in the SD configuration when I modify the LUA or when I save the changes in the editor the button will use new file?
I've now spotted it ... it is not isGuardOn in Lua 😉 (Classical Error I'd so myself often 😅 )
And: The Plugin checks for changed Filesizes on the Scripts, and if so it should reload the changed Script(s).
Great! I'm finally succeeded controlling the magnetos! Just one comment, while debugging my lua, it has happened many times that the modified functions were not updated in the SD, my trick then was to add/remove one log sentence to the code, but this is quite exasperating when you do a modification that should work but it does not just because it was not updated at SD.
Maybe you should try to refresh not by length but by Mod Date, or maybe using a checksum of the file...
And then another question. I've now moved to other control. Using developer mode I see thatyou can Inc/Dec with the code:
1 (>B:JU52_STARTER_SW_Clutch_Engine_1_Set) 0 (>B:JU52_STARTER_SW_Clutch_Engine_1_Set)
May I access those vars through LUA and/or the BVAR option? How?
Great! I'm finally succeeded controlling the magnetos! Just one comment, while debugging my lua, it has happened many times that the modified functions were not updated in the SD, my trick then was to add/remove one log sentence to the code, but this is quite exasperating when you do a modification that should work but it does not just because it was not updated at SD.
Maybe you should try to refresh not by length but by Mod Date, or maybe using a checksum of the file...
It worked well in my initial Testing. But yeah, when only changing a 0 to a 1 for Example, I also add to add a space or newline to get the Size changing - maybe per Mod Date would be something worth to look into 🤔
May I access those vars through LUA and/or the BVAR option? How?
See #60 And: yes - everything readable and sendable in the GUI should also be available for Lua. But: B-Vars have a strange "Duality" - they need to be written as a Variable (so SimWrite it is)
Maybe it's already possible and it's only I don't know how to do it, but...
There are some SimVars exposed using a unit called Rankine, which is defined as ºF+461 (or something like that), thus if I wanted to show unit in ºC I should apply a substraction to get ºF and then a factor to get ºC, but actually the only allowed conversion is the factor though the Scalar parameter,
Could be possible to extend this use to enable more complex unit conversions such as the one in my previous example?