Hallo zusammen!
Sensor- und Parameter-wahl am Beispiel von Lua_OneCapacity (von dem scheinbar viele abschreiben)
Kritik:
Hier wird die Liste sämtlicher verfügbarer Sensoren ausgelesen:
local function readSensors()
local sensors = system.getSensors()
local format = string.format
local insert = table.insert
for i, sensor in ipairs(sensors) do
if (sensor.label ~= "") then
insert(sensorLalist, format("%s", sensor.label))
insert(sensorIdlist, format("%s", sensor.id))
insert(sensorPalist, format("%s", sensor.param))
end
end
end
Danach ist sensorLalist ein assoziatives Array ( Table in Lua Sprech )
aber mit einem Numerischem Subscript (Indexing mit Zahlen)
Die Elemente sind also gespeichert in sensorLalist[1] sensorLalist[2] usw.
Jedes dieser Elemente ist selber ein Table, dessen Elemente gespeichert sind in
z.B. sensor.label oder sensor["label"].
Für mehr als ein Gerät liefert system.getSensors(), immer ein zweidimensionale Ding, sowas wie:
index: 1 label: openX-Vario ID: 78488593 param: 0
index: 2 label: Hoehe ID: 78488593 type: 1 param: 1 value: 0,0 unit: m name: openX-Vario
index: 3 label: Vario ID: 78488593 type: 1 param: 2 value: 0,0 unit: m/s name: openX-Vario
index: 4 label: Hoehe max ID: 78488593 type: 1 param: 3 value: 0,0 unit: m name: openX-Vario
index: 5 label: GPSLog2 ID: 1551409921 param: 0
...
index: 10 label: Speed ID: 1551409921 type: 0 param: 5 value: 0,0 unit: kmh name: GPSLog2
index: 11 label: Hoehe ID: 1551409921 type: 0 param: 6 value: 0,0 unit: m name: GPSLog2
index: 12 label: Hoehe NN ID: 1551409921 type: 0 param: 7 value: 0,0 unit: m name: GPSLog2
...
Abgesehen davon, dass hier in readSensors unnötigerweise die Elemente (sogar Strings) in Strings
verwandelt werden und sensorIdlist für je ein Gerät viele Einträge mit derselben ID enthält
(wir haben ja genug Speicher?) enthält sensorLalist so auch die Namen der Geräte.
Die GESAMTE lange Liste wird jeweils zur Auswahl von einem Parameter/Sensor angeboten in:
addSelectbox(sensorLalist, capSe, true, sensorChanged)
und
addSelectbox(sensorLalist, voltSe, true, sensorVoltChanged)
"openX-Vario" oder "GPSLog2" sind aber keine Sensoren/Parameter/Sensorlabel sondern Geräte
und sollten nicht als Sensoren wählbar sein.
Der jeweiligen callback Funktion z.B. sensorVoltChanged(value) wird also als Value der Index
der langen Liste übergeben, den der User ausgewählt hat:
local function sensorVoltChanged(value)
local pSave = system.pSave
local format = string.format
voltSe = value
voltSeId = format("%s", sensorIdlist[voltSe])
voltSePa = format("%s", sensorPalist[voltSe])
if (voltSeId == "...") then
voltSeId = 0
voltSePa = 0
end
pSave("voltSe", value)
pSave("voltSeId", voltSeId)
pSave("voltSePa", voltSePa)
end
Über diesen Index werden dann die konkreten Werte hier z.b. von
voltSeId und voltSePa bestimmt.
Beides und der Index werden dann auch im Modellspeicher abgespeichert.
Letzterer nur um in der zugehörigen selectbox den current Eintrag
wiederzufinden.
Abgesehen davon das hier schon wieder strings in strings verwandelt werden
und sensoId und sensorParam eigentlich von getsensors() bis getSensorValueByID()
Integers sind,
was passsiert wohl, wenn man z.B. Sensoren vom 2. Gerät gewählt hat
und das 1. Gerät aus dem Modellspeicher löscht. Die Numerischen Indexe
verschieben sich, der Sensor wird nicht mehr gefunden, die Selectboxen
zeigen mit ihren currentIndex Werten Fahrkarten an.
In meinem Code wird nur die SensoId im Modellspeicher abgelegt
und der richtige Index wird regeneriert, wenn das Setup erneut
aufgerufen wird.
Ausgehend vom gleichen Table den getSensors() zurück gibt (wird hier in init() gelesen)
wird dieser so zerlegt:
if ( not sensor_id_list[1] ) then -- sensors not yet checked or rebooted
for i,sensor in ipairs(all_sensor_rows) do
if (sensor.param == 0) then -- new multisensor/device
sensor_label_list[#sensor_label_list + 1] = sensor.label -- list presented in sensor select box
sensor_id_list[#sensor_id_list + 1] = sensor.id -- to get id from if sensor changed, same numeric indexing
if (sensor.id == sensorId) then
sensorIndex = #sensor_id_list
end
sensor_param_lists[#sensor_param_lists + 1] = {} -- start new param list only containing label and unit as string
else -- subscript is number of param for current multisensor/device
sensor_param_lists[#sensor_param_lists][sensor.param] = sensor.label .. " " .. sensor.unit -- list presented in param select box
end
end
end
sensor_label_list enthält hier nur die Gerätenamen,
das ist die Auswahlliste für das zu wählende Gerät:
form.addSelectbox(sensor_label_list, sensorIndex, true, sensorChanged)
sensor_id_list enthält die Geräte IDs und hat nur
soviel Elemente wie es Geräte gibt.
sensor_param_lists ist zweidimensional und enthält für jedes Gerät
ein Table mit der Parameternummer als Index in dem sensor.label und sensor.unit
als String die Elemente bilden.
Das ist die Auswahlliste für den jeweils zu wählenden Parameter eines Gerätes
als aktueller Sensor. Diese Auswahlen erscheinen erst nach Auswahl des Gerätes:
if ( sensor_id_list and sensorIndex > 0 ) then
form.addRow(2)
form.addLabel({label = "Parameter Vario", width=200})
form.addSelectbox(sensor_param_lists[sensorIndex], vario_param, true, paramVarioChanged)
form.addRow(2)
form.addLabel({label = trans.paramAlti, width=200})
form.addSelectbox(sensor_param_lists[sensorIndex], altitude_param, true, paramAltitudeChanged)
end
In der callback Funktion der Sensorauswahl (eigentlich müsste es Geräteauswahl heißen)
wird nur die sensorId im Modellspeicher abgelegt:
local function sensorChanged(value)
if ( not sensor_id_list[1] ) then -- no sensors found
return
end
sensorId = sensor_id_list[value]
system.pSave("sensorId", sensorId)
sensorIndex = value
vario_param = 1 -- prevent error if previous index was higher than possible in this new sensor
altitude_param = 1 -- prevent error if previous index was higher than possible in this new sensor
form.reinit()
end
In der jeweiligen callback Funktion der Parameterauswahl wird nur der Index
in die zum aktuell gewählten Gerät gehörigen Parameterliste im Modell gespeichert.
D.h. die tatsächliche Parameternummer.
local function paramVarioChanged(value)
vario_param = value
system.pSave("vario_param", vario_param)
end
Bei Verschiebungen wird alles wiedergefunden im Setup, weil der
Index für die Geräteliste durch die gemerkte sensorId neu generiert wird
und der Index über alles was getsensors() zurück gibt keine Rolle spielt.
Gruß
Dieter