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
49 changes: 44 additions & 5 deletions bouteillederouge.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import sys
import requests
import argparse
import subprocess

from threading import Thread

Expand Down Expand Up @@ -51,11 +52,10 @@
parser.print_help()
sys.exit(1)

from subprocess import call
configfile = '/tmp/poppy_config.yaml'
call(['python', 'bootstrap.py',
'--config-path', configfile,
'localhost', args.creature])
subprocess.call(['python', 'bootstrap.py',
'--config-path', configfile,
'localhost', args.creature])
else:
configfile = os.path.expanduser('~/.poppy_config.yaml')

Expand Down Expand Up @@ -210,12 +210,41 @@ def done_updating():

@app.route('/camera', methods=['POST'])
def switch_camera():
checked = request.form['checked'];
checked = request.form['checked']
pm.update_config('robot.camera', True if checked == 'on' else False)
flash('Your robot camera is now turned {}!'.format(checked), 'success')
return ('', 204)


@app.route('/configure-motors')
def configure_motors():
# Remove old poppy-configure output to avoid user confusion
try:
os.remove(pm.config.poppy_configure.logfile)
except OSError:
pass
return render_template('motor-configuration.html', motors=pm._get_robot_motor_list())


@app.route('/call_poppy_configure', methods=['POST'])
def call_poppy_configure():
motor = request.form['motor']
pm.update_config('robot.motors', motor)
return ('', 204)

@app.route('/settings/wifi')
def configure_wifi():
return render_template('wifi.html')

@app.route('/wifi/list')
def wifi_list():
return

@app.route('/configure_hostspot', methods=['POST'])
def hostspot_configuration():
return


@app.route('/ready-to-roll')
def ready_to_roll():
with open(pm.config.info.logfile) as f:
Expand Down Expand Up @@ -263,6 +292,16 @@ def update_raw_logs():
return Response(content, mimetype='text/plain')


@app.route('/api/configure_motors_logs')
def poppy_config_logs():
try:
with open(pm.config.poppy_configure.logfile) as f:
content = f.read()
except IOError:
content = ''
return Response(content, mimetype='text/plain')


def get_host():
host = pm.config.robot.name
host = host if host == 'localhost' else '{}.local'.format(host)
Expand Down
10 changes: 10 additions & 0 deletions default_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,13 @@ update:
url: https://raw.githubusercontent.com/poppy-project/raspoppy/master/auto-update.sh
logfile: $home/.install.log
lockfile: /tmp/poppy-update-pid.lock

poppy_configure:
logfile: /tmp/poppy-config.log
poppup_startup: on

wifi:
hostspot_conf_file: /boot/hotspot.txt
hostspot_service: rpi-access-point
default_ssid: Poppy Hotspot
default_password: poppyproject
61 changes: 61 additions & 0 deletions puppet_master.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import os
import time
import re
import requests

from subprocess import call, check_call
from contextlib import closing
from threading import Thread
from string import Template

from poppyd import PoppyDaemon
from config import Config, attrsetter
from pypot.creatures import installed_poppy_creatures


class PuppetMaster(object):
Expand All @@ -21,6 +24,7 @@ def __init__(self, DaemonCls, configfile, pidfile):
self.config_handlers = {
'robot.camera': lambda _: self.restart(),
'robot.name': self._change_hostname,
'robot.motors': self._configure_motors
}
self._updating = False

Expand Down Expand Up @@ -85,6 +89,62 @@ def _change_hostname(self, name):
call(['sudo', 'systemctl', 'restart', 'avahi-daemon.service'])
self.restart()

def _get_robot_motor_list(self):
try:
RobotCls = installed_poppy_creatures[self.config.robot.creature]
return sorted(RobotCls.default_config['motors'].keys())
except KeyError:
return ['']

def _configure_motors(self, motor):
self.stop()
creature = self.config.robot.creature.split('poppy-')[1]
f = open(self.config.poppy_configure.logfile,"wb")
check_call(['poppy-configure', creature, motor], stdout=f, stderr=f)
self.start()

def _set_hostspot_configuration(self, ssid, passphrase, hide_hostname=0):
conf = "ssid=%s\npassphrase=%s\nhide_hostname=%s\n" % (ssid, passphrase, hide_hostname)
with open('/tmp/hotspot.conf', 'w') as f:
f.write(conf)

os.system('sudo mv /tmp/hotspot.conf %s' % self.config.wifi.hostspot_conf_file)
call(['sudo', 'systemctl', 'restart', self.config.wifi.hostspot_service])

def _get_hostspot_configuration(self):
conf=''
with open(self.config.wifi.hostspot_conf_file, 'r') as f:
conf = f.read()
ssid=re.match('s/^ssid=\(.\+\)$/\1/p', conf)
passphrase = re.match('s/^passphrase=\(.\+\)$/\1/p', conf)
hide_hostname = re.match('s/^hide_hostname=\(.\+\)$/\1/p', conf)
return {'ssid'=ssid, 'passphrase'=passphrase, 'hide_hostname'=hide_hostname}

def _disable_hostpot(self):
conf_path = self.config.wifi.hostspot_conf_file
if os.path.isfile(conf_path):
os.system("sudo mv %s %s" % (conf_path, os.path.join(conf_path, '.backup'))
call(['sudo', 'systemctl', 'restart', self.config.wifi.hostspot_service])

def _enable_hostspot(self):
conf_path = self.config.wifi.hostspot_conf_file
if os.path.isfile(os.path.join(conf_path, '.backup')):
cmd = "sudo mv %s %s" % (os.path.join(conf_path, '.backup'), conf_path)
call(['sudo', 'systemctl', 'restart', self.config.wifi.hostspot_service])

else:
self._set_hostspot_configuration(self.config.wifi.default_ssid, self.config.wifi.default_password)


def _disable_wifi_client(self):
pass
# os.system("sudo mv /etc/wpa-supplicant.conf")

def _wifi_list(self):
pass
def _wifi connect(self, ssid, password):
pass

def shutdown(self):
try:
for m in self.get_motors():
Expand All @@ -106,6 +166,7 @@ def send_value(self, motor, register, value):
r = requests.post(url.format(motor, register), json=value)
return r


if __name__ == '__main__':
import sys

Expand Down
Binary file added static/img/motor_one_by_one.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion templates/logs.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ <h1 class="section-title">Logs</h1>
}

function startTimeout() {
timeOut = window.setTimeout(refreshLogs, 1000);
timeOut = window.setTimeout(refreshLogs, 500);
}

startTimeout();
Expand Down
97 changes: 97 additions & 0 deletions templates/motor-configuration.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
{% extends "base.html" %}
{% block content %}

<div class="row">
<div class="columns">
<h1 class="section-title">Configure your motors</h1>
</div>
</div>

<div class="row">
<div class="large-6 columns">
<div class="callout">
<p>
Out of factory motors come all with the same identifiant in their internal memory. To be able to differenciate each motor in the robot, we have to configure it, to change their identifiant.
<br>
To do so,
<b>you have to plug ONE motor at a time</b>. It is very important, otherwise, they will all have the same new identifiant and you won't be able to communicate with them.
</p>
</div>
</div>

<div class="large-6 columns">
<div class="callout">
<div class="row">
<div class="large-9 columns">
<img width="900" src="{{ url_for('static', filename='img/motor_one_by_one.jpg') }}" alt="How to plug a motor">
</div>
</div>
</div>
</div>

<div class="row">
<div class="large-6 columns">
<div class="callout">
<h4>
Which motor do you want to configure?
</h4>
{% if motors | length > 1 %}
<form>
<div class="row">
<div class="large-9 columns">
<select id="motor">
{% for m in motors %}
<option value="{{ m }}">{{ m }}</option>
{% endfor %}
</select>
</div>
<div class="large-3 columns">
<button id="configure-motor" type="button" class="button">Configure</button>
</div>
</div>
</form>
{% else %}
<p>No Poppy creature seems to be installed on the robot.</p>
{% endif %}

</div>
</div>
</div>

<div class="row">
<div class="large-12 columns">
<pre>
<code id="robot-logs" class="accesslog hljs">{{ update_logs_content }}</code>
</pre>
</div>
</div>
</div>
{% endblock content %}
{% block endscript %}
<script>
var timeOut;
// /api/configure_motors_logs
function refreshLogs() {
$.get('{{ url_for('poppy_config_logs') }}', function (rawLogs) {
var logsElement = document.getElementById('robot-logs');

logsElement.innerHTML = rawLogs;
hljs.highlightBlock(logsElement);

startTimeout();
});
}

function startTimeout() {
logTimeOut = window.setTimeout(refreshLogs, 1000);
}

startTimeout();

$('#configure-motor').click(function () {
motor_to_configure = $('#motor').val().trim();
$.post('/call_poppy_configure', {motor: motor_to_configure});

});
</script>
{% endblock endscript %}
25 changes: 21 additions & 4 deletions templates/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,26 @@ <h2>Robot hostname</h2>
</form>
</div>
</div>
</div>

<div class="row">
<div class="large-12 columns">
<div class="large-6 columns">
<div class="callout">
<h2>Configure your motors</h2>
<div class="row">
<div class="large-9 columns">
<div class="callout primary">
<p>Configure your motors when you assemble your robot for the first time.</p>
</div>
</div>
<div class="large-3 columns">
<a href={{ url_for('configure_motors') }}>
<button type="button" class="button">Start configuration</button>
</a>
</div>
</div>
</div>
</div>

<div class="large-6 columns">
<div class="callout">
<h2>Upgrade your robot software</h2>
<div class="row">
Expand All @@ -63,7 +79,8 @@ <h2>Upgrade your robot software</h2>
</div>
</div>
</div>
</div>



{% endblock content %}

Expand Down