kopia lustrzana https://github.com/botheredbybees/kilnController
220 wiersze
6.6 KiB
Python
220 wiersze
6.6 KiB
Python
![]() |
#!/usr/bin/env python2
|
||
![]() |
|
||
![]() |
import os
|
||
![]() |
import sys
|
||
![]() |
import logging
|
||
|
import json
|
||
![]() |
|
||
|
import bottle
|
||
![]() |
import gevent
|
||
|
import geventwebsocket
|
||
![]() |
from gevent.pywsgi import WSGIServer
|
||
![]() |
from geventwebsocket.handler import WebSocketHandler
|
||
![]() |
|
||
![]() |
try:
|
||
![]() |
sys.dont_write_bytecode = True
|
||
![]() |
import config
|
||
![]() |
sys.dont_write_bytecode = False
|
||
![]() |
except:
|
||
|
print "Could not import config file."
|
||
![]() |
print "Copy config.py.EXAMPLE to config.py and adapt it for your setup."
|
||
![]() |
exit(1)
|
||
|
|
||
![]() |
logging.basicConfig(level=config.log_level, format=config.log_format)
|
||
![]() |
log = logging.getLogger("kilncontrollerd")
|
||
|
log.info("Starting kilncontrollerd")
|
||
![]() |
|
||
![]() |
script_dir = os.path.dirname(os.path.realpath(__file__))
|
||
![]() |
sys.path.insert(0, script_dir + '/lib/')
|
||
![]() |
profile_path = os.path.join(script_dir, "storage", "profiles")
|
||
|
|
||
![]() |
from oven import Oven, Profile
|
||
![]() |
from ovenWatcher import OvenWatcher
|
||
![]() |
|
||
![]() |
app = bottle.Bottle()
|
||
|
oven = Oven()
|
||
|
ovenWatcher = OvenWatcher(oven)
|
||
|
|
||
![]() |
|
||
![]() |
@app.route('/')
|
||
|
def index():
|
||
![]() |
return bottle.redirect('/kilncontroller/index.html')
|
||
![]() |
|
||
![]() |
|
||
![]() |
@app.route('/kilncontroller/:filename#.*#')
|
||
![]() |
def send_static(filename):
|
||
![]() |
log.debug("serving %s" % filename)
|
||
![]() |
return bottle.static_file(filename, root=os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), "public"))
|
||
![]() |
|
||
![]() |
|
||
![]() |
def get_websocket_from_request():
|
||
![]() |
env = bottle.request.environ
|
||
![]() |
wsock = env.get('wsgi.websocket')
|
||
|
if not wsock:
|
||
|
abort(400, 'Expected WebSocket request.')
|
||
![]() |
return wsock
|
||
![]() |
|
||
![]() |
|
||
![]() |
@app.route('/control')
|
||
|
def handle_control():
|
||
|
wsock = get_websocket_from_request()
|
||
![]() |
log.info("websocket (control) opened")
|
||
![]() |
while True:
|
||
|
try:
|
||
|
message = wsock.receive()
|
||
![]() |
log.info("Received (control): %s" % message)
|
||
![]() |
msgdict = json.loads(message)
|
||
|
if msgdict.get("cmd") == "RUN":
|
||
|
log.info("RUN command received")
|
||
|
profile_obj = msgdict.get('profile')
|
||
|
if profile_obj:
|
||
|
profile_json = json.dumps(profile_obj)
|
||
|
profile = Profile(profile_json)
|
||
|
oven.run_profile(profile)
|
||
![]() |
ovenWatcher.record(profile)
|
||
![]() |
elif msgdict.get("cmd") == "SIMULATE":
|
||
|
log.info("SIMULATE command received")
|
||
|
profile_obj = msgdict.get('profile')
|
||
|
if profile_obj:
|
||
|
profile_json = json.dumps(profile_obj)
|
||
|
profile = Profile(profile_json)
|
||
![]() |
simulated_oven = Oven(simulate=True, time_step=0.05)
|
||
![]() |
simulation_watcher = OvenWatcher(simulated_oven)
|
||
|
simulation_watcher.add_observer(wsock)
|
||
|
#simulated_oven.run_profile(profile)
|
||
|
#simulation_watcher.record(profile)
|
||
![]() |
elif msgdict.get("cmd") == "STOP":
|
||
![]() |
log.info("Stop command received")
|
||
![]() |
oven.abort_run()
|
||
|
except WebSocketError:
|
||
|
break
|
||
![]() |
log.info("websocket (control) closed")
|
||
![]() |
|
||
![]() |
|
||
![]() |
@app.route('/storage')
|
||
|
def handle_storage():
|
||
![]() |
wsock = get_websocket_from_request()
|
||
![]() |
log.info("websocket (storage) opened")
|
||
![]() |
while True:
|
||
|
try:
|
||
|
message = wsock.receive()
|
||
![]() |
if not message:
|
||
|
break
|
||
![]() |
log.debug("websocket (storage) received: %s" % message)
|
||
![]() |
|
||
![]() |
try:
|
||
|
msgdict = json.loads(message)
|
||
|
except:
|
||
|
msgdict = {}
|
||
![]() |
|
||
![]() |
if message == "GET":
|
||
|
log.info("GET command recived")
|
||
![]() |
wsock.send(get_profiles())
|
||
![]() |
elif msgdict.get("cmd") == "DELETE":
|
||
|
log.info("DELETE command received")
|
||
|
profile_obj = msgdict.get('profile')
|
||
|
if delete_profile(profile_obj):
|
||
|
msgdict["resp"] = "OK"
|
||
|
wsock.send(json.dumps(msgdict))
|
||
|
#wsock.send(get_profiles())
|
||
![]() |
elif msgdict.get("cmd") == "PUT":
|
||
![]() |
log.info("PUT command received")
|
||
![]() |
profile_obj = msgdict.get('profile')
|
||
![]() |
force = msgdict.get('force', False)
|
||
![]() |
if profile_obj:
|
||
![]() |
#del msgdict["cmd"]
|
||
![]() |
if save_profile(profile_obj, force):
|
||
|
msgdict["resp"] = "OK"
|
||
![]() |
else:
|
||
![]() |
msgdict["resp"] = "FAIL"
|
||
|
log.debug("websocket (storage) sent: %s" % message)
|
||
![]() |
|
||
![]() |
wsock.send(json.dumps(msgdict))
|
||
![]() |
wsock.send(get_profiles())
|
||
![]() |
except WebSocketError:
|
||
|
break
|
||
![]() |
log.info("websocket (storage) closed")
|
||
![]() |
|
||
![]() |
|
||
![]() |
@app.route('/config')
|
||
|
def handle_config():
|
||
|
wsock = get_websocket_from_request()
|
||
|
log.info("websocket (config) opened")
|
||
|
while True:
|
||
|
try:
|
||
|
message = wsock.receive()
|
||
|
wsock.send(get_config())
|
||
|
except WebSocketError:
|
||
|
break
|
||
|
log.info("websocket (config) closed")
|
||
|
|
||
|
|
||
![]() |
@app.route('/status')
|
||
![]() |
def handle_status():
|
||
|
wsock = get_websocket_from_request()
|
||
![]() |
ovenWatcher.add_observer(wsock)
|
||
![]() |
log.info("websocket (status) opened")
|
||
![]() |
while True:
|
||
|
try:
|
||
|
message = wsock.receive()
|
||
|
wsock.send("Your message was: %r" % message)
|
||
|
except WebSocketError:
|
||
|
break
|
||
![]() |
log.info("websocket (status) closed")
|
||
![]() |
|
||
![]() |
|
||
![]() |
def get_profiles():
|
||
![]() |
try:
|
||
![]() |
profile_files = os.listdir(profile_path)
|
||
![]() |
except:
|
||
![]() |
profile_files = []
|
||
|
profiles = []
|
||
|
for filename in profile_files:
|
||
![]() |
with open(os.path.join(profile_path, filename), 'r') as f:
|
||
![]() |
profiles.append(json.load(f))
|
||
|
return json.dumps(profiles)
|
||
|
|
||
![]() |
|
||
![]() |
def save_profile(profile, force=False):
|
||
![]() |
profile_json = json.dumps(profile)
|
||
|
filename = profile['name']+".json"
|
||
![]() |
filepath = os.path.join(profile_path, filename)
|
||
![]() |
if not force and os.path.exists(filepath):
|
||
![]() |
log.error("Could not write, %s already exists" % filepath)
|
||
![]() |
return False
|
||
![]() |
with open(filepath, 'w+') as f:
|
||
|
f.write(profile_json)
|
||
|
f.close()
|
||
![]() |
log.info("Wrote %s" % filepath)
|
||
![]() |
return True
|
||
![]() |
|
||
![]() |
def delete_profile(profile):
|
||
|
profile_json = json.dumps(profile)
|
||
|
filename = profile['name']+".json"
|
||
|
filepath = os.path.join(profile_path, filename)
|
||
|
os.remove(filepath)
|
||
|
log.info("Deleted %s" % filepath)
|
||
|
return True
|
||
![]() |
|
||
![]() |
|
||
|
def get_config():
|
||
|
return json.dumps({"temp_scale": config.temp_scale,
|
||
|
"time_scale_slope": config.time_scale_slope,
|
||
|
"time_scale_profile": config.time_scale_profile,
|
||
|
"kwh_rate": config.kwh_rate,
|
||
|
"currency_type": config.currency_type})
|
||
|
|
||
|
|
||
![]() |
def main():
|
||
![]() |
ip = config.listening_ip
|
||
|
port = config.listening_port
|
||
![]() |
log.info("listening on %s:%d" % (ip, port))
|
||
![]() |
|
||
![]() |
server = WSGIServer((ip, port), app,
|
||
|
handler_class=WebSocketHandler)
|
||
![]() |
server.serve_forever()
|
||
|
|
||
![]() |
|
||
![]() |
if __name__ == "__main__":
|
||
|
main()
|