Initial commit
Signed-off-by: fly <merspieler@alwaysdata.net>
This commit is contained in:
commit
0e7415296c
5 changed files with 868 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
*.swp
|
||||||
|
*.swo
|
477
WinWingFCU.xml
Normal file
477
WinWingFCU.xml
Normal file
|
@ -0,0 +1,477 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<PropertyList>
|
||||||
|
<name type="string">Winwing WINWING FCU-320</name>
|
||||||
|
<debug-events type="bool">true</debug-events>
|
||||||
|
<nasal>
|
||||||
|
<open>
|
||||||
|
<![CDATA[
|
||||||
|
setprop("/winwing/spd", "100");
|
||||||
|
setprop("/winwing/hdg", "360");
|
||||||
|
setprop("/winwing/alt", "10000");
|
||||||
|
setprop("/winwing/vs", "----");
|
||||||
|
|
||||||
|
var updateWinwingFCUDisplay = func() {
|
||||||
|
if (getprop("/it-autoflight/input/spd-managed")) {
|
||||||
|
setprop("/winwing/spd", "---");
|
||||||
|
} else if (getprop("/controls/switches/annun-test")) {
|
||||||
|
setprop("/winwing/spd", "888");
|
||||||
|
} else if (getprop("/it-autoflight/input/kts-mach")) {
|
||||||
|
setprop("/winwing/spd", getprop("/it-autoflight/input/mach") * 1000);
|
||||||
|
} else {
|
||||||
|
setprop("/winwing/spd", getprop("/it-autoflight/input/kts"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getprop("/it-autoflight/custom/show-hdg") != true and getprop("/it-autoflight/output/lat") != 0) {
|
||||||
|
setprop("/winwing/hdg", "---");
|
||||||
|
} else if (getprop("/controls/switches/annun-test")) {
|
||||||
|
setprop("/winwing/hdg", "888");
|
||||||
|
} else {
|
||||||
|
setprop("/winwing/hdg", sprintf("%03.0f", getprop("/it-autoflight/input/hdg")));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getprop("/controls/switches/annun-test")) {
|
||||||
|
setprop("/winwing/alt", "88888");
|
||||||
|
} else {
|
||||||
|
setprop("/winwing/alt", sprintf("%05.0f", getprop("/it-autoflight/input/alt")));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getprop("/controls/switches/annun-test")) {
|
||||||
|
setprop("/winwing/vs", "8888");
|
||||||
|
} else if (getprop("/it-autoflight/output/vert") != 1 and getprop("/it-autoflight/output/vert") != 5) {
|
||||||
|
setprop("/winwing/vs", "----");
|
||||||
|
} else {
|
||||||
|
if (getprop("/it-autoflight/input/trk")) {
|
||||||
|
setprop("/winwing/vs", sprintf("%02.0f", math.abs(getprop("/it-autoflight/input/fpa")) * 10));
|
||||||
|
} else {
|
||||||
|
setprop("/winwing/vs", sprintf("%04.0f", getprop("/it-autoflight/input/vs-abs")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var flags = "";
|
||||||
|
if (getprop("/controls/switches/annun-test") or getprop("/it-autoflight/input/kts-mach") == false) {
|
||||||
|
flags = flags ~ ",spd";
|
||||||
|
}
|
||||||
|
if (getprop("/controls/switches/annun-test") or getprop("/it-autoflight/input/kts-mach")) {
|
||||||
|
flags = flags ~ ",mach";
|
||||||
|
}
|
||||||
|
if (getprop("/controls/switches/annun-test") or getprop("/it-autoflight/input/spd-managed")) {
|
||||||
|
flags = flags ~ ",spd-mgt";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getprop("/controls/switches/annun-test") or getprop("/it-autoflight/output/lat") == 1 or getprop("/it-autoflight/output/lnav-armed")) {
|
||||||
|
flags = flags ~ ",lat";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getprop("/controls/switches/annun-test") or getprop("/it-autoflight/custom/trk-fpa") == false) {
|
||||||
|
flags = flags ~ ",hdg-vs";
|
||||||
|
}
|
||||||
|
if (getprop("/controls/switches/annun-test") or getprop("/it-autoflight/custom/trk-fpa")) {
|
||||||
|
flags = flags ~ ",trk-fpa";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getprop("/controls/switches/annun-test") or (((getprop("/it-autoflight/input/vs") >= 0 and getprop("/it-autoflight/custom/trk-fpa") == false) or (getprop("/it-autoflight/input/fpa") >= 0 and getprop("/it-autoflight/custom/trk-fpa"))) and (getprop("/it-autoflight/output/vert") == 1 or getprop("/it-autoflight/output/vert") == 5))) {
|
||||||
|
flags = flags ~ ",plus";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getprop("/controls/switches/annun-test") or getprop("/it-autoflight/output/ap1")) {
|
||||||
|
flags = flags ~ ",ap1";
|
||||||
|
}
|
||||||
|
if (getprop("/controls/switches/annun-test") or getprop("/it-autoflight/output/ap2")) {
|
||||||
|
flags = flags ~ ",ap2";
|
||||||
|
}
|
||||||
|
if (getprop("/controls/switches/annun-test") or getprop("/it-autoflight/output/athr")) {
|
||||||
|
flags = flags ~ ",athr";
|
||||||
|
}
|
||||||
|
if (getprop("/controls/switches/annun-test") or ((getprop("/it-autoflight/output/lat") == 2 or getprop("/it-autoflight/output/loc-arm") == 1) and getprop("/it-autoflight/output/gs-arm") == false and getprop("/it-autoflight/output/vert") != 2 and getprop("/it-autoflight/output/vert") != 6)) {
|
||||||
|
flags = flags ~ ",loc";
|
||||||
|
}
|
||||||
|
if (getprop("/controls/switches/annun-test") or getprop("/it-autoflight/output/gs-arm") or getprop("/it-autoflight/output/vert") == 2 or getprop("/it-autoflight/output/vert") == 6) {
|
||||||
|
flags = flags ~ ",appr";
|
||||||
|
}
|
||||||
|
|
||||||
|
setprop("/winwing/flags", flags);
|
||||||
|
return [0x00]; # dummy return so log doesn't get spammed anymore
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var getButtonBrightnessReport = func(item, value) {
|
||||||
|
var r = [0x10, 0xBB, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
|
||||||
|
r[6] = item;
|
||||||
|
r[7] = int(value);
|
||||||
|
return r;
|
||||||
|
};
|
||||||
|
var updateWinwingFCUIntegLT = func() {
|
||||||
|
var value = getprop("/controls/lighting/fcu-panel-norm") * 255;
|
||||||
|
# debug.dump(getButtonBrightnessReport(0x00, value));
|
||||||
|
return getButtonBrightnessReport(0x00, value);
|
||||||
|
};
|
||||||
|
]]>
|
||||||
|
</open>
|
||||||
|
</nasal>
|
||||||
|
<hid-descriptor>
|
||||||
|
<report>
|
||||||
|
<type>input</type>
|
||||||
|
<id>1</id>
|
||||||
|
<button-1>
|
||||||
|
<size type="int">1</size>
|
||||||
|
<count type="int">128</count>
|
||||||
|
</button-1>
|
||||||
|
<unused-bits><size type="int">176</size></unused-bits>
|
||||||
|
</report>
|
||||||
|
<report>
|
||||||
|
<type>input</type>
|
||||||
|
<id>2</id>
|
||||||
|
<dummy-1>
|
||||||
|
<size type="int">8</size>
|
||||||
|
<count type="int">13</count>
|
||||||
|
</dummy-1>
|
||||||
|
<unused-bits><size type="int">0</size></unused-bits>
|
||||||
|
</report>
|
||||||
|
<report>
|
||||||
|
<type>output</type>
|
||||||
|
<id>2</id>
|
||||||
|
<display-0>
|
||||||
|
<size type="int">104</size>
|
||||||
|
<count type="int">1</count>
|
||||||
|
</display-0>
|
||||||
|
<unused-bits><size type="int">0</size></unused-bits>
|
||||||
|
</report>
|
||||||
|
<report>
|
||||||
|
<type>input</type>
|
||||||
|
<id>240</id>
|
||||||
|
<dummy2-1>
|
||||||
|
<size type="int">8</size>
|
||||||
|
<count type="int">63</count>
|
||||||
|
</dummy2-1>
|
||||||
|
<unused-bits><size type="int">0</size></unused-bits>
|
||||||
|
</report>
|
||||||
|
<report>
|
||||||
|
<type>output</type>
|
||||||
|
<id>240</id>
|
||||||
|
<display2-0>
|
||||||
|
<size type="int">8</size>
|
||||||
|
<count type="int">63</count>
|
||||||
|
</display2-0>
|
||||||
|
<unused-bits><size type="int">0</size></unused-bits>
|
||||||
|
</report>
|
||||||
|
</hid-descriptor>
|
||||||
|
<report>
|
||||||
|
<report-id type="int">2</report-id>
|
||||||
|
<type>output</type>
|
||||||
|
<watch>/controls/lighting/fcu-panel-norm</watch>
|
||||||
|
<nasal-function>updateWinwingFCUIntegLT</nasal-function>
|
||||||
|
</report>
|
||||||
|
<report>
|
||||||
|
<report-id type="int">2</report-id>
|
||||||
|
<type>output</type>
|
||||||
|
<watch>/it-autoflight/input/kts-mach</watch>
|
||||||
|
<watch>/it-autoflight/input/kts</watch>
|
||||||
|
<watch>/it-autoflight/input/mach</watch>
|
||||||
|
<watch>/it-autoflight/input/hdg</watch>
|
||||||
|
<watch>/it-autoflight/input/alt</watch>
|
||||||
|
<watch>/it-autoflight/output/vs-fcu-display</watch>
|
||||||
|
<watch>/controls/switches/annun-test</watch>
|
||||||
|
<nasal-function>updateWinwingFCUDisplay</nasal-function>
|
||||||
|
</report>
|
||||||
|
<!--report>
|
||||||
|
<type>feature</type>
|
||||||
|
<watch>/controls/lighting/fcu-digit-norm</watch>
|
||||||
|
<nasal-function>updateWinwingFCUDisplayBrightness</nasal-function>
|
||||||
|
</report-->
|
||||||
|
<event>
|
||||||
|
<name>button-1</name>
|
||||||
|
<desc type="string">IAS/Mach</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.IASMach();
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-2</name>
|
||||||
|
<desc type="string">LOC</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.LOCButton();
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-3</name>
|
||||||
|
<desc type="string">Track/Fligtht Path Angle</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.TRKFPA();
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-4</name>
|
||||||
|
<desc type="string">Autopilot 1</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.AP1();
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-5</name>
|
||||||
|
<desc type="string">Autopilot 2</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.AP2();
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-6</name>
|
||||||
|
<desc type="string">Autothrust</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.ATHR();
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-7</name>
|
||||||
|
<desc type="string">Expedite</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-8</name>
|
||||||
|
<desc type="string">Metric ALT</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.MetricAlt();
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-9</name>
|
||||||
|
<desc type="string">Approach</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.APPRButton();
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-10</name>
|
||||||
|
<desc type="string">Speed decrease</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.SPDAdjust(-1);
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-11</name>
|
||||||
|
<desc type="string">Speed increase</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.SPDAdjust(1);
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-12</name>
|
||||||
|
<desc type="string">Speed Push</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.SPDPush();
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-13</name>
|
||||||
|
<desc type="string">Speed Pull</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.SPDPull();
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-14</name>
|
||||||
|
<desc type="string">Heading decrease</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.HDGAdjust(-1);
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-15</name>
|
||||||
|
<desc type="string">Heading increase</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.HDGAdjust(1);
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-16</name>
|
||||||
|
<desc type="string">Heading push</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.HDGPush();
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-17</name>
|
||||||
|
<desc type="string">Heading pull</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.HDGPull();
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-18</name>
|
||||||
|
<desc type="string">Altitude decrease</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.ALTAdjust(-1);
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-19</name>
|
||||||
|
<desc type="string">Altitude increase</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.ALTAdjust(1);
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-20</name>
|
||||||
|
<desc type="string">Altitude Push</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.ALTPush();
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-21</name>
|
||||||
|
<desc type="string">Altitude pull</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.ALTPull();
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-22</name>
|
||||||
|
<desc type="string">Vertical Speed decrease</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.VSAdjust(-1);
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-23</name>
|
||||||
|
<desc type="string">Vertical Speed increase</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.VSAdjust(1);
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-24</name>
|
||||||
|
<desc type="string">Vertical Speed push</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.VSPush();
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-25</name>
|
||||||
|
<desc type="string">Vertical Speed pull</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command type="string">nasal</command>
|
||||||
|
<script>
|
||||||
|
fcu.FCUController.VSPull();
|
||||||
|
</script>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-26</name>
|
||||||
|
<desc type="string">Altitude mode 100</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command>property-assign</command>
|
||||||
|
<property>it-autoflight/config/altitude-dial-mode</property>
|
||||||
|
<value>0</value>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
<event>
|
||||||
|
<name>button-27</name>
|
||||||
|
<desc type="string">Altitude mode 1000</desc>
|
||||||
|
<repeatable type="string">false</repeatable>
|
||||||
|
<binding>
|
||||||
|
<command>property-assign</command>
|
||||||
|
<property>it-autoflight/config/altitude-dial-mode</property>
|
||||||
|
<value>1</value>
|
||||||
|
</binding>
|
||||||
|
</event>
|
||||||
|
</PropertyList>
|
50
displayProtocol.xml
Normal file
50
displayProtocol.xml
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<PropertyList>
|
||||||
|
<generic>
|
||||||
|
<output>
|
||||||
|
<binary_mode>false</binary_mode>
|
||||||
|
<var_separator>,</var_separator>
|
||||||
|
<chunk>
|
||||||
|
<format>d</format>
|
||||||
|
</chunk>
|
||||||
|
<chunk>
|
||||||
|
<node>/winwing/spd</node>
|
||||||
|
<type>string</type>
|
||||||
|
<format>%s</format>
|
||||||
|
</chunk>
|
||||||
|
<chunk>
|
||||||
|
<node>/winwing/hdg</node>
|
||||||
|
<type>string</type>
|
||||||
|
<format>%s</format>
|
||||||
|
</chunk>
|
||||||
|
<chunk>
|
||||||
|
<node>/winwing/alt</node>
|
||||||
|
<type>string</type>
|
||||||
|
<format>%s</format>
|
||||||
|
</chunk>
|
||||||
|
<chunk>
|
||||||
|
<node>/winwing/vs</node>
|
||||||
|
<type>string</type>
|
||||||
|
<format>%s</format>
|
||||||
|
</chunk>
|
||||||
|
<chunk>
|
||||||
|
<node>/controls/lighting/fcu-panel-norm</node>
|
||||||
|
<type>float</type>
|
||||||
|
<format>%01.2f</format>
|
||||||
|
</chunk>
|
||||||
|
<chunk>
|
||||||
|
<node>/controls/lighting/fcu-digit-norm</node>
|
||||||
|
<type>float</type>
|
||||||
|
<format>%01.2f</format>
|
||||||
|
</chunk>
|
||||||
|
<chunk>
|
||||||
|
<node>/winwing/flags</node>
|
||||||
|
<type>string</type>
|
||||||
|
<format>%s</format>
|
||||||
|
</chunk>
|
||||||
|
<chunk>
|
||||||
|
<format>d</format>
|
||||||
|
</chunk>
|
||||||
|
</output>
|
||||||
|
</generic>
|
||||||
|
</PropertyList>
|
337
fcuSync.py
Executable file
337
fcuSync.py
Executable file
|
@ -0,0 +1,337 @@
|
||||||
|
#! /usr/bin/env python3
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import socket
|
||||||
|
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
import hid
|
||||||
|
|
||||||
|
hidraw_path = ""
|
||||||
|
for device in hid.enumerate():
|
||||||
|
if device["vendor_id"] == 0x4098 and device["product_id"] == 0xbb10:
|
||||||
|
hidraw_path = device["path"]
|
||||||
|
|
||||||
|
if hidraw_path == "":
|
||||||
|
print("Unable to find FCU device")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
class Leds(Enum):
|
||||||
|
BACKLIGHT = 0 # 0 .. 255
|
||||||
|
SCREEN_BACKLIGHT = 1 # 0 .. 255
|
||||||
|
LOC_GREEN = 3 # all on/off
|
||||||
|
AP1_GREEN = 5
|
||||||
|
AP2_GREEN = 7
|
||||||
|
ATHR_GREEN = 9
|
||||||
|
EXPED_GREEN = 11
|
||||||
|
APPR_GREEN = 13
|
||||||
|
FLAG_GREEN = 17 # 0 .. 255
|
||||||
|
EXPED_YELLOW = 30 # 0 .. 255
|
||||||
|
|
||||||
|
# A
|
||||||
|
# ---
|
||||||
|
# F | G | B
|
||||||
|
# ---
|
||||||
|
# E | | C
|
||||||
|
# ---
|
||||||
|
# D
|
||||||
|
# A=0x80, B=0x40, C=0x20, D=0x10, E=0x02, F=0x08, G=0x04
|
||||||
|
# Bits are valid for Speed display only, all other share bits in 2 databyte per lcd 7-segment display.
|
||||||
|
# Use function data_from_string_swapped to recalculate values
|
||||||
|
representations = {
|
||||||
|
'0' : 0xfa,
|
||||||
|
'1' : 0x60,
|
||||||
|
'2' : 0xd6,
|
||||||
|
'3' : 0xf4,
|
||||||
|
'4' : 0x6c,
|
||||||
|
'5' : 0xbc,
|
||||||
|
'6' : 0xbe,
|
||||||
|
'7' : 0xe0,
|
||||||
|
'8' : 0xfe,
|
||||||
|
'9' : 0xfc,
|
||||||
|
'A' : 0xee,
|
||||||
|
'B' : 0xfe,
|
||||||
|
'C' : 0x9a,
|
||||||
|
'D' : 0x76,
|
||||||
|
'E' : 0x9e,
|
||||||
|
'F' : 0x8e,
|
||||||
|
'G' : 0xbe,
|
||||||
|
'H' : 0x6e,
|
||||||
|
'I' : 0x60,
|
||||||
|
'J' : 0x70,
|
||||||
|
'K' : 0x0e,
|
||||||
|
'L' : 0x1a,
|
||||||
|
'M' : 0xa6,
|
||||||
|
'N' : 0x26,
|
||||||
|
'O' : 0xfa,
|
||||||
|
'P' : 0xce,
|
||||||
|
'Q' : 0xec,
|
||||||
|
'R' : 0x06,
|
||||||
|
'S' : 0xbc,
|
||||||
|
'T' : 0x1e,
|
||||||
|
'U' : 0x7a,
|
||||||
|
'V' : 0x32,
|
||||||
|
'W' : 0x58,
|
||||||
|
'X' : 0x6e,
|
||||||
|
'Y' : 0x7c,
|
||||||
|
'Z' : 0xd6,
|
||||||
|
'-' : 0x04,
|
||||||
|
'#' : 0x36,
|
||||||
|
'/' : 0x60,
|
||||||
|
'\\' : 0xa0,
|
||||||
|
' ' : 0x00,
|
||||||
|
}
|
||||||
|
|
||||||
|
class Byte(Enum):
|
||||||
|
H0 = 0
|
||||||
|
H3 = 1
|
||||||
|
A0 = 2
|
||||||
|
A1 = 3
|
||||||
|
A2 = 4
|
||||||
|
A3 = 5
|
||||||
|
A4 = 6
|
||||||
|
A5 = 7
|
||||||
|
V2 = 8
|
||||||
|
V3 = 9
|
||||||
|
V0 = 10
|
||||||
|
V1 = 11
|
||||||
|
S1 = 12
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Flag:
|
||||||
|
name : str
|
||||||
|
byte : Byte
|
||||||
|
mask : int
|
||||||
|
value : bool = False
|
||||||
|
|
||||||
|
|
||||||
|
flags = dict([("spd", Flag('spd-mach_spd', Byte.H3, 0x08, True)),
|
||||||
|
("mach", Flag('spd-mach_mach', Byte.H3, 0x04)),
|
||||||
|
("hdg", Flag('hdg-trk-lat_hdg', Byte.H0, 0x80)),
|
||||||
|
("trk", Flag('hdg-trk-lat_trk', Byte.H0, 0x40)),
|
||||||
|
("lat", Flag('hdg-trk-lat_lat', Byte.H0, 0x20, True)),
|
||||||
|
("vshdg", Flag('hdg-v/s_hdg', Byte.A5, 0x08, True)),
|
||||||
|
("vs", Flag('hdg-v/s_v/s', Byte.A5, 0x04, True)),
|
||||||
|
("ftrk", Flag('trk-fpa_trk', Byte.A5, 0x02)),
|
||||||
|
("ffpa", Flag('trk-fpa_fpa', Byte.A5, 0x01)),
|
||||||
|
("alt", Flag('alt', Byte.A4, 0x10, True)),
|
||||||
|
("hdg_managed", Flag('hdg managed', Byte.H0, 0x10)),
|
||||||
|
("spd_managed", Flag('spd managed', Byte.H3, 0x02)),
|
||||||
|
("alt_managed", Flag('alt_managed', Byte.V1, 0x10)),
|
||||||
|
("vs_horz", Flag('v/s plus horizontal', Byte.A0, 0x10, True)),
|
||||||
|
("vs_vert", Flag('v/s plus vertical', Byte.V2, 0x10)),
|
||||||
|
("lvl", Flag('lvl change', Byte.A2, 0x10, True)),
|
||||||
|
("lvl_left", Flag('lvl change left', Byte.A3, 0x10, True)),
|
||||||
|
("lvl_right", Flag('lvl change right', Byte.A1, 0x10, True)),
|
||||||
|
("fvs", Flag('v/s-fpa_v/s', Byte.V0, 0x40, True)),
|
||||||
|
("ffpa2", Flag('v/s-fpa_fpa', Byte.V0, 0x80)),
|
||||||
|
("fpa_comma", Flag('fpa_comma', Byte.V3, 0x10)),
|
||||||
|
("mach_comma", Flag('mach_comma', Byte.S1, 0x01)),
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
def swap_nibbles(x):
|
||||||
|
return ( (x & 0x0F)<<4 | (x & 0xF0)>>4 )
|
||||||
|
|
||||||
|
|
||||||
|
def winwing_fcu_set_led(led, brightness):
|
||||||
|
data = [0x02, 0x10, 0xbb, 0, 0, 3, 0x49, led.value, brightness, 0,0,0,0,0]
|
||||||
|
cmd = bytes(data)
|
||||||
|
send_data_to_hidraw(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
def lcd_init():
|
||||||
|
data = [0xf0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0] # init packet
|
||||||
|
cmd = bytes(data)
|
||||||
|
send_data_to_hidraw(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
def data_from_string(num_7segments, string):
|
||||||
|
|
||||||
|
l = num_7segments
|
||||||
|
d = [0] * (l)
|
||||||
|
for i in range(min(l, len(string))):
|
||||||
|
r = representations.get(string.upper()[i])
|
||||||
|
if r == None:
|
||||||
|
r = 0xef
|
||||||
|
print("ERROR: char '{string.upper()[i]}' not found")
|
||||||
|
d[l-1-i] = r
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
def data_from_string_swapped(num_7segments, string): # some 7-segemnts have wired mapping, correct ist here
|
||||||
|
# return array with one byte more than lcd chars
|
||||||
|
|
||||||
|
l = num_7segments
|
||||||
|
|
||||||
|
d = data_from_string(l, string)
|
||||||
|
d.append(0)
|
||||||
|
|
||||||
|
# fix wired segment mapping special elements such at the bars at the LVL/CH
|
||||||
|
for i in range(len(d)):
|
||||||
|
d[i] = swap_nibbles(d[i])
|
||||||
|
for i in range(0, len(d) - 1):
|
||||||
|
d[l-i] = (d[l-i] & 0x0f) | (d[l-1-i] & 0xf0)
|
||||||
|
d[l-1-i] = d[l-1-i] & 0x0f
|
||||||
|
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
def winwing_fcu_lcd_set(speed, heading, alt,vs, new):
|
||||||
|
s = data_from_string( 3, str(speed))
|
||||||
|
h = data_from_string_swapped(3, str(heading))
|
||||||
|
a = data_from_string_swapped(5, str(alt))
|
||||||
|
v = data_from_string_swapped(4, str(vs))
|
||||||
|
|
||||||
|
bl = [0] * len(Byte)
|
||||||
|
for f in flags:
|
||||||
|
bl[flags[f].byte.value] |= (flags[f].mask * flags[f].value)
|
||||||
|
|
||||||
|
pkg_nr = 1
|
||||||
|
data = [0xf0, 0x0, pkg_nr, 0x31, 0x10, 0xbb, 0x0, 0x0, 0x2, 0x1, 0x0, 0x0, 0xff, 0xff, 0x2, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, s[2], s[1], s[0], h[3] | bl[Byte.H3.value], h[2], h[1], h[0] | bl[Byte.H0.value], a[5] | bl[Byte.A5.value], a[4] | bl[Byte.A4.value], a[3] | bl[Byte.A3.value], a[2] | bl[Byte.A2.value], a[1] | bl[Byte.A1.value], a[0] | v[4] | bl[Byte.A0.value], v[3] | bl[Byte.V3.value], v[2] | bl[Byte.V2.value], v[1] | bl[Byte.V1.value], v[0] | bl[Byte.V0.value], 0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]
|
||||||
|
cmd = bytes(data)
|
||||||
|
send_data_to_hidraw(cmd)
|
||||||
|
|
||||||
|
data = [0xf0, 0x0, pkg_nr, 0x11, 0x10, 0xbb, 0x0, 0x0, 0x3, 0x1, 0x0, 0x0, 0xff, 0xff, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]
|
||||||
|
cmd = bytes(data)
|
||||||
|
send_data_to_hidraw(cmd)
|
||||||
|
|
||||||
|
def send_data_to_hidraw(data):
|
||||||
|
global hidraw_path
|
||||||
|
try:
|
||||||
|
# Open the HIDRAW device
|
||||||
|
hidraw = os.open(hidraw_path, os.O_RDWR | os.O_NONBLOCK)
|
||||||
|
|
||||||
|
# Write data to the HIDRAW device
|
||||||
|
os.write(hidraw, bytes(data))
|
||||||
|
|
||||||
|
# print("Data sent successfully to HIDRAW device.")
|
||||||
|
|
||||||
|
# Close the HIDRAW device
|
||||||
|
os.close(hidraw)
|
||||||
|
except Exception as e:
|
||||||
|
print("Error:", e)
|
||||||
|
|
||||||
|
|
||||||
|
lcd_init()
|
||||||
|
|
||||||
|
speed = 100
|
||||||
|
heading = 360
|
||||||
|
alt = 10000
|
||||||
|
vs = '----'
|
||||||
|
|
||||||
|
|
||||||
|
winwing_fcu_set_led(Leds.BACKLIGHT, 70)
|
||||||
|
winwing_fcu_set_led(Leds.EXPED_YELLOW, 70)
|
||||||
|
winwing_fcu_set_led(Leds.SCREEN_BACKLIGHT, 200)
|
||||||
|
winwing_fcu_lcd_set(speed, heading, alt, vs, 0x0)
|
||||||
|
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
s.bind(('', 12000))
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
message, address = s.recvfrom(1024)
|
||||||
|
print(message)
|
||||||
|
items = str(message).split(",")
|
||||||
|
winwing_fcu_lcd_set(items[1], items[2], items[3], items[4], 0x0)
|
||||||
|
winwing_fcu_set_led(Leds.BACKLIGHT, int(float(items[5]) * 255))
|
||||||
|
winwing_fcu_set_led(Leds.EXPED_YELLOW, int(float(items[5]) * 255))
|
||||||
|
winwing_fcu_set_led(Leds.SCREEN_BACKLIGHT, int(float(items[6]) * 255))
|
||||||
|
|
||||||
|
if "spd" in items:
|
||||||
|
flags["spd"].value = True
|
||||||
|
else:
|
||||||
|
flags["spd"].value = False
|
||||||
|
if "mach" in items:
|
||||||
|
flags["mach"].value = True
|
||||||
|
flags["mach_comma"].value = True
|
||||||
|
else:
|
||||||
|
flags["mach"].value = False
|
||||||
|
flags["mach_comma"].value = False
|
||||||
|
if "spd-mgt" in items:
|
||||||
|
flags["spd_managed"].value = True
|
||||||
|
else:
|
||||||
|
flags["spd_managed"].value = False
|
||||||
|
|
||||||
|
if "lat" in items:
|
||||||
|
flags["lat"].value = True
|
||||||
|
flags["hdg_managed"].value = True
|
||||||
|
else:
|
||||||
|
flags["lat"].value = False
|
||||||
|
flags["hdg_managed"].value = False
|
||||||
|
|
||||||
|
if "hdg-vs" in items:
|
||||||
|
flags["hdg"].value = True
|
||||||
|
flags["vshdg"].value = True
|
||||||
|
flags["vs"].value = True
|
||||||
|
flags["fvs"].value = True
|
||||||
|
else:
|
||||||
|
flags["hdg"].value = False
|
||||||
|
flags["vshdg"].value = False
|
||||||
|
flags["vs"].value = False
|
||||||
|
flags["fvs"].value = False
|
||||||
|
if "trk-fpa" in items:
|
||||||
|
flags["trk"].value = True
|
||||||
|
flags["ftrk"].value = True
|
||||||
|
flags["ffpa"].value = True
|
||||||
|
flags["ffpa2"].value = True
|
||||||
|
if items[4] != "----":
|
||||||
|
flags["fpa_comma"].value = True
|
||||||
|
else:
|
||||||
|
flags["fpa_comma"].value = False
|
||||||
|
else:
|
||||||
|
flags["trk"].value = False
|
||||||
|
flags["ftrk"].value = False
|
||||||
|
flags["ffpa"].value = False
|
||||||
|
flags["ffpa2"].value = False
|
||||||
|
flags["fpa_comma"].value = False
|
||||||
|
|
||||||
|
if "plus" in items:
|
||||||
|
flags["vs_vert"].value = True
|
||||||
|
else:
|
||||||
|
flags["vs_vert"].value = False
|
||||||
|
|
||||||
|
if "ap1" in items:
|
||||||
|
winwing_fcu_set_led(Leds.AP1_GREEN, 1)
|
||||||
|
else:
|
||||||
|
winwing_fcu_set_led(Leds.AP1_GREEN, 0)
|
||||||
|
if "ap2" in items:
|
||||||
|
winwing_fcu_set_led(Leds.AP2_GREEN, 1)
|
||||||
|
else:
|
||||||
|
winwing_fcu_set_led(Leds.AP2_GREEN, 0)
|
||||||
|
if "athr" in items:
|
||||||
|
winwing_fcu_set_led(Leds.ATHR_GREEN, 1)
|
||||||
|
else:
|
||||||
|
winwing_fcu_set_led(Leds.ATHR_GREEN, 0)
|
||||||
|
if "loc" in items:
|
||||||
|
winwing_fcu_set_led(Leds.LOC_GREEN, 1)
|
||||||
|
else:
|
||||||
|
winwing_fcu_set_led(Leds.LOC_GREEN, 0)
|
||||||
|
if "appr" in items:
|
||||||
|
winwing_fcu_set_led(Leds.APPR_GREEN, 1)
|
||||||
|
else:
|
||||||
|
winwing_fcu_set_led(Leds.APPR_GREEN, 0)
|
||||||
|
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
s.close()
|
||||||
|
|
||||||
|
#while True:
|
||||||
|
# buf_in = [None] * 7
|
||||||
|
# winwing_fcu_set_led(Leds.AP1_GREEN, 1)
|
||||||
|
# winwing_fcu_set_led(Leds.AP2_GREEN, 0)
|
||||||
|
# winwing_fcu_lcd_set(speed, heading, alt, vs, 0x0)
|
||||||
|
# speed = speed + 1
|
||||||
|
# heading = heading + 3
|
||||||
|
# if heading > 360:
|
||||||
|
# heading = 0
|
||||||
|
# time.sleep(0.5)
|
||||||
|
# winwing_fcu_set_led(Leds.AP1_GREEN, 0)
|
||||||
|
# winwing_fcu_set_led(Leds.AP2_GREEN, 1)
|
||||||
|
# winwing_fcu_lcd_set(speed, heading, alt, vs, 0xff)
|
||||||
|
# time.sleep(0.5)
|
2
nix-shell.sh
Executable file
2
nix-shell.sh
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
#! /usr/bin/env bash
|
||||||
|
nix-shell -p "python311.withPackages (ps: with ps; [ hidapi ])"
|
Loading…
Reference in a new issue