Verison 1.0.3 Release
Based on Buildbotics 0.4.14
This commit is contained in:
10
scripts/11-automount.rules
Normal file
10
scripts/11-automount.rules
Normal file
@@ -0,0 +1,10 @@
|
||||
KERNEL!="sd[a-z]*", GOTO="automount_end"
|
||||
IMPORT{program}="/sbin/blkid -o udev -p %N"
|
||||
ENV{ID_FS_TYPE}=="", GOTO="automount_end"
|
||||
ENV{ID_FS_LABEL}!="", ENV{dir_name}="%E{ID_FS_LABEL}"
|
||||
ENV{ID_FS_LABEL}=="", ENV{dir_name}="usb-%k"
|
||||
ACTION=="add", ENV{mount_options}="relatime"
|
||||
ACTION=="add", ENV{ID_FS_TYPE}=="vfat|ntfs", ENV{mount_options}="$env{mount_options},utf8,gid=100,umask=002,sync"
|
||||
ACTION=="add", RUN+="/bin/mkdir -p /media/%E{dir_name}", RUN+="/bin/mount -o $env{mount_options} /dev/%k /media/%E{dir_name}"
|
||||
ACTION=="remove", ENV{dir_name}!="", RUN+="/bin/umount -l /media/%E{dir_name}", RUN+="/bin/rmdir /media/%E{dir_name}"
|
||||
LABEL="automount_end"
|
||||
206
scripts/avr109-flash.py
Normal file
206
scripts/avr109-flash.py
Normal file
@@ -0,0 +1,206 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import time
|
||||
import serial
|
||||
import binascii
|
||||
|
||||
|
||||
dev = '/dev/ttyAMA0'
|
||||
baud = 921600
|
||||
boot_id = 'bbctrl '
|
||||
verbose = False
|
||||
|
||||
|
||||
def crc16(data):
|
||||
crc = 0xffff
|
||||
|
||||
for x in data:
|
||||
crc = crc ^ int(x)
|
||||
for bit in range(8):
|
||||
if crc & 1: crc = (crc >> 1) ^ 0xa001
|
||||
else: crc = crc >> 1
|
||||
|
||||
return crc
|
||||
|
||||
|
||||
def avr_crc32(data, length):
|
||||
mem = [0xff] * length
|
||||
|
||||
for addr, chunk in data:
|
||||
for x in chunk:
|
||||
mem[addr] = x
|
||||
addr += 1
|
||||
|
||||
return binascii.crc32(bytes(mem))
|
||||
|
||||
|
||||
def read_intel_hex(f):
|
||||
base = 0
|
||||
pos = 0
|
||||
start = 0
|
||||
chunk = None
|
||||
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line or line[0] != ':': continue
|
||||
|
||||
count = int(line[1:3], 16)
|
||||
addr = int(line[3:7], 16)
|
||||
type = int(line[7:9], 16)
|
||||
data = line[9:-2]
|
||||
checksum = int(line[-2:], 16)
|
||||
|
||||
if type == 0:
|
||||
addr += base
|
||||
data = binascii.unhexlify(bytes(data, 'utf8'))
|
||||
|
||||
if chunk is None or pos != addr:
|
||||
if chunk is not None: yield (start, chunk)
|
||||
start = addr
|
||||
chunk = data
|
||||
|
||||
else: chunk += data
|
||||
|
||||
pos = addr + len(data)
|
||||
|
||||
if type == 2: base = int(data, 16) * 16
|
||||
|
||||
if chunk is not None: yield (start, chunk)
|
||||
|
||||
|
||||
def send(data):
|
||||
if verbose: print('Sending:', data)
|
||||
sp.write(bytes(data, 'utf8'))
|
||||
|
||||
|
||||
def send_int(x, size):
|
||||
if verbose: print('Sending: %d', x)
|
||||
sp.write((x).to_bytes(size, byteorder = 'big'))
|
||||
|
||||
|
||||
def recv(count):
|
||||
data = sp.read(count).decode('utf8')
|
||||
if count and verbose: print('Received:', data)
|
||||
return data
|
||||
|
||||
|
||||
def recv_int(size):
|
||||
x = int.from_bytes(sp.read(size), byteorder = 'big')
|
||||
if verbose: print('Received:', x)
|
||||
return x
|
||||
|
||||
|
||||
# Read firmware hex file
|
||||
data = list(read_intel_hex(open(sys.argv[1], 'r')))
|
||||
|
||||
# Open serial port
|
||||
sp = serial.Serial(dev, baud, timeout = 10)
|
||||
|
||||
# Reset AVR
|
||||
import RPi.GPIO as gpio
|
||||
gpio.setwarnings(False)
|
||||
gpio.setmode(gpio.BCM)
|
||||
gpio.setup(27, gpio.OUT)
|
||||
gpio.output(27, 0)
|
||||
gpio.output(27, 1)
|
||||
gpio.setup(27, gpio.IN, pull_up_down = gpio.PUD_UP)
|
||||
time.sleep(0.1)
|
||||
|
||||
# Sync
|
||||
for i in range(10): send('\x1b')
|
||||
|
||||
# Flush serial
|
||||
try:
|
||||
recv(sp.in_waiting)
|
||||
except: pass
|
||||
|
||||
# Get bootloader ID
|
||||
send('S')
|
||||
if boot_id != recv(len(boot_id)):
|
||||
raise Exception('Failed to communicate with bootloader')
|
||||
|
||||
# Get version
|
||||
send('V')
|
||||
major = int(recv(1))
|
||||
minor = int(recv(1))
|
||||
print('Bootloader version: %d.%d' % (major, minor))
|
||||
|
||||
# If bootloader is new enough compare checksums
|
||||
if 0 < major or 1 < minor:
|
||||
# Get flash length
|
||||
send('n')
|
||||
flash_len = recv_int(3)
|
||||
|
||||
# Get current flash CRC
|
||||
send('X')
|
||||
new_crc = avr_crc32(data, flash_len)
|
||||
old_crc = recv_int(4)
|
||||
if old_crc == new_crc:
|
||||
print('Flash already up to date')
|
||||
sys.exit(0)
|
||||
|
||||
print('CRC: old=0x%08x new=0x%08x' % (old_crc, new_crc))
|
||||
|
||||
# Erase
|
||||
send('e')
|
||||
if recv(1) != '\r': raise Exception('Flash erase failed')
|
||||
|
||||
# Get page size
|
||||
send('b')
|
||||
if recv(1) != 'Y': raise Exception('Cannot get page size')
|
||||
page_size = recv_int(2)
|
||||
print('Page size:', page_size)
|
||||
|
||||
|
||||
# Program
|
||||
print('Programming', end = '')
|
||||
count = 0
|
||||
retry = 0
|
||||
for addr, chunk in data:
|
||||
# Set address
|
||||
send('H')
|
||||
send_int(addr, 3)
|
||||
if recv(1) != '\r': raise Exception('Failed to set address')
|
||||
|
||||
while len(chunk):
|
||||
sys.stdout.flush()
|
||||
page = chunk[0:512]
|
||||
|
||||
# Block command
|
||||
send('B')
|
||||
|
||||
# Send block size
|
||||
send_int(len(page), 2)
|
||||
|
||||
# Send memory type
|
||||
send('F')
|
||||
|
||||
# Send block
|
||||
sp.write(page)
|
||||
|
||||
if recv(1) != '\r': raise Exception('Failed to write block')
|
||||
|
||||
# Get and check block CRC
|
||||
send('i')
|
||||
crc = recv_int(2)
|
||||
expect = crc16(page)
|
||||
if crc != expect:
|
||||
retry += 1
|
||||
if retry == 5:
|
||||
raise Exception('CRC mismatch %d != %d' % (crc, expect))
|
||||
|
||||
print('x', end = '')
|
||||
continue
|
||||
|
||||
count += len(page)
|
||||
chunk = chunk[512:]
|
||||
retry = 0
|
||||
print('.', end = '')
|
||||
|
||||
|
||||
print('done')
|
||||
print('Wrote %d bytes' % count)
|
||||
|
||||
# Exit bootloader
|
||||
send('E')
|
||||
15
scripts/bbctrl.service
Normal file
15
scripts/bbctrl.service
Normal file
@@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=Buildbotics Controller
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=root
|
||||
ExecStart=/usr/local/bin/bbctrl -l /var/log/bbctrl.log
|
||||
WorkingDirectory=/var/lib/bbctrl
|
||||
Restart=always
|
||||
StandardOutput=null
|
||||
Nice=-10
|
||||
KillMode=process
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
15
scripts/browser
Normal file
15
scripts/browser
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
|
||||
def enter_cgroup():
|
||||
with open('/sys/fs/cgroup/memory/chrome/tasks', 'w') as f:
|
||||
f.write(str(os.getpid()))
|
||||
|
||||
|
||||
# Start browser
|
||||
args = ['/usr/lib/chromium-browser/chromium-browser'] + sys.argv[1:]
|
||||
subprocess.Popen(args, preexec_fn = enter_cgroup).wait()
|
||||
37
scripts/check-config-vars.py
Normal file
37
scripts/check-config-vars.py
Normal file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
'''Check that the configuration variable template used on the RPi matches the
|
||||
variables used in the AVR'''
|
||||
|
||||
import sys
|
||||
import json
|
||||
|
||||
templ = json.load(open('src/resources/config-template.json', 'r'))
|
||||
vars = json.load(open('avr/build/vars.json', 'r'))
|
||||
|
||||
|
||||
def check(section):
|
||||
errors = 0
|
||||
|
||||
for name, entry in section.items():
|
||||
if 'type' in entry:
|
||||
ok = False
|
||||
|
||||
# TODO check that defaults are valid
|
||||
# TODO check that types match
|
||||
|
||||
if 'code' in entry and not entry['code'] in vars:
|
||||
print('"%s" with code "%s" not found' % (name, entry['code']))
|
||||
|
||||
else: ok = True
|
||||
|
||||
if not ok: errors += 1
|
||||
|
||||
else: errors += check(entry)
|
||||
|
||||
return errors
|
||||
|
||||
|
||||
errors = check(templ)
|
||||
print('\n%d errors' % errors)
|
||||
sys.exit(errors != 0)
|
||||
32
scripts/config-screen
Normal file
32
scripts/config-screen
Normal file
@@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ $# != 3 ]; then
|
||||
echo "Usage: $0 <width> <height> <rotation>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
WIDTH="$1"
|
||||
HEIGHT="$2"
|
||||
ROTATION="$3"
|
||||
|
||||
if [[ ! "$WIDTH" =~ ^[0-9]+$ ]]; then
|
||||
echo "Invalid width '$WIDTH'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! "$HEIGHT" =~ ^[0-9]+$ ]]; then
|
||||
echo "Invalid height '$HEIGHT'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! "$ROTATION" =~ ^[0-3]$ ]]; then
|
||||
echo "Invalid rotation '$ROTATION'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
OPTIONS="framebuffer_width=$WIDTH "
|
||||
OPTIONS+="framebuffer_height=$HEIGHT "
|
||||
OPTIONS+="display_rotate=$ROTATION"
|
||||
|
||||
edit-boot-config $OPTIONS
|
||||
259
scripts/config-wifi
Normal file
259
scripts/config-wifi
Normal file
@@ -0,0 +1,259 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
AP=false
|
||||
DISABLE=false
|
||||
SSID=
|
||||
PASS=
|
||||
CHANNEL=7
|
||||
REBOOT=false
|
||||
|
||||
WLAN0_CFG=/etc/network/interfaces.d/wlan0
|
||||
HOSTAPD_CFG=/etc/hostapd/hostapd.conf
|
||||
DNSMASQ_CFG=/etc/dnsmasq.conf
|
||||
DHCPCD_CFG=/etc/dhcpcd.conf
|
||||
WPA_CFG=/etc/wpa_supplicant/wpa_supplicant.conf
|
||||
|
||||
|
||||
function query_config() {
|
||||
if [ -e $WLAN0_CFG ]; then
|
||||
SSID=$(grep wpa-ssid $WLAN0_CFG |
|
||||
sed 's/^[[:space:]]*wpa-ssid "\([^"]*\)"/\1/')
|
||||
echo "{\"ssid\": \"$SSID\", \"mode\": \"client\"}"
|
||||
|
||||
else
|
||||
if [ -e $HOSTAPD_CFG -a -e /etc/default/hostapd ]; then
|
||||
SSID=$(grep ^ssid= $HOSTAPD_CFG | sed 's/^ssid=\(.*\)$/\1/')
|
||||
CHANNEL=$(grep ^channel= $HOSTAPD_CFG |
|
||||
sed 's/^channel=\(.*\)$/\1/')
|
||||
|
||||
echo -n "{\"ssid\": \"$SSID\", "
|
||||
echo "\"channel\": $CHANNEL, \"mode\": \"ap\"}"
|
||||
|
||||
else
|
||||
echo "{\"mode\": \"disabled\"}"
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
|
||||
function disable_wifi() {
|
||||
rm -f $WLAN0_CFG $HOSTAPD_CFG /etc/default/hostapd
|
||||
}
|
||||
|
||||
|
||||
function configure_wlan0() {
|
||||
echo "auto wlan0"
|
||||
echo "allow-hotplug wlan0"
|
||||
echo "iface wlan0 inet dhcp"
|
||||
echo " wpa-scan-ssid 1"
|
||||
echo " wpa-ap-scan 1"
|
||||
echo " wpa-key-mgmt WPA-PSK"
|
||||
echo " wpa-proto RSN WPA"
|
||||
echo " wpa-pairwise CCMP TKIP"
|
||||
echo " wpa-group CCMP TKIP"
|
||||
echo " wpa-ssid \"$SSID\""
|
||||
|
||||
if [ ${#PASS} -ne 0 ]; then
|
||||
echo " wpa-psk \"$PASS\""
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function configure_wpa() {
|
||||
echo "country=US"
|
||||
echo "ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev"
|
||||
echo "update_config=1"
|
||||
|
||||
if [ ${#PASS} -eq 0 ]; then
|
||||
echo "network={"
|
||||
echo " ssid=\"$SSID\""
|
||||
echo " key_mgmt=NONE"
|
||||
echo "}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function configure_dhcpcd() {
|
||||
echo "hostname"
|
||||
echo "clientid"
|
||||
echo "persistent"
|
||||
echo "option rapid_commit"
|
||||
echo "option domain_name_servers, domain_name, domain_search, host_name"
|
||||
echo "option classless_static_routes"
|
||||
echo "option ntp_servers"
|
||||
echo "option interface_mtu"
|
||||
echo "require dhcp_server_identifier"
|
||||
echo "slaac private"
|
||||
|
||||
if $AP; then
|
||||
echo
|
||||
echo "interface wlan0"
|
||||
echo " static ip_address=192.168.43.1/24"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function configure_wifi() {
|
||||
disable_wifi
|
||||
echo "source-directory /etc/network/interfaces.d" > /etc/network/interfaces
|
||||
configure_wlan0 > $WLAN0_CFG
|
||||
configure_wpa > $WPA_CFG
|
||||
configure_dhcpcd > $DHCPCD_CFG
|
||||
}
|
||||
|
||||
|
||||
function configure_dnsmasq() {
|
||||
echo "interface=wlan0"
|
||||
echo "domain-needed"
|
||||
echo "bogus-priv"
|
||||
echo "dhcp-range=192.168.43.2,192.168.43.20,255.255.255.0,12h"
|
||||
}
|
||||
|
||||
|
||||
function configure_hostapd() {
|
||||
echo "interface=wlan0"
|
||||
echo "driver=nl80211"
|
||||
echo "ssid=$SSID"
|
||||
echo "hw_mode=g"
|
||||
echo "channel=$CHANNEL"
|
||||
echo "wmm_enabled=0"
|
||||
echo "macaddr_acl=0"
|
||||
echo "auth_algs=1"
|
||||
echo "ignore_broadcast_ssid=0"
|
||||
echo "wpa=2"
|
||||
echo "wpa_passphrase=$PASS"
|
||||
echo "wpa_key_mgmt=WPA-PSK"
|
||||
echo "wpa_pairwise=TKIP"
|
||||
echo "rsn_pairwise=CCMP"
|
||||
}
|
||||
|
||||
|
||||
function is_installed() {
|
||||
dpkg-query -W --showformat='${Status}' $1 |
|
||||
grep "install ok installed" >/dev/null
|
||||
if [ $? -eq 0 ]; then echo true; else echo false; fi
|
||||
}
|
||||
|
||||
|
||||
function configure_ap() {
|
||||
disable_wifi
|
||||
|
||||
# Install packages
|
||||
(
|
||||
$(is_installed dnsmasq) &&
|
||||
$(is_installed hostapd) &&
|
||||
$(is_installed iptables-persistent)
|
||||
|
||||
) || (
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update
|
||||
apt-get install -yq dnsmasq hostapd iptables-persistent
|
||||
)
|
||||
|
||||
configure_dhcpcd > $DHCPCD_CFG
|
||||
configure_dnsmasq > $DNSMASQ_CFG
|
||||
configure_hostapd > $HOSTAPD_CFG
|
||||
|
||||
echo "DAEMON_CONF=\"/etc/hostapd/hostapd.conf\"" > /etc/default/hostapd
|
||||
|
||||
# Enable IP forwarding
|
||||
sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /etc/sysctl.conf
|
||||
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||
|
||||
# Enable IP masquerading
|
||||
iptables -t nat -F
|
||||
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
||||
iptables-save > /etc/iptables/rules.v4
|
||||
}
|
||||
|
||||
|
||||
function usage() {
|
||||
echo "Usage: config-wifi [OPTIONS]"
|
||||
echo
|
||||
echo "Configure wifi as either a client or access point."
|
||||
echo
|
||||
echo "OPTIONS:"
|
||||
echo
|
||||
echo " -a Configure access point."
|
||||
echo " -d Disable wifi."
|
||||
echo " -r Reboot when done."
|
||||
echo " -s <SSID> Set SSID."
|
||||
echo " -p <PASS> Set password."
|
||||
echo " -c <CHANNEL> Set wifi channel."
|
||||
echo " -j Report wifi config as JSON data."
|
||||
echo
|
||||
}
|
||||
|
||||
|
||||
# Parse args
|
||||
while [ $# -ne 0 ]; do
|
||||
case "$1" in
|
||||
-a) AP=true ;;
|
||||
-d) DISABLE=true ;;
|
||||
-r) REBOOT=true; ;;
|
||||
-s) SSID="$2"; shift ;;
|
||||
-p) PASS="$2"; shift ;;
|
||||
-c) CHANNEL="$2"; shift ;;
|
||||
-j) query_config; exit 0 ;;
|
||||
|
||||
-h)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
|
||||
*)
|
||||
usage
|
||||
echo "Unknown argument '$1'"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
|
||||
if $DISABLE; then
|
||||
disable_wifi
|
||||
|
||||
else
|
||||
# Check args
|
||||
function clean_str() {
|
||||
echo "$1" | tr -d '\n\r"'
|
||||
}
|
||||
|
||||
SSID=$(clean_str "$SSID")
|
||||
PASS=$(clean_str "$PASS")
|
||||
|
||||
LANG=C LC_ALL=C # For correct string byte length
|
||||
|
||||
if [ ${#SSID} -eq 0 -o 32 -lt ${#SSID} ]; then
|
||||
echo "Invalid or missing SSID '$SSID'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ${#PASS} -ne 0 ]; then
|
||||
if [ ${#PASS} -lt 8 -o 128 -lt ${#PASS} ]; then
|
||||
echo "Invalid passsword"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$CHANNEL" | grep '^[0-9]\{1,2\}' > /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Invalid channel '$CHANNEL'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Execute
|
||||
if $AP; then
|
||||
echo "Configuring Wifi access point"
|
||||
configure_ap
|
||||
|
||||
else
|
||||
echo "Configuring Wifi"
|
||||
configure_wifi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if $REBOOT; then nohup reboot & fi
|
||||
17
scripts/demo-chroot
Normal file
17
scripts/demo-chroot
Normal file
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash -ex
|
||||
|
||||
ROOT="$PWD/demo"
|
||||
|
||||
# Clean up on EXIT
|
||||
function cleanup {
|
||||
umount "$ROOT"/{dev/pts,dev,sys,proc} 2>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# mount binds
|
||||
mount --bind /dev "$ROOT/dev/"
|
||||
mount --bind /sys "$ROOT/sys/"
|
||||
mount --bind /proc "$ROOT/proc/"
|
||||
mount --bind /dev/pts "$ROOT/dev/pts"
|
||||
|
||||
chroot "$ROOT" "$@"
|
||||
12
scripts/edit-boot-config
Normal file
12
scripts/edit-boot-config
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
cp /boot/config.txt /tmp/
|
||||
|
||||
edit-config /tmp/config.txt "$@"
|
||||
|
||||
diff /boot/config.txt /tmp/config.txt >/dev/null
|
||||
if [ $? -eq 1 ]; then
|
||||
mount -o remount,rw /boot
|
||||
mv /tmp/config.txt /boot/
|
||||
mount -o remount,ro /boot
|
||||
fi
|
||||
83
scripts/edit-config
Normal file
83
scripts/edit-config
Normal file
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import argparse
|
||||
import re
|
||||
|
||||
|
||||
def option_type(s, pat = re.compile(r'\w+=.*')):
|
||||
if not pat.match(s): raise argparse.ArgumentTypeError
|
||||
return s
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description = 'Edit config file.')
|
||||
parser.add_argument('config', help = 'The configuration file to edit.')
|
||||
parser.add_argument('options', nargs = '*', type = option_type,
|
||||
metavar = '<name>=<value>', help = 'An option to set.')
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
# Parse config lines and options
|
||||
lines = []
|
||||
options = {}
|
||||
optRE = re.compile(r'(\w+)\s*=\s*([^#]+)(#.*)?')
|
||||
|
||||
|
||||
class Line:
|
||||
def __init__(self, text, name = None, value = None, comment = None):
|
||||
self.text = text
|
||||
self.name = name
|
||||
self.value = value
|
||||
self.comment = comment
|
||||
|
||||
|
||||
def __str__(self):
|
||||
if self.name is not None:
|
||||
if self.value.strip():
|
||||
text = '%s=%s' % (self.name, self.value)
|
||||
if self.comment: text += ' # ' + self.comment
|
||||
text += '\n'
|
||||
return text
|
||||
|
||||
else: return ''
|
||||
|
||||
return self.text
|
||||
|
||||
|
||||
with open(args.config, 'r') as f:
|
||||
for line in f:
|
||||
m = optRE.match(line.strip())
|
||||
|
||||
if m: name, value, comment = m.groups()
|
||||
else: name, value, comment = None, None, None
|
||||
|
||||
l = Line(line, name, value, comment)
|
||||
lines.append(l)
|
||||
if name is not None: options[name] = l
|
||||
|
||||
|
||||
# Save original config
|
||||
config = ''.join(map(str, lines))
|
||||
|
||||
|
||||
# Set options
|
||||
first = True
|
||||
for opt in args.options:
|
||||
name, value = opt.split('=', 1)
|
||||
|
||||
if name in options: options[name].value = value
|
||||
else:
|
||||
if first and len(lines) and str(lines[:-1]).strip() != '':
|
||||
first = False
|
||||
lines.append(Line('\n'))
|
||||
|
||||
lines.append(Line(None, name, value, None))
|
||||
|
||||
|
||||
# Assemble new config
|
||||
new_config = ''.join(map(str, lines))
|
||||
|
||||
|
||||
if new_config != config:
|
||||
with open(args.config, 'w') as f:
|
||||
f.write(new_config)
|
||||
6
scripts/gplan-build.sh
Normal file
6
scripts/gplan-build.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash -ex
|
||||
|
||||
cd /mnt/host
|
||||
scons -C cbang disable_local="re2 libevent"
|
||||
export CBANG_HOME="/mnt/host/cbang"
|
||||
scons -C camotics gplan.so with_gui=0 with_tpl=0
|
||||
59
scripts/gplan-init-build.sh
Normal file
59
scripts/gplan-init-build.sh
Normal file
@@ -0,0 +1,59 @@
|
||||
#!/bin/bash -ex
|
||||
|
||||
IMG_DATE=2017-11-29
|
||||
IMG_BASE=${IMG_DATE}-raspbian-stretch-lite
|
||||
BASE_URL=https://downloads.raspberrypi.org/raspbian_lite/images
|
||||
IMG_URL=$BASE_URL/raspbian_lite-2017-12-01/$IMG_BASE.zip
|
||||
GPLAN_IMG=gplan-dev.img
|
||||
|
||||
# Create dev image
|
||||
if [ ! -e $GPLAN_IMG ]; then
|
||||
|
||||
# Get base image
|
||||
if [ ! -e $IMG_BASE.img ]; then
|
||||
if [ ! -e $IMG_BASE.zip ]; then
|
||||
wget $IMG_URL
|
||||
fi
|
||||
|
||||
unzip $IMG_BASE.zip
|
||||
fi
|
||||
|
||||
# Copy base image
|
||||
cp $IMG_BASE.img $GPLAN_IMG.tmp
|
||||
|
||||
# Init image
|
||||
mkdir -p rpi-share
|
||||
cp ./scripts/gplan-init-dev-img.sh rpi-share
|
||||
sudo ./scripts/rpi-chroot.sh $GPLAN_IMG.tmp /mnt/host/gplan-init-dev-img.sh
|
||||
|
||||
# Move image
|
||||
mv $GPLAN_IMG.tmp $GPLAN_IMG
|
||||
fi
|
||||
|
||||
# Get repos
|
||||
function fetch_local_repo() {
|
||||
mkdir -p $1
|
||||
git -C $1 init
|
||||
git -C $1 fetch -t "$2" $3
|
||||
git -C $1 reset --hard FETCH_HEAD
|
||||
}
|
||||
|
||||
mkdir -p rpi-share || true
|
||||
|
||||
if [ ! -e rpi-share/cbang ]; then
|
||||
if [ "$CBANG_HOME" != "" ]; then
|
||||
fetch_local_repo rpi-share/cbang "$CBANG_HOME" master
|
||||
else
|
||||
git clone https://github.com/CauldronDevelopmentLLC/cbang \
|
||||
rpi-share/cbang
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -e rpi-share/camotics ]; then
|
||||
if [ "$CAMOTICS_HOME" != "" ]; then
|
||||
fetch_local_repo rpi-share/camotics "$CAMOTICS_HOME" master
|
||||
else
|
||||
git clone https://github.com/CauldronDevelopmentLLC/camotics \
|
||||
rpi-share/camotics
|
||||
fi
|
||||
fi
|
||||
11
scripts/gplan-init-dev-img.sh
Normal file
11
scripts/gplan-init-dev-img.sh
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
export LC_ALL=C
|
||||
cd /mnt/host
|
||||
|
||||
# Update the system
|
||||
apt-get update
|
||||
#apt-get dist-upgrade -y
|
||||
|
||||
# Install packages
|
||||
apt-get install -y scons build-essential libssl-dev python3-dev
|
||||
121
scripts/install.sh
Normal file
121
scripts/install.sh
Normal file
@@ -0,0 +1,121 @@
|
||||
#!/bin/bash
|
||||
|
||||
UPDATE_AVR=true
|
||||
UPDATE_PY=true
|
||||
REBOOT=false
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--no-avr) UPDATE_AVR=false ;;
|
||||
--no-py) UPDATE_PY=false ;;
|
||||
esac
|
||||
shift 1
|
||||
done
|
||||
|
||||
|
||||
if $UPDATE_PY; then
|
||||
systemctl stop bbctrl
|
||||
|
||||
# Update service
|
||||
rm -f /etc/init.d/bbctrl
|
||||
cp scripts/bbctrl.service /etc/systemd/system/
|
||||
systemctl daemon-reload
|
||||
systemctl enable bbctrl
|
||||
fi
|
||||
|
||||
if $UPDATE_AVR; then
|
||||
./scripts/avr109-flash.py src/avr/bbctrl-avr-firmware.hex
|
||||
fi
|
||||
|
||||
# Update config.txt
|
||||
./scripts/edit-boot-config max_usb_current=1
|
||||
./scripts/edit-boot-config config_hdmi_boost=8
|
||||
|
||||
# TODO Enable GPU
|
||||
#./scripts/edit-boot-config dtoverlay=vc4-kms-v3d
|
||||
#./scripts/edit-boot-config gpu_mem=16
|
||||
#chmod ug+s /usr/lib/xorg/Xorg
|
||||
|
||||
# Fix camera
|
||||
grep dwc_otg.fiq_fsm_mask /boot/cmdline.txt >/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
mount -o remount,rw /boot &&
|
||||
sed -i 's/\(.*\)/\1 dwc_otg.fiq_fsm_mask=0x3/' /boot/cmdline.txt
|
||||
mount -o remount,ro /boot
|
||||
REBOOT=true
|
||||
fi
|
||||
|
||||
# Enable memory cgroups
|
||||
grep cgroup_memory /boot/cmdline.txt >/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
mount -o remount,rw /boot &&
|
||||
sed -i 's/\(.*\)/\1 cgroup_memory=1/' /boot/cmdline.txt
|
||||
mount -o remount,ro /boot
|
||||
REBOOT=true
|
||||
fi
|
||||
|
||||
# Remove Hawkeye
|
||||
if [ -e /etc/init.d/hawkeye ]; then
|
||||
apt-get remove --purge -y hawkeye
|
||||
fi
|
||||
|
||||
# Decrease boot delay
|
||||
sed -i 's/^TimeoutStartSec=.*$/TimeoutStartSec=1/' \
|
||||
/etc/systemd/system/network-online.target.wants/networking.service
|
||||
|
||||
# Change to US keyboard layout
|
||||
sed -i 's/^XKBLAYOUT="gb"$/XKBLAYOUT="us" # Comment stops change on upgrade/' \
|
||||
/etc/default/keyboard
|
||||
|
||||
# Setup USB stick automount
|
||||
diff ./scripts/11-automount.rules /etc/udev/rules.d/11-automount.rules \
|
||||
>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
cp ./scripts/11-automount.rules /etc/udev/rules.d/
|
||||
sed -i 's/^\(MountFlags=slave\)/#\1/' \
|
||||
/lib/systemd/system/systemd-udevd.service
|
||||
REBOOT=true
|
||||
fi
|
||||
|
||||
# Increase swap
|
||||
grep 'CONF_SWAPSIZE=1000' /etc/dphys-swapfile >/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
sed -i 's/^CONF_SWAPSIZE=.*$/CONF_SWAPSIZE=1000/' /etc/dphys-swapfile
|
||||
REBOOT=true
|
||||
fi
|
||||
|
||||
# Install xinitrc
|
||||
cp scripts/xinitrc ~pi/.xinitrc
|
||||
chmod +x ~pi/.xinitrc
|
||||
chown pi:pi ~pi/.xinitrc
|
||||
|
||||
# Install bbserial
|
||||
MODSRC=src/bbserial/bbserial.ko
|
||||
MODDST=/lib/modules/$(uname -r)/kernel/drivers/tty/serial/bbserial.ko
|
||||
diff -q $MODSRC $MODDST 2>/dev/null >/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
cp $MODSRC $MODDST
|
||||
depmod
|
||||
REBOOT=true
|
||||
fi
|
||||
|
||||
# Install rc.local
|
||||
cp scripts/rc.local /etc/
|
||||
|
||||
# Install bbctrl
|
||||
if $UPDATE_PY; then
|
||||
rm -rf /usr/local/lib/python*/dist-packages/bbctrl-*
|
||||
./setup.py install --force
|
||||
service bbctrl restart
|
||||
HTTP_DIR=$(find /usr/local/lib/ -type d -name "http")
|
||||
chmod 777 $HTTP_DIR
|
||||
fi
|
||||
|
||||
sync
|
||||
|
||||
if $REBOOT; then
|
||||
echo "Rebooting"
|
||||
reboot
|
||||
fi
|
||||
|
||||
echo "Install complete"
|
||||
27
scripts/log-position-to-gcode
Normal file
27
scripts/log-position-to-gcode
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import json
|
||||
import sys
|
||||
|
||||
p = [0, 0, 0]
|
||||
|
||||
|
||||
print('F400 G21')
|
||||
|
||||
for line in sys.stdin:
|
||||
try:
|
||||
if not line.startswith('I:Comm:> '): continue
|
||||
line = line[9:]
|
||||
|
||||
data = json.loads(line)
|
||||
|
||||
changed = False
|
||||
for axis in range(3):
|
||||
var = 'xyz'[axis] + 'p'
|
||||
if var in data:
|
||||
p[axis] = data[var]
|
||||
changed = True
|
||||
|
||||
if changed: print('G1 X%d Y%d Z%d' % tuple(p))
|
||||
|
||||
except json.decoder.JSONDecodeError: pass
|
||||
19
scripts/next-rc
Normal file
19
scripts/next-rc
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import json
|
||||
|
||||
if os.path.exists('dist/latest-beta.txt'):
|
||||
with open('dist/latest-beta.txt', 'r') as f:
|
||||
latest_beta = f.read().strip()
|
||||
|
||||
else: latest_beta = ''
|
||||
|
||||
with open('package.json', 'r') as f:
|
||||
version = json.load(f)['version']
|
||||
|
||||
if latest_beta.startswith(version + '-rc'):
|
||||
print(int(latest_beta[len(version) + 3:]) + 1)
|
||||
|
||||
else:
|
||||
print(1)
|
||||
1
scripts/ratpoisonrc
Normal file
1
scripts/ratpoisonrc
Normal file
@@ -0,0 +1 @@
|
||||
startup_message off
|
||||
31
scripts/rc.local
Normal file
31
scripts/rc.local
Normal file
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Mount /boot read only
|
||||
mount -o remount,ro /boot
|
||||
|
||||
# Load bbserial
|
||||
echo 3f201000.serial > /sys/bus/amba/drivers/uart-pl011/unbind
|
||||
modprobe -r bbserial
|
||||
modprobe bbserial
|
||||
|
||||
# Set SPI GPIO mode
|
||||
gpio mode 27 alt3
|
||||
|
||||
# Create browser memory limited cgroup
|
||||
if [ -d sys/fs/cgroup/memory ]; then
|
||||
CGROUP=/sys/fs/cgroup/memory/chrome
|
||||
mkdir $CGROUP
|
||||
chown -R pi:pi $CGROUP
|
||||
echo 650000000 > $CGROUP/memory.soft_limit_in_bytes
|
||||
echo 750000000 > $CGROUP/memory.limit_in_bytes
|
||||
fi
|
||||
|
||||
# Reload udev
|
||||
/etc/init.d/udev restart
|
||||
|
||||
# Stop boot splash so it doesn't interfere with X if GPU enabled and to save CPU
|
||||
plymouth quit
|
||||
|
||||
# Start X in /home/pi
|
||||
cd /home/pi
|
||||
sudo -u pi startx
|
||||
23
scripts/reset-video
Normal file
23
scripts/reset-video
Normal file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
import os.path
|
||||
import time
|
||||
|
||||
if not os.path.exists('/dev/video0'):
|
||||
print('/dev/video0 not found')
|
||||
sys.exit(1)
|
||||
|
||||
p = subprocess.Popen('udevadm info -q path /dev/video0'.split(),
|
||||
stdout = subprocess.PIPE)
|
||||
s = p.communicate()[0].decode('utf-8')
|
||||
dev = s.split('/')[7]
|
||||
|
||||
with open('/sys/bus/usb/drivers/usb/unbind', 'w') as f:
|
||||
f.write(dev)
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
with open('/sys/bus/usb/drivers/usb/bind', 'w') as f:
|
||||
f.write(dev)
|
||||
63
scripts/rpi-chroot.sh
Normal file
63
scripts/rpi-chroot.sh
Normal file
@@ -0,0 +1,63 @@
|
||||
#!/bin/bash -ex
|
||||
|
||||
ROOT="$PWD/rpi-root"
|
||||
LOOP=9
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "Usage: $0 <image> <exec>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
IMAGE="$1"
|
||||
LOOP_DEV=/dev/loop${LOOP}
|
||||
EXEC=
|
||||
|
||||
if [ $# -gt 1 ]; then
|
||||
shift
|
||||
EXEC="$@"
|
||||
fi
|
||||
|
||||
# install dependecies
|
||||
if [ ! -e /usr/bin/qemu-arm-static ]; then
|
||||
apt-get update
|
||||
apt-get install -y qemu qemu-user-static binfmt-support
|
||||
fi
|
||||
|
||||
# Clean up on EXIT
|
||||
function cleanup {
|
||||
umount "$ROOT"/{dev/pts,dev,sys,proc,boot,mnt/host,} 2>/dev/null || true
|
||||
losetup -d $LOOP_DEV 2>/dev/null || true
|
||||
rmdir "$ROOT" 2>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# set up image as loop device
|
||||
losetup $LOOP_DEV "$IMAGE"
|
||||
partprobe $LOOP_DEV
|
||||
|
||||
# check and fix filesystems
|
||||
fsck -f ${LOOP_DEV}p1
|
||||
fsck -f ${LOOP_DEV}p2
|
||||
|
||||
# make dir
|
||||
mkdir -p "$ROOT"
|
||||
|
||||
# mount partition
|
||||
mount -o rw ${LOOP_DEV}p2 -t ext4 "$ROOT"
|
||||
mount -o rw ${LOOP_DEV}p1 "$ROOT/boot"
|
||||
|
||||
# mount binds
|
||||
mount --bind /dev "$ROOT/dev/"
|
||||
mount --bind /sys "$ROOT/sys/"
|
||||
mount --bind /proc "$ROOT/proc/"
|
||||
mount --bind /dev/pts "$ROOT/dev/pts"
|
||||
if [ -e ./rpi-share ]; then
|
||||
mkdir -p "$ROOT/mnt/host"
|
||||
mount --bind ./rpi-share "$ROOT/mnt/host"
|
||||
fi
|
||||
|
||||
# copy qemu binary
|
||||
cp /usr/bin/qemu-arm-static "$ROOT/usr/bin/"
|
||||
|
||||
# chroot to raspbian
|
||||
chroot "$ROOT" $EXEC
|
||||
26
scripts/sethostname
Normal file
26
scripts/sethostname
Normal file
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
HOSTNAME="$(echo "$1" | tr '[:upper:]' '[:lower:]')"
|
||||
|
||||
if [ "$HOSTNAME" == "" ]; then
|
||||
echo "Usage: $0 <hostname>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$HOSTNAME" == "localhost" ]; then
|
||||
echo "Cannot set hostname to 'localhost'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$HOSTNAME" =~ ^.*\.local$ ]; then
|
||||
echo "Hostname cannot end with '.local'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! "$HOSTNAME" =~ ^[a-zA-Z][a-zA-Z0-9-]{0,62}$ ]]; then
|
||||
echo "Invalid hostname '$HOSTNAME'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sed -i "s/^127.0.1.1\([[:space:]]*\).*$/127.0.1.1\1$HOSTNAME/" /etc/hosts
|
||||
echo "$HOSTNAME" > /etc/hostname
|
||||
110
scripts/setup_rpi.sh
Normal file
110
scripts/setup_rpi.sh
Normal file
@@ -0,0 +1,110 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
export LC_ALL=C
|
||||
cd /mnt/host
|
||||
|
||||
# Update the system
|
||||
apt-get update
|
||||
apt-get dist-upgrade -y
|
||||
|
||||
# Install packages
|
||||
apt-get install -y avahi-daemon avrdude minicom python3-pip python3-smbus \
|
||||
i2c-tools python3-rpi.gpio libjpeg8 wiringpi dnsmasq hostapd \
|
||||
iptables-persistent chromium-browser xorg rpd-plym-splash samba
|
||||
pip3 install --upgrade tornado sockjs-tornado pyserial
|
||||
|
||||
# Clean
|
||||
apt-get autoclean
|
||||
|
||||
# Enable avahi
|
||||
update-rc.d avahi-daemon defaults
|
||||
|
||||
# Change hostname
|
||||
sed -i "s/raspberrypi/bbctrl/" /etc/hosts /etc/hostname
|
||||
|
||||
# Create bbmc user
|
||||
useradd -m -p $(openssl passwd -1 buildbotics) -s /bin/bash bbmc
|
||||
sed -i 's/pi$/pi,bbmc/g' /etc/group
|
||||
passwd -l pi
|
||||
|
||||
# Disable console on serial port
|
||||
sed -i 's/console=[a-zA-Z0-9]*,115200 \?//' /boot/cmdline.txt
|
||||
|
||||
# Disable i2c HAT ID probe
|
||||
echo -n " bcm2708.vc_i2c_override=1" >> /boot/cmdline.txt
|
||||
|
||||
# Enable I2C
|
||||
sed -i 's/#dtparam=i2c/dtparam=i2c/' /boot/config.txt
|
||||
#echo 'dtparam=i2c_vc=on' >> /boot/config.txt
|
||||
echo i2c-bcm2708 >> /etc/modules
|
||||
echo i2c-dev >> /etc/modules
|
||||
|
||||
# Install bbctrl w/ init.d script
|
||||
cp bbctrl.init.d /etc/init.d/bbctrl
|
||||
chmod +x /etc/init.d/bbctrl
|
||||
update-rc.d bbctrl defaults
|
||||
|
||||
# Disable Pi 3 USART BlueTooth swap
|
||||
echo -e "\ndtoverlay=pi3-disable-bt" >> /boot/config.txt
|
||||
rm -f /etc/systemd/system/multi-user.target.wants/hciuart.service
|
||||
|
||||
# Install hawkeye
|
||||
dpkg -i hawkeye_0.6_armhf.deb
|
||||
sed -i 's/localhost/0.0.0.0/' /etc/hawkeye/hawkeye.conf
|
||||
echo 'ACTION=="add", KERNEL=="video0", RUN+="/usr/sbin/service hawkeye restart"' > /etc/udev/rules.d/50-hawkeye.rules
|
||||
adduser hawkeye video
|
||||
|
||||
# Disable HDMI to save power and remount /boot read-only
|
||||
sed -i 's/^exit 0$//' /etc/rc.local
|
||||
echo "mount -o remount,ro /boot" >> /etc/rc.local
|
||||
echo "gpio mode 27 alt3" >> /etc/rc.local # Enable serial CTS on pin 27
|
||||
|
||||
# Dynamic clock to save power
|
||||
echo -e "\n# Dynamic clock\nnohz=on" >> /boot/config.txt
|
||||
|
||||
# Shave 2 sec off of boot time
|
||||
echo -e "\n# Faster boot\ndtparam=sd_overclock=100" >> /boot/config.txt
|
||||
|
||||
# Enable ssh
|
||||
touch /boot/ssh
|
||||
|
||||
# Fix boot
|
||||
sed -i 's/ root=[^ ]* / root=\/dev\/mmcblk0p2/' /boot/cmdline.txt
|
||||
sed -i 's/^PARTUUID=.*\/boot/\/dev\/mmcblk0p1 \/boot/' /etc/fstab
|
||||
sed -i 's/^PARTUUID=.*\//\/dev\/mmcblk0p2 \//' /etc/fstab
|
||||
|
||||
# Enable browser in xorg
|
||||
sed -i 's/allowed_users=console/allowed_users=anybody/' /etc/X11/Xwrapper.config
|
||||
echo "sudo -u pi startx" >> /etc/rc.local
|
||||
cp /mnt/host/xinitrc /home/pi/.xinitrc
|
||||
cp /mnt/host/ratpoisonrc /home/pi/.ratpoisonrc
|
||||
cp /mnt/host/xorg.conf /etc/X11/
|
||||
|
||||
# Set screen resolution
|
||||
sed -i 's/^#disable_overscan/disable_overscan/' /boot/config.txt
|
||||
sed -i 's/^#framebuffer_/framebuffer_/' /boot/config.txt
|
||||
|
||||
# Boot splash
|
||||
mkdir -p /usr/share/plymouth/themes/buildbotics/
|
||||
cp -av /mnt/host/splash/* /usr/share/plymouth/themes/buildbotics/
|
||||
echo -n " quiet splash logo.nologo plymouth.ignore-serial-consoles" >> /boot/cmdline.txt
|
||||
plymouth-set-default-theme -R buildbotics
|
||||
|
||||
# Samba
|
||||
# TODO install custom smb.conf
|
||||
smbpasswd -a bbmc
|
||||
|
||||
# Install bbctrl
|
||||
tar xf /mnt/host/bbctrl-*.tar.bz2
|
||||
cd $(basename bbctrl-*.tar.bz2 .tar.bz2)
|
||||
./setup.py install
|
||||
cd ..
|
||||
rm -rf $(basename bbctrl-*.tar.bz2 .tar.bz2)
|
||||
|
||||
|
||||
# Allow any user to shutdown
|
||||
chmod +s /sbin/{halt,reboot,shutdown,poweroff}
|
||||
|
||||
# Clean up
|
||||
apt-get autoremove -y
|
||||
apt-get autoclean -y
|
||||
16
scripts/ssh-bbctrl
Normal file
16
scripts/ssh-bbctrl
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
USER=bbmc
|
||||
HOST=bbctrl.local
|
||||
|
||||
if [ $# -eq 1 ]; then
|
||||
if [[ "$1" = *@ ]]; then
|
||||
LOGIN="$1"
|
||||
else
|
||||
LOGIN=$USER@"$1"
|
||||
fi
|
||||
else
|
||||
LOGIN=$USER@$HOST
|
||||
fi
|
||||
|
||||
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "$LOGIN"
|
||||
64
scripts/svg2abs.js
Normal file
64
scripts/svg2abs.js
Normal file
@@ -0,0 +1,64 @@
|
||||
function convertToAbsolute(path) {
|
||||
var x0, y0, x1, y1, x2, y2, segs = path.pathSegList;
|
||||
|
||||
for (var x = 0, y = 0, i = 0, len = segs.numberOfItems; i < len; i++) {
|
||||
var seg = segs.getItem(i), c = seg.pathSegTypeAsLetter;
|
||||
|
||||
if (/[MLHVCSQTA]/.test(c)){
|
||||
if ('x' in seg) x = seg.x;
|
||||
if ('y' in seg) y = seg.y;
|
||||
|
||||
} else {
|
||||
if ('x1' in seg) x1 = x + seg.x1;
|
||||
if ('x2' in seg) x2 = x + seg.x2;
|
||||
if ('y1' in seg) y1 = y + seg.y1;
|
||||
if ('y2' in seg) y2 = y + seg.y2;
|
||||
if ('x' in seg) x += seg.x;
|
||||
if ('y' in seg) y += seg.y;
|
||||
|
||||
switch(c) {
|
||||
case 'm':
|
||||
segs.replaceItem(path.createSVGPathSegMovetoAbs(x, y), i);
|
||||
break;
|
||||
case 'l':
|
||||
segs.replaceItem(path.createSVGPathSegLinetoAbs(x, y), i);
|
||||
break;
|
||||
case 'h':
|
||||
segs.replaceItem(path.createSVGPathSegLinetoHorizontalAbs(x), i);
|
||||
break;
|
||||
case 'v':
|
||||
segs.replaceItem(path.createSVGPathSegLinetoVerticalAbs(y), i);
|
||||
break;
|
||||
case 'c':
|
||||
segs.replaceItem(
|
||||
path.createSVGPathSegCurvetoCubicAbs(x, y, x1, y1, x2, y2), i);
|
||||
break;
|
||||
case 's':
|
||||
segs.replaceItem(
|
||||
path.createSVGPathSegCurvetoCubicSmoothAbs(x, y, x2, y2), i);
|
||||
break;
|
||||
case 'q':
|
||||
segs.replaceItem(
|
||||
path.createSVGPathSegCurvetoQuadraticAbs(x, y, x1, y1), i);
|
||||
break;
|
||||
case 't':
|
||||
segs.replaceItem(
|
||||
path.createSVGPathSegCurvetoQuadraticSmoothAbs(x, y), i);
|
||||
break;
|
||||
case 'a':
|
||||
segs.replaceItem(
|
||||
path.createSVGPathSegArcAbs(x, y, seg.r1, seg.r2, seg.angle,
|
||||
seg.largeArcFlag, seg.sweepFlag), i);
|
||||
break;
|
||||
|
||||
case 'z': case 'Z':
|
||||
x = x0;
|
||||
y = y0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Record the start of a subpath
|
||||
if (c == 'M' || c == 'm') x0 = x, y0 = y;
|
||||
}
|
||||
}
|
||||
27
scripts/update-bbctrl
Normal file
27
scripts/update-bbctrl
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
(
|
||||
flock -n 9
|
||||
|
||||
UPDATE=/var/lib/bbctrl/firmware/update.tar.bz2
|
||||
|
||||
if [ ! -e "$UPDATE" ]; then
|
||||
echo "Missing $UPDATE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
systemctl stop bbctrl
|
||||
|
||||
rm -rf /tmp/update
|
||||
mkdir /tmp/update
|
||||
cd /tmp/update
|
||||
|
||||
LOG=/var/log/bbctrl.$(date +%Y%m%d-%H%M%S).install
|
||||
tar xf "$UPDATE"
|
||||
cd *
|
||||
./scripts/install.sh "$*" 2>&1 > $LOG
|
||||
|
||||
cd -
|
||||
rm -rf /tmp/update $UPDATE
|
||||
|
||||
) 9> /var/lock/bbctrl.update.lock
|
||||
25
scripts/upgrade-bbctrl
Normal file
25
scripts/upgrade-bbctrl
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
(
|
||||
flock -n 9
|
||||
|
||||
VERSION=$(curl -s https://raw.githubusercontent.com/OneFinityCNC/onefinity/master/latest.txt)
|
||||
PKG_NAME=onefinity-$VERSION
|
||||
PKG=/var/lib/bbctrl/firmware/update.tar.bz2
|
||||
PKG_URL=https://https://raw.githubusercontent.com/OneFinityCNC/onefinity/master/release/$PKG_NAME.tar.bz2
|
||||
|
||||
logger Installing bbctrl firmware $VERSION
|
||||
|
||||
cd /var/lib/bbctrl
|
||||
mkdir -p firmware
|
||||
|
||||
echo Downloading $PKG_URL
|
||||
curl -s $PKG_URL > $PKG
|
||||
|
||||
/usr/local/bin/update-bbctrl
|
||||
|
||||
echo Success
|
||||
|
||||
logger bbctrl firmware $VERSION installed
|
||||
|
||||
) 9> /var/lock/bbctrl.upgrade.lock
|
||||
22
scripts/xinitrc
Normal file
22
scripts/xinitrc
Normal file
@@ -0,0 +1,22 @@
|
||||
hostinfo.sh &
|
||||
ratpoison &
|
||||
|
||||
xset -dpms
|
||||
xset s off
|
||||
xset s noblank
|
||||
|
||||
while true; do
|
||||
tvservice -s 2>&1 | grep "state 0x40001" >/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
# Clear browser errors
|
||||
PREFS='/home/pi/.config/chromium/Default/Preferences'
|
||||
sed -i 's/"exited_cleanly":false/"exited_cleanly":true/' $PREFS
|
||||
sed -i 's/"exit_type":"Crashed"/"exit_type":"Normal"/' $PREFS
|
||||
|
||||
# Start browser
|
||||
/usr/local/bin/browser --no-first-run --disable-infobars \
|
||||
--noerrdialogs --disable-3d-apis http://localhost/
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
done
|
||||
3
scripts/xorg.conf
Normal file
3
scripts/xorg.conf
Normal file
@@ -0,0 +1,3 @@
|
||||
Section "ServerFlags"
|
||||
Option "DontVTSwitch" "on"
|
||||
EndSection
|
||||
Reference in New Issue
Block a user