kopia lustrzana https://github.com/jbruce12000/kiln-controller
				
				
				
			Revert "profile filetype checks"
							rodzic
							
								
									2e756178dc
								
							
						
					
					
						commit
						0958eddbfb
					
				| 
						 | 
				
			
			@ -8,4 +8,3 @@ thumbs.db
 | 
			
		|||
#storage/profiles
 | 
			
		||||
#config.py
 | 
			
		||||
.idea/*
 | 
			
		||||
.DS_Store
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,8 +8,7 @@ import json
 | 
			
		|||
import bottle
 | 
			
		||||
import gevent
 | 
			
		||||
import geventwebsocket
 | 
			
		||||
 | 
			
		||||
# from bottle import post, get
 | 
			
		||||
#from bottle import post, get
 | 
			
		||||
from gevent.pywsgi import WSGIServer
 | 
			
		||||
from geventwebsocket.handler import WebSocketHandler
 | 
			
		||||
from geventwebsocket import WebSocketError
 | 
			
		||||
| 
						 | 
				
			
			@ -17,11 +16,10 @@ from geventwebsocket import WebSocketError
 | 
			
		|||
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.")
 | 
			
		||||
    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)
 | 
			
		||||
| 
						 | 
				
			
			@ -29,7 +27,7 @@ log = logging.getLogger("kiln-controller")
 | 
			
		|||
log.info("Starting kiln controller")
 | 
			
		||||
 | 
			
		||||
script_dir = os.path.dirname(os.path.realpath(__file__))
 | 
			
		||||
sys.path.insert(0, script_dir + "/lib/")
 | 
			
		||||
sys.path.insert(0, script_dir + '/lib/')
 | 
			
		||||
profile_path = config.kiln_profiles_directory
 | 
			
		||||
 | 
			
		||||
from oven import SimulatedOven, RealOven, Profile
 | 
			
		||||
| 
						 | 
				
			
			@ -47,99 +45,93 @@ ovenWatcher = OvenWatcher(oven)
 | 
			
		|||
# this ovenwatcher is used in the oven class for restarts
 | 
			
		||||
oven.set_ovenwatcher(ovenWatcher)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.route("/")
 | 
			
		||||
@app.route('/')
 | 
			
		||||
def index():
 | 
			
		||||
    return bottle.redirect("/picoreflow/index.html")
 | 
			
		||||
    return bottle.redirect('/picoreflow/index.html')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.get("/api/stats")
 | 
			
		||||
@app.get('/api/stats')
 | 
			
		||||
def handle_api():
 | 
			
		||||
    log.info("/api/stats command received")
 | 
			
		||||
    if hasattr(oven, "pid"):
 | 
			
		||||
        if hasattr(oven.pid, "pidstats"):
 | 
			
		||||
    if hasattr(oven,'pid'):
 | 
			
		||||
        if hasattr(oven.pid,'pidstats'):
 | 
			
		||||
            return json.dumps(oven.pid.pidstats)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.post("/api")
 | 
			
		||||
@app.post('/api')
 | 
			
		||||
def handle_api():
 | 
			
		||||
    log.info("/api is alive")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    # run a kiln schedule
 | 
			
		||||
    if bottle.request.json["cmd"] == "run":
 | 
			
		||||
        wanted = bottle.request.json["profile"]
 | 
			
		||||
        log.info("api requested run of profile = %s" % wanted)
 | 
			
		||||
    if bottle.request.json['cmd'] == 'run':
 | 
			
		||||
        wanted = bottle.request.json['profile']
 | 
			
		||||
        log.info('api requested run of profile = %s' % wanted)
 | 
			
		||||
 | 
			
		||||
        # start at a specific minute in the schedule
 | 
			
		||||
        # for restarting and skipping over early parts of a schedule
 | 
			
		||||
        startat = 0
 | 
			
		||||
        if "startat" in bottle.request.json:
 | 
			
		||||
            startat = bottle.request.json["startat"]
 | 
			
		||||
        startat = 0;      
 | 
			
		||||
        if 'startat' in bottle.request.json:
 | 
			
		||||
            startat = bottle.request.json['startat']
 | 
			
		||||
 | 
			
		||||
        # get the wanted profile/kiln schedule
 | 
			
		||||
        profile = find_profile(wanted)
 | 
			
		||||
        if profile is None:
 | 
			
		||||
            return {"success": False, "error": "profile %s not found" % wanted}
 | 
			
		||||
            return { "success" : False, "error" : "profile %s not found" % wanted }
 | 
			
		||||
 | 
			
		||||
        # FIXME juggling of json should happen in the Profile class
 | 
			
		||||
        profile_json = json.dumps(profile)
 | 
			
		||||
        profile = Profile(profile_json)
 | 
			
		||||
        oven.run_profile(profile, startat=startat)
 | 
			
		||||
        oven.run_profile(profile,startat=startat)
 | 
			
		||||
        ovenWatcher.record(profile)
 | 
			
		||||
 | 
			
		||||
    if bottle.request.json["cmd"] == "stop":
 | 
			
		||||
    if bottle.request.json['cmd'] == 'stop':
 | 
			
		||||
        log.info("api stop command received")
 | 
			
		||||
        oven.abort_run()
 | 
			
		||||
 | 
			
		||||
    if bottle.request.json["cmd"] == "memo":
 | 
			
		||||
    if bottle.request.json['cmd'] == 'memo':
 | 
			
		||||
        log.info("api memo command received")
 | 
			
		||||
        memo = bottle.request.json["memo"]
 | 
			
		||||
        memo = bottle.request.json['memo']
 | 
			
		||||
        log.info("memo=%s" % (memo))
 | 
			
		||||
 | 
			
		||||
    # get stats during a run
 | 
			
		||||
    if bottle.request.json["cmd"] == "stats":
 | 
			
		||||
    if bottle.request.json['cmd'] == 'stats':
 | 
			
		||||
        log.info("api stats command received")
 | 
			
		||||
        if hasattr(oven, "pid"):
 | 
			
		||||
            if hasattr(oven.pid, "pidstats"):
 | 
			
		||||
        if hasattr(oven,'pid'):
 | 
			
		||||
            if hasattr(oven.pid,'pidstats'):
 | 
			
		||||
                return json.dumps(oven.pid.pidstats)
 | 
			
		||||
 | 
			
		||||
    return {"success": True}
 | 
			
		||||
 | 
			
		||||
    return { "success" : True }
 | 
			
		||||
 | 
			
		||||
def find_profile(wanted):
 | 
			
		||||
    """
 | 
			
		||||
    '''
 | 
			
		||||
    given a wanted profile name, find it and return the parsed
 | 
			
		||||
    json profile object or None.
 | 
			
		||||
    """
 | 
			
		||||
    # load all profiles from disk
 | 
			
		||||
    '''
 | 
			
		||||
    #load all profiles from disk
 | 
			
		||||
    profiles = get_profiles()
 | 
			
		||||
    json_profiles = json.loads(profiles)
 | 
			
		||||
 | 
			
		||||
    # find the wanted profile
 | 
			
		||||
    for profile in json_profiles:
 | 
			
		||||
        if profile["name"] == wanted:
 | 
			
		||||
        if profile['name'] == wanted:
 | 
			
		||||
            return profile
 | 
			
		||||
    return None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.route("/picoreflow/:filename#.*#")
 | 
			
		||||
@app.route('/picoreflow/: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"),
 | 
			
		||||
    )
 | 
			
		||||
    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")
 | 
			
		||||
    wsock = env.get('wsgi.websocket')
 | 
			
		||||
    if not wsock:
 | 
			
		||||
        abort(400, "Expected WebSocket request.")
 | 
			
		||||
        abort(400, 'Expected WebSocket request.')
 | 
			
		||||
    return wsock
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.route("/control")
 | 
			
		||||
@app.route('/control')
 | 
			
		||||
def handle_control():
 | 
			
		||||
    wsock = get_websocket_from_request()
 | 
			
		||||
    log.info("websocket (control) opened")
 | 
			
		||||
| 
						 | 
				
			
			@ -151,7 +143,7 @@ def handle_control():
 | 
			
		|||
                msgdict = json.loads(message)
 | 
			
		||||
                if msgdict.get("cmd") == "RUN":
 | 
			
		||||
                    log.info("RUN command received")
 | 
			
		||||
                    profile_obj = msgdict.get("profile")
 | 
			
		||||
                    profile_obj = msgdict.get('profile')
 | 
			
		||||
                    if profile_obj:
 | 
			
		||||
                        profile_json = json.dumps(profile_obj)
 | 
			
		||||
                        profile = Profile(profile_json)
 | 
			
		||||
| 
						 | 
				
			
			@ -159,15 +151,15 @@ def handle_control():
 | 
			
		|||
                    ovenWatcher.record(profile)
 | 
			
		||||
                elif msgdict.get("cmd") == "SIMULATE":
 | 
			
		||||
                    log.info("SIMULATE command received")
 | 
			
		||||
                    # profile_obj = msgdict.get('profile')
 | 
			
		||||
                    # if profile_obj:
 | 
			
		||||
                    #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)
 | 
			
		||||
                    #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()
 | 
			
		||||
| 
						 | 
				
			
			@ -177,7 +169,7 @@ def handle_control():
 | 
			
		|||
    log.info("websocket (control) closed")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.route("/storage")
 | 
			
		||||
@app.route('/storage')
 | 
			
		||||
def handle_storage():
 | 
			
		||||
    wsock = get_websocket_from_request()
 | 
			
		||||
    log.info("websocket (storage) opened")
 | 
			
		||||
| 
						 | 
				
			
			@ -198,18 +190,18 @@ def handle_storage():
 | 
			
		|||
                wsock.send(get_profiles())
 | 
			
		||||
            elif msgdict.get("cmd") == "DELETE":
 | 
			
		||||
                log.info("DELETE command received")
 | 
			
		||||
                profile_obj = msgdict.get("profile")
 | 
			
		||||
                profile_obj = msgdict.get('profile')
 | 
			
		||||
                if delete_profile(profile_obj):
 | 
			
		||||
                    msgdict["resp"] = "OK"
 | 
			
		||||
                  msgdict["resp"] = "OK"
 | 
			
		||||
                wsock.send(json.dumps(msgdict))
 | 
			
		||||
                # wsock.send(get_profiles())
 | 
			
		||||
                #wsock.send(get_profiles())
 | 
			
		||||
            elif msgdict.get("cmd") == "PUT":
 | 
			
		||||
                log.info("PUT command received")
 | 
			
		||||
                profile_obj = msgdict.get("profile")
 | 
			
		||||
                # force = msgdict.get('force', False)
 | 
			
		||||
                profile_obj = msgdict.get('profile')
 | 
			
		||||
                #force = msgdict.get('force', False)
 | 
			
		||||
                force = True
 | 
			
		||||
                if profile_obj:
 | 
			
		||||
                    # del msgdict["cmd"]
 | 
			
		||||
                    #del msgdict["cmd"]
 | 
			
		||||
                    if save_profile(profile_obj, force):
 | 
			
		||||
                        msgdict["resp"] = "OK"
 | 
			
		||||
                    else:
 | 
			
		||||
| 
						 | 
				
			
			@ -223,7 +215,7 @@ def handle_storage():
 | 
			
		|||
    log.info("websocket (storage) closed")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.route("/config")
 | 
			
		||||
@app.route('/config')
 | 
			
		||||
def handle_config():
 | 
			
		||||
    wsock = get_websocket_from_request()
 | 
			
		||||
    log.info("websocket (config) opened")
 | 
			
		||||
| 
						 | 
				
			
			@ -236,7 +228,7 @@ def handle_config():
 | 
			
		|||
    log.info("websocket (config) closed")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.route("/status")
 | 
			
		||||
@app.route('/status')
 | 
			
		||||
def handle_status():
 | 
			
		||||
    wsock = get_websocket_from_request()
 | 
			
		||||
    ovenWatcher.add_observer(wsock)
 | 
			
		||||
| 
						 | 
				
			
			@ -253,39 +245,31 @@ def handle_status():
 | 
			
		|||
def get_profiles():
 | 
			
		||||
    try:
 | 
			
		||||
        profile_files = os.listdir(profile_path)
 | 
			
		||||
        profile_files.sort()
 | 
			
		||||
    except:
 | 
			
		||||
        profile_files = []
 | 
			
		||||
    profiles = []
 | 
			
		||||
    for filename in profile_files:
 | 
			
		||||
        if filename.startswith("._"):
 | 
			
		||||
            pass
 | 
			
		||||
        else:
 | 
			
		||||
            if filename.endswith(".json"):
 | 
			
		||||
                with open(os.path.join(profile_path, filename), "r") as f:
 | 
			
		||||
                    profiles.append(json.load(f))
 | 
			
		||||
            else:
 | 
			
		||||
                pass
 | 
			
		||||
        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"
 | 
			
		||||
    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:
 | 
			
		||||
    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"
 | 
			
		||||
    filename = profile['name']+".json"
 | 
			
		||||
    filepath = os.path.join(profile_path, filename)
 | 
			
		||||
    os.remove(filepath)
 | 
			
		||||
    log.info("Deleted %s" % filepath)
 | 
			
		||||
| 
						 | 
				
			
			@ -293,15 +277,11 @@ def delete_profile(profile):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
        }
 | 
			
		||||
    )
 | 
			
		||||
    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():
 | 
			
		||||
| 
						 | 
				
			
			@ -309,7 +289,8 @@ def main():
 | 
			
		|||
    port = config.listening_port
 | 
			
		||||
    log.info("listening on %s:%d" % (ip, port))
 | 
			
		||||
 | 
			
		||||
    server = WSGIServer((ip, port), app, handler_class=WebSocketHandler)
 | 
			
		||||
    server = WSGIServer((ip, port), app,
 | 
			
		||||
                        handler_class=WebSocketHandler)
 | 
			
		||||
    server.serve_forever()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue