kilnController/kilncontrollerd.py

223 wiersze
6.7 KiB
Python
Czysty Zwykły widok Historia

#!/usr/bin/python
2013-12-10 09:34:32 +00:00
2013-12-10 00:29:21 +00:00
import os
2013-12-10 09:34:32 +00:00
import sys
2013-12-10 00:29:21 +00:00
import logging
import json
2013-11-23 21:25:20 +00:00
import bottle
2014-10-31 16:30:44 +00:00
import gevent
import geventwebsocket
2014-11-01 12:02:33 +00:00
from gevent.pywsgi import WSGIServer
from geventwebsocket.handler import WebSocketHandler
from geventwebsocket import WebSocketError
2013-11-23 21:25:20 +00:00
2013-11-29 23:13:06 +00:00
try:
sys.dont_write_bytecode = True
2013-11-29 23:13:06 +00:00
import config
sys.dont_write_bytecode = False
2013-11-29 23:13:06 +00:00
except:
2019-01-03 21:26:26 +00:00
print("Could not import config file.")
print("Copy config.py.EXAMPLE to config.py and adapt it for your setup.")
2013-11-29 23:13:06 +00:00
exit(1)
2013-12-10 00:29:21 +00:00
logging.basicConfig(level=config.log_level, format=config.log_format)
2019-01-03 07:25:49 +00:00
log = logging.getLogger("kilncontrollerd")
log.info("Starting kilncontrollerd")
2013-11-24 15:18:42 +00:00
2013-12-10 09:34:32 +00:00
script_dir = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, script_dir + '/lib/')
2013-12-10 09:34:32 +00:00
profile_path = os.path.join(script_dir, "storage", "profiles")
2013-11-24 17:35:08 +00:00
from oven import Oven, Profile
2013-11-24 15:18:42 +00:00
from ovenWatcher import OvenWatcher
2013-11-23 23:21:26 +00:00
2013-11-23 21:25:20 +00:00
app = bottle.Bottle()
oven = Oven()
ovenWatcher = OvenWatcher(oven)
2013-12-10 00:29:21 +00:00
2013-11-23 22:26:06 +00:00
@app.route('/')
def index():
2019-01-03 07:25:49 +00:00
return bottle.redirect('/kilncontroller/index.html')
2013-11-23 22:26:06 +00:00
2013-12-10 00:29:21 +00:00
2019-01-03 07:25:49 +00:00
@app.route('/kilncontroller/:filename#.*#')
2013-11-23 22:26:06 +00:00
def send_static(filename):
2013-12-10 00:29:21 +00:00
log.debug("serving %s" % filename)
2019-01-03 21:26:26 +00:00
return bottle.static_file(filename,
root=os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])),
"public"))
2013-11-23 22:26:06 +00:00
2013-12-10 00:29:21 +00:00
2013-11-24 15:07:59 +00:00
def get_websocket_from_request():
2013-12-10 00:29:21 +00:00
env = bottle.request.environ
2013-11-23 21:25:20 +00:00
wsock = env.get('wsgi.websocket')
if not wsock:
abort(400, 'Expected WebSocket request.')
2013-11-24 15:12:45 +00:00
return wsock
2013-12-10 00:29:21 +00:00
2013-11-24 15:07:59 +00:00
@app.route('/control')
def handle_control():
wsock = get_websocket_from_request()
2013-11-24 15:50:16 +00:00
log.info("websocket (control) opened")
2013-11-23 21:25:20 +00:00
while True:
try:
message = wsock.receive()
2013-12-10 00:29:21 +00:00
log.info("Received (control): %s" % message)
2013-11-24 17:35:08 +00:00
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)
2013-11-30 00:42:35 +00:00
ovenWatcher.record(profile)
2013-12-06 22:02:07 +00:00
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)
2013-12-10 00:29:21 +00:00
simulated_oven = Oven(simulate=True, time_step=0.05)
2013-12-06 22:02:07 +00:00
simulation_watcher = OvenWatcher(simulated_oven)
simulation_watcher.add_observer(wsock)
2019-01-03 21:26:26 +00:00
# simulated_oven.run_profile(profile)
# simulation_watcher.record(profile)
2013-11-24 17:35:08 +00:00
elif msgdict.get("cmd") == "STOP":
2013-11-23 23:21:26 +00:00
log.info("Stop command received")
2013-11-23 21:25:20 +00:00
oven.abort_run()
except WebSocketHandler.WebSocketError:
2013-11-23 21:25:20 +00:00
break
2013-11-24 15:50:16 +00:00
log.info("websocket (control) closed")
2013-12-10 00:29:21 +00:00
2013-11-24 14:50:07 +00:00
@app.route('/storage')
def handle_storage():
2013-11-24 15:07:59 +00:00
wsock = get_websocket_from_request()
2013-11-24 15:50:16 +00:00
log.info("websocket (storage) opened")
2013-11-24 14:50:07 +00:00
while True:
try:
message = wsock.receive()
2013-11-24 15:50:16 +00:00
if not message:
break
2013-12-10 00:29:21 +00:00
log.debug("websocket (storage) received: %s" % message)
2013-12-09 11:51:08 +00:00
2013-11-24 19:01:33 +00:00
try:
msgdict = json.loads(message)
except:
msgdict = {}
2013-12-09 11:51:08 +00:00
2013-11-24 14:50:07 +00:00
if message == "GET":
log.info("GET command recived")
2013-11-24 15:07:59 +00:00
wsock.send(get_profiles())
2016-03-12 20:16:29 +00:00
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())
2013-11-24 19:01:33 +00:00
elif msgdict.get("cmd") == "PUT":
2013-11-24 14:50:07 +00:00
log.info("PUT command received")
2013-11-24 19:01:33 +00:00
profile_obj = msgdict.get('profile')
2013-12-10 00:29:21 +00:00
force = msgdict.get('force', False)
2013-11-24 19:01:33 +00:00
if profile_obj:
2013-11-25 00:12:58 +00:00
#del msgdict["cmd"]
2013-12-10 00:29:21 +00:00
if save_profile(profile_obj, force):
msgdict["resp"] = "OK"
2013-11-25 00:12:58 +00:00
else:
2013-12-10 00:29:21 +00:00
msgdict["resp"] = "FAIL"
log.debug("websocket (storage) sent: %s" % message)
2013-12-06 23:01:05 +00:00
2013-11-25 00:12:58 +00:00
wsock.send(json.dumps(msgdict))
2013-11-25 00:24:20 +00:00
wsock.send(get_profiles())
except WebSocketHandler.WebSocketError:
2013-11-24 14:50:07 +00:00
break
2013-11-24 15:50:16 +00:00
log.info("websocket (storage) closed")
2013-11-24 14:50:07 +00:00
2013-12-10 00:29:21 +00:00
2016-07-08 04:41:06 +00:00
@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 WebSocketHandler.WebSocketError:
2016-07-08 04:41:06 +00:00
break
log.info("websocket (config) closed")
2013-11-23 21:25:20 +00:00
@app.route('/status')
2013-11-24 15:07:59 +00:00
def handle_status():
wsock = get_websocket_from_request()
2013-11-29 23:47:35 +00:00
ovenWatcher.add_observer(wsock)
2013-11-24 15:50:16 +00:00
log.info("websocket (status) opened")
2013-11-23 21:25:20 +00:00
while True:
try:
message = wsock.receive()
wsock.send("Your message was: %r" % message)
except WebSocketHandler.WebSocketError:
2013-11-23 21:25:20 +00:00
break
2013-11-24 15:50:16 +00:00
log.info("websocket (status) closed")
2013-11-23 21:25:20 +00:00
2013-11-24 19:01:33 +00:00
2013-11-24 15:07:59 +00:00
def get_profiles():
2013-12-10 00:29:21 +00:00
try:
2013-11-24 19:01:33 +00:00
profile_files = os.listdir(profile_path)
2013-12-10 00:29:21 +00:00
except:
2013-11-24 14:50:07 +00:00
profile_files = []
profiles = []
for filename in profile_files:
2013-12-10 00:29:21 +00:00
with open(os.path.join(profile_path, filename), 'r') as f:
2013-11-24 14:50:07 +00:00
profiles.append(json.load(f))
return json.dumps(profiles)
2013-12-10 00:29:21 +00:00
2013-11-25 00:12:58 +00:00
def save_profile(profile, force=False):
2013-11-24 19:01:33 +00:00
profile_json = json.dumps(profile)
2019-01-03 21:26:26 +00:00
filename = profile['name'] + ".json"
2013-12-10 00:29:21 +00:00
filepath = os.path.join(profile_path, filename)
2013-11-25 00:12:58 +00:00
if not force and os.path.exists(filepath):
2013-12-10 00:29:21 +00:00
log.error("Could not write, %s already exists" % filepath)
2013-11-25 00:12:58 +00:00
return False
2013-11-24 19:01:33 +00:00
with open(filepath, 'w+') as f:
f.write(profile_json)
f.close()
2013-12-10 00:29:21 +00:00
log.info("Wrote %s" % filepath)
2013-11-25 00:12:58 +00:00
return True
2013-11-24 19:01:33 +00:00
2019-01-03 21:26:26 +00:00
2016-03-12 20:16:29 +00:00
def delete_profile(profile):
2019-01-03 21:26:26 +00:00
# profile_json = json.dumps(profile)
filename = profile['name'] + ".json"
2016-03-12 20:16:29 +00:00
filepath = os.path.join(profile_path, filename)
os.remove(filepath)
log.info("Deleted %s" % filepath)
return True
2013-12-10 00:29:21 +00:00
2016-07-08 04:41:06 +00:00
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})
2013-11-23 21:25:20 +00:00
def main():
2013-12-06 22:16:51 +00:00
ip = config.listening_ip
port = config.listening_port
2013-12-10 00:29:21 +00:00
log.info("listening on %s:%d" % (ip, port))
2013-12-09 11:51:08 +00:00
2013-12-10 00:29:21 +00:00
server = WSGIServer((ip, port), app,
handler_class=WebSocketHandler)
2013-11-23 21:25:20 +00:00
server.serve_forever()
2013-12-10 00:29:21 +00:00
2013-11-23 21:25:20 +00:00
if __name__ == "__main__":
main()