Browser-based firmware generator
-
Need to bounce this off someone. Please share your thoughts.
I've always wanted to make it possible to directly flash the hardware from the browser. Of course, browsers don't allow communication with serial devices. So, to work around this, I thought I'd create a browser extension. This is already a bad idea, since I'd have to develop extensions for every browser out there. Regardless, I decided to start with Chrome since it has the largest market-share for browsers. However, after a day's work, I discovered that Chrome extensions don't allow serial communication either!
The suggested alternative is to use Chrome Apps. However, Google has end-of-life-'d Chrome Apps, and starting a new project based on Chrome Apps would be a bad idea.
Even if I do somehow get this to work in Chrome, I'd still have the other browsers to care about.
There's two other alternatives I can think of:
- Create a CLI tool that communicates with a browser. Users have to install and run the CLI app in a terminal, and while its running, they can flash their devices from the browser. This is the most minimal approach that solves the problem, but requires the user to juggle a terminal, which isn't ideal.
- [Preferred] Create a native app, throw away the site, do everything inside the app. The native app can reuse most of the site's code, so the work put in so far is not wasted effort. The app also gets much more privileges, since it is running natively.
The big problem with both these approaches, of course, is that it requires the user to download and install an app. That's a lot to ask for, when compared to hitting a link in the browser, which means that many (most?) people are unlikely to use the app.
So, in summary, the options are:
- Don't flash the device from the browser, and just offer the generated code for download, as is happening right now. Limits utility and future features, and frankly, isn't exciting.
- Ask the user to install a native app. The app gets lots of capabilities this way, but has the downside of requiring a download and install, which is a massive cause of friction.
If I'm building a native app, I'll be using Electron, which is the JS way of building desktop apps. It's awesome, since it is effectively OS agnostic - the same code-base can work across Windows, Mac and Linux. However, Electron is notorious for creating large binaries, since it packages up both Chrome and Node.js within it. Expect download sizes in the 40-50 Mb range, maybe higher. (Popular apps that use Electron include Slack, GitHub desktop, and Atom.)
I'm confused about how to proceed. What would you do? What do you think is the best way ahead?
-
Need to bounce this off someone. Please share your thoughts.
I've always wanted to make it possible to directly flash the hardware from the browser. Of course, browsers don't allow communication with serial devices. So, to work around this, I thought I'd create a browser extension. This is already a bad idea, since I'd have to develop extensions for every browser out there. Regardless, I decided to start with Chrome since it has the largest market-share for browsers. However, after a day's work, I discovered that Chrome extensions don't allow serial communication either!
The suggested alternative is to use Chrome Apps. However, Google has end-of-life-'d Chrome Apps, and starting a new project based on Chrome Apps would be a bad idea.
Even if I do somehow get this to work in Chrome, I'd still have the other browsers to care about.
There's two other alternatives I can think of:
- Create a CLI tool that communicates with a browser. Users have to install and run the CLI app in a terminal, and while its running, they can flash their devices from the browser. This is the most minimal approach that solves the problem, but requires the user to juggle a terminal, which isn't ideal.
- [Preferred] Create a native app, throw away the site, do everything inside the app. The native app can reuse most of the site's code, so the work put in so far is not wasted effort. The app also gets much more privileges, since it is running natively.
The big problem with both these approaches, of course, is that it requires the user to download and install an app. That's a lot to ask for, when compared to hitting a link in the browser, which means that many (most?) people are unlikely to use the app.
So, in summary, the options are:
- Don't flash the device from the browser, and just offer the generated code for download, as is happening right now. Limits utility and future features, and frankly, isn't exciting.
- Ask the user to install a native app. The app gets lots of capabilities this way, but has the downside of requiring a download and install, which is a massive cause of friction.
If I'm building a native app, I'll be using Electron, which is the JS way of building desktop apps. It's awesome, since it is effectively OS agnostic - the same code-base can work across Windows, Mac and Linux. However, Electron is notorious for creating large binaries, since it packages up both Chrome and Node.js within it. Expect download sizes in the 40-50 Mb range, maybe higher. (Popular apps that use Electron include Slack, GitHub desktop, and Atom.)
I'm confused about how to proceed. What would you do? What do you think is the best way ahead?
@rakeshpai if you go for a cloud based programming method, you also need to mind security. Users would like insurance that their nodes that happen to be hooked up to a pc do get exactly the firmware they ask for and only when they ask for it. Also that the firmware goes only in one direction.
-
@rakeshpai if you go for a cloud based programming method, you also need to mind security. Users would like insurance that their nodes that happen to be hooked up to a pc do get exactly the firmware they ask for and only when they ask for it. Also that the firmware goes only in one direction.
@Anticimex Agreed, and I'm very sensitive to the security issue of cloud compilation. However, the primary issue at the moment is that we can't flash from the browser. The choice is either (a) forget about flashing altogether, or (b) build a native app. Regardless of the option we pick, the cloud doesn't fit in.
The cloud would've been in the picture if we were to flash from the browser, and I've thought extensively about the security ramifications of doing so, but that's a little irrelevant now, since we can't flash from the browser. A native app could simply do the compilation locally.
As a side note, I've been keeping an eye on web standards like WebSerial and WebUSB, which are designed to put the user in control far more than any native app does. If these standards make it through, we'll have a much more enjoyable way to work with hardware. I'm certainly looking forward to it.
So the question is: (a) Go native to offer more features at the cost of a largish download, or (b) Stay in the browser but with lesser features and conveniences.
-
I am one of those few users that opened chrome://flags, and set:
Enable WebUSB support: disabled.
I already have installed a tool to program my Arduinos. I guess, it's the first thing most people install after aquiring an Arduino.
I also do not understand why i would ever use a cloud.
Perhaps i am "too oldskool".. using a browser to find what i search for, and (if it is code,) then download it.
When i want code, i do not care how i get it. Important is, that i can download it..
The bare product is what counts.. -
@Anticimex Agreed, and I'm very sensitive to the security issue of cloud compilation. However, the primary issue at the moment is that we can't flash from the browser. The choice is either (a) forget about flashing altogether, or (b) build a native app. Regardless of the option we pick, the cloud doesn't fit in.
The cloud would've been in the picture if we were to flash from the browser, and I've thought extensively about the security ramifications of doing so, but that's a little irrelevant now, since we can't flash from the browser. A native app could simply do the compilation locally.
As a side note, I've been keeping an eye on web standards like WebSerial and WebUSB, which are designed to put the user in control far more than any native app does. If these standards make it through, we'll have a much more enjoyable way to work with hardware. I'm certainly looking forward to it.
So the question is: (a) Go native to offer more features at the cost of a largish download, or (b) Stay in the browser but with lesser features and conveniences.
@rakeshpai just out of curiosity, how do you plan to handle code compilation? If we look beyond the problem of interfacing with a serial device, you also need to compile the sketch, and link it to a hex executable hex file. I'm on saying it can't be done (it has been done before) but I would like to understand how it is practically done. I am curious since I maintain the Jenkins instance for MySensors, and I am open for alternatives to compile things. It uses installed instances of the Arduino IDE on the server side.
-
@Anticimex My current favourite is the PlatformIO Core CLI. While it was built to work in an IDE, it's actually completely independent, and only requires Python to run. It has support for lots of boards too, and has a built-in package manager making dependency management very easy. Since it's a CLI, it can easily be automated with bash scripts, can run headless, and doesn't require a windowing environment. Can't do that with GUIs like Arduino. There are alternatives to PlatformIO, but none that I found were feature-complete.
In fact, while I haven't exposed it, I've already implemented a way to download the code in a folder-structure that platformio prefers. I'll be rolling that out soon.
@core_c I completely understand the security issues of cloud compilation. But I also see the convenience it brings. If I do implement compilation in the cloud, I'm not going to take away the ability to download the code. You won't be forced to use the cloud. That said, I'm not going to implement cloud compilation at this moment, since it's pointless to do so if I can't also flash the device, and I currently can't flash the device from the browser.
-
Hi, I can give a quick look from my (noob) perspective.
I'm no programmer, just tinkering around, new to Mysensors, but already managed to get something working and starting to learn how this stuff works so I can expand my installation.
Im wery interested in this firmware generator because of my lack of knowledge and understand that people with more knowledge probably will not use this tool for their installation as they are more comfortable with programming and Mysensors.Intro aside I do not have any problems with using additional application, I already use Windows GUI/Controller for MySensors made by @tekka and Android application to debug and develop my installation.
Best part would be that code generation and debugging could be in one application, but that's not necessary.Keep up the good work.
-
Hi, I can give a quick look from my (noob) perspective.
I'm no programmer, just tinkering around, new to Mysensors, but already managed to get something working and starting to learn how this stuff works so I can expand my installation.
Im wery interested in this firmware generator because of my lack of knowledge and understand that people with more knowledge probably will not use this tool for their installation as they are more comfortable with programming and Mysensors.Intro aside I do not have any problems with using additional application, I already use Windows GUI/Controller for MySensors made by @tekka and Android application to debug and develop my installation.
Best part would be that code generation and debugging could be in one application, but that's not necessary.Keep up the good work.
@archiijs I'm very much in the same boat as you. While I have some experience writing code, C and C++ is all Greek and Latin to me. I can maybe read a little bit of C/C++ if my life depends on it, but that's about it. That's why I'm creating this tool. :)
Thanks for the feedback about app downloads being ok. I'll keep that in mind. Ideally, there won't be any need for debugging, since the generated code would be perfect right away, but I've been told that we don't live in an perfect world. However, viewing the serial monitor is definitely one of those things a desktop app can do, which a browser can't. I'm definitely excited about the possibility of communicating straight with the device.
It might take me some time to get to it though. However, all of the work I'm doing right now will be reused for the desktop app as well, so effort isn't wasted. At this moment, I guess it's wisest to see if this web app gets traction. Once we know it's being used, it'll be worthwhile making it better.
PS: How does the name 'MySensors Configurator' sound? Not the most creative, I know...
-
@rakeshpai Hi, I'm following this topic closely, found your project on google to see if something similar already exists. I was surprised that it does + it's based on nodejs, couldn't be more happy!
It's really a good intention for people who wants to get started quickly and it would perfectly complete the NodeManager.About the method, i was thinking about something similar that dagoma did ( a 3d printer manufacturer, based on Marlin firmware --> Arduino ). They made a subdomain where you can generate a .hex files, functions of the options you have. Then they made a desktop app which lets you upload the generated file.
That's not the most integrated and straight, but it works fine!
Which looks like your approch you show on your demo (btw the link on your github doesn't work, http://rakeshpai.github.io/~~m~~mysensors-network-manager )That maybe a good start to flash an arduino with an app ? https://github.com/noopkat/avrgirl-arduino
If you need / want help, I'm actually working on a project with nodejs and react, so 'im in the good mood ;)
-
@rakeshpai Hi, I'm following this topic closely, found your project on google to see if something similar already exists. I was surprised that it does + it's based on nodejs, couldn't be more happy!
It's really a good intention for people who wants to get started quickly and it would perfectly complete the NodeManager.About the method, i was thinking about something similar that dagoma did ( a 3d printer manufacturer, based on Marlin firmware --> Arduino ). They made a subdomain where you can generate a .hex files, functions of the options you have. Then they made a desktop app which lets you upload the generated file.
That's not the most integrated and straight, but it works fine!
Which looks like your approch you show on your demo (btw the link on your github doesn't work, http://rakeshpai.github.io/~~m~~mysensors-network-manager )That maybe a good start to flash an arduino with an app ? https://github.com/noopkat/avrgirl-arduino
If you need / want help, I'm actually working on a project with nodejs and react, so 'im in the good mood ;)
@getlarge Thanks! It's always nice to know that this is potentially useful. :)
Dogoma's approach is interesting, but as you said, not the most integrated. If there has to be an app downloaded anyway, why not go the next step and make it all easy to use.
Thanks for pointing out the issue with the readme. Fixed.
avrgirl is awesome! Finally someone decided to modernise a 20 year old piece of software. :)
You are welcome to dive into the code if you like. Node is only used for development. It's hosted on a static server, so there's no server-side language. The only problem with diving into code right now is that things aren't documented well, I haven't outlined what the goals/directions are, and it's kinda early, so I'm making sweeping changes all the time. But if you can get past that, feel free to dive in and familiarise yourself with the code, and even start making changes.
Speaking of which:
Update: No functionality change, but I've applied a fresh coat of paint to the UI. Hopefully it looks a little better now. There are still some cobwebs in the corners - I'll get to them soon. :) -
Since I haven't actually done this yet, I thought I'd outline the 'stack' used for this app, in case folks want to dive into the code.
- Based on React, using create-react-app.
- Offline first. Uses service-workers and localStorage for offline support.
- There's no server-side language. It's just a static site hosted on GitHub pages. Node.js is used for local development tooling.
- Uses redux for state management, and react-router for client-side routing.
- CSS-in-JS with glamor.
So, it's a very modern stack. Cutting-edge web stuff.
It's very early in the project, so I don't have any long-term plans outlined. In fact, I'll be honest, I haven't thought that far. But it's a community project, so you are welcome to steer the project as you see right.
Some areas to help:
- I suck at UI beautification work. Any help will be awesome.
- Need to investigate Electron for building native apps. Some things to look for: (a) Reusing the website directly from GitHub pages, so that we have a single deploy for the UI and the site still works fine if people don't want to download an app. Ideally, the electron app will simply be a container for the site. (b) Automatic updates to the container app. (c) Serial communication (node-serialport? avrgirl?) (d) More, as we go deeper.
- Ideas, suggestions? Like I said, I haven't thought too far. ;)
Actually, the absolute best way to help right now is to simply poke around the UI and point out issues, no matter how minor they are. It's the little things and attention to detail in an app that make it nice to use, so it'll help to have an obsessive pair of eyes going over the UI. You can point out bugs, usability issues, things that might be confusing, errors in the generated code, or any other changes you think will improve the app.
You can comment here with suggestions, or use GitHub if you like.
-
Just a quick update: I've been doing a bunch of work on the visual aspects of the app. Dare I say, it looks a lot better now. :) Check it out. Feedback welcome.
-
Awesome @rakeshpai!. Not sure if it is a glitch in my chrome, but I wasn't able to download the code any longer.
@hek Thanks. The download works for me just fine. Can you provide any more details? Do you see any errors in the browser's console? Also, hope you are using a desktop OS.
I haven't made much/any changes to the functionality, so downloads should be working as it was.
-
I just discovered this: https://github.com/arduino/arduino-create-agent
It's a project by the folks at Arduino, so it's as official as it gets. It's an app that you run locally, that runs in the background, puts an icon in the system tray, and starts a WebSocket server, with which a browser can connect to the local USB devices. It looks like it has been built for the Arduino Web Editor, and is in more-or-less active development.
I just spent under 15 mins with it, and I was able to talk to it from a CLI tool over websockets, and get it to list the available serial ports successfully. This is very encouraging.
Does anyone have any opinion about / experience with this? They have binaries for the three big desktop OSs. It's written in Go, so it's very clean in terms of deployment - it's just a single binary with no dependencies.
It looks like they enforce security by having a config.ini file with a list of allowed origins (domains) that are allowed to access the local web server. Since our page is running over HTTPS, the browser also imposes a restriction that it won't connect to insecure origins, which these chaps circumvent by creating a certificate locally during install (a process that I don't completely understand yet).
So, if someone is to use this, they'll have to install the app based on their platform, then modify config.ini to give access to this URL. That's relatively easy to do. It gives us access to everything that Arduino can do, but from a browser.
Most importantly, it's an official project by the folks at Arduino, so it can be trusted. Also, we don't have to replicate this work, and simply build on top of their APIs.
Thoughts?
-
I just discovered this: https://github.com/arduino/arduino-create-agent
It's a project by the folks at Arduino, so it's as official as it gets. It's an app that you run locally, that runs in the background, puts an icon in the system tray, and starts a WebSocket server, with which a browser can connect to the local USB devices. It looks like it has been built for the Arduino Web Editor, and is in more-or-less active development.
I just spent under 15 mins with it, and I was able to talk to it from a CLI tool over websockets, and get it to list the available serial ports successfully. This is very encouraging.
Does anyone have any opinion about / experience with this? They have binaries for the three big desktop OSs. It's written in Go, so it's very clean in terms of deployment - it's just a single binary with no dependencies.
It looks like they enforce security by having a config.ini file with a list of allowed origins (domains) that are allowed to access the local web server. Since our page is running over HTTPS, the browser also imposes a restriction that it won't connect to insecure origins, which these chaps circumvent by creating a certificate locally during install (a process that I don't completely understand yet).
So, if someone is to use this, they'll have to install the app based on their platform, then modify config.ini to give access to this URL. That's relatively easy to do. It gives us access to everything that Arduino can do, but from a browser.
Most importantly, it's an official project by the folks at Arduino, so it can be trusted. Also, we don't have to replicate this work, and simply build on top of their APIs.
Thoughts?
Not as rosy as I initially thought. I thought I might be able to compile the sketch locally using the app above. However, it looks like compilation is not a responsibility that this app has taken on. It only deals with listing serial devices, connecting to them, and flashing them, but not compiling sketches.
Arduino Web Editor appears to use arduino-builder, which I'm assuming they run in the cloud, since the setup isn't very easy at all. This means that we'll have to do cloud compilation as well. (@Anticimex, you might find arduino-builder interesting. They've specifically documented running arduino-builder in a CI system.)
It's still awesome that we have a solution to talk to the device from the browser. It's just that it'd have been even better if it did compilation as well. Hosting a cloud compilation service is not a huge problem - I run a reasonably high-traffic online service as my main gig, so I have some experience - but it'd have been better if we didn't have to.
I wonder why Arduino chose to compile in the cloud, considering that they ask their users to download a local app anyway to talk to the hardware. They wouldn't have to run a large part of their infrastructure, thus saving lots of associated costs and effort. And, they'd have a local toolchain, removing the need for an internet connection for compilation. They'd have to deal with setting up the toolchain locally, but they've been doing that for years, and have a lot of experience with it. Also, they would've enabled an ecosystem of apps like ours, so that we don't have to host compilers in the cloud. Maybe I'm not seeing some detail, but I think I'd have made the choice of having the compiler run locally too.
EDIT: I've raised an issue in their repo.
-
Not as rosy as I initially thought. I thought I might be able to compile the sketch locally using the app above. However, it looks like compilation is not a responsibility that this app has taken on. It only deals with listing serial devices, connecting to them, and flashing them, but not compiling sketches.
Arduino Web Editor appears to use arduino-builder, which I'm assuming they run in the cloud, since the setup isn't very easy at all. This means that we'll have to do cloud compilation as well. (@Anticimex, you might find arduino-builder interesting. They've specifically documented running arduino-builder in a CI system.)
It's still awesome that we have a solution to talk to the device from the browser. It's just that it'd have been even better if it did compilation as well. Hosting a cloud compilation service is not a huge problem - I run a reasonably high-traffic online service as my main gig, so I have some experience - but it'd have been better if we didn't have to.
I wonder why Arduino chose to compile in the cloud, considering that they ask their users to download a local app anyway to talk to the hardware. They wouldn't have to run a large part of their infrastructure, thus saving lots of associated costs and effort. And, they'd have a local toolchain, removing the need for an internet connection for compilation. They'd have to deal with setting up the toolchain locally, but they've been doing that for years, and have a lot of experience with it. Also, they would've enabled an ecosystem of apps like ours, so that we don't have to host compilers in the cloud. Maybe I'm not seeing some detail, but I think I'd have made the choice of having the compiler run locally too.
EDIT: I've raised an issue in their repo.
@rakeshpai we use the arduino-builder. It is just a shell command bundled with the IDE. You will still need to host a build environment, install all necessary libraries and BSP:s.
-
tl;dr: Arduino Create Agent is only for the Arduino Create site. Everyone else is locked out. We're back to square one, and we'll need to implement a native app on the desktop.
I've hit a dead-end with Arduino Create Agent.
Firstly, I got bad vibes when I was using their API. It felt very kludgey, and it was very hard to do very simple things. API troubles aren't that big a deal though, and soon enough, I had a decent reliable wrapper on top of their API. I was able to successfully list serial ports, connect to one, and talk over serial to it. I also found a lot of undocumented reliability issues along the way, which I had to fix by trial and error, but in the end it was pretty solid. It felt great to see MySensors' Serial.print messages in the browser! :metal:
However, I hit a complete road-block when trying to upload firmware. They require that every upload be signed, and they verify signatures. About signatures, their readme says that the signature should be:
(...) signed with the private key that matches the public key contained in the config.ini of the arduino-create-agent
However, the config.ini doesn't have any field allowing for public keys to be put in there. Also, their code for verification uses a hard-coded public key anyway. Presumably the private key lies on their servers.
If I understand correctly, this basically locks out everyone but Arduino from using Arduino Create Agent to upload firmware.
Aside: It's the upload 'commandline' that requires signatures, not the firmware itself, which is very strange. Also, the upload command-line is literally the shell command used to invoke avrdude. It doesn't sound like a good idea at all to take a shell command as input from a web server, via a browser, and execute it locally, signed or not. See what I mean when I say their API is kludgy? This isn't the most massive security loophole though, since they cryptographically verify the command's signature, and this is all over SSL anyway so MITM isn't possible, but I don't think I would have implemented it like this.
Can't fault Arduino for the agent not working with our site. There's no reason they would have designed for third-parties using their app to flash Arduinos. But it does mean that we are locked out.
Now, I can file bugs, and if they are interested they could address them, but even if they agree that this is a good idea, it's unlikely that this would be a priority for them. We can't wait for them, but if/when they are ready, we could move over to using their plugin. Until then, we are on our own.
Onwards!
-
tl;dr: Arduino Create Agent is only for the Arduino Create site. Everyone else is locked out. We're back to square one, and we'll need to implement a native app on the desktop.
I've hit a dead-end with Arduino Create Agent.
Firstly, I got bad vibes when I was using their API. It felt very kludgey, and it was very hard to do very simple things. API troubles aren't that big a deal though, and soon enough, I had a decent reliable wrapper on top of their API. I was able to successfully list serial ports, connect to one, and talk over serial to it. I also found a lot of undocumented reliability issues along the way, which I had to fix by trial and error, but in the end it was pretty solid. It felt great to see MySensors' Serial.print messages in the browser! :metal:
However, I hit a complete road-block when trying to upload firmware. They require that every upload be signed, and they verify signatures. About signatures, their readme says that the signature should be:
(...) signed with the private key that matches the public key contained in the config.ini of the arduino-create-agent
However, the config.ini doesn't have any field allowing for public keys to be put in there. Also, their code for verification uses a hard-coded public key anyway. Presumably the private key lies on their servers.
If I understand correctly, this basically locks out everyone but Arduino from using Arduino Create Agent to upload firmware.
Aside: It's the upload 'commandline' that requires signatures, not the firmware itself, which is very strange. Also, the upload command-line is literally the shell command used to invoke avrdude. It doesn't sound like a good idea at all to take a shell command as input from a web server, via a browser, and execute it locally, signed or not. See what I mean when I say their API is kludgy? This isn't the most massive security loophole though, since they cryptographically verify the command's signature, and this is all over SSL anyway so MITM isn't possible, but I don't think I would have implemented it like this.
Can't fault Arduino for the agent not working with our site. There's no reason they would have designed for third-parties using their app to flash Arduinos. But it does mean that we are locked out.
Now, I can file bugs, and if they are interested they could address them, but even if they agree that this is a good idea, it's unlikely that this would be a priority for them. We can't wait for them, but if/when they are ready, we could move over to using their plugin. Until then, we are on our own.
Onwards!
