Blinkup with impOS 42: how to reproduce old behaviour with cm?

For a few days, I can’t blinkup my imp004 devices when I start them. Then I found this:

From impOS 42 and up, there will no longer be any period for which BlinkUp will always remain active after the code imp.enableblinkup(false); has run, even if the host imp is still in the BOOTING phase

Am I the only one who find this change extremly dangerous, with a high risk to brick a device? The only solution I found is to clear the device settings at the exact second it starts. Then I have several seconds to configure it with my WiFi credentials.

For the devices that are online, I must provide a patch to quickly fix them, calling imp.enableblinkup() with I dont know what: true or false? at startup of after 60 seconds ?

Here are my needs:

  • I want to be able to blink up in the 1st 60 seconds
  • In my code, I don’t call imp.enableblinkup() so far, but I use the ConnectionManager lib that implicitly deals with it
  • I often call cm.connect() and cm.disconnect() to reduce power, and I don’t want the LED to blink at connection or disconnection. So I guess none of the “blinkupBehavior” from that lib would match my needs.

I guess I would need to open a ticket in the ConnectionManager github to ask for a “NoBlinkUpBehaviour”, but what should I manually do with the imp.enableblinkup to get back to the previous behaviour?

Thanks for your advice :slight_smile:

This is a really good point. We’ll look into this, and I’ll be updating the release notes to make this change more clear.

From a cold boot there is always a very brief period in which a device can be configured with BlinkUp. If the device has bad credentials, the initial connection attempt will timeout, Squirrel will start after 10s and application code will stop further BlinkUps. What I don’t yet know — I’ll find out — is if a BlinkUp operation initiated within that 10s period will continue even after Squirrel disables BlinkUp.

If the device has good credentials, BlinkUp will be disabled as before, but you can at least send it updated code that, for example, sets a timer after which BlinkUp is disabled:

imp.wakeup(30, function() {
    imp.enableblinkup(false);
});

Put it at the top of your code, right after your #requires. That should (working off the top of my head) give you at least 30s (or whatever you prefer) to do a BlinkUp in future. Set CM to use the default BlinkUp behavior in the meantime.

Thanks, that is what I had in mind.

I also made a change in the Content Manager lib, because anyone who uses that lib with the “CM_BLINK_NEVER” behaviour will not have the 10s you are talking about.

From my tests, the only way to blink up a device in this situation is:

  • First you clear previous settings. But power on your device when the 3-2-1 count down on your phone reaches 1, not before!!
  • Then you can do the blink up, you also have to be quick (maybe 10s after the boot)

Not great if you have to send these instructions to a real user…

As long as a blinkup starts within the first 10s when the squirrel has not been started, the OS (should) let the blinkup complete before running the squirrel - which in your case would turn off blinkup. I believe this is part of our system testing, and I’ve never run into a time when it didn’t work personally. Do you not see this happen with your device?

The period is the shorter of 10s or a successful connection to the server validating that the code being run is the latest version. So, if wifi credentials are stale then it’ll be 10s, but if credentials are valid then there’s no issue here as you can deploy a fixed squirrel build OTA.

The one way to really brick a device is to configure a rescue pin (which defeats the cold boot 10s timeout), but not actually put a rescue switch in your design to trigger the rescue functionality. Configuring rescue pins is a feature only available to commercial customers to try and limit the blast radius of dangerous APIs :slight_smile:

1 Like

Verified that this is in our system tests; the test follows this flow:

First we prepare the imp, with this code:

    signalPin <- hardware.pinX;
    signalPin.configure(DIGITAL_OUT, 0);
    imp.clearconfiguration();
    server.disconnect();
    signalPin.write(1);
    imp.enableblinkup(false);
    imp.sleep(0.2);
    imp.onidle(function() {
        imp.deepsleepfor(1);
    });

As you can see, the code clears wifi credentials, disconnects, and goes to deep sleep (which will prevent any blinkup from happening as the imp is asleep). We verify that this code has run by checking pinX is high (briefly, before the imp sleeps).

From this point onwards, a power cycle will show 10s of LED blinking, then the squirrel will run - clearing config, disconnecting and entering deep sleep. If blinkups started within 10s of cold boot didn’t work, then this would be an unrecoverable state.

So, we test recovery: we power cycle the imp - to give a cold boot - and start a blinkup with valid wifi credentials and new squirrel queued, within the 10s window. Here’s the new squirrel we send from the server side:

server.log("Rescued");

As the blinkup process takes longer than 10s to complete, and we verify that the new code has been picked up by the device by checking for the server.log output, this proves that the rescue procedure works.

You do need to cold power cycle and start a blinkup with valid wifi credentials within the first 10s though.

Thanks for your answer.

The initial issue was on a remote device that we can’t have blinked-up (by our tester overthere). So we tried to reproduce it at the office.

Most of my tests were on such device: we wanted to change its wifi settings, with no success. So I guess that is what you describe: the device connects and checks for any update, instantly disconnect (I can’t even see a log) and disable blinkup. I just have a fraction of second to interract with my phone (< 10s) but I am still able to update its firmware with all your safety. I hope to think there is no way to brick it :slight_smile:

Anyway, on my side:

  • I still need to update my code (and ConnectionManager) to enable blinkup during the 1st 60s (changing a working Wifi to another working Wifi is a common use-case I still want to support)
  • I’ll confirm if the “remote” device’s issue, which can’t connect at all, has nothing to do with this current ticket. When I get it back here.

Thanks!

Yes, if the credentials are valid and a secure connection to the server can be established then - without a cold power cycle - the only way to change credentials would be OTA (using eg imp.setwifi…).

You can use the default setting of CM_BLINK_ON_DISCONNECT which means that blinkup will be enabled only when the device cannot get connected - makes it easy to blinkup when you do need to provide new credentials due to the wireless environment changing.