Hallo,
ich bastel an einem Modellauto das ich via Raspi über Web steuern kann.
Mein Problem ist die Datenübertragung Python <--> HTML.
Konkret möchte ich ein Kommando geben, z.B. losfahren, dann möchte ich über eine Schieberegler die Geschwindigkeit übertragen.
Meigrafd hatte in einem Beitrag schon einmal eine Lösung dafür: Beitrag
Ich finde die Lösung optimal für meine Bedürfnisse. Ich nutze die 3. Variante in der die Daten in JSON gespeichert und via Bottle übergeben werden.
Das Beispiel von ihm funktioniert super, jedoch sieht es leider nur vor, die Daten auf der Webseite anzuzeigen, jedoch nicht dort auch Daten zu laden.
Ich könnte natürlich hinter das Kommando den Wert schreiben und diesen dann in Python abschneiden, aber diese Krücke will ich nicht gehen.
Hier der Python Code:
data = {}
data["MotorSpeed"] = rangepwm
data["servo_untenlinks"] = rangepwm
def servo_unten_func():
servo_unten.set_servo(PIN_SERVO_UNTEN, rangepwm)
print (data)
time.sleep(.2)
servo_unten.stop_servo(PIN_SERVO_UNTEN)
return (rangepwm)
@bottle.route('/')
def MainHandler():
values = {
'test': randrange(1, 1000),
'debug': DEBUG,
}
return bottle.template('index.html', values)
@bottle.route('/static/<filename>')
def StaticHandler(filename):
if filename.endswith(".css"):
bottle.response.content_type = 'text/css'
elif filename.endswith(".js"):
bottle.response.content_type = 'text/javascript'
elif filename.endswith(".png"):
bottle.response.content_type = 'image/png'
return bottle.static_file(filename, root=os.path.join(os.path.dirname(__file__), 'static'))
@bottle.route('/data/')
def TelemetryHandler():
printD("Telemetry Request.")
bottle.response.content_type = 'application/json'
data["PiTEMP"] = getPiTemperature()
rangepwm = data["servo_untenlinks"]
print (data)
return json.dumps(data)
@bottle.route('/cmd/<command>')
def CommandHandler(command):
response = ''
printD("Command Request: {}".format(command))
if command == 'PiTEMP':
response = getPiTemperature()
elif command == 'servo_untenlinks':
response = servo_unten_func()
elif command == 'exit':
response = beenden()
printD("response: %s"% response)
return str(response)
Alles anzeigen
if (typeof(String.prototype.strip) === "undefined") {
String.prototype.strip = function() {
return String(this).replace(/^\s+|\s+$/g, '');
};
}
function isset(strVariableName) {
try {
eval( strVariableName );
} catch( err ) {
if ( err instanceof ReferenceError )
return false;
}
return true;
}
function sleep(millis, callback) {
setTimeout(function() { callback(); } , millis);
}
//source of: http://www.html5tutorial.info/html5-range.php
function printValue(sliderID, textbox) {
var x = document.getElementById(textbox);
var y = document.getElementById(sliderID);
x.value = y.value;
}
function mylog(message) {
if (isset(DEBUG) && DEBUG == 1) {
console.log(message);
if (document.getElementById("Log") !== null) {
var logthingy;
logthingy = document.getElementById("Log");
if( logthingy.innerHTML.length > 5000 )
logthingy.innerHTML = logthingy.innerHTML.slice(logthingy.innerHTML.length-5000);
logthingy.innerHTML = logthingy.innerHTML+"<br/>"+message;
logthingy.scrollTop = logthingy.scrollHeight*2;
}
}
}
//----------------------------------------------------------------
function Send(command) {
$.ajax({
type: "GET",
url: "/cmd/" + command,
dataType: "JSON",
success: function(data) {
mylog("Command Response: " + data);
if (document.getElementById(command) !== null) {
document.getElementById(command).innerHTML = data;
}
}
});
}
function receive() {
$.getJSON("/data/")
.fail(function() {
console.log("Empfangen_error");
clearTimeout(telemetryTimer);
})
.done(function(data) {
//Wert des Schiebereglers lesen
data["servo_untenlinks"] = ("servo_untenlinks", document.getElementById("servo_untenlinks").value);
mylog("servo" + document.getElementById("servo_untenlinks").value);
console.log(data);
})
}
function get_telemetry() {
$.getJSON("/data/")
.fail(function() {
console.log("Error processing get_telemetry");
clearTimeout(telemetryTimer);
})
.done(function(data) {
$.each(data, function(id,val) {
if (document.getElementById(id) !== null) {
mylog("JSON Data: " + id + ":" + val);
document.getElementById(id).innerHTML = val;
}
})
telemetryTimer = setTimeout(get_telemetry, 2000);
});
}
Alles anzeigen
<!DOCTYPE html>
<html>
<head>
<script>
var DEBUG = {{ debug }};
</script>
<script src="/static/jquery-3.3.1.min.js" type="text/javascript"></script>
<script src="/static/control.js" type="text/javascript"></script>
</head>
<body>
Test: {{ test }}
<br/>
<input type="button" value="RAM" onClick="Send('PiRAM')" />
<span id="PiRAM"></span>
<br/> <input type="button" value="CPU Temperatur" onClick="Send('PiTEMP')" />
<span id="PiTEMP"></span> °C
<br/>
<br/> <input type="button" value="Empfangen" onClick="receive()" />
<br/>
<br/> <input type="button" value="Exit" onClick="Send('exit')" />
<span id="Exit"></span>
<br/>
<br/> <input type="button" value="get_telemetry" onClick="get_telemetry()" />
<span id="telemtry"></span>
<br/>
<p><div id="servo_untenlinksslider" style="text-align:left; width:100%;"> </div></p>
<div class="slidecontainer">
<p>Default range slider:</p>
<input type="range" min="1" max="2000" value="50" id="servo_untenlinks">
</div>
<p><div id="Log" style="text-align:left; width:100%;"> </div></p>
</body>
</html>
Alles anzeigen
Ich kann den eingestellten Wert am Slider auslesen (servo_untenlinks).
Diesen möchte ich jetzt zurück ins Json schreiben:
data["servo_untenlinks"] = ("servo_untenlinks", document.getElementById("servo_untenlinks").value);
Das funktioniert nur so halb..
Über http://IP_adresse:8080/data/ kann ich mir den Inhalt des JSONs anzeigen lassen, der Wert von servo_untenlinks wird nicht aktuallisiert!
Ich lasse mir den Wert von servo_untenlinks jedoch in der Konsole ausgeben (die Konsole im Browser).
Dort kann ich sehen das der Wert sehr wohl als servo_untenlinks gespeichert wird! Nur wird der Wert scheinbar nicht richtig aktuallisiert.
Was mache ich falsch?
Wäre super wenn jemand einen Tipp hätte!
Besten Dank schon mal!