Introduction
PeachCloud is a low-power, lightweight hardware device designed to facilitate peer-to-peer communication across social networks. We aim to return (cloud) computing back into our homes and local communities in a way which fosters increased trust in one another and the socio-technical systems we inhabit.
This guide is intended to comprehensively document the PeachCloud project. It includes information about the hardware and software which comprises the device, as well as insight into the goals and design principles the project has grown from.
Story
Below are excerpts from Scuttlebutt private messages exchanged between @dinosaur (Michael Williams) and @glyph (Andrew Reid) at the start of their collaboration in early-2018. These conversations helped tell the story of what PeachCloud was to become:
@dinosaur
for me, i know at least one story in my mind, which relates to the story i told you about solarpunk trailer parks.
in the book Walkaway, i was struck by how computers were portrayed. every home had a computer system to help automate the household. and not just physical automation as we know it today (automated cooking, automation fabrication, etc), but so much was social automation, group resource coordination, task planning and management. that’s what i find most exciting.
so for me, PeachCloud is part of a larger story about every household having a home computer, which helps them connect with others, which helps them communicate with others, which helps them coordinate shared resources with others, which helps them get shit done with others.
then, if every home (and the corresponding infrastructure) itself is modular, portable, reproducible, and enjoyable, then our home computers can support us in this ever-evolving lifestyle. i find this future very exciting!
@glyph
I love the vision you put forward of the houeshold as facilitator of connecting, communicating, coordinating and acting.
Perhaps it’ll come as no surprise, but I couldn’t help thinking of mycelium while reading your messages. I think this connects beautifully with what you shared about your Spirit-Being / Creature being a Tree: nurturing, calm, stable, sensorially-opened and receptive, deeply-rooted, seasonally-responsive. This also seems like a great metaphor for the household. Who wouldn’t want to dwell in a tree?! So then, perhaps PeachCloud could be envisioned as part of the rhizosphere of the household; the digital access-point to the Reciprocity Transport Layer (RTL) [fundamentally about sharing with one another and growing together].
Here’s a little sketch I did this morning, inspired by your thoughts (there are some mixed metaphors / concerns in there but I think it’ll make sense to you). I took a high-level pass at thinking about measures of project success…will think-feel into this more deeply as we go. I also used the tree metaphor as a way to think about the layering of the interface:
Design Principles
The following design principles were created through collaborative story-telling and visioning at the start of the PeachCloud project. While not strictly technical in nature, this information is shared here to give future contributors and peers a feel for the guiding spirit behind this work. Implementation details should always be made in service of this underlying vision.
- Better communication infrastructure for local communities
- Able to store the long-tail data (the niche content that isn’t mass popular but nevertheless important to support libraries of local culture and knowledge)
- Able to support real-time media-rich interactions
- Not just text, but also voice and video mail!
- Able to transport your data with you as you move locations
- Create local network topologies and local data centers to match our local social topologies
- Less dependence on external networks, external data centers, etc
- Accessible to users
- Easy to get started for you and your community
- Easy for non-technical people to use
- The system is a teacher to guide you on your journey
- Invite less technical people to become more technical
- Simple on the surface, powerful under the hood
- Example: more like Excel spreadsheets, less like Apple interfaces
- The interface should embody the underlying system
- Let all the internals leak out for you to see
- A living system of activity playing on the physical lights
- Allow users to look at the firehouse of logs, usage, metrics, etc
- Easy to grok what is happening
- Physical lights should give you the status at a glance
- Friendly automation
- Your personal robot friend, your home computer
- No surprises, any automation should be upfront and clear
- Be helpful, but don’t try to guess what the user wants
- Give the user the power tools to automate their own desires
- Let all the internals leak out for you to see
- Accessible to contributors
- Modules are well-documented
- Code follows best practices
- Focus on being accessible and maintainable, not being clever and complicated
- Focus on being boring and just working, not being shiny and perfect
- Provide an opinionated foundation to build flexible ecosystem
- Frame is restrictive and has constraints, enables scope and freedom to play inside
- “Bondage sets you free”
- Contributions are more than tech
- Living cultural documentation
- Peer production as a deployment strategy
Features
PeachCloud features can be broadly divided between device management and Scuttlebutt functionality.
The anticipated features for the MVP release of PeachCloud are listed below. The majority of these features will be exposed via the web interface and some will also be exposed via the physical interface.
Since PeachCloud is built on a JSON-RPC microservices architecture, the APIs of the underlying system should be relatively simple for developers to interface with and extend. Please visit the documentation for individual microservices for further information.
Note: This is a work-in-progress. Expect changes.
Device Features
- Device status
- Hardware
- CPU usage
- Memory usage
- Storage usage
- Disk I/O
- Software
- Version info of PeachCloud, sbot, plugins
- Scripts
- Plugins
- Network
-
Display network mode (AP or client)
- If AP, list connected devices
-
Display current connection(s)
- Ethernet
- WiFi
- Display signal strength
- Display bandwidth usage
- Display hostname & external IP
- Display internal IP
-
Display network mode (AP or client)
- Logs
- Display system logs
- Errors
- List errors
- Report a bug / error
- Via SSB message
- Via email
- Hardware
- Configuration
- Access control
- Change user password
- Change administrator password
- Network
- Set network mode (AP or client)
- List available networks
- Connect to a network
- Disconnect from a network
- Forget a network
- Modify a network password
- Updates
- Check for available updates
- Download updates
- Install / apply update
- Backups
- Create backup
- Secret key
- Configuration (device settings)
-
Export backup
- External storage (USB)
- List backup history
- Schedule backups
- Delete previous backups / backup history
- Create backup
- Alerts
- Set alerts based on:
- CPU
- Memory
- Disk
- Bandwith-usage
- List previously-defined alerts
- Reset alerts
- Set alerts based on:
- Miscellaneous
- List current datetime
- Set datetime
- Display current timezone
- Set timezone
- Access control
- Documentation
- Browse
- Scuttlebot
- Scuttlebutt
- PeachCloud
- Search
- Browse
Scuttlebutt Features
- Profile
- Display avatar
- Set avatar (upload file)
- Display bio
- Update bio
- Peers
- List friends
- List followers
- List follows
- List locally-connected peers
- Follow
- Unfollow
- Block
- Mute (private block)
- Invites
-
Create an invite
- Text-based (hash)
-
Share an invite
- Send to a peer within SSB (private message)
- Share publically within SSB (public post)
- Send via email
- Accept an invite
-
Monitor an invite
- Check if the invite has been accepted
- For multi-use invites, show number of used & unused invite-slots
- Cancel an invite (not sure if this is currently possible)
-
Create an invite
- Blobs
- Display size of blob store (disk utilisation)
- Prune blobs
- By size
- By date
- By author
Quick Deployment
The instructions, configuration files and scripts referred to in this section can all be found in the peach-config repo.
Prerequisite Steps
Download the latest Debian Buster preview image for RPi3 and flash it to an SD card.
Note: Be sure to use the correct device location in the dd
command, otherwise you risk wiping another connected USB device. sudo dmesg | tail
can be run after plugging in the SD card to determine the correct device location:
wget https://raspi.debian.net/verified/20200831_raspi_3.img.xz
xzcat 20200831_raspi_3.img.xz | sudo dd of=/dev/mmcblk0 bs=64k oflag=dsync status=progress
On Mac OS, use the following command to flash the SD card:
xzcat 20200831_raspi_3.img.xz | sudo dd of=/dev/sdcarddisc
Alternatively, use Etcher.
Note: if the above image link stops working, you can find the complete list of Raspberry Pi Debian images here.
Setup
Quick setup commands to connect to a local WiFi network over the wlan0
interface (assuming eth0
connection is not possible):
# username
root
# password (by default raspberry debian requires no password, so we set the password for root here)
passwd
# set interface up (run command twice if you receive 'link is not ready' error on first try)
ip link set wlan0 up
# append ssid and password for wifi access point
wpa_passphrase <SSID> <PASS> > /etc/wpa_supplicant/wpa_supplicant.conf
# open wpa_supplicant.conf
nano /etc/wpa_supplicant/wpa_supplicant.conf
[ Add the following two lines to top of file ]
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=wpactrl-user
update_config=1
[ Save and exit ]
# open network interfaces config
nano /etc/network/interfaces
[ Add the following lines to the file ]
auto lo
iface lo inet loopback
allow-hotplug wlan0
auto wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
[ Save and exit ]
reboot now
[ Pi should now be connected to the WiFi network ]
Scripts
The setup_dev_env.py
script can be executed once your Pi is internet-connected and git
and python
have been installed.
apt update
apt install git python
git clone https://github.com/peachcloud/peach-config.git
cd peach-config
# run the script with --i2c and --rtc flags to configure
python scripts/setup_dev_env.py -i -r ds3231 <USER>
Running the script with the -h
flag shows the help menu:
usage: setup_dev_env.py [-h] [-i] [-r {ds1307,ds3231}] user
positional arguments:
user username for the default user account
optional arguments:
-h, --help show this help message and exit
-i, --i2c configure i2c
-r {ds1307,ds3231}, --rtc {ds1307,ds3231}
configure real-time clock
A <USER>
argument must be supplied to create a new system user. You will be prompted to enter a password for your newly created user.
The script also allows optional configuration of I2C and real-time clock (RTC) modules. I2C configuration is necessary for the OLED display and physical interface to work correctly. RTC configuration is required for the real-time clock to work correctly. When passing the -r
flag, the type of real-time clock module must be included (either ds1307 or ds3231). Selecting real-time clock configuration will not work if the I2C flag is not selected (in other words, the real-time clock requires I2C).
Run the script as follows for a full installation and configuration with I2C and the ds3231 RTC module (username in this case is peach
):
python scripts/setup_dev_env.py -i -r ds3231 peach
Hardware
PeachCloud is intended to be a low-cost device with a small footprint and relatively low power consumption. It should be easy to modify and extend through the inclusion of additional peripherals and hardware modules, either for future release by the PeachCloud team or by third-parties with basic technical competence.
Single-board Computer (SBC)
The Raspberry Pi 3B+ has been chosen as the development platform for PeachCloud. The 3B+ offers extensive documentation, a 64-bit processor, integrated wireless LAN, Bluetooth and BLE, as well as a 40-pin GPIO header. All of these features make it a powerful and flexible platform for system development.
It is important to note that a range of single-board computers (SBC) can be substituted in place of the 3B+, though some changes in system configuration may be required.
Real-time Clock (RTC)
A real-time clock (RTC) module is included in the PeachCloud device as a means of keeping accurate system time, regardless of any power supply interruptions which may occur during deployment. The RTC module consists of an integrated circuit (IC) for time-keeping and a battery. Having a consistently-accurate system time will make it easier to schedule updates and prevent the end-user from having to update the time themselves.
Physical Interface
PeachCloud includes a 128x64 pixel OLED display and several push-buttons. Together, these components form a physical interface which exposes a simple menu system for displaying system state and allowing basic device interactions. The physical interface is intended to be useful in contexts when browser-based interactions are not possible or desirable.
Requirements
Development is currently taking place with the following hardware:
- Raspberry Pi 3B+
- Adafruit 128x64 1.3" OLED Bonnet (product page)
- DS1338 Real-Time Clock (RTC) module (datasheet)
A breadboard and male-to-female jumper wires are also recommended for prototyping.
If the exact parts specified above are not available, substitutes can be used - provided they conform the following specifications:
- OLED display
- 128 x 64 pixels
- SSD1306-compatible
- Buttons
- 7 x push-buttons or 2 x push-buttons and 1 x 5-direction joystick
- Real-Time Clock (RTC)
- DS1338 or DS1307
Note: the hardware peripherals listed on this page do not work out-of-the-box with Debian Buster ARM64. You will need to patch the device tree and run additional configuration steps (patches are applied automatically if following the 'quick deployment' method using install scripts). See Configuration in the Operating System section of this document for further information.
GPIO Pinout
The OLED bonnet (with buttons) and DS1338 RTC module are connected to the Pi via GPIO pins.
BCM Pin # | Function | Physical Pin # | Used By |
---|---|---|---|
3v3 Power | 1 | OLED Bonnet & RTC | |
BCM 2 | SDA | 3 | OLED Bonnet & RTC |
BCM 3 | SCL | 5 | OLED Bonnet & RTC |
Ground | 6 | OLED Bonnet & RTC | |
BCM 4 | Joystick Center | 7 | OLED Bonnet |
BCM 17 | Joystick Up | 11 | OLED Bonnet |
BCM 27 | Joystick Left | 13 | OLED Bonnet |
BCM 22 | Joystick Down | 15 | OLED Bonnet |
BCM 23 | Joystick Right | 16 | OLED Bonnet |
BCM 5 | Button A | 29 | OLED Bonnet |
BCM 6 | Button B | 31 | OLED Bonnet |
Physical Interface
The PeachCloud physical interface consists of a 5-way joystick, two push-buttons and a 128x64 OLED display.
Development is taking place on the AdaFruit 128x64 1.3" OLED Bonnet. This bonnet comes in the pHAT form-factor and requires 3.3V power. It uses 9 GPIO pins and communicates over I2C. The included OLED display utilises the SSD1306 driver.
Note: the 5-way joystick may be replaced by four or five push-buttons in the release version of the physical interface.
Control
The OLED display shows the PeachCloud logo on start-up. Pressing the A
button (#5
) loads the root of the menu system. The UP
and DOWN
directions on the joystick allow scrolling through the menu options, while the A
button functions as Select and the B
button (#6
) functions as Back.
Any button or joystick direction can be pressed to wake the display after selecting Display Off.
Menu Structure
.
├── Networking
│ └── MODE
│ └── STATUS
│ └── NETWORK
│ └── IP
│ └── SIGNAL
│ └── Configuration
│ └── Client Mode
│ └── Access Point Mode
├── System Stats
│ └── CPU
│ └── MEM
│ └── LOAD
│ └── UPTIME
│ └── DATA RX
│ └── DATA TX
├── Display Off
├── Reboot
└── Shutdown
Configuration
This page contains the detailed, step-by-step software configuration instructions required to ensure that all the hardware works correctly. Skip to the quick deployment section for the scripted deployment instructions.
GPIO
GPIO (General Purpose Input Output) appears to be working out-of-the-box, but be aware that all pin numbers are offset by 458 for Debian on the Raspberry Pi 3 (as mentioned in the Debian RaspberryPi3 wiki).
RTC over I²C
Additional configuration is required for Debian Buster ARM64 before I²C devices can function correctly. The following steps are required for the DS1338 module / DS1307 chip:
Tested with DS1338 RTC module.
Ensure i2c-tools
and python-smbus
Debian packages have been installed. Then run the following to ensure the RTC is correctly wired and connected to the Pi:
sudo modprobe i2c-dev
sudo i2cdetect -y 1
The final command in the sequence prints an array to the console, with 68 denoting the presence of the RTC module. This is a sign that the device is properly wired and connected.
Append the following two lines to /boot/firmware/config.txt
:
dtoverlay=i2c-rtc,ds1307
dtparam=i2c_arm=on
Append the following line to /etc/modules
:
i2c-dev
Patch the device tree in order to set the clock frequency for I²C devices:
Note: the steps below can be shortened by downloading the pre-patched dtb
file from the peach-config repo and using it to replace the dtb
file on the Pi's SD card.
Copy the existing dtb
(device tree blob) from the Pi microSD card to a more powerful computer running Linux (exact location is up to you). You will find the dtb
in the following location:
/boot/firmware/bcm2710-rpi-3-b.dtb
Note: the file may be named bcm2837-rpi-3-b.dtb
. In that case, replace all instances of bcm2710
in these instructions with bcm2837
.
Once it has been copied to your Linux computer, run the following commands (on the Linux machine):
Install the compiler / decompiler:
sudo apt-get install device-tree-compiler
Change into the direction where you copied the dtb
from the Pi:
cd /place/where/dtb/file/was/pasted
Generate a human-readable decompiled device tree (dts
):
dtc -I dtb -O dts > bcm2710-rpi-3-b.dts
Open the dts
in a text editor and add the clock-frequency property (line 570):
clock-frequency = <0x186a0>;
Save and exit the document. Recompile the patched dts
to binary blob format:
dtc -O dtb -o bcm2710-rpi-3-b.dtb bcm2710-rpi-3-b.dts
Copy the resulting dtb
onto the Pi microSD card and overwrite the old dtb
file (you may wish to backup the old dtb
first):
cp bcm2710-rpi-3-b.dtb /boot/firmware/bcm2710-rpi-3-b.dtb
Finally, run the following commands to complete the process:
sudo modprobe i2c-bcm2835
su
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
exit
sudo modprobe rtc-ds1307
Run the i2cdetect
tool to ensure the RTC kernel driver is working:
sudo i2cdetect -y 1
A UU
entry in the output arrays denotes success. If you still see 68
or similar, the module is not being controlled by the kernel driver.
Ensure no i2c could not read clock-frequency property
errors persist in the kernel logs (/var/log/kern.log
).
Note: This Scuttlebutt dev-diary post by @glyph documents the process step-by-step (%aEVy1gyTSl4qrbazrwrgnrLs4pRVobELwQjH/TUtsAc=.sha256).
OLED Bonnet
A device tree overlay is required to activate the internal pull-up resistors on the Pi. Without this overlay, some of the buttons on the OLED bonnet will not work.
Begin by downloading the device tree overlay file: mygpio.dtbo
.
wget https://github.com/peachcloud/peach-config/raw/main/conf/mygpio.dtbo
Create an overlays
directory on the Pi filesystem:
sudo mkdir /boot/firmware/overlays
Copy the overlay file into the overlays
directory:
sudo cp mygpio.dtbo /boot/firmware/overlays/
Append the following line to /boot/firmware/config.txt
:
device_tree_overlay=overlays/mygpio.dtbo
Reboot to apply the changes. All buttons on the OLED bonnet should now function correctly.
Software
Operating System
Images
PeachCloud runs an unofficial preview image of Debian 10 (Buster). Kernel version: 4.19.0-5-arm64.
Tested images are now available via the Raspberry Pi Debian images page on the Debian wiki. According to Gunnar Wolf, project maintainer and Debian developer, the page: "should serve as a go-grab-it destination for regularly autobuilt images for the Raspberry Pi family". Note that these images are considered unofficial, ie. they are not part of an official Debian project.
Why Debian?
In order to be flexible in supporting single-board computers beyond the Raspberry Pi alone, and to take full advantage of 64-bit support on ARMv8 devices, development for PeachCloud is being targeted at Debian ARM64.
Debian was chosen over the Raspbian operating system for several reasons:
- Full ARM64 support, unlike Raspbian which uses 32 bit mode
- Flexibile deployment to a range of single board computers
- Access to latest code in Debian testing
- Relatively lightweight base install ( < 2GB )
The downsides to this approach are a lack of support (most online resources assume use of Raspbian) and a minimal set of drivers on the base install.
Networking
PeachCloud has three primary network interfaces: eth0
, wlan0
and ap0
(virtual interface). The device supports two wireless modes: client and access point (AP).
In client mode, the wlan0
interface is managed by wpa_supplicant
. This allows the PeachCloud device to connect to a WiFi access point in the vicinity. The IP address of the wlan0
interface is dynamically-assigned by the WiFi router it is associated with. While the device is running in this mode, the ap0
interface is set DOWN
and the dnsmasq
and hostapd
processes are stopped.
In access point mode, the ap0
interface is managed by hostapd
- with DNS and DHCP leasing being handled by dnsmasq
. The IP address of the ap0
interface is set to 11.11.11.10
by default. Connected devices are leased IP addresses in the range of 11.11.11.11 - 11.11.11.30
(for now). While the device is running in this mode, the wlan0
interface is set DOWN
and the wpa_supplicant
process is stopped.
The peach-network
microservice exposes activate_ap()
and activate_client()
RPC calls for simple switching of the networking mode. This functionality is also exposed by the menu system of the physical interface.
Direct Ethernet Setup
This file contains documentation for two different ways of working with PeachCloud using a direct ethernet connection (useful for development purposes).
Method 1
If you are close to a router, you can plug your Pi into the router via ethernet and you should be able to SSH into the Pi from any laptop connected to the same router via WiFi or ethernet.
Method 2
Using a DHCP server on your laptop (instructions for a laptop running Debian).
Install the DHCP server:
sudo apt-get install isc-dhcp-server
Configure the DHCP server:
In /etc/dhcp/dhcpd.conf
, add the following section:
subnet 10.0.2.0 netmask 255.255.255.240 {
range 10.0.2.2 10.0.2.14;
option routers 10.0.2.1;
host peach {
hardware ethernet b8:27:eb:b1:b1:4e;
fixed-address 10.0.2.4;
}
}
Note that b8:27:eb:b1:b1:4e
may need to be replaced with the address of your Pi's ethernet interface, which you can look up by running ip a
on the Pi. This address should be static. The fixed-address
section of the config tells the DHCP server to always give the specified client (peach
) the 10.0.2.4
IP address.
In /etc/default/isc-dhcp-server
, add the following section with the name of your ethernet interface (in this case ens9
):
INTERFACESv4="ens9"
INTERFACESv6=""
In /etc/network/interfaces
, set a static IP for your ethernet interface by adding this section:
auto ens9
iface ens9 inet static
address 10.0.2.1
Start the DHCP server:
sudo systemctl start isc-dhcp-server
Connect the ethernet cable:
Connect your Pi to the laptop via an ethernet cable. You should then be able to SSH into the Pi using the following command:
ssh peach@10.0.2.4
Note: On the Pi, internet traffic will still need to go through wlan0
interface.
On Mac OS you don't need to change the network config on your laptop. Simply enable internet sharing over ethernet and you should be able to connect to the Pi.
Nginx Configuration
Nginx is used as a reverse proxy for the peach-web
application. Requests to http://peach
and http://www.peach
on port 80
are passed to the peach-web
application on http://127.0.0.1:3000
.
The configuration file for nginx
can be found at /etc/nginx/sites-available/peach.conf
. The contents are as follows:
server {
listen 80;
server_name peach www.peach;
location / {
proxy_pass http://127.0.0.1:3000;
}
}
Nginx Cheatsheet
Symlink sites-available/*.conf
to sites-enabled/*.conf
:
sudo ln -s /etc/nginx/sites-available/peach.conf /etc/nginx/sites-enabled/
Check correctness of configuration:
sudo nginx -t
Reload nginx:
sudo nginx -s reload
Microservices
PeachCloud is built primarily with a microservices architecture. Each microservice utilises JSON-RPC - a stateless, light-weight remote procedure call protocol - as a means of exposing functionality and allowing interoperability. This approach produces a collection of services which are highly maintainable and testable, loosely coupled and independently deployable. HTTP and WebSockets are used as transports for the microservices.
The suite of PeachCloud microservices currently includes:
- peach-buttons (repo)
- poll GPIO pins for button presses and emit events via pub-sub
- peach-menu (repo)
- monitor and interact with the device via the physical interface
- peach-monitor (repo)
- monitor network data usage and set alert flags
- peach-network (repo)
- query and configure network interfaces
- peach-oled (repo)
- write and draw to the OLED display
- peach-stats (repo)
- query system statistics
peach-buttons
GPIO microservice module for handling button presses. peach-buttons
implements a JSON-RPC server with Publish-Subscribe extension. Each button press results in a JSON-RPC request being sent over websockets to any subscribers. A button code for the pressed button is sent with the request to subscribers, allowing state-specific actions to be taken by the subscriber.
In the case of PeachCloud, the peach-menu
microservice (repo) subscribes to peach-buttons
in order to update the state of the menu after each button press.
Note: This module is relatively stable but is still a work-in-progress.
Directory Tree
.
├── Cargo.lock
├── Cargo.toml
├── README.md
├── src
│ ├── error.rs // custom ButtonError type and From implementation
│ ├── interrupt.rs // interrupt handler with GPIO polling
│ ├── lib.rs // RPC server and pubsub handler, pin definitions
│ └── main.rs // init logger, call run() & catch application errors
Pin to Button to Button Code Mappings
4 => Center => 0,
27 => Left => 1,
23 => Right => 2,
17 => Up => 3,
22 => Down => 4,
5 => A => 5,
6 => B => 6
Note: peach-buttons
utilizes the GPIO character device ABI. This API, stabilized with Linux v4.4, deprecates the legacy sysfs interface to GPIOs that is planned to be removed from the upstream kernel after year 2020.
Environment
The JSON-RPC WS server address and port can be configured with the PEACH_BUTTONS_SERVER
environment variable:
export PEACH_BUTTONS_SERVER=127.0.0.1:5000
When not set, the value defaults to 127.0.0.1:5111
.
Logging is made availabe with env_logger
:
export RUST_LOG=info
Other logging levels include debug
, warn
and error
.
Setup
Clone this repo:
git clone https://github.com/peachcloud/peach-buttons.git
Move into the repo and compile:
cd peach-buttons
cargo build --release
Run the binary with sudo:
sudo ./target/release/peach-buttons
Debian Packaging
A systemd
service file and Debian maintainer scripts are included in the debian
directory, allowing peach-buttons
to be easily bundled as a Debian package (.deb
). The cargo-deb
crate can be used to achieve this.
Install cargo-deb
:
cargo install cargo-deb
Move into the repo:
cd peach-buttons
Build the package:
cargo deb
The output will be written to target/debian/peach-buttons_0.1.0_arm64.deb
(or similar).
Build the package (aarch64):
cargo deb --target aarch64-unknown-linux-gnu
Install the package as follows:
sudo dpkg -i target/debian/peach-buttons_0.1.0_arm64.deb
The service will be automatically enabled and started.
Uninstall the service:
sudo apt-get remove peach-buttons
Remove configuration files (not removed with apt-get remove
):
sudo apt-get purge peach-buttons
Testing Subscription
Request:
{"id":1,"jsonrpc":"2.0","method":"subscribe_buttons"}
Response:
{"jsonrpc":"2.0","result":1,"id":1}
Event:
{"jsonrpc":"2.0","method":"button_press","params":[0]}
Licensing
AGPL-3.0
peach-menu
OLED menu microservice module for PeachCloud. A state machine which listens for GPIO events (button presses) by subscribing to peach-buttons
over websockets and makes JSON-RPC calls to relevant PeachCloud microservices (peach-network
, peach-oled
, peach-stats
).
Note: This module is a work-in-progress.
Directory Tree
.
├── Cargo.lock
├── Cargo.toml
├── README.md
├── src
│ ├── buttons.rs // JSON-RPC WebSocket client for peach-buttons
│ ├── error.rs // custom MenuError type & From implementations
│ ├── lib.rs // launch state machine & RPC client for buttons
│ ├── main.rs // init logger, call run() & catch application errors
│ ├── network.rs // JSON-RPC HTTP client for peach-network
│ ├── oled.rs // JSON-RPC HTTP client for peach-oled
│ ├── state_machine.rs // state machine & state_changer()
│ ├── states.rs // state-specific logic called by state machine
│ ├── stats.rs // JSON-RPC HTTP client for peach-stats
│ └── structs.rs // data types used by RPC clients
Button Code Mappings
0 => Center,
1 => Left,
2 => Right,
3 => Up,
4 => Down,
5 => A,
6 => B
States
Home(0), // home menu
Home(1), // networking selected
Home(2), // system stats selected
Home(3), // display off selected
Home(4), // shutdown selected
Logo, // logo splash screen
Network, // network device view
NetworkConf(0), // network configuration menu
NetworkConf(1), // client mode selected
NetworkConf(2), // access point mode selected
NetworkMode(0), // client mode activated
NetworkMode(1), // access point mode activated
OledPower(0), // oled display off
OledPower(1), // oled display on
Reboot, // rebooting
Shutdown, // shutting down
Stats, // system statistics view
Setup
Clone this repo:
git clone https://github.com/peachcloud/peach-menu.git
Move into the repo and compile:
cd peach-menu
cargo build --release
Run the binary:
./target/target/peach-menu
Note: Will currently panic if peach_buttons
is not running (connection to ws server fails).
Environment
The JSON-RPC HTTP server address and port for the OLED microservice can be configured with the PEACH_OLED_SERVER
environment variable:
export PEACH_OLED_SERVER=127.0.0.1:5000
When not set, the value defaults to 127.0.0.1:5112
.
Logging is made available with env_logger
:
export RUST_LOG=info
Other logging levels include debug
, warn
and error
.
Resources
This work was made much, much easier by the awesome blog post titled Pretty State Machine Patterns in Rust by hoverbear. Thanks hoverbear!
Licensing
AGPL-3.0
peach-monitor
Monitor network data usage and set alert flags based on user-defined thresholds.
peach-monitor
is a CLI tool capable of running as a one-shot data store updater or as a daemon for continually updating data usage alert flags.
The utility is intended to be run with the --save
flag prior to each system reboot or shutdown. This allows network transmission totals (upload and download) to be persisted to the filesystem in the form of a JSON data store.
When the --update
flag is set, peach-monitor
retrieves user-defined alert thresholds from the data store, calculates the latest data usage statistics and sets alert flags accordingly. These flag values can be accessed from other parts of the PeachCloud system to alert the user (for example, by peach-web
for web application display).
The --daemon
flag executes the --update
functionality in a loop and is intended to be run as a background process for convenient alert flag updates. The optional --interval
argument defines the frequency with which the alert flags are updated. The default update frequency is once every 60 seconds.
The --iface
argument is used to define the network interface from which to retrieve network traffic data. This defaults to wlan0
if not defined.
Usage
peach-monitor [FLAGS] [OPTIONS]
FLAGS:
-d, --daemon Run daemon
-h, --help Prints help information
-s, --save Save latest usage totals to file
-u, --update Update alert flags
-V, --version Prints version information
OPTIONS:
-i, --iface <iface> Define network interface [default: wlan0]
-t, --interval <interval> Define time interval for updating alert flags (seconds) [default: 60]
Data Store
~/.local/share/peachcloud
.
└── net
├── alert.json // programatically-defined alert flags
├── notify.json // user-defined alert thresholds
└── traffic.json // network transmission totals
Alert Types
peach-monitor
defines warning and cutoff thresholds and corresponding alert flags for both received and transmitted network data. The cutoff thresholds are intended to allow data-intensive processes such as Scuttlebutt replication to be enabled and disabled dynamically.
Debian Packaging
A systemd
service file and Debian maintainer scripts are included in the debian
directory, allowing peach-monitor
to be easily bundled as a Debian package (.deb
). The cargo-deb
crate can be used to achieve this.
Install cargo-deb
:
cargo install cargo-deb
Move into the repo:
cd peach-monitor
Build the package:
cargo deb
The output will be written to target/debian/peach-monitor_0.1.0_arm64.deb
(or similar).
Install the package as follows:
sudo dpkg -i target/debian/peach-monitor_0.1.0_arm64.deb
The service will be automatically enabled and started.
Uninstall the service:
sudo apt-get remove peach-monitor
Remove configuration files (not removed with apt-get remove
):
sudo apt-get purge peach-monitor
Roadmap
- Add disk-usage tracking and alerts
Licensing
AGPL-3.0
peach-network
Networking microservice module for PeachCloud. Query and configure device interfaces using JSON-RPC over HTTP.
Interaction with wireless interfaces occurs primarily through the wpactrl crate which provides "a pure-Rust lowlevel library for controlling wpasupplicant remotely". This approach is akin to using wpa_cli
(a WPA command line client).
Note: This module is a work-in-progress.
JSON-RPC API
Methods for retrieving data:
Method | Parameters | Description |
---|---|---|
available_networks | iface | List SSID, flags (security), frequency and signal level for all networks in range of given interface |
id | iface , ssid | Return ID of given SSID |
ip | iface | Return IP of given network interface |
ping | Respond with success if microservice is running | |
rssi | iface | Return average signal strength (dBm) for given interface |
rssi_percent | iface | Return average signal strength (%) for given interface |
saved_networks | List all networks saved in wpasupplicant config | |
ssid | iface | Return SSID of currently-connected network for given interface |
state | iface | Return state of given interface |
status | iface | Return status parameters for given interface |
traffic | iface | Return network traffic for given interface |
Methods for modifying state:
Method | Parameters | Description |
---|---|---|
activate_ap | Activate WiFi access point (start wpa_supplicant@ap0.service ) | |
activate_client | Activate WiFi client connection (start wpa_supplicant@wlan0.service ) | |
add | ssid , pass | Add WiFi credentials to wpa_supplicant-wlan0.conf |
check_iface | Activate WiFi access point if client mode is active without a connection | |
connect | id , iface | Disable other networks and attempt connection with AP represented by given id |
delete | id , iface | Remove WiFi credentials for given network id and interface |
disable | id , iface | Disable connection with AP represented by given id |
disconnect | iface | Disconnect given interface |
modify | id , iface , password | Set a new password for given network id and interface |
reassociate | iface | Reassociate with current AP for given interface |
reconfigure | Force wpa_supplicant to re-read its configuration file | |
reconnect | iface | Disconnect and reconnect given interface |
save | Save configuration changes to wpa_supplicant-wlan0.conf |
API Documentation
API documentation can be built and served with cargo doc --no-deps --open
. This set of documentation is intended for developers who wish to work on the project or better understand the API of the src/network.rs
module.
Directory Tree
.
├── Cargo.lock
├── Cargo.toml
├── README.md
├── src
│ ├── error.rs // custom NetworkError type & From implementations
│ ├── lib.rs // RPC server, methods & tests
│ ├── main.rs // init logger, call run() & catch application errors
│ └── network.rs // logic for network methods exposed via RPC
Setup
Clone this repo:
git clone https://github.com/peachcloud/peach-network.git
Move into the repo and compile:
cd peach-network
cargo build --release
Run the binary (sudo needed to satisfy permission requirements):
sudo ./target/release/peach-network
Environment
The JSON-RPC HTTP server address and port can be configured with the PEACH_NETWORK_SERVER
environment variable:
export PEACH_NETWORK_SERVER=127.0.0.1:5000
When not set, the value defaults to 127.0.0.1:5110
.
Logging is made available with env_logger
:
export RUST_LOG=info
Other logging levels include debug
, warn
and error
.
Debian Packaging
A systemd
service file and Debian maintainer scripts are included in the debian
directory, allowing peach-network
to be easily bundled as a Debian package (.deb
). The cargo-deb
crate can be used to achieve this.
Install cargo-deb
:
cargo install cargo-deb
Move into the repo:
cd peach-network
Build the package:
cargo deb
The output will be written to target/debian/peach-network_0.2.4_arm64.deb
(or similar).
Build the package (aarch64):
cargo deb --target aarch64-unknown-linux-gnu
Install the package as follows:
sudo dpkg -i target/debian/peach-network_0.2.4_arm64.deb
The service will be automatically enabled and started.
Uninstall the service:
sudo apt-get remove peach-network
Remove configuration files (not removed with apt-get remove
):
sudo apt-get purge peach-network
Example Usage
Retrieve IP address for wlan0
With microservice running, open a second terminal window and use curl
to call server methods:
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "ip", "params" : {"iface": "wlan0" }, "id":1 }' 127.0.0.1:5000
Server responds with:
{"jsonrpc":"2.0","result":"192.168.1.21","id":1}
Retrieve SSID of connected access point for wlan1
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "ssid", "params" : {"iface": "wlan1" }, "id":1 }' 127.0.0.1:5000
Server response when interface is connected:
{"jsonrpc":"2.0","result":"Home","id":1}
Server response when interface is not connected:
{"jsonrpc":"2.0","error":{"code":-32003,"message":"Failed to retrieve SSID for wlan1. Interface may not be connected."},"id":1}
Retrieve list of SSIDs for all networks in range of wlan0
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "available_networks", "params" : {"iface": "wlan0" }, "id":1 }' 127.0.0.1:5000
Server response when interface is connected:
{"jsonrpc":"2.0","result":"[{\"frequency\":\"2412\",\"signal_level\":\"-72\",\"ssid\":\"Home\",\"flags\":\"[WPA2-PSK-CCMP][ESS]\"},{\"frequency\":\"2472\",\"signal_level\":\"-56\",\"ssid\":\"podetium\",\"flags\":\"[WPA2-PSK-CCMP+TKIP][ESS]\"}]","id":1}
Server response when interface is not connected:
{"jsonrpc":"2.0","error":{"code":-32006,"message":"No networks found in range of wlan0"},"id":1}
Retrieve network traffic statistics for wlan1
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "traffic", "params" : {"iface": "wlan1" }, "id":1 }' 127.0.0.1:5000
Server response if interface exists:
{"jsonrpc":"2.0","result":"{\"received\":26396361,\"transmitted\":22352530}","id":1}
Server response when interface is not found:
{"jsonrpc":"2.0","error":{"code":-32004,"message":"Failed to retrieve network traffic for wlan3. Interface may not be connected"},"id":1}
Retrieve status information for wlan0
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "status", "params" : {"iface": "wlan0" }, "id":1 }' 127.0.0.1:5110
Server response if interface exists:
{"jsonrpc":"2.0","result":"{\"address\":\"b8:27:eb:9b:5d:5f\",\"bssid\":\"f4:8c:eb:cd:31:81\",\"freq\":\"2412\",\"group_cipher\":\"CCMP\",\"id\":\"0\",\"ip_address\":\"192.168.0.162\",\"key_mgmt\":\"WPA2-PSK\",\"mode\":\"station\",\"pairwise_cipher\":\"CCMP\",\"ssid\":\"Home\",\"wpa_state\":\"COMPLETED\"}","id":1}
Server response when interface is not found:
{"jsonrpc":"2.0","error":{"code":-32013,"message":"Failed to open control interface for wpasupplicant: No such file or directory (os error 2)"},"id":1}
Licensing
AGPL-3.0
peach-oled
OLED microservice module for PeachCloud. Write to a 128x64 OLED display with SDD1306 driver (I2C) using JSON-RPC over HTTP.
JSON-RPC API
Method | Parameters | Description |
---|---|---|
clear | Clear the display buffer | |
draw | bytes , width , height , x_coord , y_coord | Draw graphic to display buffer for given byte array, dimensions and co-ordinates |
flush | Flush the display | |
ping | Respond with success if microservice is running | |
power | on | Toggle the display (memory is retained while off) |
write | x_coord , y_coord , string , font_size | Write message to display buffer for given co-ordinates using given font size |
peach-oled
allows text to be written with the following font sizes:
Font Sizes |
---|
6x8 |
6x12 |
8x16 |
12x16 |
Directory Tree
.
├── Cargo.lock
├── Cargo.toml
├── docs
│ └── images
│ └── peachcloud_oled.jpg
├── README.md
├── src
│ ├── error.rs // custom OledError type & From implementations
│ ├── lib.rs // RPC server, methods & tests (includes OLED logic)
│ └── main.rs // init logger, call run() & catch application errors
Setup
Clone this repo:
git clone https://github.com/peachcloud/peach-oled.git
Move into the repo and compile:
cd peach-oled
cargo build --release
Run the binary:
./target/release/peach-oled
Environment
The JSON-RPC HTTP server address and port can be configured with the PEACH_OLED_SERVER
environment variable:
export PEACH_OLED_SERVER=127.0.0.1:5000
When not set, the value defaults to 127.0.0.1:5112
.
Logging is made available with env_logger
:
export RUST_LOG=info
Other logging levels include debug
, warn
and error
.
Example Usage
Write Text to the OLED Display
With microservice running, open a second terminal window and use curl
to call server methods:
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "write", "params" : {"x_coord": 0, "y_coord": 0, "string": "Welcome to PeachCloud", "font_size": "6x8" }, "id":1 }' 127.0.0.1:5112
Server responds with:
{"jsonrpc":"2.0","result":success","id":1}
OLED will remain blank because no flush command has been issued.
Write to the second line of the display:
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "write", "params" : {"x_coord": 0, "y_coord": 8, "string": "Born in cypherspace", "font_size": "6x12" }, "id":1 }' 127.0.0.1:5112
Flush the display:
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "flush", "id":1 }' 127.0.0.1:5112
OLED display shows:
Welcome to PeachCloud!
Born in cypherspace
Validation checks are performed for all three parameters: x_coord
, y_coord
and string
. An appropriate error is returned if the validation checks are not satisfied:
{"jsonrpc":"2.0","error":{"code":1,"message":"Validation error: coordinate x out of range 0-128: 129."},"id":1}
{"jsonrpc":"2.0","error":{"code":1,"message":"validation error","data":"y_coord not in range 0-57"},"id":1}
{"jsonrpc":"2.0","error":{"code":1,"message":"Validation error: string length 47 out of range 0-21."},"id":1}
An error is returned if one or all of the expected parameters are not supplied:
{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params: missing field
font_size."},"id":1}
Draw Graphic to the OLED Display
With microservice running, open a second terminal window and use curl
to call server methods:
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "draw", "params" : {"bytes": [30, 0, 33, 0, 64, 128, 128, 64, 140, 64, 140, 64, 128, 64, 64, 128, 33, 0, 30, 0], "width": 10, "height": 10, "x_coord": 32, "y_coord": 32}, "id":1 }' 127.0.0.1:5112
Server responds with:
{"jsonrpc":"2.0","result":success","id":1}
OLED will remain blank because no flush command has been issued.
Flush the display:
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "flush", "id":1 }' 127.0.0.1:5112
OLED display shows a 10x10 graphic of a dot inside a circle.
No validation checks are currently performed on the parameters of the draw
RPC, aside from type-checks when the parameters are parsed.
Clear the Display
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "clear", "id":1 }' 127.0.0.1:5112
Server responds with:
{"jsonrpc":"2,0","result":"success","id":1}
Licensing
AGPL-3.0
peach-stats
System statistics microservice module for PeachCloud. Provides a JSON-RPC wrapper around the probes and systemstat crates.
JSON-API
Method | Description | Returns |
---|---|---|
cpu_stats | CPU statistics | user , system , nice , idle |
cpu_stats_percent | CPU statistics as percentages | user , system , nice , idle |
disk_usage | Disk usage statistics (array of disks) | filesystem , one_k_blocks , one_k_blocks_used , one_k_blocks_free , used_percentage , mountpoint |
load_average | Load average statistics | one , five , fifteen |
mem_stats | Memory statistics | total , free , used |
ping | Microservice status | success if running |
uptime | System uptime | secs , nanos |
Directory Tree
.
├── Cargo.lock
├── Cargo.toml
├── README.md
└── src
├── error.rs // custom StatError type & From implementations
├── lib.rs // RPC server, methods & tests
├── main.rs // init logger, call run() & catch application errors
├── stats.rs // logic for stats methods exposed via RPC
└── structs.rs // data types for stats
Setup
Clone this repo:
git clone https://github.com/peachcloud/peach-stats.git
Move into the repo and compile a release build:
cd peach-stats
cargo build --release
Run the binary:
./target/release/peach-stats
Environment
The JSON-RPC HTTP server address and port can be configured with the PEACH_STATS_SERVER
environment variable:
export PEACH_STATS_SERVER=127.0.0.1:5000
When not set, the value defaults to 127.0.0.1:5113
.
Logging is made available with env_logger
:
export RUST_LOG=info
Other logging levels include debug
, warn
and error
.
Debian Packaging
A systemd
service file and Debian maintainer scripts are included in the debian
directory, allowing peach-stats
to be easily bundled as a Debian package (.deb
). The cargo-deb
crate can be used to achieve this.
Install cargo-deb
:
cargo install cargo-deb
Move into the repo:
cd peach-stats
Build the package:
cargo deb
The output will be written to target/debian/peach-stats_0.1.0_arm64.deb
(or similar).
Build the package (aarch64):
cargo deb --target aarch64-unknown-linux-gnu
Install the package as follows:
sudo dpkg -i target/debian/peach-stats_0.1.0_arm64.deb
The service will be automatically enabled and started.
Uninstall the service:
sudo apt-get remove peach-stats
Remove configuration files (not removed with apt-get remove
):
sudo apt-get purge peach-stats
Example Usage
Get CPU Statistics
With microservice running, open a second terminal window and use curl
to call server methods:
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "cpu_stats", "id":1 }' 127.0.0.1:5113
Server responds with:
{"jsonrpc":"2.0","result":"{\"user\":4661083,\"system\":1240371,\"idle\":326838290,\"nice\":0}","id":1}
Get System Uptime
With microservice running, open a second terminal window and use curl
to call server methods:
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "uptime", "id":1 }' 127.0.0.1:5113
Server responds with:
{"jsonrpc":"2.0","result":"{\"secs\":840968,\"nanos\":0}","id":1}
Licensing
AGPL-3.0
Utilities
Simple tools and utilities for contract testing PeachCloud microservice APIs and ensuring version consistency.
peach-probe
Probe PeachCloud microservices to evaluate their state and ensure correct API responses.
peach-probe
is a CLI tool for contract testing of the public API's exposed by PeachCloud microservices.
It is composed of JSON-RPC clients which make calls to the methods of their respective servers and
generates a report with the results.
peach-probe
also makes use of systemctl status
commands to test the status of all PeachCloud microservices.
This utility is intended to provide a rapid means of testing a deployed PeachCloud system and allow informed trouble-shooting in the case of errors.
Installation
After adding releases.peachcloud.org to /etc/sources.list, as described here,
peach-probe can be installed by running:
sudo apt-get install peach-probe
Usage
USAGE:
peach-probe [FLAGS] [services]...
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
-v, --verbose prints successful endpoint calls in addition to errors
ARGS:
<services>... [possible values: peach_oled, peach_Network, peach_stats, peach_menu, peach_web,
peach_Buttons, peach_monitor]
If no service arguments are provided, peach-probe will query all services.
Custom Port Numbers
If peach-microservices are running on ports other than the default ports, this can be specified using environmental variables as documented here.
Todo
- On detecting certain errors, suggest possible fixes
- Finish querying of all peach-network endpoints
Licensing
AGPL-3.0
peach-version-checker
A simple commandline tool which helps to ensure version consistency across software and documentation.
peach-version-checker
compares version numbers in crate READMEs, manifests and developer documentation for each microservice and program in the PeachCloud ecosystem. Each program is given a passing or failing grade in the generated report. Project maintainers can then act accordingly if any version inconsistencies are found.
Usage
git clone git@github.com:peachcloud/peach-version-checker.git
cd peach-version-checker
cargo build --release
./release/target/peach-version-checker
Example Output
[ peach-buttons ]
Dev-docs: 0.1.3
Manifest: 0.1.3
Readme : 0.1.3
PASS
[ peach-oled ]
Dev-docs: 0.1.0
Manifest: 0.1.3
Readme : 0.1.3
FAIL
[ peach-probe ]
Dev-docs: No version number found
Manifest: 0.1.1
Readme : 0.1.1
FAIL
Licensing
AGPL-3.0
Web Interface
peach-web provides a web interface for monitoring and interacting with the PeachCloud device. This allows administration of the single-board computer (ie. Raspberry Pi) running PeachCloud, as well as the ssb-server and related plugins.
Design
peach-web
is written primarily in Rust and presents a web interface for interacting with the device. The stack currently consists of Rocket (Rust web framework), Tera (Rust template engine inspired by Jinja2 and the Django template language), HTML, CSS and JavaScript. Additional functionality is provided by JSON-RPC clients for the peach-network
and peach-stats
microservices.
HTML is rendered server-side. Request handlers call JSON-RPC microservices and serve HTML and assets. A JSON API is exposed for remote calls and dynamic client-side content updates via vanilla JavaScript following unobstructive design principles. A basic Websockets server is included, though is not currently utilised. Each Tera template is passed a context object. In the case of Rust, this object is a struct
and must implement Serialize
. The fields of the context object are available in the context of the template to be rendered.
Directory Tree
.
├── Cargo.lock
├── Cargo.toml
├── docs
│ ├── api_docs.md
│ ├── FEATURES.md
│ ├── js_docs.md
│ └── RESOURCES.md
├── .gitignore
├── README.md
├── Rocket.toml
├── src
│ ├── device.rs
│ ├── error.rs
│ ├── lib.rs
│ ├── main.rs
│ ├── network.rs
│ ├── stats.rs
│ ├── structs.rs
│ ├── tests.rs
│ └── ws.rs
├── static
│ ├── css
│ │ ├── peachcloud.css
│ │ └── _variables.css
│ ├── favicon.ico
│ ├── icons
│ ├── js
│ │ ├── network_card.js
│ │ ├── shutdown_menu.js
│ └── templates
│ ├── base.html.tera
│ ├── device.html.tera
│ ├── index.html.tera
│ ├── nav.html.tera
│ ├── network_add.html.tera
│ ├── network_card.html.tera
│ ├── network_detail.html.tera
│ ├── network_list.html.tera
│ ├── network_modify.html.tera
│ ├── not_found.html.tera
│ └── shutdown.html.tera
WEB ROUTES (src/routes.rs
)
Endpoint | Method | Parameters | Description |
---|---|---|---|
/ | GET | Home | |
/device | GET | Device status overview | |
/device/reboot | GET | Reboot device | |
/device/shutdown | GET | Shutdown device | |
/login | GET | Login form | |
/network | GET | Network status overview | |
/network/ap/activate | GET | Activate WiFi access point mode | |
/network/wifi | GET | List of networks | |
/network/wifi?<ssid> | GET | ssid | Details of a single network |
/network/wifi/activate | GET | Activate WiFi client mode | |
/network/wifi/add | GET | ssid (optional - prepopulation value of SSID in form) | Add a WiFi network |
/network/wifi/add | POST | ssid & pass | Submit form to add a WiFi network |
/network/wifi/connect | POST | ssid | Connect to the given WiFi network |
/network/wifi/disconnect | POST | ssid | Disconnect from currently associated WiFi network |
/network/wifi/forget | POST | ssid | Submit form to forget a saved WiFi network |
/network/wifi/modify?<ssid> | GET | ssid | Form for updating a WiFi network password |
/network/wifi/modify | POST | ssid & pass | Submit form to update a WiFi network password |
/network/wifi/usage | GET | Network data usage values and a form to update alert thresholds | |
/network/wifi/usage | POST | rx_warn , rx_cut , tx_warn , tx_cut , rx_warn_flag , rx_cut_flag , tx_warn_flag , tx_cut_flag | Submit form to update alert thresholds & set flags |
/network/wifi/usage/reset | GET | Reset the stored network data usage total to zero | |
/shutdown | GET | Shutdown menu |
JSON API (src/json_api.rs
)
All JSON API calls are prefixed by /api/v1/
. This has been excluded from the table below to keep the table compact.
Endpoint | Method | Parameters | Description |
---|---|---|---|
device/reboot | POST | Reboot device | |
device/shutdown | POST | Shutdown device | |
network/activate_ap | POST | Activate WiFi access point mode | |
network/activate_client | POST | Activate WiFi client mode | |
network/ip | GET | Returns IP address values for wlan0 & ap0 interfaces | |
network/rssi | GET | Returns RSSI for connected WiFi network | |
network/ssid | GET | Returns SSID for connected WiFi network | |
network/state | GET | Returns state of wlan0 & ap0 interfaces | |
network/status | GET | Returns status object for connected WiFi network | |
network/wifi | GET | Returns scan results for in-range access-points | |
network/wifi | POST | ssid & pass | Submit SSID & password to create new WiFi connection |
network/wifi/connect | POST | ssid | Submit SSID to connect to a given WiFi network |
network/wifi/disconnect | POST | ssid | Disconnect from the currently associated WiFi network |
network/wifi/forget | POST | ssid | Submit SSID to delete credentials for given WiFi network |
network/wifi/modify | POST | ssid & pass | Submit SSID & password to update the credentials for given WiFi network |
/network/wifi/usage | POST | rx_warn , rx_cut , tx_warn , tx_cut , rx_warn_flag , rx_cut_flag , tx_warn_flag , tx_cut_flag | Submit form to update alert thresholds & set flags |
/network/wifi/usage/reset | POST | Reset network data usage total | |
ping | GET | Returns pong! if peach-web is running | |
ping/network | GET | Returns pong! if peach-network microservice is running | |
ping/oled | GET | Returns pong! if peach-oled microservice is running | |
ping/stats | GET | Returns pong! if peach-stats microservice is running |
Environment
The web application deployment mode is configured with the ROCKET_ENV
environment variable:
export ROCKET_ENV=stage
Other deployment modes are dev
and prod
. Read the Rocket Environment Configurations docs for further information.
The WebSocket server port can be configured with PEACH_WEB_WS
environment variable:
export PEACH_WEB_WS=2333
When not set, the value defaults to 5115
.
Logging is made available with env_logger
:
export RUST_LOG=info
Other logging levels include debug
, warn
and error
.
Setup
Clone this repo:
git clone https://github.com/peachcloud/peach-web.git
Move into the repo and compile:
cd peach-web
cargo build --release
Run the tests:
cargo test
Run the binary:
./target/release/peach-web
Note: Networking functionality requires peach-network microservice to be running.
Debian Packaging
A systemd
service file and Debian maintainer scripts are included in the debian
directory, allowing peach-web
to be easily bundled as a Debian package (.deb
). The cargo-deb
crate can be used to achieve this.
Install cargo-deb
:
cargo install cargo-deb
Move into the repo:
cd peach-web
Build the package:
cargo deb
The output will be written to target/debian/peach-web_0.3.0_arm64.deb
(or similar).
Install the package as follows:
sudo dpkg -i target/debian/peach-web_0.3.0_arm64.deb
The service will be automatically enabled and started.
Uninstall the service:
sudo apt-get remove peach-web
Remove configuration files (not removed with apt-get remove
):
sudo apt-get purge peach-web
Licensing
AGPL-3.0
peach-patterns
A pattern library for building and maintaining PeachCloud user interfaces.
index.html
currently serves as the primary aggregator and displayer of patterns in the form of atoms and molecules (see Atomic Design by Brad Frost for more information on this approach to building design systems).
css/css_class_names
contains a simple list of all the custom css class names used in the PeachCloud design system. This list builds on css/_variables.css
, which contains css variables drawn from the Tachyons library. The content of css/_variables.css
will be pruned of unneeded code once the design system stabilizes.
css/peachcloud.css
contains all the custom css class definitions used in the PeachCloud design system.
Note: This is a work-in-progress.
Directory Tree
.
├── css
│ ├── css_class_names // list of all custom class names
│ ├── peachcloud.css // custom css class definitions and styles
│ └── _variables.css // css variables from Tachyons
├── icons // all icon files (svg & png)
├── index.html // markup of pattern library
├── README.md
Setup
For now you can simply clone the repo and open the index.html
file in your browser to view the pattern library.
Licensing
AGPL-3.0
Compilation
Since the majority of PeachCloud is written in the Rust programming language, a compiler and associated toolchain(s) is required to build the software from source. Visit the rustup website to download the Rust toolchain installer. In addition to the default stable
installation of Rust, many PeachCloud crates require the nightly
toolchain channel in order to compile. Instructions for installing and updating toolchains can be found in the README of the rustup GitHub repo.
Cross-Compilation
While PeachCloud crates can be compiled directly on the Raspberry Pi or equivalent single board computer, this process is resource intensive and relatively slow - especially when compiling release builds. Cross-compilation is an effective means of leveraging greater compute resources to reduce compilation time.
These instructions cover cross-compilation for Debian Buster running on a Raspberry Pi 3B+, using a host machine running Debian Stretch with an x86_64 architecture:
Install target platform:
rustup target add aarch64-unknown-linux-gnu
Install toolchain:
rustup toolchain install nightly-aarch64-unknown-linux-gnu
Install aarch64-linux-gnu-gcc:
sudo apt-get install gcc-aarch64-linux-gnu
Configure the linker:
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=/usr/bin/aarch64-linux-gnu-gcc
Alternatively, create a file named config
in the ~/.cargo
directory of the home user and add the following:
[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"
objcopy = { path ="aarch64-linux-gnu-objcopy" }
strip = { path ="aarch64-linux-gnu-strip" }
The objcopy
and strip
parameters are needed by cargo deb
when cross-compiling Debian packages.
Compile release build:
cargo build --release --target=aarch64-unknown-linux-gnu
The generated binary will be saved at target/aarch64-unknown-linux-gnu/release/name_of_crate
Debian Packaging
The microservices comprising the PeachCloud software suite are packaged for easy deployment and maintainance on Debian and derivative operating systems.
Each microservice repository includes a debian
directory which includes a systemd
service file and Debian maintainer scripts, including postinst
, postrm
and prerm
scripts. These scripts define behavior for installing and uninstalling the respective services. deb
packages are created using the cargo-deb
tool (crate).
Install cargo-deb:
cargo install cargo-deb
Create the package:
cargo deb --target aarch64-unknown-linux-gnu
Note: the correct linker, objcopy and strip parameters must be defined in ~/.cargo/config
for the above command to execute successfully. Visit the Compilation page and look under 'Configure the linker' for more details.
Install the package:
sudo dpkg -i peach-network_0.1.0_arm64.deb
The service will be automatically enabled and started.
Uninstall the package:
sudo apt-get remove peach-network
Remove configuration files (not removed with apt-get remove
):
sudo apt-get purge peach-network
Configuration
The microservices and other components comprising the PeachCloud software are configurable via the following environment variables:
Microservice | Variable | Description | Default |
---|---|---|---|
peach-network | PEACH_NETWORK_SERVER | HTTP server address and port for JSON-RPC | 127.0.0.1:5110 |
peach-buttons | PEACH_BUTTONS_SERVER | WebSocket server address and port for JSON-RPC | 127.0.0.1:5111 |
peach-oled | PEACH_OLED_SERVER | HTTP server address and port for JSON-RPC | 127.0.0.1:5112 |
peach-stats | PEACH_STATS_SERVER | HTTP server address and port for JSON-RPC | 127.0.0.1:5113 |
peach-web | ROCKET_ENV | Web application deployment mode | prod |
peach-web | ROCKET_TEMPLATE_DIR | Tera template directory | static/templates |
peach-web | PEACH_WEB_WS | WebSocket server port | 5115 |
Contributor's Guide
Anyone who feels excited about PeachCloud is encouraged to contact @glyph on Scuttlebutt or via email to discuss potential contributions. Please include details on what attracts you to PeachCloud, how you might like to contribute and what relevant experience you have. It's worth noting that you don't have to be a programmer to offer meaningful contributions.
SSB: @HEqy940T6uB+T+d9Jaa58aNfRzLx9eRWqkZljBmnkmk=.ed25519
Email: glyph@mycelial.technology
Processes
Coordination
Project management and coordination take place on Asana. This service allows the creation and assignment of tasks - as well as the ability to track task completion and share task-related notes among team members. Upon invitation to contribute to PeachCloud, new contributors will be sent an email invitation to join the MVP Development project on Asana.
Signal messenger is used for day-to-day communications, process-related queries and interpersonal check-ins. Jitsi Meet video calls are held once every two weeks and prior to the onboarding of new developers. Mumble is used for audio calls when one or several contributors are on slow or degraded internet connections.
Code
PeachCloud repositories are based on GitHub and are collected under the PeachCloud organization. New contributors will be added to the 'contributors' team and given appropriate access permissions.
GitHub issues are used to discuss repository-specific bugs and features.
Contributions to repositories are made in the form of pull-requests from forked repositories. Pull-requests bundle multiple commits and offer an opportunity to request comment or code review from fellow contributors. Contributors are encouraged to submit concise yet detailed descriptions when submitting pull-requests, and may even add screenshots or other images when desired. Over time, the pull-request history helps to tell the story of component development at a greater level of granularity than single commits.
Developer Diaries
Contributors to PeachCloud may wish to create a 'dev diary' thread on Scuttlebutt, though this is entirely optional and up to each individual. Dev diaries are a fun way to share and celebrate project progress with fellow Butts. A personal diary / log may also be kept to track work tasks and rhythms, and to offer a document for reflection.