import htmlPy
from htmlPy import Bridge, attach
import urllib2, cookielib, urllib
import time
import os, json, sys, logging
from threading import Thread
logging.basicConfig(level=logging.DEBUG)
global_cur_heat = 0
global_cur_fan = 0
global_cur_temp = 0
global_iter = 0
global_remaining_time = 0
global_error = ""
HOST_URL = "http://10.102.152.15/sbhs/experiment/"
class SBHSClient(Bridge):
def __init__(self):
self.path = os.path.dirname(sys.executable) if getattr(sys, 'frozen', False) else os.path.dirname(os.path.realpath(__file__))
super(SBHSClient, self).__init__()
self.app = htmlPy.AppWindow(title="SBHS Vlabs Client", width=360, height=600, x_pos=32, y_pos=32)
self.app.window.setFixedSize(360, 600)
#setting up urllib object and host link
try:
config_options = {}
with open(os.path.join(self.path, "config.txt")) as f:
logging.debug("config.txt present. Loading configuration.")
for line in f:
if len(line.strip()) > 2:
opt = line.split(":")
config_options[opt[0].strip()] = opt[1].strip()
if config_options["base_link"] != "None" and len(config_options["base_link"]) > 2:
link = config_options["base_link"]
else:
link = HOST_URL
if config_options["use_proxy"] != "Yes":
proxy_handler = urllib2.ProxyHandler({})
logging.debug("Proxy: None")
else:
logging.debug("Loading proxy.")
proxy_url = config_options["proxy_type"] + "://"
proxy_url += (urllib.quote(config_options["proxy_username"]) + ":" if config_options["proxy_username"] != "" else "")
proxy_url += (urllib.quote(config_options["proxy_password"]) + "@" if config_options["proxy_username"] != "" else "")
proxy_url += config_options["proxy_host"] + ":"
proxy_url += config_options["proxy_port"] + "/"
proxy_handler = urllib2.ProxyHandler({config_options["proxy_type"]: proxy_url})
logging.debug("Proxy: " + config_options["proxy_type"] + ": " + proxy_url)
logging.debug("BASE_LINK: " + link)
except Exception as e:
logging.exception("Error while loading config. Switching to default configuration.")
link = HOST_URL
proxy_handler = urllib2.ProxyHandler({})
logging.debug("Proxy: None")
logging.debug("BASE_LINK: " + link)
#initializing class variables
self.base_url = ""
self.version = "3"
self.urllib2 = urllib2
self.logdir = "logs"
self.scilabreadfname = "scilabread.sce"
self.scilabwritefname = "scilabwrite.sce"
self.cur_heat = 0
self.cur_fan = 0
self.cur_temp = 0
self.iter = 0
self.remaining_time = 0
self.error = ""
self.status = False
self.machine_ip=""
self.link = link
cookie_support = cookielib.CookieJar()
opener = urllib2.build_opener(proxy_handler, urllib2.HTTPCookieProcessor(cookie_support))
self.urllib2.install_opener(opener)
self.app.setTemplatePath(self.path)
@attach(result=str)
def check_connection(self):
try:
print self.link+"check_connection"
br = urllib2.urlopen(self.link + "check_connection")
return br.read()
except Exception:
logging.exception("Failed in checking server connection")
return "NO"
@attach(result=bool)
def client_version(self):
try:
br = urllib2.urlopen(self.link + "client_version")
return br.read() == self.version
except Exception:
logging.exception("Failed in checking client version")
return False
@attach(str, str, result=str)
def authenticate(self, username, password):
try:
username = str(username)
password = str(password)
#Setting Up the base_url on which experiment is to be done
input_data = urllib.urlencode({"username": username, "password": password})
ip_req = self.urllib2.Request(self.link + "initiallogin", input_data)
json_response = urllib2.urlopen(ip_req)
data = json.loads(json_response.read())
if not data["STATUS"]==200:
self.error = data["MESSAGE"]["DATA"]
global_error = self.error
return data["MESSAGE"]["DATA"]
if data["MESSAGE"]["IS_IP"] == "1":
#For architecture with RPis connected through LAN
self.machine_ip = data["MESSAGE"]["DATA"]
self.base_url = self.link + "pi/" + self.machine_ip +"/pi/experiment/"
else:
#For architecture with SBHS directly connected to master Server
self.base_url = self.link
#Initiate a new Experiment on base_url
req = self.urllib2.Request(self.base_url + "initiate", input_data)
br = urllib2.urlopen(req)
data = json.loads(br.read())
if data["STATUS"] == 1:
#On Successful creation of new experiment
self.username = username
if not os.path.exists(self.logdir):
os.makedirs(self.logdir)
logdir = os.path.join(self.logdir, username)
if not os.path.exists(logdir):
os.makedirs(logdir)
self.logfile_handler = open(os.path.join(logdir, data["MESSAGE"]), "a")
self.status = True
self.app.execute_javascript("document.getElementById('logfile').innerHTML='" + data["MESSAGE"] + "'")
f = open(self.scilabreadfname, 'w')
f.close()
f = open(self.scilabwritefname, 'w')
f.close()
global global_error
global_error = ""
return "TRUE"
else:
self.error = data["MESSAGE"]
global_error = self.error
return data["MESSAGE"]
except Exception:
logging.exception("Error in authentication")
self.error = "Cannot connect to SBHS server."
global global_error
global_error = self.error
return self.error
@attach(result=str)
def get_data(self):
return json.dumps({
"iter": global_iter,
"heat": global_cur_heat,
"fan": global_cur_fan,
"temp": global_cur_temp,
"time": global_remaining_time,
"error": global_error
})
def experiment(self):
while self.status == False:
time.sleep(0.2)
try:
scilabreadf = file(self.scilabreadfname, 'w')
scilabwritef = file(self.scilabwritefname, 'r')
logf = self.logfile_handler
self.scilabreadf = scilabreadf
self.scilabwritef = scilabwritef
scilabreadf.flush()
except Exception:
logging.exception("Error in experiment files.")
self.error = 'Failed to access files needed for experiment'
global global_error
global_error = self.error
return False
while True:
# read data from file that scilab writes to
retry_read = True
while retry_read:
time.sleep(0.001)
cur_scilabwrite_pos = scilabwritef.tell()
scilabwritestr = scilabwritef.readline()
if not scilabwritestr.endswith('\n'):
scilabwritef.seek(cur_scilabwrite_pos)
retry_read = True
else:
retry_read = False
scilabwritestr = scilabwritestr.strip()
if scilabwritestr != "":
try:
scilabwritedata = scilabwritestr.split(' ', 3)
cur_iter = int(float(scilabwritedata[0]))
cur_heat = int(float(scilabwritedata[1]))
cur_fan = int(float(scilabwritedata[2]))
if (cur_heat > 100):
cur_heat = 100
elif (cur_heat < 0):
cur_heat = 0
if (cur_fan > 100):
cur_fan = 100
elif (cur_fan < 0):
cur_fan = 0
cur_variables = ''.join(scilabwritedata[3:]) # converting variable arguments list to string
cur_time = int(time.time() * 1000)
self.cur_heat = cur_heat
self.cur_fan = cur_fan
self.iter = cur_iter
except Exception:
logging.exception("Error in reading data.")
self.error = 'Invalid data format in ' + self.scilabwritefname + '.'
global global_error
global_error = self.error
return False
else:
continue
# read data from server
srv_data = False
while not srv_data:
try:
url_com = self.base_url + 'experiment'
postdata = urllib.urlencode({
'iteration' : cur_iter,
'heat' : cur_heat,
'fan' : cur_fan,
'variables' : cur_variables,
'timestamp' : cur_time
})
req = self.urllib2.Request(url_com)
res = self.urllib2.urlopen(req, postdata)
content = res.read()
srv_data = True
content = json.loads(content)
# print content
# check if content is received properly
if content["STATUS"] == 1:
data_str = content["MESSAGE"]
data = data_str.split(",")
data_str = data[0]
data_str += ' %d' % int(time.time() * 1000) # add client received time stamp
# if variable arguments present in server response append it
if data[1] != "":
data_str += ' ' + data[1]
# calculating and printing time remaining in minutes
self.remaining_time = data[2]
# write data to file
scilabreadf.write(data_str + '\n')
scilabreadf.flush()
templist = data_str.split(" ")
self.cur_temp = templist[3]
# write data to log
logf.write(data_str + '\n')
logf.flush()
global global_cur_heat, global_cur_fan, global_cur_temp
global global_iter, global_remaining_time, global_error
global_cur_heat = self.cur_heat
global_cur_fan = self.cur_fan
global_cur_temp = self.cur_temp
global_iter = self.iter
global_remaining_time = self.remaining_time
global_error = ""
else:
self.error = content["MESSAGE"]
global global_error
global_error = self.error
self.status = False
return False
except Exception:
logging.exception("Error in communicating data to server")
self.error = "Failed to connect to SBHS. Retrying....."
global global_error
global_error = self.error
time.sleep(0.1)
srv_data = False
def run(self):
self.app.setTemplate("index.html")
t2 = Thread(target=self.experiment)
t2.setDaemon(True)
t2.start()
self.app.window.resize(self.app.width, self.app.height)
self.app.window.move(self.app.x_pos, self.app.y_pos)
self.app.window.show()
def runner():
self.app.app.exec_()
try:
self.reset()
self.logfile_handler.close()
self.scilabreadf.close()
self.scilabwritef.close()
except Exception:
logging.exception("Error while reseting SBHS.")
pass
import sys
sys.exit(runner())
def reset(self):
print self.base_url + "reset"
self.urllib2.urlopen(self.base_url + "reset")
if __name__ == "__main__":
s = SBHSClient()
s.app.register(s)
s.run()