OTA firmware update with external MQTT broker
-
@imedia
Seem you are on the right track. If you make a simple wiki document for newbie after you success, it will be huge help for the community.
English is my second language so it will take long time for me and afraid not crystal clear for everyone^^; -
I would be more than happy to do the writing, I am quite new to the platform however so I'm still discovering the system myself as you can see...
With your help I can write the documentation once I understand what exactly it is I'm documenting. I see @jkandasa has already an outline created on GIT hub, we just need to add moer specifics to that. Hotlinking to support right in the application will also be a huge help to users.
-
@imedia Have you checked user manual? Which is available on http://www.mycontroller.org/files/docs/0.0.3.Alpha2.pdf for the last released version. I hope this manual will help you to understand more on configuration.
How node gets new firmware from Controller?
Once you installed and turned on brand new node, following actions done.
- Requests node id from controller, Controller gives next available node for the new node. Node id will be stores on eeprom, So this is permanent node id for this node(Until we trigger
Erase configuration
from controller). - By default brand new node has type id as
65535
and version id as65535
. node sends this information to MyController. - If you have enabled and configured, Support default firmware on MyController, default firmware will be sent to node. Otherwise controller will not respond for the firmware request, as controller does not know which firmware have to send.
- Once node appeared on nodes list. You have to select your firmware for that node and trigger reboot.
- Now your node will request with
65535
as version id and type id. However controller has different type id and version id for this node. Controller will send configured firmware type id and version id. Now node takes the controller configuration and requests firmware for that configuration. - New firmware will be loaded on your node.(Which is configured on controller's node page)
Hope this will help you to understand more depth about firmware update on node.
- Requests node id from controller, Controller gives next available node for the new node. Node id will be stores on eeprom, So this is permanent node id for this node(Until we trigger
-
Great, thanks again @jkandasa!
I tried this and got it to work, however, some clarification is still needed as my results are inconsistent.
First thing I noticed is, when the .hex file is generated by the Arduino IDE two .hex files are created:
-
SketchName.ino.hex
-
SketchName.ino.with_bootloader.hex
Which one should be uploaded to the MyController Firmware section? Does it matter?
Next, a little more clarification on the update process...
Once a new version of the firmware is uploaded into MyController, how do we push that out to the node?
I know there is an option to select the node and then from the Actions Menu choose "Upload firmware". Does that initiate the upload immediately and refresh refresh the node or must a "Reboot" be selected after pushing "Upload firmware"?
If a reboot is needed, can it be done immediately after choosing "Upload firmware"? If not how long should we wait before clicking "Reboot"?
I'm able to get the updates out eventually but that is just because I keep clicking reboot and upload, and even resetting the node manually. That seems like a poor way to achieve what I am doing. There must be a certain order to doing this with consistent results. I would like to know what part of what I am doing is actually necessary and what is not.
Can you please provide a step by step guide.
Also, is there any way we could monitor the Firmware Upload progress in MyController? That would be very helpful. Should I add that feature request to GitHub?
-
-
@imedia First I would explain supported boot-loaders. For now AFAIK MySensors supports two type of boot-loaders,
MYSBootloader:
This boot-loader does not required any external memory. This boot-loader occupies approx 2K of memory on chip. It is isolated completely from actual program. When you reboot your node(Arduino board with MYSBootloader) It sends current available version of Users firmware to controller. Controller checks locally and respond with what firmware node should have. If node do not see any different on controller response. Boot-loader changes control to users program. Now boot-loader goes away from actions, all the control goes to users program. Boot-loader gets control only on next reboot of node.
DualOptiboot:
This boot-loader comes along with users program. This boot-loader needs external memory. This boot-loader never request firmware configuration from controller. If controller sends firmware configuration, it reads local configuration and if the received one is different receives the firmware from controller and stores on external memory. Once it receives all the firmware bytes successfully. Reboots the node, on reboot node checks external memory with some flag. If there is a flag enabled, copies firmware from external memory to actual program memory space and starts with new firmware.
This is how both boot-loader works.
- When we use
MYSBootloader
, we need to reboot the node to update new firmware. - When we use
DualOptiboot
, we need to clickUpdate firmware
for the node.
You have to use always use the firmware without boot-loader (SketchName.ino.hex). I hope now you I have cleared your confusions.
- When we use
-
Thank you for your explain. I didn't know how DualOptiboot works.
However if your node is battery powered and has sleep mode, it may work differently.
Mysensors 2.0.0 library has smartSleep() when it wake up, wait 500ms to get command from controller. (You can change wait time from config)
You can place reboot command when node send heartbeat.
I use node-Red to send reboot command because MyController current official version doesn't support this.I'm not sure how firmware update function work battery powered node with DualOptiboot.
-
@yd in SNAPSHOT version we have smartSleep support. If you issue reboot, command will be on queue. When it receives heartbeat from node, sends queued commands to that node.
-
@jkandasa Is there any easy update Snapshot version. Just overwrite all files?
-
@yd SNAPSHOT build is available here with upgrade instruction.
-
I loaded your latest snapshot, I am not getting the following error, OTA firmware update no longer seems to work either.
ERROR [Thread-5] [org.mycontroller.standalone.message.MessageMonitorThread:123] Throws exception while processing!, [RawMessage(gatewayId=1, data=1;255;4;0;2;010001007E04, subData=null, isTxMessage=false, networkType=MY_SENSORS, timestamp=1478706446658)]
java.lang.IndexOutOfBoundsException: Index: 18400, Size: 1024
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.get(ArrayList.java:429)
at org.mycontroller.standalone.message.McMessageEngine.procressFirmwareRequestMySensors(McMessageEngine.java:552)
at org.mycontroller.standalone.message.McMessageEngine.streamSubMessageTypeSelector(McMessageEngine.java:489)
at org.mycontroller.standalone.message.McMessageEngine.execute(McMessageEngine.java:136)
at org.mycontroller.standalone.message.McMessageEngine.run(McMessageEngine.java:1148)
at org.mycontroller.standalone.message.McMessageUtils.sendToMcMessageEngine(McMessageUtils.java:616)
at org.mycontroller.standalone.provider.mysensors.MySensorsProviderBridge.executeRawMessage(MySensorsProviderBridge.java:58)
at org.mycontroller.standalone.message.McMessageUtils.sendToProviderBridge(McMessageUtils.java:562)
at org.mycontroller.standalone.message.MessageMonitorThread.processRawMessage(MessageMonitorThread.java:112)
at org.mycontroller.standalone.message.MessageMonitorThread.run(MessageMonitorThread.java:191)
at java.lang.Thread.run(Thread.java:745)
2016-11-09 10:47:30,960 ERROR [Thread-5] [org.mycontroller.standalone.message.MessageMonitorThread:123] Throws exception while processing!, [RawMessage(gatewayId=1, data=1;255;4;0;2;010001007E04, subData=null, isTxMessage=false, networkType=MY_SENSORS, timestamp=1478706450936)]
java.lang.IndexOutOfBoundsException: Index: 18400, Size: 1024
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.get(ArrayList.java:429)
at org.mycontroller.standalone.message.McMessageEngine.procressFirmwareRequestMySensors(McMessageEngine.java:552)
at org.mycontroller.standalone.message.McMessageEngine.streamSubMessageTypeSelector(McMessageEngine.java:489)
at org.mycontroller.standalone.message.McMessageEngine.execute(McMessageEngine.java:136)
at org.mycontroller.standalone.message.McMessageEngine.run(McMessageEngine.java:1148)
at org.mycontroller.standalone.message.McMessageUtils.sendToMcMessageEngine(McMessageUtils.java:616)
at org.mycontroller.standalone.provider.mysensors.MySensorsProviderBridge.executeRawMessage(MySensorsProviderBridge.java:58)
at org.mycontroller.standalone.message.McMessageUtils.sendToProviderBridge(McMessageUtils.java:562)
at org.mycontroller.standalone.message.MessageMonitorThread.processRawMessage(MessageMonitorThread.java:112)
at org.mycontroller.standalone.message.MessageMonitorThread.run(MessageMonitorThread.java:191)
at java.lang.Thread.run(Thread.java:745) -
@imedia Thanks to report this. Let me have a look.
-
@imedia I do not see error on my side, Could please post screenshot of firmware page, As shown here,
-
Not sure what is up, I rebooted flashed the bootloader again on the node and deleted re-added the node and now it works. Also not getting the error either.
-
I've been testing more... It seems that in order for the new firmware to be loaded to the node and then show as running in MyController the node needs a hard reset (pull power and restore). Issuing reboots from the controller does not seem to work.
I've yet to figure out what combination of things is actually triggering the update though. I just keep trying different things and eventually it works. But consistently the new firmware version will not be shown in MyController until a hard reset on the node is completed.
I'm using 5v 16Mhz Pro Mini.
I've also noticed that once the firmware version has been put on a node I can't re-send the same version, I need to increment the versions everywhere. Is this correct or should I be able to re-flash with the same firmware version by issuing the command?
-
@imedia said:
Issuing reboots from the controller does not seem to work.
I do not know what causes this issue for you. Hence I could not reproduce this issue locally in my environment. I am using pro mini 5 volt cloned version and MySensors version
2.0.1-beta
I've also noticed that once the firmware version has been put on a node I can't re-send the same version, I need to increment the versions everywhere. Is this correct or should I be able to re-flash with the same firmware version by issuing the command?
Yes, this is known limitation on MySensors. To avoid firmware update on every reboot. If you have any changes on your firmware, your
CRC
will be changed. Then node will consider it a new firmware. Node will check three thingstype
,version
andCRC
, if either once is changed node assumes that there is anew firmware available for me and run firmware update. -
@jkandasa Hi jkandasa,
I did upgrade with SNAPSHOT version from google drive.
Seems it works fine but I'm unable to select firmware from node. There are many firmware in utilities.
Do you know this issue?
Thank you in advance. -
@jkandasa Oh, it works now. I have to restart after restore from backup.
After restart server then I'm able to see all firmware^^ however I can't see smart sleep option on firefox.
I can see it on chrome. -
@yd Thanks to report this. Could you please remove your browser cache on firefox. It could be a firefox browser caching issue.
Please report SmartSleep support status with MyController. I didn't test this feature as I do not have any SmartSellp node.
Thank you!
-
@jkandasa You are right. It's working now after clear cache. There is no plan to firmware upgrade at this moment. I will let you know when I do test this function.
-
I can confirm smartsleep works fine with mysensors 2.0.0 (battery powered arduino pro mini 3.3V )
Thank you for your support! This is awesome controller!