Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/custopize.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@ jobs:
uses: pozetroninc/github-action-get-latest-release@master
with:
repository: guysoft/OctoPi
excludes: prerelease, draft

- name: "🔎 Determine SimplyPrint version"
id: simplyprint_version
uses: pozetroninc/github-action-get-latest-release@master
with:
repository: SimplyPrint/OctoPrint-SimplyPrint
excludes: prerelease, draft

- name: "⬇ Download latest OctoPi"
id: octopi_download
Expand Down
2 changes: 1 addition & 1 deletion scripts/03-install-simplyprint
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ install_cleanup_trap

plugins=(
# add quoted URLs for install archives, separated by newlines, e.g.:
"https://github.com/SimplyPrint/OctoPrint-SimplyPrint/archive/refs/heads/master.zip"
"https://github.com/SimplyPrint/OctoPrint-SimplyPrint/archive/refs/tags/3.1.2rc9.zip"
"https://github.com/eyal0/OctoPrint-PrintTimeGenius/archive/master.zip"
)

Expand Down
23 changes: 23 additions & 0 deletions scripts/06-install-raspiwifi
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
set -x
set -e

export LC_ALL=C

source /common.sh
install_cleanup_trap

apt install python3 python3-pip dnsmasq hostapd -y
pip3 install flask cryptography==36.0.0 pyopenssl
cp -a /files/root/* /
mv /etc/wpa_supplicant/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant.conf.original
mv /etc/dnsmasq.conf /etc/dnsmasq.conf.original
cp /usr/lib/raspiwifi/reset_device/static_files/dnsmasq.conf /etc/
cp /usr/lib/raspiwifi/reset_device/static_files/hostapd.conf.wpa /etc/hostapd/hostapd.conf
mv /etc/dhcpcd.conf /etc/dhcpcd.conf.original
cp /usr/lib/raspiwifi/reset_device/static_files/dhcpcd.conf /etc/
mkdir /etc/cron.raspiwifi
cp /usr/lib/raspiwifi/reset_device/static_files/aphost_bootstrapper /etc/cron.raspiwifi
chmod +x /etc/cron.raspiwifi/aphost_bootstrapper
echo "# RaspiWiFi Startup" >> /etc/crontab
echo "@reboot root run-parts /etc/cron.raspiwifi/" >> /etc/crontab
touch /etc/raspiwifi/host_mode
7 changes: 7 additions & 0 deletions scripts/files/root/etc/raspiwifi/raspiwifi.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ssid_prefix=SimplyPi
auto_config=1
auto_config_delay=300
ssl_enabled=0
server_port=8000
wpa_enabled=0
wpa_key=
103 changes: 103 additions & 0 deletions scripts/files/root/usr/lib/raspiwifi/configuration_app/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
from flask import Flask, request, jsonify
import subprocess
import os
import time
from threading import Thread
import fileinput

app = Flask(__name__)
app.debug = True


@app.route('/')
def index():
wifi_ap_array = scan_wifi_networks()
config_hash = config_file_hash()

# return render_template('app.html', wifi_ap_array = wifi_ap_array, config_hash = config_hash)
return jsonify({'wifi_ap_array': wifi_ap_array, 'config_hash': config_hash})


@app.route('/save_credentials', methods = ['POST'])
def save_credentials():
data = request.json
ssid = data['ssid']
wifi_key = data['wifi_key']

create_wpa_supplicant(ssid, wifi_key)

# Call set_ap_client_mode() in a thread otherwise the reboot will prevent
# the response from getting to the browser
def sleep_and_start_ap():
time.sleep(2)
set_ap_client_mode()
t = Thread(target=sleep_and_start_ap)
t.start()

# return render_template('save_credentials.html', ssid = ssid)
return jsonify({'success': True, 'ssid': ssid})


######## FUNCTIONS ##########

def scan_wifi_networks():
iwlist_raw = subprocess.Popen(['iwlist', 'scan'], stdout=subprocess.PIPE)
ap_list, err = iwlist_raw.communicate()
ap_array = []

for line in ap_list.decode('utf-8').rsplit('\n'):
if 'ESSID' in line:
ap_ssid = line[27:-1]
if ap_ssid != '':
ap_array.append(ap_ssid)

return ap_array

def create_wpa_supplicant(ssid, wifi_key):
temp_conf_file = open('wpa_supplicant.conf.tmp', 'w')

temp_conf_file.write('ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev\n')
temp_conf_file.write('update_config=1\n')
temp_conf_file.write('\n')
temp_conf_file.write('network={\n')
temp_conf_file.write(' ssid="' + ssid + '"\n')

if wifi_key == '':
temp_conf_file.write(' key_mgmt=NONE\n')
else:
temp_conf_file.write(' psk="' + wifi_key + '"\n')

temp_conf_file.write(' }')

temp_conf_file.close

os.system('mv wpa_supplicant.conf.tmp /etc/wpa_supplicant/wpa_supplicant.conf')

def set_ap_client_mode():
os.system('rm -f /etc/raspiwifi/host_mode')
os.system('rm /etc/cron.raspiwifi/aphost_bootstrapper')
os.system('cp /usr/lib/raspiwifi/reset_device/static_files/apclient_bootstrapper /etc/cron.raspiwifi/')
os.system('chmod +x /etc/cron.raspiwifi/apclient_bootstrapper')
os.system('mv /etc/dnsmasq.conf.original /etc/dnsmasq.conf')
os.system('mv /etc/dhcpcd.conf.original /etc/dhcpcd.conf')
os.system('reboot')

def config_file_hash():
config_file = open('/etc/raspiwifi/raspiwifi.conf')
config_hash = {}

for line in config_file:
line_key = line.split("=")[0]
line_value = line.split("=")[1].rstrip()
config_hash[line_key] = line_value

return config_hash


if __name__ == '__main__':
config_hash = config_file_hash()

if config_hash['ssl_enabled'] == "1":
app.run(host = '0.0.0.0', port = int(config_hash['server_port']), ssl_context='adhoc')
else:
app.run(host = '0.0.0.0', port = int(config_hash['server_port']))
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import time
import sys
import os
import reset_lib
import requests

no_conn_counter = 0
consecutive_active_reports = 0
config_hash = reset_lib.config_file_hash()

# If auto_config is set to 0 in /etc/raspiwifi/raspiwifi.conf exit this script
if config_hash['auto_config'] == "0":
sys.exit()
else:
# Main connection monitoring loop at 10 second interval
while True:
time.sleep(10)

# If iwconfig report no association with an AP add 10 to the "No
# Connection Couter"
if reset_lib.is_wifi_active() == False:
no_conn_counter += 10
consecutive_active_reports = 0
# If iwconfig report association with an AP add 1 to the
# consecutive_active_reports counter and 10 to the no_conn_counter
else:
consecutive_active_reports += 1
no_conn_counter += 10
# Since wpa_supplicant seems to breifly associate with an AP for
# 6-8 seconds to check the network key the below will reset the
# no_conn_counter to 0 only if two 10 second checks have come up active.
if consecutive_active_reports >= 2:
no_conn_counter = 0
consecutive_active_reports = 0

# If the number of seconds not associated with an AP is greater or
# equal to the auto_config_delay specified in the /etc/raspiwifi/raspiwifi.conf
# trigger a reset into AP Host (Configuration) mode.
if no_conn_counter >= int(config_hash['auto_config_delay']):
check_reboot = requests.get("http://localhost:5000/plugin/SimplyPrint/can_reboot")
if check_reboot.json().get("can_reboot", False) is True:
reset_lib.reset_to_host_mode()
else:
no_conn_counter = 0

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import reset_lib

reset_lib.reset_to_host_mode()
49 changes: 49 additions & 0 deletions scripts/files/root/usr/lib/raspiwifi/reset_device/reset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import os
import re
import subprocess
import reset_lib

pi_map = {'Raspberry Pi Zero 2 W Rev 1.0': 'PiZero2',
'Raspberry Pi 3 Model B Rev 1.2': 'Pi3B',
'Raspberry Pi 3 Model B Plus Rev 1.3': 'Pi3B+',
'Raspberry Pi 4 Model B Rev 1.2': 'Pi4B',
'Raspberry Pi 4 Model B Rev 1.1': 'Pi4B',
'Raspberry Pi 4 Model B Rev 1.4': 'Pi4B',
'Raspberry Pi 2 Model B Rev 1.1': 'Pi2B',
'Raspberry Pi Zero W Rev 1.1': 'PiZero',
'Raspberry Pi Zero 2 Rev 1.0': 'PiZero2',
'Raspberry Pi 3 Model A Plus Rev 1.0': 'Pi3A',
'Raspberry Pi Model B Rev 2': 'Pi1B',
'Raspberry Pi Model B Plus Rev 1.2': 'Pi1B+',
'Raspberry Pi 400 Rev 1.0': 'Pi400',
'Hardkernel Odroid XU4': 'OdroidXU4',
'Raspberry Pi Compute Module 3 Plus Rev 1.0': 'PiCompute3+',
'Xunlong Orange Pi Zero': 'OrangePiZero',
'Xunlong Orange Pi PC': 'OrangePiPC'
}

counter = 0
cpuinfo = subprocess.check_output(['cat', '/proc/cpuinfo']).decode('utf-8')

serial_match = re.search(r"Serial\s+:\s(\S+)$", cpuinfo, re.MULTILINE)
if serial_match:
serial_last_four = serial_match.group(1)[-4:]
else:
serial_last_four = '0000'

model_info_match = re.search(r"Model\s+:\s(.+)$", cpuinfo, re.MULTILINE)
if model_info_match:
model_info = pi_map[model_info_match.group(1).strip()] or ''
else:
model_info = ''

config_hash = reset_lib.config_file_hash()
ssid_prefix = config_hash['ssid_prefix'].strip()
reboot_required = False

reboot_required = reset_lib.wpa_check_activate(config_hash['wpa_enabled'], config_hash['wpa_key'])

reboot_required = reset_lib.update_ssid(ssid_prefix, serial_last_four, model_info)

if reboot_required:
os.system('reboot')
92 changes: 92 additions & 0 deletions scripts/files/root/usr/lib/raspiwifi/reset_device/reset_lib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import os
import fileinput
import subprocess

def config_file_hash():
config_file = open('/etc/raspiwifi/raspiwifi.conf')
config_hash = {}

for line in config_file:
line_key = line.split("=")[0]
line_value = line.split("=")[1].rstrip()
config_hash[line_key] = line_value

return config_hash

def wpa_check_activate(wpa_enabled, wpa_key):
wpa_active = False
reboot_required = False

with open('/etc/hostapd/hostapd.conf') as hostapd_conf:
for line in hostapd_conf:
if 'wpa_passphrase' in line:
wpa_active = True

if wpa_enabled == '1' and wpa_active == False:
reboot_required = True
os.system('cp /usr/lib/raspiwifi/reset_device/static_files/hostapd.conf.wpa /etc/hostapd/hostapd.conf')

if wpa_enabled == '1':
with fileinput.FileInput('/etc/hostapd/hostapd.conf', inplace=True) as hostapd_conf:
for line in hostapd_conf:
if 'wpa_passphrase' in line:
if 'wpa_passphrase=' + wpa_key not in line:
print('wpa_passphrase=' + wpa_key)
os.system('reboot')
else:
print(line, end = '')
else:
print(line, end = '')

if wpa_enabled == '0' and wpa_active == True:
reboot_required = True
os.system('cp /usr/lib/raspiwifi/reset_device/static_files/hostapd.conf.nowpa /etc/hostapd/hostapd.conf')

return reboot_required

def update_ssid(ssid_prefix, serial_last_four, model_info):
reboot_required = False
ssid_correct = False

with open('/etc/hostapd/hostapd.conf') as hostapd_conf:
for line in hostapd_conf:
if ssid_prefix in line:
ssid_correct = True

if ssid_correct == False:
with fileinput.FileInput("/etc/hostapd/hostapd.conf", inplace=True) as file:
for line in file:
if 'ssid=' in line:
line_array = line.split('=')
line_array[1] = ssid_prefix + '-' + serial_last_four + ' ' + model_info.strip()
print(line_array[0] + '=' + line_array[1])
else:
print(line, end = '')

reboot_required = True

return reboot_required

def is_wifi_active():
iwconfig_out = subprocess.check_output(['iwconfig']).decode('utf-8')
wifi_active = True

if "Access Point: Not-Associated" in iwconfig_out:
wifi_active = False

return wifi_active

def reset_to_host_mode():
if not os.path.isfile('/etc/raspiwifi/host_mode'):
os.system('aplay /usr/lib/raspiwifi/reset_device/button_chime.wav')
os.system('rm -f /etc/wpa_supplicant/wpa_supplicant.conf')
os.system('rm -f /home/pi/Projects/RaspiWifi/tmp/*')
os.system('rm /etc/cron.raspiwifi/apclient_bootstrapper')
os.system('cp /usr/lib/raspiwifi/reset_device/static_files/aphost_bootstrapper /etc/cron.raspiwifi/')
os.system('chmod +x /etc/cron.raspiwifi/aphost_bootstrapper')
os.system('mv /etc/dhcpcd.conf /etc/dhcpcd.conf.original')
os.system('cp /usr/lib/raspiwifi/reset_device/static_files/dhcpcd.conf /etc/')
os.system('mv /etc/dnsmasq.conf /etc/dnsmasq.conf.original')
os.system('cp /usr/lib/raspiwifi/reset_device/static_files/dnsmasq.conf /etc/')
os.system('touch /etc/raspiwifi/host_mode')
os.system('reboot')
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

python3 /usr/lib/raspiwifi/reset_device/reset.py &

python3 /usr/lib/raspiwifi/reset_device/connection_monitor.py &
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

python3 /usr/lib/raspiwifi/reset_device/reset.py &

python3 /usr/lib/raspiwifi/configuration_app/app.py &

hostapd -dd /etc/hostapd/hostapd.conf &
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
interface wlan0
static ip_address=192.168.100.1/24
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
interface=wlan0
dhcp-range=192.168.100.10,192.168.100.15,12h
#dhcp-option=option:router,192.168.100.1
#dhcp-option=option:netmask,255.255.255.0

# Delays sending DHCPOFFER and proxydhcp replies for at least the specified number of seconds.
dhcp-mac=set:client_is_a_pi,B8:27:EB:*:*:*
dhcp-reply-delay=tag:client_is_a_pi,2

address=/simplypisetup.com/192.168.100.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface=wlan0
driver=nl80211
ssid=temp-ssid
channel=1
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
interface=wlan0
driver=nl80211
ssid=temp-ssid
channel=1
auth_algs=1
wpa=2
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
wpa_passphrase=0
Loading