Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding simplistic webserver #15

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
29 changes: 29 additions & 0 deletions sem-6000-web.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Simple Webfrontend
_"Simplistic python/flask wrapper for the _sem-6000.exp_ command"_

This little webserver lets you control your known (`.known_sem6`) devices through a browser.

## Getting started
Install flask and yattag python modules.
```
sudo pip3 install flask yattag
```

## Check functionality
Start the service once.
```
$ python3 ./sem-6000-web.py
```
Access via _http://IP:5000_

## Register as Service
Register as SystemD service at bootup.
```
sudo systemctl enable --now "$(pwd)/sem-6000-web.service"
```

Check the status and logs.
```
systemctl status sem-6000-web
journalctl -f -u sem-6000-web
```
95 changes: 95 additions & 0 deletions sem-6000-web.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os, subprocess
from flask import Flask, request, Response, abort
from yattag import Doc


# learn known devices
devices = []
with open(os.path.expanduser("~/.known_sem6"), 'r') as f:
for line in f.readlines():
devices.append(line.strip().split(' ')[-1])

actions = [ 'on', 'off', 'toggle', 'status' ]


def run_command(command):
""" execute the given command, return it's std-out and -err"""
result = subprocess.run(command.split(' '), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out = result.stdout.decode('utf-8'); err = result.stderr.decode('utf-8')
out = F"{command}{os.linesep}{out}"
if err != '':
out = F"{out}{os.linesep}{err}"
return out


# flask application starts here
app = Flask(__name__)

@app.route('/sem/<path:device>/', methods=["GET", "POST"])
def handle_sem(device):
""" run this when '/sem/<device>/?action=<action>' was accessed """
# verfiy parameters
if device not in devices:
return abort(404, F"device '{device}' unknown")

action = request.args.get('action') # parse GET or POST arguments to identify 'action' parameter
if request.environ['REQUEST_METHOD'] == 'POST':
action = request.form['action']

if action is None:
action = 'status'

if action not in actions:
return abort(404, F"action '{action}' unknown")

# start assembly of page
doc, tag, text = Doc().tagtext()
with tag('title'):
text(device)

# if request was anything than 'status' redirect back to status
if action != 'status':
doc.asis(F"<meta http-equiv=\"refresh\" content=\"1;{request.environ['PATH_INFO']}\">")

# add buttons at the top of page
with tag('form', method='get', action=request.environ['PATH_INFO']):
with tag('table', border='0', style="text-align:center;"):
for a in actions:
with tag('td'):
with tag('input', type='submit', name='action', value=a):
pass

# add section with output of command
with tag('hr'):
with tag('pre'):
# assemble and run command
text(run_command(F"./sem-6000.exp {device} --{action} --print"))
with tag('hr'):
pass

# render and return page
return Response(doc.getvalue(), mimetype='text/html;charset=UTF-8')


@app.route('/', methods=["GET"])
def handle_root():
""" run this when '/' was accessed """
# start assembly of page
doc, tag, text = Doc().tagtext()
with tag('h1'):
text('known SEM-6000 devices')

for device in devices:
with tag('h2'):
with tag('a', href=F"/sem/{device}/"): text(F"Device {device}")

# render and return page
return Response(doc.getvalue(), mimetype='text/html;charset=UTF-8')


if __name__ == "__main__":
app.run(debug=False, host='0.0.0.0', port=5000)

11 changes: 11 additions & 0 deletions sem-6000-web.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[Unit]
Description=voltcraft sem-6000 web control
After=bluetooth.target

[Service]
User=pi
WorkingDirectory=/home/pi/voltcraft-sem-6000
ExecStart=/usr/bin/python3 sem-6000-web.py

[Install]
WantedBy=multi-user.target