makeWebRequest and error -403

So, this program I'm working on is now starting to give makeWebRequest error -403 when running from Glance on a watch with 32 KB of background space.

However, as can be seen from this screenshot, only about 50% of the space is being used. Sure, makeWebRequest is returning a big chunk of data (6901 bytes here) but I'm reading it as plain text so I don't get why I'm running out of data.

The data returned is in JSON format but I read it in plain text and extracting what I need manually (3 fields out of almost 300). It was returning a code of 200 until I added these two simple functions, worth of 30 lines of code and somehow, it was enough to bring it over the limit, but again, only half of the space is used.

Is this normal? Something I can do? It would suck to limit watches with 64 KB of background space because I've reached a limit on the 32 KB watches, and it would suck to drop these users and also maintain two code base.

Thanks.

  • Where in your code are you getting the exception?  It could be in your background service or in your glance view.

    When you see 32k for a background service, what your app has is 28k, You can see this in the bottom line of the sim.

    Also when showing a glance, it's not 32k(well 28k) for the backgound (:background annotation) and the same for the glance (:glance annotation)

    it's a total of 32k/28k for both.

  • Hi Jim,

    It's a makeWebRequest called made from onTemporalEvent, so a background process. Peak memory above shows 18.8 KB, which leaves 9.2 KB for data and such. My makeWebRequest response was 6.7 KB so technically it shouldn't have ran out, especially since I'm not even converting the data received into a Dictionary.

  • Hi again,

    Down to almost its basic format, I still get error -403. I fail to see how this code can take all that space:

    PS. Sorry for the inline pasting, I tried to insert it as code, but I get a 'You have been blocked" when I try to insert the code :-O I stripped the code of all its comments to better show its limited space.

    (:background)
    class TeslaLink extends App.AppBase {
        function initialize() {
            AppBase.initialize();
        }

        (:can_glance)
        function getServiceDelegate(){
            return [ new MyServiceDelegate() ];
        }

        (:can_glance)
        function onBackgroundData(data) {
            if (data != null) {
                var status = data["status"];
                if (status != null) {
                    Application.getApp().setProperty("status", status);
                }
            }

            Background.registerForTemporalEvent(new Time.Duration(300));

            Ui.requestUpdate();
        }  

        (:glance, :can_glance)
        function getGlanceView() {
            Background.registerForTemporalEvent(new Time.Duration(60*5));
            return [ new GlanceView() ];
        }

        function getInitialView() {
            if (!System.getDeviceSettings().phoneConnected) {
                return [ new OfflineView() ];
            }

            var data = new TeslaData();
            var view = new MainView(data);
            return [ view, new MainDelegate(view, data, view.method(:onReceive)) ];
        }
    }

    (:glance, :can_glance)
    class GlanceView extends Ui.GlanceView {
      function initialize() {
        GlanceView.initialize();
      }

      function onUpdate(dc) {
        var vehicle_name = Application.getApp().getProperty("vehicle_name");
        var status = Application.getApp().getProperty("status");
        vehicle_name = (vehicle_name == null) ? Ui.loadResource(Rez.Strings.vehicle) : vehicle_name;
        status = (status == null) ? Ui.loadResource(Rez.Strings.label_waiting_data) : status;

        dc.setColor(Gfx.COLOR_WHITE, Graphics.COLOR_TRANSPARENT);
        dc.drawText(
          0,
          (dc.getHeight() / 8) * 2,
          Graphics.FONT_TINY,
          vehicle_name.toUpper(),
          Graphics.TEXT_JUSTIFY_LEFT | Graphics.TEXT_JUSTIFY_VCENTER
        );

        dc.drawText(
          0,
          (dc.getHeight() / 8) * 6,
          Graphics.FONT_TINY,
          status,
          Graphics.TEXT_JUSTIFY_LEFT | Graphics.TEXT_JUSTIFY_VCENTER
        );
      }
    }

    (:background, :can_glance)
    class MyServiceDelegate extends System.ServiceDelegate {

        function initialize() {
            System.ServiceDelegate.initialize();
        }

        function onTemporalEvent() {
            if (App.getApp().getProperty("token") != null && App.getApp().getProperty("vehicle") != null)
            {
                Communications.makeWebRequest(
                    "https://" + App.getApp().getProperty("serverAPILocation") + "/api/1/vehicles/" + App.getApp().getProperty("vehicle").toString() + "/vehicle_data", null,
                    {
                        :method => Communications.HTTP_REQUEST_METHOD_GET,
                        :headers => {
                            "Authorization" => "Bearer " + App.getApp().getProperty("token"),
                            "User-Agent" => "Tesla-Link for Garmin"
                        },
                        :responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN
                    },
                    method(:onReceiveVehicleData)
                );
            }
        }

        function onReceiveVehicleData(responseCode, responseData) {
            var data = Background.getBackgroundData();
            if (data == null) {
                data = {};
            }

            if (responseCode == 200 && responseData != null) {
                var pos = responseData.find("battery_level");
                var str = responseData.substring(pos + 15, pos + 20);
                var posEnd = str.find(",");
                var battery_level = str.substring(0, posEnd);

                pos = responseData.find("battery_range");
                str = responseData.substring(pos + 15, pos + 22);
                posEnd = str.find(",");
                var battery_range = str.substring(0, posEnd);

                pos = responseData.find("charging_state");
                str = responseData.substring(pos + 17, pos + 37);
                posEnd = str.find("\"");
                var charging_state = str.substring(0, posEnd);

                data.put("status", battery_level + "%" + (charging_state.equals("Charging") ? "+" : "") + " / " + battery_range.toNumber());
            } else if (responseCode == 401) {
                data.put("status", Application.loadResource(Rez.Strings.label_launch_widget));
            } else if (responseCode == 408) {
                data.put("status", Application.loadResource(Rez.Strings.label_asleep));
            }
            Background.exit(data);
        }
    }

  • So, I dropped the whole project to just these functions and I've emptied them to almost all their code, that's what is left:

    (:background)
    class TeslaLink extends App.AppBase {
        function initialize() {
            AppBase.initialize();
        }

        (:can_glance)
        function getServiceDelegate(){
            return [ new MyServiceDelegate() ];
        }

        (:can_glance)
        function onBackgroundData(data) {
        }  

        (:glance, :can_glance)
        function getGlanceView() {
            return [ new GlanceView() ];
        }

        function getInitialView() {
        }
    }

    (:glance, :can_glance)
    class GlanceView extends Ui.GlanceView {
        
      function initialize() {
        GlanceView.initialize();
      }

      function onUpdate(dc) {
      }
    }

    (:background, :can_glance)
    class MyServiceDelegate extends System.ServiceDelegate {

        function initialize() {
            System.ServiceDelegate.initialize();
        }

        function onTemporalEvent() {
        }
    }

    The only strings defined with glance or background are these five.

        <string id="vehicle" scope="glance">vehicle</string>
        <string id="label_asleep" scope="background">Asleep</string>
        <string id="label_status_unknown" scope="glance">Status unknown</string>
        <string id="label_launch_widget" scope="background">Launch widget</string>
        <string id="label_waiting_data" scope="background">Waiting for data</string>

    And yet, the memory footprint of the app is still 17,6 KB at its peek and 11.6 KB while basically doing nothing.

    Is this normal?

  • 10KB of that space turns out to be space taken by settings.xml. Most of that stuff is irrelevant to the glance code, is there a way to prune it for glance/background?

  • Sucks that you can do it for strings but not resources.

    I guess I'll try the 'Crystal way'

    I'll create resources directory for the watches I still support with just 32KB of background space with glance (most are the marq* one).

    resources-descentmk2
    resources-descentmk2s
    resources-fenix6pro
    resources-fenix6spro
    resources-fenix6xpro
    resources-marqadventurer
    resources-marqathlete
    resources-marqaviator
    resources-marqcaptain
    resources-marqgolfer
    resources-marqcommander
    resources-marqdriver
    resources-marqexpedition

    and put a different settings.xml and properties.xml file in there to reduce the size of space taken by it.

  • Well that's a bust, if the properties aren't the the watch specific resource file, it grabs them from the default one. I would need to put the 16 entries in the default one but that would mean all watches not limited to 32KB of background space (including all watches without Glance) would need its own resource directory. I think I'll change tactic and put a field where the user will enter in a coma separated way the order they want the items to appear in the menu. Will take way less space.