Your packages consist of Lua code that controls what to display. Often you need to fetch external information for that. For example if you want to show a weather forecast you need to fetch weather information and make this data available to the display code. Services allow you to do that.
Every directory in your package might contain an optional file named service. The sychronization process on a device will automatically ensure that every service file is made executable and is started.
Package services are sandboxed by default and can't access any remote network service. If you want to grant your service additional priviledges you have to declare them in the permissions value inside the node.json file.
Running a service
Each service file should be something that can be executed on a normal armv6 system. The following technologies are recommended and can run on your devices out of the box.
The hosted OS provides the busybox shell, so basic shell operations should work.
An executable python script. So a normal python script with the
as the first line. The hosted OS provides Python 2.7 in addition to the following libraries:
- PIL, for image manipulation
- pytz, for timezone manipulation
- requests, for easy http/https requests
You might ship precompiled binaries, but be aware that you have to compile your code for armv6h architecture, so it runs on all Raspberry Pi versions. You also have to make sure to include all dependencies, so it's probably a good idea to statically link the binary.
Using the Go programming language might be a good idea, since it satisfies these requirements.
Each service will operate as a separate randomly assigned user without root permissions. Its current work directory is its node directory, so writing to files will be picked up by, for example, the util.file_watch function.
The service cannot overwrite existing package files. It can only create new files.
If the service script is updated by the synchronization process the syncer will remove all files created by the service, terminate the running version and then restart the new version.
The service will be automatically restarted if it terminates for any reason. You should try to make your services robust, so they don't randomly exit in case of an error as that would require a full service restart. It's recommended to handle errors inside your service.
Network access is prevented by default, unless the network permission is set in the node.json file. Note, that changing the node.json file will not automatically restart your service. It will only be restarted when the service file itself is updated.
The service will not even restart when config.json is changed as the result of configuration changes done in the info-beamer.com website. If you want to react to config changes, you have to monitor config.json. Using inotify is probably a good idea to limit polling.
If the device reboots, all files created by the service will be lost. If you need a more permanent storage, you might use the SCRATCH directory (see below). Or you might store data outside the device in a web service you provide.
The following environment variables will be set:
|PATH||So that a variety of shell commands is available|
|SHELL||Set to /bin/sh|
|SERIAL||The device/Raspberry Pi's serial number|
|NODE||The complete node name of the node associated with the service. The root node is always named root. Child nodes will look like root/<child> and so on. You can use this value to talk to your node code running in info-beamer by connecting to it using UDP or TCP.|
|USER||The username of the account running the service script. It will consist of "svc" followed by a number.|
|SCRATCH||Points to a directory which might survive reboots. Your service can read and write files there. You should not trust those files without verification as they might be damaged from an unexpected reboot.|
|TMPDIR||A memory-backed temporary directory. Don't store big files there, as the Pi might run out of memory.|