Hi All,
I've just started working on making my own watchfaces and now working on a DataField. I've almost zero programming knowledge so it has been a hard but fun slog.
So far I've got the DF working nicely including ActivityInfo (DerailleurIndex, Cadence, HR, Speed, Ascent, etc..), SensorHistory (Temp), SystemStats (battery, Notifications, clock) but I can't figure out how to get the BatteryStatus from my ANT+ devices (eTAP and Bontrager lights).
I've spent a fair bit of time reading and testing examples from the Knowledge base, specifically looking at LightNetworkListener without much luck. What I'd like to do is get the BatteryStatus (I understand that if you have a "Pair" i..e eTAP or 2xlights, then the lowest battery will be reported rather than both) and then use the status to plot a battery bar.
My full code is below, (happy for other feedback as well ,it's a good learning experience) if some generous person could help me out.
using Toybox.WatchUi; using Toybox.Activity as Act; using Toybox.Graphics as Gfx; using Toybox.System as Sys; using Toybox.UserProfile; using Toybox.Lang; using Toybox.SensorHistory; using Toybox.AntPlus; //Gear Graphics Constants const x = 90; const y = 20; const barheight = 20; const barwidth = 7; const gap = 8; //Pedal Cadence const CADLow = 55; const CADMid = 76; const CADHigh = 105; //HR Zones if not using UserProfile //const HRZone1 = 143; //const HRZone2 = 157; //const HRZone3 = 164; //const HRZone4 = 174; //const HRZone5 = 205; class RideView extends WatchUi.DataField { var activityInfo; var HR, CAD, SPEED, ASC, DISTANCE, TIMER,timerhr, timermin, timersec, GEARFRONT, GEARREAR, BATTERY; var h, w, h2, w2; var Icons22; var HRZone, HRZone1, HRZone2, HRZone3, HRZone4, HRZone5; var LightBatteryStatus; var eTapBatteryStatus; //Initialise Class Veriables function initialize() { DataField.initialize(); Icons22 = Toybox.WatchUi.loadResource(Rez.Fonts.typicons22); LightBatteryStatus = 1; eTapBatteryStatus = 1; HRZone = UserProfile.getHeartRateZones(UserProfile.getCurrentSport()); } // Set your layout here. Anytime the size of obscurity of // the draw context is changed this will be called. function onLayout(dc) { // Get Screen Dimensions w = dc.getWidth(); h = dc.getHeight(); h2 = h/2; w2 = w/2; // Set the background color dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_BLACK); dc.fillRectangle(0,0,240,240); } // Get the Metrics from the Activity. See Activity.Info in the documentation for available information. function compute(info) { } // Display the value you computed here. This will be called // once a second when the data field is visible. function onUpdate(dc) { activityInfo = Act.getActivityInfo(); dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_TRANSPARENT); if (activityInfo != null && activityInfo.frontDerailleurIndex != null) { GEARFRONT = activityInfo.frontDerailleurIndex;} else {GEARFRONT = 0;} if (activityInfo != null && activityInfo.rearDerailleurIndex != null) { GEARREAR = activityInfo.rearDerailleurIndex;} else {GEARREAR = 0;} // GEARS in X/Y format // dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_TRANSPARENT); // dc.drawText(120, h-65, Gfx.FONT_TINY, GEARFRONT+ " /" +GEARREAR, Gfx.TEXT_JUSTIFY_LEFT); // Front Gear Image dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_TRANSPARENT); dc.drawRectangle(x, y, barwidth, barheight); dc.drawRectangle(x+(1*gap), y-15, barwidth, barheight+15); if (GEARFRONT == 1) {dc.fillRectangle(x,y,barwidth,barheight);} if (GEARFRONT == 2) {dc.fillRectangle(x+(1*gap), y-15, barwidth, barheight+15);} // Rear Gear Image dc.drawRectangle(x+13+(1*gap), y-15, barwidth, barheight+15); dc.drawRectangle(x+13+(2*gap), y-13, barwidth, barheight+13); dc.drawRectangle(x+13+(3*gap), y-11, barwidth, barheight+11); dc.drawRectangle(x+13+(4*gap), y-9, barwidth, barheight+9); dc.drawRectangle(x+13+(5*gap), y-7, barwidth, barheight+7); dc.drawRectangle(x+13+(6*gap), y-5, barwidth, barheight+5); dc.drawRectangle(x+13+(7*gap), y-3, barwidth, barheight+3); dc.drawRectangle(x+13+(8*gap), y-1, barwidth, barheight+1); dc.drawRectangle(x+13+(9*gap), y+1, barwidth, barheight-1); dc.drawRectangle(x+13+(10*gap), y+3, barwidth, barheight-3); dc.drawRectangle(x+13+(11*gap), y+5, barwidth, barheight-5); if (GEARREAR == 1) {dc.fillRectangle(x+13+(1*gap), y-15, barwidth, barheight+15);} else if (GEARREAR == 2) {dc.fillRectangle(x+13+(2*gap), y-13, barwidth, barheight+13);} else if (GEARREAR == 3) {dc.fillRectangle(x+13+(3*gap), y-11, barwidth, barheight+11);} else if (GEARREAR == 4) {dc.fillRectangle(x+13+(4*gap), y-9, barwidth, barheight+9);} else if (GEARREAR == 5) {dc.fillRectangle(x+13+(5*gap), y-7, barwidth, barheight+7);} else if (GEARREAR == 6) {dc.fillRectangle(x+13+(6*gap), y-5, barwidth, barheight+5);} else if (GEARREAR == 7) {dc.fillRectangle(x+13+(7*gap), y-3, barwidth, barheight+3);} else if (GEARREAR == 8) {dc.fillRectangle(x+13+(8*gap), y-1, barwidth, barheight+1);} else if (GEARREAR == 9) {dc.fillRectangle(x+13+(9*gap), y+1, barwidth, barheight-1);} else if (GEARREAR == 10) {dc.fillRectangle(x+13+(10*gap), y+3, barwidth, barheight-3);} else if (GEARREAR == 11) {dc.fillRectangle(x+13+(11*gap), y+5, barwidth, barheight-5);} // Gear Battery Bar dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_TRANSPARENT); dc.drawRectangle(0, 43, 240, 8); // eTapBatteryStatus = Toybox.AntPlus.getBatteryStatus({}); dc.setColor(Gfx.COLOR_GREEN, Gfx.COLOR_TRANSPARENT); if (eTapBatteryStatus == 1) {dc.fillRectangle(0,44, 240, 6);} else if (eTapBatteryStatus == 2) {dc.fillRectangle(0,44, 180, 6);} else if (eTapBatteryStatus == 3) {dc.fillRectangle(0,44, 120, 6);} else if (eTapBatteryStatus == 4) {dc.fillRectangle(0,44, 60, 6);} else if (eTapBatteryStatus == 5) {dc.fillRectangle(0,44, 1, 6);} // Watch Battery Bar var myStats = Sys.getSystemStats(); BATTERY = myStats.battery; dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_TRANSPARENT); dc.drawRectangle(0, 120, 240, 9); dc.setColor(Gfx.COLOR_RED, Gfx.COLOR_TRANSPARENT); dc.fillRectangle(0,121, 240*BATTERY/100, 7); // dc.drawText(162, 200, Gfx.FONT_XTINY, BATTERY.format("%d") + "%", Gfx.TEXT_JUSTIFY_LEFT); // Light Battery Bar // BATT_STATUS_NEW = 1, BATT_STATUS_GOOD = 2, BATT_STATUS_OK = 3, BATT_STATUS_LOW = 4, BATT_STATUS_CRITICAL = 5 dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_TRANSPARENT); dc.drawRectangle(0, 190, 240, 8); // LightBatteryStatus = Toybox.AntPlus.getBatteryStatus({}); dc.setColor(Gfx.COLOR_BLUE, Gfx.COLOR_TRANSPARENT); if (LightBatteryStatus == 1) {dc.fillRectangle(0,191, 240, 6);} else if (LightBatteryStatus == 2) {dc.fillRectangle(0,191, 180, 6);} else if (LightBatteryStatus == 3) {dc.fillRectangle(0,191, 120, 6);} else if (LightBatteryStatus == 4) {dc.fillRectangle(0,191, 60, 6);} else if (LightBatteryStatus == 5) {dc.fillRectangle(0,191, 1, 6);} // Heart Rate if (activityInfo != null && activityInfo.currentHeartRate != null) { HR = activityInfo.currentHeartRate;} else {HR = 0;} dc.drawRectangle(0, 52, 72, 67); if ( HR <= HRZone[1]) {dc.setColor(Gfx.COLOR_LT_GRAY,Gfx.COLOR_TRANSPARENT);} else if ( HR > HRZone[1] && HR <= HRZone[2]) {dc.setColor(Gfx.COLOR_BLUE,Gfx.COLOR_TRANSPARENT);} else if ( HR > HRZone[2] && HR <= HRZone[3]) {dc.setColor(Gfx.COLOR_GREEN,Gfx.COLOR_TRANSPARENT);} else if ( HR > HRZone[3] && HR <= HRZone[4]) {dc.setColor(Gfx.COLOR_ORANGE,Gfx.COLOR_TRANSPARENT);} else if ( HR > HRZone[4]) {dc.setColor(Gfx.COLOR_RED,Gfx.COLOR_TRANSPARENT);} dc.fillRectangle(0,52, 72, 67); dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_TRANSPARENT); dc.drawText(42, 53, Gfx.FONT_XTINY, "HR", Gfx.TEXT_JUSTIFY_RIGHT); dc.drawText(67, 70, Gfx.FONT_NUMBER_MEDIUM, HR, Gfx.TEXT_JUSTIFY_RIGHT); // SPEED if (activityInfo != null && activityInfo.currentSpeed != null) { SPEED = activityInfo.currentSpeed;} else {SPEED = 0;} SPEED = SPEED*3.6; dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_TRANSPARENT); dc.drawText(120, 53, Gfx.FONT_XTINY, "km/h", Gfx.TEXT_JUSTIFY_CENTER); dc.drawText(120, 70, Gfx.FONT_NUMBER_MEDIUM, SPEED.format("%.1f"), Gfx.TEXT_JUSTIFY_CENTER); // Cadence if (activityInfo != null && activityInfo.currentCadence != null) { CAD = activityInfo.currentCadence;} else {CAD = 0;} dc.drawRectangle(168, 52, 240, 67); if ( CAD <= CADMid) {dc.setColor(Gfx.COLOR_YELLOW,Gfx.COLOR_TRANSPARENT);} else if ( CAD > CADMid && CAD <= CADHigh) {dc.setColor(Gfx.COLOR_GREEN,Gfx.COLOR_TRANSPARENT);} else if ( CAD > CADHigh) {dc.setColor(Gfx.COLOR_PURPLE,Gfx.COLOR_TRANSPARENT);} dc.fillRectangle(168, 52, 240, 67); dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_TRANSPARENT); dc.drawText(190, 52, Gfx.FONT_XTINY, "CAD", Gfx.TEXT_JUSTIFY_LEFT); dc.drawText(170, 70, Gfx.FONT_NUMBER_MEDIUM, CAD, Gfx.TEXT_JUSTIFY_LEFT); // ASCENT dc.drawRectangle(80, 129, 2, 61); if (activityInfo != null && activityInfo.totalAscent != null) { ASC = activityInfo.totalAscent;} else {ASC = 0;} dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_TRANSPARENT); dc.drawText(78, 130, Gfx.FONT_NUMBER_MILD, ASC.format("%2d"), Gfx.TEXT_JUSTIFY_RIGHT); dc.drawText(78, 170, Gfx.FONT_XTINY, "Ascent", Gfx.TEXT_JUSTIFY_RIGHT); // DISTANCE if (activityInfo != null && activityInfo.elapsedDistance != null) { DISTANCE = activityInfo.elapsedDistance / 1000;} else {DISTANCE = 0;} dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_TRANSPARENT); if (DISTANCE < 100){ dc.drawText(120, 129, Gfx.FONT_NUMBER_MEDIUM, DISTANCE.format("%.1f"), Gfx.TEXT_JUSTIFY_CENTER);} else { dc.drawText(120, 129, Gfx.FONT_NUMBER_MEDIUM, DISTANCE.format("%2d"), Gfx.TEXT_JUSTIFY_CENTER);} dc.drawText(120, 170, Gfx.FONT_XTINY, "km", Gfx.TEXT_JUSTIFY_CENTER); // TIMER dc.drawRectangle(153, 129, 2, 61); if (activityInfo != null && activityInfo.timerTime != null) { TIMER = activityInfo.timerTime/1000 ; timerhr = TIMER/3600; timermin = (TIMER-(timerhr*3600))/60; timersec = TIMER%60;} else {TIMER = 0;} dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_TRANSPARENT); dc.drawText(160, 130, Gfx.FONT_NUMBER_MILD, timerhr.format("%01d")+":"+timermin.format("%02d"), Gfx.TEXT_JUSTIFY_LEFT); dc.drawText(160, 170, Gfx.FONT_XTINY, "Timer", Gfx.TEXT_JUSTIFY_LEFT); // Notifications var mySettings = Sys.getDeviceSettings(); var flags = ""; if (mySettings.notificationCount > 0) {flags = flags + "l";} dc.setColor(Gfx.COLOR_RED, Gfx.COLOR_TRANSPARENT); dc.drawText(76, 200, Icons22, flags, Gfx.TEXT_JUSTIFY_RIGHT); // Temperature var TempC = Toybox.SensorHistory.getTemperatureHistory({}); dc.setColor(Gfx.COLOR_RED, Gfx.COLOR_TRANSPARENT); dc.drawText(165, 200, Gfx.FONT_XTINY, TempC.next().data.format("%2d")+""+"c", Gfx.TEXT_JUSTIFY_LEFT); // Get and show the current time var clock = Sys.getClockTime(); var timeDisplay = getClockTime (clock); dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_TRANSPARENT); dc.drawText(120, 195, Gfx.FONT_NUMBER_MILD, timeDisplay, Gfx.TEXT_JUSTIFY_CENTER); } // Convert to 12 hour time hidden function getClockTime(clockTime) { var hour, min,ampm, result; hour = clockTime.hour; min = clockTime.min.format("%02d"); ampm = (hour > 11) ? "PM" : "AM"; hour = hour % 12; hour = (hour == 0) ? 12 : hour; hour = hour.format("%2d"); result = Lang.format("$1$:$2$", [hour, min]); return result; } }