The Simple IoT source code is available on Github.
Simple IoT is written in Go. Go package documentation is available.
Simple IoT build has currently been testing on Linux and MacOS systems. See
for scripts used in building.
npm install -g run-pty
siot_watch command can be used when developing Simple IoT. This does the
elm-watchon the Elm code.
elm-watchwill automatically update the UI without losing state any time an Elm file changes.
- runs the Go backend and rebuilds it anytime a Go module changes (only tested on Linux and MacOS, but should be easy to set up Windows as well)
Both of the above are run in a run-pty
wrapper, which allows you to see the output of either process. The output of the
Elm compile is displayed in the browser, so it is rarely necessary to view the
Simple IoT can be used a library for your custom application. The siot main.go illustrates how to start the SIOT server, and add clients. You can do this from any Go application. With a few lines of code, this gives you a lot of functionality including a NATS server.
Simple IoT provides utilities that assist in creating new clients. See the Go package documentation for more information. A client manager is created for each client type. This manager instantiates new client instances when new nodes are detected and then sends point updates to the client. Two levels of nodes are currently supported for client configuration. An example of this would be a Rule node that has Condtion and Action child nodes.
A disable option is useful and should be considered for every new client.
The process for creating a new client:
- look at existing clients and use one of them for a model.
- register your client with the server using the
- create a frontend UI for the client. Again, model after existing client UIs.
Currently, there is no simple way to customize the SIOT UI when using SIOT as a library package. Forking and changing the SIOT Elm code is probably the simplest way if you want to make a small change now.
In the future, we plan to provide an API for passing in a custom UI to the SIOT Server. You can also implement a custom http client that serves up a custom UI.
Currently, there are a lot of subdirectories. One reason for this is to limit
the size of application binaries when building edge/embedded Linux binaries. In
some use cases, we want to deploy app updates over cellular networks, therefore
we want to keep packages as small as possible. For instance, if we put the
natsserver stuff in the
nats package, then app binaries grow a couple MB,
even if you don't start a NATS server. It is not clear yet what Go does for dead
code elimination, but at this point, it seems referencing a package increases
the binary size, even if you don't use anything in it. (Clarification welcome!)
For edge applications on Embedded Linux, we'd eventually like to get rid of net/http, since we can do all network communications over NATS. We're not there yet, but be careful about pulling in dependencies that require net/http into the NATS package, and other low level packages intended for use on devices.
See Go docs directory descriptions
envsetup.sh before submitting pull requests. All
code should be formatted and linted before committing.
Please configure your editor to run code formatters:
prettier(note, there is a
.prettierrcin this project that configures prettier to wrap markdown to 80 characters. Whether to wrap markdown or not is debatable, as wrapping can make diffs harder to read, but Markdown is much more pleasant to read in an editor if it is wrapped. Since more people will be reading documentation than reviewing, lets optimize for the reading in all scenarios -- editor, Github, and generated docs)
We plan to keep the main Simple IoT application a pure Go binary if possible. Statically linked pure Go has huge advantages:
- you can easily cross compile to any target from any build machine.
- blazing fast compile times
- deployment is dead simple – zero dependencies. Docker is not needed.
- you are not vulnerable to security issues in the host systems SSL/TLS libs. What you deploy is pretty much what you get.
- although there is high quality code written in C/C++, it is much easier to write safe, reliable programs in Go, so I think long term there is much less risk using a Go implementation of about anything – especially if it is widely used.
- Go’s network programming model is much simpler than about anything else. Simplicity == less bugs.
Once you link to C libs in your Go program, you forgo many of the benefits of Go. The Go authors made a brilliant choice when they chose to build Go from the ground up. Yes, you loose the ability to easily use some of the popular C libraries, but what you gain is many times more valuable.
There are not a lot of unit tests in the project yet, but below are some examples of running tests:
- test everything:
go test -race ./...
- test only client directory:
go test -race ./client
- run only a specific: `go test -race ./client -run BackoffTest (run takes a RegEx)
siot_testruns tests as well as vet/lint, frontend tests, etc.
./ is important, otherwise Go things you are giving it a package
name, not a directory. The
... tells Go to recursively test all subdirs.
It is much more pleasant to write documentation and tests as you develop, rather than after the fact. These efforts add value to your development if done concurrently. Quality needs to be designed-in, and leading with documentation will result in better thinking and a better product.
If you develop a feature, please update/create any needed documentation and write any tests (especially end-to-end) to verify the feature works and continues to work.