From ac15b88c46ac74c4444997d962830d2ffd601869 Mon Sep 17 00:00:00 2001 From: Offer Shmuely Date: Fri, 15 Jul 2022 01:54:38 +0300 Subject: [PATCH] widget(color): Add RotaryGauge widget (#63) * new Rotary Gauge widget * Rotary Gauge widget: less ticks on small size * new Rotary Gauge widget * new Rotary Gauge widget * Rotary Gauge widget: fix error if no telemetry sensor exists * Rotary Gauge widget: show last values when battery disconnected from plane (with disconnected indication) * Rotary Gauge widget: perf improve (do not call getValue() with string) * Rotary Gauge widget: cosmetics * Rotary Gauge widget: show gauge data when telemetry disconnected add indication of "no telemetry data" * Rotary Gauge widget: fix typo * Rotary Gauge widget: fix error if no telemetry sensor exists * Rotary Gauge widget: show last values when battery disconnected from plane (with disconnected indication) * Rotary Gauge widget: perf improve (do not call getValue() with string) * Rotary Gauge widget: cosmetics * Rotary Gauge widget: show gauge data when telemetry disconnected add indication of "no telemetry data" * Rotary Gauge widget: fix typo * Rotary Gauge widget: additional telemetry sources Co-authored-by: Shmuely --- .../WIDGETS/GaugeRotary/gauge_core.lua | 34 +++--- sdcard/c480x272/WIDGETS/GaugeRotary/main.lua | 104 ++++++++++++------ sdcard/c480x272/WIDGETS/GaugeRotary/tools.lua | 76 +++++++++++++ 3 files changed, 162 insertions(+), 52 deletions(-) create mode 100644 sdcard/c480x272/WIDGETS/GaugeRotary/tools.lua diff --git a/sdcard/c480x272/WIDGETS/GaugeRotary/gauge_core.lua b/sdcard/c480x272/WIDGETS/GaugeRotary/gauge_core.lua index 09a02784..046e9389 100644 --- a/sdcard/c480x272/WIDGETS/GaugeRotary/gauge_core.lua +++ b/sdcard/c480x272/WIDGETS/GaugeRotary/gauge_core.lua @@ -70,32 +70,32 @@ function self.getRangeColor(value, red_value, green_value) end end -function self.drawGauge(centerX, centerY, centreR, isFull, percentageValue, percentageValueMin, percentageValueMax, txt1, txt2) +function self.drawGauge(centerX, centerY, centerR, isFull, percentageValue, percentageValueMin, percentageValueMax, txt1, txt2) local fender = 4 local tickWidth = 9 - local armCenterR = centreR / 2.5 - local armR = centreR - 8 + local armCenterR = centerR / 2.5 + local armR = centerR - 8 local txtSize = DBLSIZE - if centreR < 65 then + if centerR < 65 then txtSize = MIDSIZE end - if centreR < 30 then + if centerR < 30 then txtSize = SMLSIZE end -- main gauge background if isFull then - lcd.drawFilledCircle(centerX, centerY, centreR, lcd.RGB(0x1A1A1A)) + lcd.drawFilledCircle(centerX, centerY, centerR, lcd.RGB(0x1A1A1A)) else - lcd.drawPie(centerX,centerY,centreR, -110,110, lcd.RGB(0x1A1A1A)) + lcd.drawPie(centerX,centerY,centerR, -110,110, lcd.RGB(0x1A1A1A)) end -- fender if isFull then - lcd.drawAnnulus(centerX, centerY, centreR - fender, centreR, 0, 360, BLACK) + lcd.drawAnnulus(centerX, centerY, centerR - fender, centerR, 0, 360, BLACK) else - lcd.drawAnnulus(centerX, centerY, centreR - fender, centreR, -110, 110, BLACK) + lcd.drawAnnulus(centerX, centerY, centerR - fender, centerR, -110, 110, BLACK) end -- ticks @@ -109,22 +109,24 @@ function self.drawGauge(centerX, centerY, centreR, isFull, percentageValue, perc to_tick = 210 tick_offset = 250 end - if (centreR < 100) then - tick_step = 10 + 0.15 * (100 - centreR) + if (centerR < 100) then + tick_step = 10 + 0.15 * (100 - centerR) end for i = 0, to_tick, tick_step do --log("HighAsGreen: " .. self.HighAsGreen) if (self.HighAsGreen == 1) then - lcd.setColor(CUSTOM_COLOR, self.getRangeColor(i, 0, to_tick - 10)) + local newColor = self.getRangeColor(i, 0, to_tick - 10) + lcd.setColor(CUSTOM_COLOR, newColor) + --lcd.setColor(CUSTOM_COLOR, self.getRangeColor(i, 0, to_tick - 10)) else lcd.setColor(CUSTOM_COLOR, self.getRangeColor(i, to_tick - 10, 0)) --lcd.setColor(CUSTOM_COLOR, self.getRangeColor(i, 120 , 30)) end - lcd.drawAnnulus(centerX, centerY, centreR - fender - 3 - tickWidth, centreR - fender - 3, tick_offset + i, tick_offset + i + 7, CUSTOM_COLOR) - --lcd.drawAnnulus(centerX, centerY, centreR -fender -3 -tickWidth, centreR -fender -3 , 250 +i, 250 +i +7, YELLOW) - --lcd.drawAnnulus(centerX, centerY, centreR -fender -3 -tickWidth -15, centreR -fender -3 -tickWidth -4 , 250 +i, 250 +i +7, RED) + lcd.drawAnnulus(centerX, centerY, centerR - fender - 3 - tickWidth, centerR - fender - 3, tick_offset + i, tick_offset + i + 7, CUSTOM_COLOR) + --lcd.drawAnnulus(centerX, centerY, centerR -fender -3 -tickWidth, centerR -fender -3 , 250 +i, 250 +i +7, YELLOW) + --lcd.drawAnnulus(centerX, centerY, centerR -fender -3 -tickWidth -15, centerR -fender -3 -tickWidth -4 , 250 +i, 250 +i +7, RED) end - --lcd.drawPie(centerX,centerY,centreR - fender, 0,20) + --lcd.drawPie(centerX,centerY,centerR - fender, 0,20) local armColor = lcd.RGB(255, 255, 255) local armColorMin, armColorMax diff --git a/sdcard/c480x272/WIDGETS/GaugeRotary/main.lua b/sdcard/c480x272/WIDGETS/GaugeRotary/main.lua index a5e7232c..d835fb6e 100644 --- a/sdcard/c480x272/WIDGETS/GaugeRotary/main.lua +++ b/sdcard/c480x272/WIDGETS/GaugeRotary/main.lua @@ -32,9 +32,17 @@ -- * batt-capacity -- * A1/A2 analog voltage --- Version: 0.1 +-- Version: 0.3 -- Author : Offer Shmuely + +local app_name = "GaugeRotary" + +-- imports +local GaugeClass = loadScript("/WIDGETS/" .. app_name .. "/gauge_core.lua") +local ToolsClass = loadScript("/WIDGETS/" .. app_name .. "/tools.lua") + +-- consts local UNIT_ID_TO_STRING = { "V", "A", "mA", "kts", "m/s", "f/s", "km/h", "mph", "m", "f", "°C", "°F", "%", "mAh", "W", "mW", "dB", "rpm", "g", "°", "rad", "ml", "fOz", "ml/m", "Hz", "uS", "km" } local DEFAULT_MIN_MAX = { {"RSSI" , 0, 100, 0}, @@ -78,6 +86,8 @@ local function setAutoMinMax(wgt) print("GaugeRotary-setting: " .. "AutoMinMax") local sourceName = getSourceName(wgt.options.Source) + if (sourceName == nil) then return end + -- workaround for bug in getFiledInfo() if string.byte(string.sub(sourceName,1,1)) > 127 then sourceName = string.sub(sourceName,2,-1) -- ???? why? @@ -107,27 +117,28 @@ local function setAutoMinMax(wgt) end -local function create(zone, options) - local GaugeClass = loadScript("/WIDGETS/GaugeRotary/gauge_core.lua") +local function update(wgt, options) + wgt.options = options + setAutoMinMax(wgt) + wgt.gauge1 = GaugeClass(options.HighAsGreen, 2) + wgt.tools = ToolsClass() +end +local function create(zone, options) local wgt = { zone = zone, options = options, - gauge1 = GaugeClass(options.HighAsGreen, 2) + last_value = -1, + last_value_min = -1, + last_value_max = -1, + gauge1 = nil } - setAutoMinMax(wgt) - + update(wgt, options) return wgt end -local function update(wgt, options) - wgt.options = options - setAutoMinMax(wgt) - wgt.gauge1.HighAsGreen = wgt.options.HighAsGreen -end - --- ----------------------------------------------------------------------------------------------------- +-------------------------------------------------------------------------------------------------------- local function getPercentageValue(value, options_min, options_max) if value == nil then @@ -152,7 +163,6 @@ end local function getWidgetValue(wgt) local currentValue = getValue(wgt.options.Source) local sourceName = getSourceName(wgt.options.Source) - log("aaaaaa: ".. sourceName) log("aaaaaa: ".. sourceName .. ": " .. string.byte(string.sub(sourceName, 1, 1))) -- workaround for bug in getFiledInfo() @@ -161,8 +171,6 @@ local function getWidgetValue(wgt) end --log("Source: " .. wgt.options.Source .. ",name: " .. sourceName) - --local currentValue = getValue(wgt.options.Source) / 10.24 - local fieldinfo = getFieldInfo(wgt.options.Source) if (fieldinfo == nil) then log(string.format("getFieldInfo(%s)==nil", wgt.options.Source)) @@ -177,28 +185,43 @@ local function getWidgetValue(wgt) end end - log("") - log(string.format("id: %s", fieldinfo.id)) - log(string.format(" sourceName: %s", sourceName)) - log(string.format(" curr: %2.1f", currentValue)) - log(string.format(" name: %s", fieldinfo.name)) - log(string.format(" desc: %s", fieldinfo.desc)) - log(string.format(" idUnit: %s", fieldinfo.unit)) - log(string.format(" txtUnit: %s", txtUnit)) - - -- try to get min/max value (if exist) - local minValue = getValue(sourceName .. "-") - local maxValue = getValue(sourceName .. "+") - --log("min/max: " .. minValue .. " < " .. currentValue .. " < " .. maxValue) - - return sourceName, currentValue, minValue, maxValue, txtUnit + --log("") + --log(string.format("id: %s", fieldinfo.id)) + --log(string.format(" sourceName: %s", sourceName)) + --log(string.format(" curr: %2.1f", currentValue)) + --log(string.format(" name: %s", fieldinfo.name)) + --log(string.format(" desc: %s", fieldinfo.desc)) + --log(string.format(" idUnit: %s", fieldinfo.unit)) + --log(string.format(" txtUnit: %s", txtUnit)) + + if (wgt.tools.isTelemetryAvailable()) then + + -- try to get min/max value (if exist) + local minValue = nil + local maxValue = nil + if source_min_id == nil or source_max_id == nil then + source_min_id = getFieldInfo(sourceName .. "-").id + source_max_id = getFieldInfo(sourceName .. "+").id + end + if source_min_id ~= nil and source_max_id ~= nil then + minValue = getValue(source_min_id) + maxValue = getValue(source_max_id) + end + + wgt.last_value = currentValue + wgt.last_value_min = minValue + wgt.last_value_max = maxValue + + --log("min/max: " .. minValue .. " < " .. currentValue .. " < " .. maxValue) + return sourceName, currentValue, minValue, maxValue, txtUnit + else + log("overriding value with last_value: " .. wgt.last_value) + return sourceName, wgt.last_value, wgt.last_value_min, wgt.last_value_max, txtUnit + end end -local function refresh_app_mode(wgt, event, touchState, w_name, value, minValue, maxValue, w_unit, percentageValue, percentageValueMin, percentageValueMax) +local function refresh_app_mode(wgt, event, touchState) local w_name, value, minValue, maxValue, w_unit = getWidgetValue(wgt) - if (value == nil) then - return - end local percentageValue = getPercentageValue(value, wgt.options.Min, wgt.options.Max) local percentageValueMin = getPercentageValue(minValue, wgt.options.Min, wgt.options.Max) @@ -220,7 +243,7 @@ local function refresh_app_mode(wgt, event, touchState, w_name, value, minValue, end -local function refresh_widget(wgt, w_name, value, minValue, maxValue, w_unit, percentageValue, percentageValueMin, percentageValueMax) +local function refresh_widget(wgt) local w_name, value, minValue, maxValue, w_unit = getWidgetValue(wgt) if (value == nil) then return @@ -266,6 +289,10 @@ local function refresh_widget(wgt, w_name, value, minValue, maxValue, w_unit, pe wgt.gauge1.drawGauge(centerX, centerY, centerR, isFull, percentageValue, percentageValueMin, percentageValueMax, value_fmt, w_name) --lcd.drawText(wgt.zone.x, wgt.zone.y, value_fmt, XXLSIZE + YELLOW) + if wgt.tools.isTelemetryAvailable() == false then + lcd.drawText(wgt.zone.x, wgt.zone.y + wgt.zone.h /2, "Disconnected...", MIDSIZE + WHITE+ BLINK) + end + end @@ -273,6 +300,11 @@ local function refresh(wgt, event, touchState) if (wgt == nil) then return end if (wgt.options == nil) then return end if (wgt.zone == nil) then return end + local sourceName = getSourceName(wgt.options.Source) + if (sourceName == nil) then + lcd.drawText(wgt.zone.x, wgt.zone.y + wgt.zone.h /2, "No source selected...", MIDSIZE + WHITE+ BLINK) + return + end --lcd.drawRectangle(wgt.zone.x, wgt.zone.y, wgt.zone.w, wgt.zone.h, BLACK) diff --git a/sdcard/c480x272/WIDGETS/GaugeRotary/tools.lua b/sdcard/c480x272/WIDGETS/GaugeRotary/tools.lua new file mode 100644 index 00000000..5bc47025 --- /dev/null +++ b/sdcard/c480x272/WIDGETS/GaugeRotary/tools.lua @@ -0,0 +1,76 @@ +local wgt_options_xx = ... + +local self = {} +self.wgt_options_xx = wgt_options_xx +self.tele_src_name = nil +self.tele_src_id = nil + +self.periodic1 = {startTime = getTime(), sampleIntervalMili = sampleIntervalMili} + +-------------------------------------------------------------- +local function log(s) + --return; + print("appValue2: " .. s) +end +-------------------------------------------------------------- + +----------------------------------------------------------------- +local function periodicReset(t) + t.startTime = getTime(); +end + +local function periodicHasPassed(t) + local elapsed = getTime() - t.startTime; + local elapsedMili = elapsed * 10; + if (elapsedMili < t.sampleIntervalMili) then + return false; + end + return true; +end + +local function periodicGetElapsedTime(t) + local elapsed = getTime() - t.startTime; + --log(string.format("elapsed: %d",elapsed)); + local elapsedMili = elapsed * 10; + --log(string.format("elapsedMili: %d",elapsedMili)); + return elapsedMili; +end + +-------------------------------------------------------------------------------------------------------- + +function self.isTelemetryAvailable() + -- select telemetry source + if not self.tele_src_id then + log("select telemetry source") + tele_src = getFieldInfo("RSSI") + if not tele_src then tele_src = getFieldInfo("RxBt") end + if not tele_src then tele_src = getFieldInfo("A1") end + if not tele_src then tele_src = getFieldInfo("A2") end + if not tele_src then tele_src = getFieldInfo("1RSS") end + if not tele_src then tele_src = getFieldInfo("2RSS") end + if not tele_src then tele_src = getFieldInfo("RQly") end + + if tele_src == nil then + log("no telemetry sensor found") + self.tele_src_id = nil + self.tele_src_name = "---" + tele_is_available = false + return + end + end + self.tele_src_id = tele_src.id + self.tele_src_name = tele_src.name + + if self.tele_src_id == nil then + return false + end + + local rx_val = getValue(self.tele_src_id) + if rx_val ~= 0 then + return true + end + return false +end +-------------------------------------------------------------------------------------------------------- + +return self \ No newline at end of file