Thanks to visit codestin.com
Credit goes to github.com

Skip to content

A Garmin widget that displays data from evcc, an open-source software solution for solar-powered EV charging.

License

Notifications You must be signed in to change notification settings

TheNinth7/evccg

Repository files navigation

evccg

evccg is a Garmin wearable app that displays real-time data from evcc, an open-source platform for solar-optimized EV charging.

You can find the app in the Garmin Connect IQ store:
https://apps.garmin.com/apps/2bc2ba9d-b117-4cdf-8fa7-078c1ac90ab0

The user manual is published via GitHub Pages at:
https://evccg.the-ninth.com


Table of Contents

This README covers the following topics:


Introduction

Built using the Garmin Connect IQ SDK, evccg includes the following application types:

  • Glance: A quick overview of site statistics, available in both full-featured and minimal ("tiny") versions for lower-memory devices.
  • Widget: The main interface, including detail views for multiple sites.
  • Background: Supports HTTP requests for glance functionality on devices with limited memory.

Further reading:


Project Structure

The project is organized into the following directories:

Root Folder /

The root directory contains essential project files.

Key files:

  • README.md: This file
  • manifest.xml: Defines the app's structure, supported devices, and required permissions (e.g., storage, background tasks)
  • monkey.jungle: The build script that determines available features per device. It includes extensive documentation in the file itself.

Further reading:


Folder /.vscode

Contains VS Code customizations.

Key files:

Folder /docs

Contains the user manual, published at https://evccg.the-ninth.com.

Key files:

  • README.md: The user manual itself
  • _config.yml: Theme configuration
  • assets/css/style.css: Custom styles to adapt the theme

Folder /resources-drawables-gen

This folder contains the SVG icon source files and scripts used to generate device-specific PNG icons.

Icons are created in multiple font sizes based on each device's display resolution and are stored in the corresponding resource folders.

At runtime, the app dynamically selects the appropriate font size based on the displayed content.

Key files:

  • generate.json: Defines font/icon sizes per device which icons to generate.
  • drawables*.xml: Garmin resource definition file that associates icon files with resource identifiers used in the source code. Three versions of this file exist, and one is copied—along with the corresponding generated PNGs—into each device-specific resource folder based on the device type.
  • generate.bat: Generates icons.
  • generate.js: JavaScript script, run by generate.bat using Windows Scripting Host

For more information on these files, see To Generate the Device-Specific Icons.


Folders /resources*

In the Connect IQ SDK, resources define:

  • Properties: Parameters stored outside the app, hidden to the user
  • Settings: User-facing configurations
  • Drawables: Image assets used by the app
  • Strings: Text values like app name and version

Folder breakdown:

  • /resources: Shared across all devices
  • /resources-drawables/[devicename]: Drawables specific to individual devices. However, if multiple devices share the same font sizes, they can also share drawables. In such cases, only one folder is created for the shared drawables, typically named after one of the devices. The other devices then reference this folder in monkey.jungle. Similarly, in generate.json, there will be a single entry for the shared drawable set, using the devices property to list all applicable devices.
  • /resources-drawables/[devicename]: Properties specific to individual devices. Optional and currently only used for a few devices.
  • /resources-settings/site1: Settings for devices supporting one site
  • /resources-settings/site5: Settings for devices supporting up to five sites

Further reading:


Folders /source*

The app is written in Monkey C, Garmin's programming language, using the Connect IQ SDK API for UI, settings, persistent storage, and HTTP requests to evcc.

Annotations:

  • (:glance) and (:background) are used to isolate code for those specific modules.
  • Extensive use of exclude annotations helps the build system tailor the code to each device (see the root folder for details).

Key files and directories:

  • /source/app/EvccApp.mc: Entry point for glance, widget, and background modes
  • /source/_base: Shared code
  • /source/background: Background data handling, to support the tiny glance
  • /glance: Glance versions (full-featured and tiny)
  • /widget: Widget app
  • /source-annot-glance: Some classes are required in the glance scope for the full-featured glance but not for the tiny glance. Therefore, their source files must be duplicated—once with the :glance annotation and once without. The source-annot-glance directory contains the master versions of these annotated files, and any modifications to these classes should be made there.
  • /source-annot-tinyglance: This folder contains the duplicated source files mentioned above, with the :glance annotation removed.
  • /source-annot-tinyglance/create-source-files.bat: This script generates the duplicated source files (see here for details).

Further reading:


Build Instructions

Follow the steps below to build, run, and test the app using the Connect IQ SDK and Garmin simulator.

To Run the App in the Garmin Simulator

  1. Install:

    • Visual Studio Code
    • Git
    • Connect IQ SDK
    • Monkey C extension for VS Code
  2. Open VS Code and clone the evcc-garmin repository

  3. Open any file in the /source folder

  4. Press F5 to start the simulator and select a target device

  5. Go to FileEdit Persistent StorageEdit Application.Properties and configure as needed

    • Use https://demo.evcc.io/ for testing if you don’t have a local instance
    • To allow HTTP URLs, uncheck Settings > Use Device HTTPS Requirements

To Compile for a Single Device

  1. Press CTRL+SHIFT+PMonkey C: Build Current Project

To Compile for All Devices and Export .iq File for Upload

The following command generates the .iq file, which is used for uploading the app to the Garmin Connect IQ Store.

  1. Make sure all debug statements are commented out. See Removing Debug Statements for details.
  2. Press CTRL+SHIFT+PMonkey C: Export Project

Modifcations in /source-annot-glance

As explained in Folders /source, the /source-annot-tinyglance folder contains duplicates of the files in /source-annot-glance, but without the :glance annotations. All changes should be made only in /source-annot-glance.

After making changes, run /source-annot-tinyglance/create-source-files.bat to regenerate the tiny glance source files. This script copies the files and removes the :glance annotations. It requires sed for Windows to be installed and added to your PATH environment variable. You can download it from here.

Alternatively, you can use the custom VS Code task defined in the project. Press CTRL+SHIFT+B and choose evccg: Generate Source for Tiny Glance to run the batch file from the integrated terminal.


To Add a New Device

To support a new device:

  1. If the device isn't available in your current SDK, launch the SDK Manager and download/activate the latest version.

  2. In manifest.xml, check the new device in the supported device list.

  3. Configure device-specific features in the monkey.jungle build file (see Root Folder /). You need to at least add an entry for the resourcePath. For sourcePath and excludeAnnotations, the default is a good starting point. You can launch the app in the simulator to evaluate whether any adjustments are needed. For example:

    • If the app reports that vector fonts are not supported, switch to static fonts—or to static optimized fonts if standard sizes overlap.
    • If out-of-memory errors occur during testing, consider switching to the tiny glance, limiting support to a single site, and removing the system info view.
    • If watchdog errors occur (indicating that execution is taking too long), switch from complex to simple calculations.
    • If the select/enter button is not in the standard 30° position, switch to the appropriate option.
  4. Generate the icons for the new device following the steps described in How to Generate Icons for a New Device.

  5. Test in the simulator (see above)

  6. Export the project (CTRL+SHIFT+PMonkey C: Export Project) and upload the .iq file to the Connect IQ Store


To Generate the Device-Specific Icons

All icons are stored in SVG format in the icons folder. From these, device-specific PNGs are generated at multiple font sizes, tailored to each device's display resolution. The resulting PNGs are stored in the appropriate resource folders.

At runtime, the app dynamically selects the appropriate icon size based on the displayed content. Font sizes per device are defined in /icons/generate.json.

Each icon also requires entries in /icons/drawables.xml for every size it will be used at.

The following sections explain how font sizes are selected, how to add support for a new device, how to add new icons, and how to generate the PNGs.

How the App Selects Font Sizes

For glances, a single font size is defined in generate.json under each device entry:

  • icon_glance → always equaling FONT_GLANCE as defined by Garmin for the device

For the widget, five icon/font sizes are defined per device in generate.json:

  • icon_medium
  • icon_small
  • icon_tiny
  • icon_xtiny
  • icon_micro

Note: These entries do not set the font sizes themselves. Instead, they must match the font sizes the app selects at runtime, based on one of the three methods below:

1. Vector Font Mode (Modern Devices)

Modern devices support scalable vector fonts, allowing the app to evenly distribute font sizes as needed.

  • The app calculates icon_medium based on the standard FONT_MEDIUM and screen resolution.
  • icon_micro is derived from FONT_XTINY and, if necessary, adjusted to maintain a proportional relationship to FONT_MEDIUM.
  • The remaining font sizes (small, tiny, xtiny) are evenly distributed between medium and micro.

You can enable debugging in EvccUILibWidgetSingleton to print the actual font sizes used at runtime.

2. Static Mode

In static mode, the app uses the device’s built-in font sizes without modification. You can refer to Garmin’s Device Reference for exact font dimensions per device.

The mapping is as follows:

  • icon_mediumFONT_MEDIUM
  • icon_smallFONT_SMALL
  • icon_tinyFONT_TINY
  • icon_xtinyFONT_GLANCE
  • icon_microFONT_XTINY

3. Static Optimized Mode

In this mode, the app still relies on the device's standard fonts, but improves distribution by filtering out duplicate sizes, resulting in a more balanced range.

You can enable debugging in EvccUILibWidgetSingleton to print the actual font sizes used at runtime.

Example: If FONT_SMALL and FONT_TINY are the same size, the app might assign:

  • icon_mediumFONT_MEDIUM
  • icon_smallFONT_SMALL
  • icon_tinyFONT_GLANCE
  • icon_xtinyFONT_XTINY
  • icon_microFONT_XTINY

Generating Icons for a New Device

To determine the actual font sizes used by the app, follow these steps:

  1. Add an entry to generate.json for the target device. You can use placeholder values for the icon sizes—copying from a similar existing device works fine. This step is only required to get the app running so you can retrieve the font sizes.

  2. Generate the icons by running:

    generate.bat [device-family]

    Replace [device-family] with the name of the entry you just added to generate.json.

  3. Ensure you added the device-specific resourcePath in monkey.jungle, with the device-specific drawable path (see above).

  4. Run the app in the simulator, open the widget, and press the m key twice to open the system info view. The app will print the actual font sizes to the debug console.

  5. Update the generate.json entry with the correct font sizes based on the output.

  6. Re-generate the icons with the updated sizes:

    generate.bat [device-family]

Example entries:

"fenix6":{
    "fontMode":"static",
    "deviceType":"noglance-lowmemory",
    "logo_flash":"40",
    "logo_evcc":"13",
    "icon_micro":"19",
    "icon_xtiny":"22",
    "icon_tiny":"29",
    "icon_small":"32",
    "icon_medium":"37"
},
"fenix847mm": {
  "fontMode": "vector",
  "logo_flash": "65",
  "logo_evcc": "26",
  "icon_glance": "42",
  "icon_micro": "33",
  "icon_xtiny": "40",
  "icon_tiny": "46",
  "icon_small": "53",
  "icon_medium": "59"
}

Explanation of fields:

  • icon_*: These values correspond to the font sizes selected by the app, based on the method described above.
  • logo_flash: Must match the Launcher Icon Size as listed in Garmin’s Device Reference.
  • logo_evcc: The logo shown at the bottom of the screen. Typically set to 65% of icon_xtiny.
  • deviceType: Enables special handling for older devices that either do not support glances or use the tiny glance. Can be omitted for newer models. See the section on drawables*.xml for more details.
  • fontMode: A comment indicating the font sizing mode used by the app for this device (e.g., "vector", "static", or "static-optimized").
  • devices: A comment listing the devices this entry applies to.

Adding, Removing, or Modifying Icons

To add, remove, or change icons, you'll need to update the following files in the /icons directory:

1. generate.json

This file serves as input for the PNG generation script.

  • The device-families entry, covered in the previous section, defines available icon sizes for each device family.

  • The files section specifies how each SVG should be processed and which sizes to generate. Each entry includes:

    • anti-aliasing: Level of anti-aliasing applied by Inkscape (range: 0 = none, 3 = max).
    • types: An array of size identifiers (e.g., icon_medium) that match entries in device-families. PNGs will be generated for each type listed.
    • png-name (optional): For entries with only one type, this overrides the default PNG filename.

    Example:

    "files": {
      "battery_empty.svg": { 
        "anti-aliasing": "3", 
        "types": ["icon_glance", "icon_xtiny", "icon_tiny", "icon_small", "icon_medium"] 
      },
      "sun.svg": { 
        "anti-aliasing": "3", 
        "types": ["icon_xtiny", "icon_tiny", "icon_small", "icon_medium"] 
      },
      "evcc.svg": { 
        "anti-aliasing": "3", 
        "types": ["logo_evcc"], 
        "png-name": "logo_evcc.png" 
      }
    }

In this example:

  • battery_empty.svg will be generated in multiple sizes for various UI contexts.
  • sun.svg is limited to widget-specific sizes.
  • evcc.svg is generated in a single size with a custom filename.

Default PNG naming convention:

<type>_<name>.png

Where:

  • <type> = icon size (e.g., icon_medium)
  • <name> = original SVG filename (without extension)

For example, the output PNGs for sun.svg would include:
icon_xtiny_sun.png, icon_small_sun.png, etc.


2. drawables*.xml

Defines resources for use in the app via the Connect IQ SDK.

There are three versions of this file:

  • drawables.xml: The default version, containing all icons and using the full color palette available on the device.
  • drawables-noglance-lowmemory.xml: A version for devices without glances and with limited memory. Glance icons are omitted, and all other icons are compiled with a reduced color palette and no transparency to conserve memory.
  • drawables-tinyglance.xml: A version for tiny glance devices. Only the icons used in the tiny glance are included, with a reduced color palette and no transparency.

Each icon must have an entry for every size it's used in, and in all applicable versions of the drawables file.
For example, the medium-sized sun.svg icon would be defined in both drawables.xml and drawables-tinyglance.xml like this:

<bitmap scope="foreground" id="sun_medium" filename="icon_medium_sun_crushed.png" packingFormat="png"/>
  • scope="foreground" indicates the icon is only available in widget contexts.

In drawables-noglance-lowmemory.xml, the same icon would appear as:

<bitmap scope="foreground" id="sun_medium" filename="icon_medium_sun.png">
    <palette disableTransparency="true">
        <color>FFFFFF</color>
        <color>AAAAAA</color>
        <color>555555</color>
        <color>000000</color>    
    </palette>
</bitmap>
  • The <palette> tag limits the icon to four grayscale colors: white, light gray, dark gray, and black.
  • disableTransparency="true" disables transparency, which would otherwise occupy a separate color slot. In this case, transparency is replaced with black—already part of the palette—so no extra color is needed.

Further reading:


3. /source/_base/EvccResourceSet.mc

This file contains Monkey C classes that define resource sets used in the app. Each resource set defines font sizes to be used and maps them to the corresponding PNG resources.

  • EvccWidgetResourceSetBase: Defines resources for widgets
  • EvccGlanceResourceSetBase: Defines resources for glances

These mappings act as the bridge between the resource definitions in drawables.xml and the font sizes used in the Monkey C code.


Generating the Device-Specific PNG Files

Whenever you make changes to /icons/generate.json, any of the /icons/drawables*.xml, or any of the SVG files, you need to run generate.bat to regenerate the device-specific PNG icons and copy drawables.xml into each device’s resource folder.

Based on the deviceType specified in generate.json, the script selects the appropriate drawables*.xml version and generates certain icons without transparency.

You can run generate.bat with the following parameters:

  • No parameters: Generates icons for all devices.
  • Device folder (e.g. resources-fenix7): Generates icons only for that specific device.
  • drawables.xml: Copies drawables.xml to all device resource folders without generating icons.

Alternatively, you can use the custom VS Code task defined in the project. Press CTRL+SHIFT+B and choose one of the following tasks to run the batch file from the integrated terminal.

  • evccg: Generate Icons for All Devices: Generates icons for all devices.
  • evccg: Copy drawables.xml for All Devices: Copies drawables.xml to all device resource folders without generating icons.
  • evccg: Generate Icons for <device name>: Generates icons only for that specific device. Note: not available for all devices.

Dependencies

The script relies on the following third-party tools:

  • Inkscape – Converts SVG files to PNG. It must be available in your system’s PATH.
  • pngcrush.exe – Optimizes PNG files. This tool is included in the project directory and requires no installation.

Exception Messages

To conserve memory, short codes are used for exception messages that result from programming errors (as opposed to user-related issues such as misconfiguration).

Shortcode Class Description
CENTANGINV EvccPageIndicator setCenterAngle: is not a valid value
DOTANGINV EvccPageIndicator setDotDistanceAngle: is not a valid value
FFNTFND EvccResourceSets Font faces not found
JUSTCENTONL EvccHorizontalBlock Vertical block supports only justify center
JUSTNOTSUP EvccHorizontalBlock Horizontal block does not support justification for elements
MTHDUN EvccPreRenderContentTask Unknown method
NODC EvccBlock :dc not set
NOFONT EvccBlock :font not set
NOICFOR EvccIconBlock Icon not found for font
NOREZID EvccBitmapBlock ResourceId is missing
ORBITDEG EvccPageIndicator orbitXY: is not a valid value
VECNOTSUP EvccResourceSets Device does not support vector fonts

Supported Devices

A table listing supported devices and their features is available in the user manual.

Below is an additional reference for developers, showing the Connect IQ (CIQ) API level supported by each device.

Device CIQ API Level
fenix6 3.4.0
fenix6s 3.4.0
fenix6pro 3.4.0
fenix6spro 3.4.0
fenix6xpro 3.4.0
fenix7 5.1.0
fenix7s 5.1.0
fenix7x 5.1.0
epix2pro42mm 5.1.0
epix2pro47mm 5.1.0
epix2pro51mm 5.1.0
fenix7pro 5.1.0
fenix7pronowifi 5.1.0
fenix7spro 5.1.0
fenix7xpro 5.1.0
fenix7xpronowifi 5.1.0
fenix843mm 5.1.0
fenix847mm 5.1.0
fenix8solar47mm 5.1.0
fenix8solar51mm 5.1.0
fr745 3.3.0
fr945 3.3.0
fr945lte 3.4.0
fr955 5.1.0
fr165 5.1.0
fr165m 5.1.0
fr265 5.1.0
fr265s 5.1.0
fr965 5.1.0
venu2 5.0.0
venu2plus 5.0.0
venu2s 5.0.0
venu3 5.1.0
venu3s 5.1.0
vivoactive3 3.1.0
vivoactive3m 3.2.0
vivoactive3mlte 3.1.0
vivoactive4 3.3.0
vivoactive4s 3.3.0
vivoactive5 5.1.0
vivoactive6 5.1.0

Further reading


Helpful Tips and Notes

A collection of useful information for working on this project.

Removing Debug Statements

While debug statements are only printed in debug builds, they still occupy code space in release builds. Therefore, when building a release, all debug statements should be commented out.

To find all active debug statements in VS Code, press CTRL+SHIFT+H to open the global search and replace panel. Enable regular expressions by clicking the .* icon next to the search field, and use the following pattern to locate all active debug statements:

(?<!\/\/ )EvccHelperBase\.debug\(

To deactivate the debug statements, replace them with:

// EvccHelperBase.debug(

This will comment them out without affecting any lines that are already commented.

About

A Garmin widget that displays data from evcc, an open-source software solution for solar-powered EV charging.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •