class TSMrecv(Component): def __init__(self, logfile): super(TSMrecv, self).__init__() self.pid = os.getpid() self.logger.info("(PID %s) - starting TSM receiver",str(self.pid)) self.dbase = Database() logpath = '/tmp/' + logfile + '.log' try: os.remove(logpath) except OSError: pass self.fh = logging.FileHandler(logpath) self.fh.setLevel(logging.WARNING) self.fh.setFormatter(self.logformatter) self.logger.addHandler(self.fh) self.logger.warning("(PID %s) - starting TSM receiver",str(self.pid)) def on_ack(self): '''Time Sensitive Messaging ''' msg = self.ack.recv_pyobj() self.logger.info("PID (%s) - on_ack():%s",str(self.pid),str(msg)) sendTime = self.ack.get_sendTime() recvTime = self.ack.get_recvTime() self.logger.warning("sendTime: %s, recvTime: %s" %(sendTime, recvTime)) self.logger.warning("%s FlightTime: %s" %(msg, recvTime-sendTime)) self.dbase.post(now=datetime.datetime.now(), tag_dict={"ID":msg}, seriesName="TSM", value=recvTime-sendTime) def __destroy__(self): self.logger.info("(PID %s) - stopping TSM reciever",str(self.pid))
def __init__(self, logfile): super(Solver, self).__init__() self.pid = os.getpid() self.logger.info("(PID %s) - starting Solver", str(self.pid)) #Waste Space parameters self.delta = 1 # 1 MB # self.size = self.delta self.name = '/tmp/tmp%s' % randomword(8) self.logger.info(os.getcwd()) #App Specific parameters self.solverID = 1 print("solverID %s" % self.solverID) self.solution = None self.objective = 0 self.connected = 0 self.new_offers = False self.solver = MatchingSolver(MICROGRID) self.buying_offers = [] self.selling_offers = [] self.finalized = -1 self.waiting_solutionID = False self.PREDICTION_WINDOW = 5 self.recordTime = False self.interval_trades = {} self.solutions = {} self.ISID = 0 self.DeadLine = 0.5 #seconds ideally this would be gotten from the framework API self.Pgain = 25 #50 self.PWMax = 50 self.priorPW = self.PREDICTION_WINDOW self.logpath = '/tmp/' + logfile + '.log' self.killLog = 'killLog.log' try: os.remove(self.logpath) except OSError: pass self.fh = logging.FileHandler(self.logpath) self.fh.setLevel(logging.INFO) self.fh.setFormatter(self.logformatter) self.logger.addHandler(self.fh) self.logger.info("(PID %s) - starting Solver", str(self.pid)) self.s = open('/dev/zero').read(1024 * 100 - 1) self.dbase = Database() self.dbase.post(now=datetime.datetime.now(), tag_dict={"object": "Solver_" + str(self.solverID)}, seriesName="PWMax", value=self.PWMax) self.uid = os.geteuid() # self.logger.info("UID: %s" %self.uid) self.username = pwd.getpwuid(self.uid)[0] # self.logger.info("USERNAME: %s" %self.username) self.thisProcess = psutil.Process(self.pid) self.cpuUtil = self.thisProcess.cpu_percent()
def __init__(self, logfile): super(TSMrecv, self).__init__() self.pid = os.getpid() self.logger.info("(PID %s) - starting TSM receiver",str(self.pid)) self.dbase = Database() logpath = '/tmp/' + logfile + '.log' try: os.remove(logpath) except OSError: pass self.fh = logging.FileHandler(logpath) self.fh.setLevel(logging.WARNING) self.fh.setFormatter(self.logformatter) self.logger.addHandler(self.fh) self.logger.warning("(PID %s) - starting TSM receiver",str(self.pid))
def __init__(self,ID,logfile): super(Trader, self).__init__() self.pid = os.getpid() self.logger.info("(PID %s) - starting Trader",str(self.pid)) self.prosumer_id = ID self.net_production = self.read_data(self.prosumer_id) self.selling_offers = set() self.buying_offers = set() self.connected =0 self.dbase = Database() self.role = None self.roleID = 0 #self.grid = zmq.Context().socket(zmq.PUB) #self.grid.bind('tcp://127.0.0.1:2000') self.interval_asks = {} self.interval_bids = {} self.interval_trades ={} self.finalized = -1 #RESOURCE MANAGEMENT PARAMETERS #NETWORK self.blk = 512 self.min = 1*self.blk self.max = 4*self.blk self.msg_size = self.min logpath = '/tmp/' + logfile + '.log' self.killLog = 'killLog.log' try: os.remove(logpath) except OSError: pass self.fh = logging.FileHandler(logpath) self.fh.setLevel(logging.WARNING) self.fh.setFormatter(self.logformatter) self.logger.addHandler(self.fh) self.logger.warning("(PID %s) - starting Trader",str(self.pid))
def __init__(self, logfile): super(Recorder, self).__init__() self.pid = os.getpid() self.logger.info("(PID %s) - starting Recorder", str(self.pid)) self.connected = 0 self.interval_trades = {} self.finalized = -1 self.solutions = collections.defaultdict(dict) self.solution2solver = {} self.dbase = Database() logpath = '/tmp/' + logfile + '.log' try: os.remove(logpath) except OSError: pass self.fh = logging.FileHandler(logpath) self.fh.setLevel(logging.WARNING) self.fh.setFormatter(self.logformatter) self.logger.addHandler(self.fh) self.logger.warning("(PID %s) - starting Recorder", str(self.pid))
def __init__(self, logfile): super(DSO, self).__init__() self.pid = os.getpid() self.logger.info("(PID %s) - starting DSO",str(self.pid)) self.client = EthereumClient(ip=MINER, port=PORT) self.account = self.client.accounts()[0] # use the first owned address self.deploy_contract() self.next_interval = START_INTERVAL t = time() self.epoch = t - START_INTERVAL * INTERVAL_LENGTH self.dbase = Database() logpath = '/tmp/' + logfile + '.log' try: os.remove(logpath) except OSError: pass self.fh = logging.FileHandler(logpath) self.fh.setLevel(logging.WARNING) self.fh.setFormatter(self.logformatter) self.logger.addHandler(self.fh) self.logger.warning("(PID %s) - starting DSO",str(self.pid))
class Solver(Component): def __init__(self, logfile): super(Solver, self).__init__() self.pid = os.getpid() self.logger.info("(PID %s) - starting Solver", str(self.pid)) #Waste Space parameters self.delta = 1 # 1 MB # self.size = self.delta self.name = '/tmp/tmp%s' % randomword(8) self.logger.info(os.getcwd()) #App Specific parameters self.solverID = 1 print("solverID %s" % self.solverID) self.solution = None self.objective = 0 self.connected = 0 self.new_offers = False self.solver = MatchingSolver(MICROGRID) self.buying_offers = [] self.selling_offers = [] self.finalized = -1 self.waiting_solutionID = False self.PREDICTION_WINDOW = 5 self.recordTime = False self.interval_trades = {} self.solutions = {} self.ISID = 0 self.DeadLine = 0.5 #seconds ideally this would be gotten from the framework API self.Pgain = 25 #50 self.PWMax = 50 self.priorPW = self.PREDICTION_WINDOW self.logpath = '/tmp/' + logfile + '.log' self.killLog = 'killLog.log' try: os.remove(self.logpath) except OSError: pass self.fh = logging.FileHandler(self.logpath) self.fh.setLevel(logging.INFO) self.fh.setFormatter(self.logformatter) self.logger.addHandler(self.fh) self.logger.info("(PID %s) - starting Solver", str(self.pid)) self.s = open('/dev/zero').read(1024 * 100 - 1) self.dbase = Database() self.dbase.post(now=datetime.datetime.now(), tag_dict={"object": "Solver_" + str(self.solverID)}, seriesName="PWMax", value=self.PWMax) self.uid = os.geteuid() # self.logger.info("UID: %s" %self.uid) self.username = pwd.getpwuid(self.uid)[0] # self.logger.info("USERNAME: %s" %self.username) self.thisProcess = psutil.Process(self.pid) self.cpuUtil = self.thisProcess.cpu_percent() # def connectGrafana(self): # try : # # self.db = InfluxDBClient(Config.INFLUX_DBASE_HOST,Config.INFLUX_DBASE_PORT, # # Config.INFLUX_DBASE_USER,Config.INFLUX_DBASE_PASSWORD, # # "solverDbase") # # self.db.create_database(Config.INFLUX_DBASE_NAME) # # self.db.switch_database(Config.INFLUX_DBASE_NAME) # self.dbase = Database() # self.dbase.post(now=datetime.datetime.now(), tag_dict={"object":"Solver_"+str(self.solverID)}, seriesName="PWMax", value=self.PWMax) # # except requests.exceptions.ConnectionError as e: # self.logger.warning("CONNECTION ERROR %s" %e) # self.logger.warning("try again") # self.connectGrafana() # def on_contractAddr(self): # self.logger.info("on_contractAddr()") # # req = self.contractAddr.recv_pyobj() # self.logger.info("PID (%s) - on_contractAddr():%s",str(self.pid),str(req)) # # self.epoch = time() - req['time'] # self.contract_address = req['contract'] # self.logger.info("Contract address: " + self.contract_address) # self.logger.info("Setting up connection to Ethereum client...") # client = EthereumClient(ip=MINER, port=PORT) # self.account = client.accounts()[0] # use the first owned address # self.logger.info("Creating contract object...") # self.contract = MatchingContract(client, self.contract_address) # self.connected = 1 def on_contractAddr(self): try: req = self.contractAddr.recv_pyobj() if 'contract' in req: self.logger.info("PID (%s) - on_contractAddr():%s", str(self.pid), str(req)) self.epoch = time() - req['time'] self.time_interval = int(time() - self.epoch) // INTERVAL_LENGTH self.solutions[self.time_interval] = {} self.contract_address = req['contract'] self.logger.info("Contract address: " + self.contract_address) self.logger.info("Setting up connection to Ethereum client...") client = EthereumClient(ip=MINER, port=PORT) self.account = client.accounts()[ 0] # use the first owned address self.logger.info("Creating contract object...") self.contract = MatchingContract(client, self.contract_address) self.contract.registerProsumer(self.account, prosumer_id, PROSUMER_FEEDER[prosumer_id]) self.connected = 1 else: self.logger.info("reply is:%s " % req) except PortError as e: self.logger.info("on_contractAddr:port exception = %d" % e.errno) if e.errno in (PortError.EAGAIN, PortError.EPROTO): self.logger.info("on_contractAdd: port error received") def on_poller(self): now = self.poller.recv_pyobj() self.logger.info('PID(%s) - on_poller(): %s', str(self.pid), str(now)) self.logger.info('update') if self.connected == 0: self.query_contract_address() elif self.connected == 1: self.logger.debug("Polling events...") # # if self.time_interval == 28: # with open(self.killLog, 'w') as f: # f.write("KILL PROCESS: %s" %time()) # self.logger.warning("KILL PROCESS: %s" %time()) # os.kill(self.pid,signal.SIGKILL) for event in self.contract.poll_events(): params = event['params'] name = event['name'] self.logger.info("{}({}).".format(name, params)) if (name == "BuyingOfferPosted") or (name == "SellingOfferPosted"): self.new_offers = True offer = Offer(params['ID'], params['prosumer'], params['startTime'], params['endTime'], params['energy']) if name == "BuyingOfferPosted": self.buying_offers.append(offer) else: self.selling_offers.append(offer) elif (name == "SolutionCreated") and (params['solverID'] == self.solverID): self.waiting_solutionID = False solutionID = params['solutionID'] self.solutions[self.time_interval][self.ISID] = solutionID if self.solution is not None: self.logger.info( "Solution {} created by contract, adding trades..." .format(solutionID)) trades = [ trade for trade in self.solution if int(trade['p']) > 0 ] for trade in trades: self.contract.addTrade(self.account, solutionID, trade['s'].ID, trade['b'].ID, trade['t'], int(trade['p'])) self.logger.info( "{} trades have been submitted to the contract.". format(len(trades))) # if self.PREDICTION_WINDOW < 60: # self.PREDICTION_WINDOW +=5 # self.logger.info("PREDICTION_WINDOW: %s" %self.PREDICTION_WINDOW) # self.dbase.post(now=datetime.datetime.now(), tag_dict={"resource":"Memory", "ID":'Solver'+str(self.solverID)}, seriesName="Waste", value=self.PREDICTION_WINDOW) else: self.logger.info( "Solution {} created by contract, but no solution has been found for this time interval (yet)." .format(solutionID)) elif name == "Finalized": self.logger.info("INTERVAL:%s SOLUTIONS: %s" % (self.time_interval, self.solutions[self.time_interval])) self.finalized = params['interval'] self.time_interval = self.finalized + 1 self.objective = float("-inf") self.solution = None self.solutions[self.time_interval] = {} if self.waiting_solutionID: self.logger.error( "INTERVAL FINALIZED BEFORE SOLUTION WAS CREATED, AND TRADES ADDED" ) self.waiting_solutionID = False # new_offers = False # TODO: offers for next interval might be added in the same block as the finalization for the previous! self.logger.info( "Trades for interval {} are now final, matching will consider only later intervals from now on." .format(self.finalized)) self.logger.info("New interval is : {}".format( self.time_interval)) elif name == "TradeFinalized": self.logger.info("{}({}).".format(name, params)) for offer in self.selling_offers: if offer.ID == params['sellerID']: offer.energy -= params['power'] break for offer in self.buying_offers: if offer.ID == params['buyerID']: offer.energy -= params['power'] break elif name == "TradeAdded": self.logger.info("{}({}).".format(name, params)) # bashCommand = 'quota -w %s | awk "NR==3"' %self.uid # returns row # # self.logger.info("bashCommand: %s" %bashCommand) # p1 = subprocess.Popen(bashCommand, shell=True, stdout=subprocess.PIPE) # output, error = p1.communicate() # quota = " ".join(output.decode().split()).split(' ') # # self.logger.info("QUOTA: %s" %quota) # space = quota[1].strip('*') # I think the asterisk shows because the value is changing. # # self.logger.info("SPACE: %s" %space) # limit = quota[3] now = datetime.datetime.now() self.cpuUtil = self.thisProcess.cpu_percent() self.memUsage = self.thisProcess.memory_info() # self.logger.info("rss: %s" %self.memUsage[0]) # self.dbase.post(now=now , tag_dict={"disk":"space"}, seriesName="Disk", value=space) # self.dbase.post(now=now , tag_dict={"disk":"limit"}, seriesName="Disk", value=limit) self.dbase.post(now=now, tag_dict={"cpu": "use"}, seriesName="CPU", value=self.cpuUtil) self.dbase.post(now=now, tag_dict={"mem": "rss"}, seriesName="Mem", value=self.memUsage[0]) self.dbase.post(now=now, tag_dict={"mem": "vms"}, seriesName="Mem", value=self.memUsage[1]) def on_solve(self): timer = {} timer['start'] = time() now = self.solve.recv_pyobj() self.logger.info('PID(%s) - on_solve(): %s', str(self.pid), str(now)) if self.connected: if (self.new_offers or self.solutions[self.time_interval] == {}): if self.new_offers: self.logger.info("NEW OFFERS") if self.solutions[self.time_interval] == {}: self.logger.info("NEW INTERVAL") self.ISID += 1 self.solutions[self.time_interval][self.ISID] = None self.recordTime = True self.new_offers = False self.logger.info("Solving...") stopWatch = { "interval": self.time_interval, "start": time(), "running": 1 } # self.logger.info("buying offers") # for offer in self.buying_offers: # self.logger.info("%s, %s, %s, %s, %s" %(str(offer.ID), str(offer.prosumer), str(offer.startTime), str(offer.endTime), str(offer.energy))) # # self.logger.info("selling offers") # for offer in self.selling_offers: # self.logger.info("%s, %s, %s, %s, %s" %(str(offer.ID), str(offer.prosumer), str(offer.startTime), str(offer.endTime), str(offer.energy))) boffers = [] for offer in self.buying_offers: if offer.endTime < self.time_interval: pass elif offer.startTime <= self.time_interval + self.PREDICTION_WINDOW: # print(offer.__dict__) boffers.append(offer) soffers = [] for offer in self.selling_offers: if offer.endTime < self.time_interval: pass elif offer.startTime <= self.time_interval + self.PREDICTION_WINDOW: # print(offer.__dict__) soffers.append(offer) (solution, objective) = self.solver.solve(boffers, soffers, finalized=self.finalized) stopWatch["split"] = time() - stopWatch["start"] now = datetime.datetime.now() self.logger.info( "Solve Time: %s, buy offers: %s, sell offers: %s, total: %s" % (stopWatch["split"], len( self.buying_offers), len(self.selling_offers), len(self.buying_offers) + len(self.selling_offers))) if objective > self.objective: self.solution = solution self.objective = objective self.logger.info( "interval: {}, New solution: (objective = {}).".format( self.time_interval, objective)) self.interval_trades[self.time_interval] = 0 for offer in self.solution: self.logger.info("interval: %s; trade interval: %s" % (self.time_interval, offer['t'])) if offer['t'] == self.time_interval: self.interval_trades[ self.time_interval] += offer['p'] energy = self.interval_trades[self.time_interval] self.logger.info( "Interval: {}, Proposed Energy: {}".format( self.time_interval, energy)) if not self.waiting_solutionID: self.contract.createSolution(self.account, self.solverID) self.waiting_solutionID = True self.logger.info( "Trades will be submitted once a solution is created in the contract." ) else: self.logger.info( "No better solution found (objective = {}).".format( objective)) try: self.dbase.post(now=datetime.datetime.now(), tag_dict={"resource": "storage"}, seriesName="Waste", value=os.stat(self.logpath).st_size) except FileNotFoundError as e: self.logger.info("file does not exist") # self.waste() timer['stop'] = time() timer['split'] = timer['stop'] - timer['start'] if self.recordTime: self.recordTime = False self.logger.info("SOLVE TIME: %s PREDICTION WINDOW: %s" % (timer['split'], self.PREDICTION_WINDOW)) error = timer['split'] - self.DeadLine self.dbase.post( now=now, tag_dict={"object": "Solver_" + str(self.solverID)}, seriesName="error", value=error) self.priorPW = self.PREDICTION_WINDOW self.PREDICTION_WINDOW = self.PREDICTION_WINDOW + 5 #- self.Pgain*error if self.PREDICTION_WINDOW < 0: self.PREDICTION_WINDOW = 0 if self.PREDICTION_WINDOW > self.PWMax: self.PREDICTION_WINDOW = self.PWMax self.dbase.post( now=now, tag_dict={"object": "Solver_" + str(self.solverID)}, seriesName="PW", value=self.PREDICTION_WINDOW) self.dbase.post( now=now, tag_dict={"object": "Solver_" + str(self.solverID)}, seriesName="on_solve_time", value=timer["split"]) self.dbase.post( now=now, tag_dict={"object": "Solver_" + str(self.solverID)}, seriesName="solveTime", value=stopWatch["split"]) def handleSpcLimit(self): '''This is a function called by the riaps platform and should be generated if we are doing disk limits''' self.logger.warning('handleSpcLimit() ') try: with open(self.logpath, 'w'): #opening the log file like this truncates it. pass # os.remove(self.logpath) # os.remove(self.name) # self.size = self.delta # now = datetime.datetime.now() # self.dbase.post(now=now, tag_dict={"resource":"storage"}, seriesName="Waste", value=self.size) except FileNotFoundError as e: self.logger.info("handleSpcLimit: Remove Error = %s" % e) self.logger.info("file does not exist") def handleMemLimit(self): now = datetime.datetime.now() memNow = self.thisProcess.memory_info() self.logger.warning('handleMEMLimit(): %s' % str(memNow)) self.PWMax = self.priorPW - 1 self.dbase.post(now=now, tag_dict={"object": "Solver_" + str(self.solverID)}, seriesName="RSSNow", value=memNow[0]) self.dbase.post(now=now, tag_dict={"object": "Solver_" + str(self.solverID)}, seriesName="PWMax", value=self.PWMax) def handleDeadline(self, funcName): self.logger.warning("handleDeadline(): %s" % funcName) #if self.self.Pgain += 1 self.PWMax = self.priorPW - 1 self.dbase.post(now=datetime.datetime.now(), tag_dict={"object": "Solver_" + str(self.solverID)}, seriesName="PWMax", value=self.PWMax) def handleCPULimit(self): self.logger.warning('handleCPULimit()') self.PWMax = self.priorPW - 1 self.dbase.post(now=datetime.datetime.now(), tag_dict={"object": "Solver_" + str(self.solverID)}, seriesName="PWMax", value=self.PWMax) def handleNICStateChange(self, state): if state == "down": self.logger.warning("NIC is %s" % state) # lost connection to contract self.connected = 0 # self.connectGrafana() self.dbase.post( now=datetime.datetime.now(), tag_dict={"object": "Solver_" + str(self.solverID)}, seriesName="PWMax", value=self.PWMax) else: self.logger.warning("NIC is %s" % state) def __destroy__(self): self.logger.info("(PID %s) - stopping Solver", str(self.pid)) def query_contract_address(self): msg = {'request': "query_contract_address"} self.logger.info(msg) try: #self.cltReqPort.send_pyobj(msg) self.contractAddr.send_pyobj(msg) except PortError as e: self.logger.info("query_contract_address:send exception = %d" % e.errno) if e.errno in (PortError.EAGAIN, PortError.EPROTO): self.logger.info("query_contract_address: try again") def waste(self): self.logger.info("WASTE %s" % self.s)
class Recorder(Component): def __init__(self, logfile): super(Recorder, self).__init__() self.pid = os.getpid() self.logger.info("(PID %s) - starting Recorder", str(self.pid)) self.connected = 0 self.interval_trades = {} self.finalized = -1 self.solutions = collections.defaultdict(dict) self.solution2solver = {} self.dbase = Database() logpath = '/tmp/' + logfile + '.log' try: os.remove(logpath) except OSError: pass self.fh = logging.FileHandler(logpath) self.fh.setLevel(logging.WARNING) self.fh.setFormatter(self.logformatter) self.logger.addHandler(self.fh) self.logger.warning("(PID %s) - starting Recorder", str(self.pid)) def on_contractAddr(self): req = self.contractAddr.recv_pyobj() self.logger.info("PID (%s) - on_contractAddr():%s", str(self.pid), str(req)) self.epoch = time() - req['time'] self.contract_address = req['contract'] self.logger.info("Contract address: " + self.contract_address) self.logger.info("Setting up connection to Ethereum client...") client = EthereumClient(ip=MINER, port=PORT) self.account = client.accounts()[0] # use the first owned address self.logger.info("Creating contract object...") self.contract = MatchingContract(client, self.contract_address) self.connected = 1 def on_poller(self): now = self.poller.recv_pyobj() self.logger.info('PID(%s) - on_poller(): %s', str(self.pid), str(now)) if self.connected == 0: self.query_contract_address() elif self.connected == 1: self.logger.debug("Polling events...") for event in self.contract.poll_events(): params = event['params'] name = event['name'] self.logger.info("{}({}).".format(name, params)) if name == "Finalized": self.finalized = params['interval'] stopWatch = { "interval": self.finalized, "start": time(), "running": 1 } self.logger.info("interval finalized : {}".format( self.finalized)) self.interval_trades[self.finalized] = [] elif name == "TradeFinalized": if (stopWatch["running"]): stopWatch["running"] = 0 stopWatch["split"] = time() - stopWatch["start"] self.dbase.log(self.finalized, "Solver", "FinalizeTime", stopWatch["split"]) interval = params['time'] power = params['power'] self.interval_trades[self.finalized].append(power) self.logger.info(self.finalized) self.logger.info(self.interval_trades[self.finalized]) self.dbase.log(self.finalized, "Solver", "TotalEnergyTraded", sum(self.interval_trades[self.finalized])) elif name == "TradeAdded": interval = params['time'] ID = params['solutionID'] pwr = params['power'] solverID = self.solution2solver[ID] if int(ID) < 10: ID = "0" + str(ID) if int(ID) < 100: ID = "0" + str(ID) try: self.solutions[ID][interval] += pwr except KeyError: self.solutions[ID][interval] = pwr #TradeAdded({'solutionID': 63, 'power': 400, 'time': 93, 'objective': 400, 'buyerID': 65, 'sellerID': 27}). self.logger.info( "TradeAdded : interval:{}, Solver:{}, SolutionID:{}, pwr:{}" .format(interval, solverID, ID, self.solutions[ID][interval])) self.dbase.log(interval, "solution" + str(ID), "Solver" + str(solverID), self.solutions[ID][interval]) self.logger.info("{}({}).".format(name, params)) elif (name == "SolutionCreated"): solverID = params['solverID'] solutionID = params['solutionID'] self.solution2solver[solutionID] = solverID self.logger.info( "SolutionCreated Solver:{} Solution:{}".format( solverID, solutionID)) def handlePeerStateChange(self, state, uuid): self.logger.warning("peer %s is %s at: %s" % (uuid, state, time())) def __destroy__(self): self.logger.info("(PID %s) - stopping Recorder", str(self.pid)) def query_contract_address(self): msg = {'request': "query_contract_address"} self.logger.info(msg) try: #self.cltReqPort.send_pyobj(msg) self.contractAddr.send_pyobj(msg) except PortError as e: self.logger.info("query_contract_address:send exception = %d" % e.errno) if e.errno in (PortError.EAGAIN, PortError.EPROTO): self.logger.info("query_contract_address: try again")
class Trader(Component): def __init__(self,ID,logfile): super(Trader, self).__init__() self.pid = os.getpid() self.logger.info("(PID %s) - starting Trader",str(self.pid)) self.prosumer_id = ID self.net_production = self.read_data(self.prosumer_id) self.selling_offers = set() self.buying_offers = set() self.connected =0 self.dbase = Database() self.role = None self.roleID = 0 #self.grid = zmq.Context().socket(zmq.PUB) #self.grid.bind('tcp://127.0.0.1:2000') self.interval_asks = {} self.interval_bids = {} self.interval_trades ={} self.finalized = -1 #RESOURCE MANAGEMENT PARAMETERS #NETWORK self.blk = 512 self.min = 1*self.blk self.max = 4*self.blk self.msg_size = self.min logpath = '/tmp/' + logfile + '.log' self.killLog = 'killLog.log' try: os.remove(logpath) except OSError: pass self.fh = logging.FileHandler(logpath) self.fh.setLevel(logging.WARNING) self.fh.setFormatter(self.logformatter) self.logger.addHandler(self.fh) self.logger.warning("(PID %s) - starting Trader",str(self.pid)) def on_contractAddr(self): try : req = self.contractAddr.recv_pyobj() if 'contract' in req: self.logger.info("PID (%s) - on_contractAddr():%s",str(self.pid),str(req)) self.epoch = time() - req['time'] self.time_interval = int(time() - self.epoch) // INTERVAL_LENGTH self.contract_address = req['contract'] self.logger.info("Contract address: " + self.contract_address) self.logger.info("Setting up connection to Ethereum client...") client = EthereumClient(ip=MINER, port=PORT) self.account = client.accounts()[0] # use the first owned address self.logger.info("Creating contract object...") self.contract = MatchingContract(client, self.contract_address) self.contract.registerProsumer(self.account, prosumer_id, PROSUMER_FEEDER[prosumer_id]) self.connected = 1 self.logger.warning("Connected: %s" %self.connected) else : self.logger.info("reply is:%s " %req) except PortError as e: self.logger.info("on_contractAddr:port exception = %d" % e.errno) if e.errno in (PortError.EAGAIN,PortError.EPROTO): self.logger.info("on_contractAdd: port error received") def on_poller(self): now = self.poller.recv_pyobj() self.logger.info('PID(%s) - on_poller(): %s',str(self.pid),str(now)) if self.connected == 0 : self.query_contract_address() elif self.connected == 1 : self.logger.debug("Polling events...") # if self.time_interval == 28 and self.prosumer_id == 106: # with open(self.killLog, 'a') as f: # f.write("KILL PROCESS: %s" %time()) # self.logger.warning("KILL PROCESS: %s" %time()) # os.kill(self.pid,signal.SIGKILL) events = self.contract.poll_events() # try:# added this because laptop lost connection, and would need to reconnect to miner and grafana # events = self.contract.poll_events() # except Exception as e: # self.logger.warning("LOST CONNECTION TO HOST: %s" %e) # self.connected =0 for event in events: #self.contract.poll_events(): params = event['params'] name = event['name'] if (name == "BuyingOfferPosted") and (params['prosumer'] == self.prosumer_id): self.buying_offers.add(params['ID']) self.logger.info("{}({}).".format(name, params)) elif (name == "SellingOfferPosted") and (params['prosumer'] == self.prosumer_id): self.selling_offers.add(params['ID']) self.logger.info("{}({}).".format(name, params)) elif (name == "TradeAdded") and ((params['sellerID'] in self.selling_offers) or (params['buyerID'] in self.buying_offers)): self.logger.info("{}({}).".format(name, params)) elif name == "Finalized": self.finalized = params['interval'] self.logger.info("interval finalized : {}".format(self.finalized)) self.interval_trades[self.finalized] = [] #List of trades finalized for a given interval self.time_interval = self.finalized + 1 self.logger.info("time_interval: %s = finalized: %s + 1" %(self.time_interval, self.finalized)) self.dbase.log(self.finalized-2, "interval_now", self.prosumer_id, self.finalized-2) self.dbase.log(self.time_interval, self.prosumer_id, self.role, 0) elif (name == "TradeFinalized") and ((params['sellerID'] in self.selling_offers) or (params['buyerID'] in self.buying_offers)): self.logger.warning("{}({}).".format(name, params)) time_interval = params['time'] power = params['power'] self.interval_trades[time_interval].append(power) #self.grid.send_pyobj({"interval" : self.finalized, "power": self.roleID*sum(self.interval_trades[self.finalized]), "INTERVAL_LENGTH" : INTERVAL_LENGTH, "time_stamp" : next_actuation}) self.dbase.log(time_interval, self.prosumer_id, self.role, sum(self.interval_trades[time_interval])) self.ack.send_pyobj("%s" %(self.prosumer_id)) #Time Sensitive Messaging # self.waste_network() def on_post(self): now = self.post.recv_pyobj() self.logger.info('PID(%s) - on_post(): %s',str(self.pid),str(now)) if self.connected : self.post_offers(self.time_interval) def handleActivate(self): with open(self.killLog, 'a') as f: f.write("Live: %s" %time()) self.logger.warning("handleActivate: %s" %time()) self.logger.warning("UUID: %s" %self.getUUID()) # self.cltReqPort.set_recv_timeout(1.0) # self.cltReqPort.set_send_timeout(1.0) # rto = self.cltReqPort.get_recv_timeout() # sto = self.cltReqPort.get_send_timeout() # self.logger.info("handleActivate: (rto,sto) = (%s,%s)" % (str(rto),str(sto))) def handlePeerStateChange(self,state,uuid): self.logger.warning("UUID: %s, STATE: %s" %(uuid, state)) def handleNICStateChange(self, state): if state=="down": self.logger.warning("UUID: %s" %self.getUUID()) self.logger.warning("NIC is %s" % state) self.connected = 0 self.logger.warning("Connected: %s" %self.connected) elif state =="up": self.logger.warning("NIC is %s" % state) # self.connectGrafana()#This appears to be unnecessary... # def __destroy__(self): self.logger.info("(PID %s) - stopping Trader",str(self.pid)) def query_contract_address(self): msg = { 'request': "query_contract_address" } self.logger.info(msg) try: #self.cltReqPort.send_pyobj(msg) self.contractAddr.send_pyobj(msg) except PortError as e: self.logger.info("query_contract_address:send exception = %d" % e.errno) if e.errno in (PortError.EAGAIN,PortError.EPROTO): self.logger.info("query_contract_address: try again") def post_offers(self, time_interval): remaining_offers = [] self.logger.info("Posting offers for interval {}...".format(time_interval)) for offer in self.net_production: self.logger.info("energy: %s" %(offer['energy'])) if offer['end'] < time_interval: # offer in the past, discard it pass elif offer['start'] <= time_interval + PREDICTION_WINDOW: # offer in near future, post it if offer['energy'] < 0: self.role = "consumer" self.roleID = -1 self.logger.info("postBuyingOffer({}, {}, {}, {})".format(self.prosumer_id, offer['start'], offer['end'], -offer['energy'])) self.contract.postBuyingOffer(self.account, self.prosumer_id, offer['start'], offer['end'], -offer['energy']) try: self.interval_bids[offer['start']].append(offer['energy']) except KeyError: self.interval_bids[offer['start']] = [offer['energy']] self.dbase.log(offer['start'], self.prosumer_id, "buying", sum(self.interval_bids[offer['start']])) else: self.role = "producer" self.roleID = 1 self.logger.info("postSellingOffer({}, {}, {}, {})".format(self.prosumer_id, offer['start'], offer['end'], offer['energy'])) self.contract.postSellingOffer(self.account, self.prosumer_id, offer['start'], offer['end'], offer['energy']) try: self.interval_asks[offer['start']].append(offer['energy']) except KeyError: self.interval_asks[offer['start']] = [offer['energy']] self.dbase.log(offer['start'], self.prosumer_id, "selling", sum(self.interval_asks[offer['start']])) else: # offer in far future, post it later remaining_offers.append(offer) self.net_production = remaining_offers self.logger.info("Offers posted.") def read_data(self, prosumer_id): self.logger.info("Reading net production values...") feeder = int(prosumer_id / 100) prosumer = prosumer_id % 100 print(os.getcwd()) with open(DATA_PATH + "prosumer_{}.csv".format(prosumer_id), "rt") as fin: line = next(fin) data = [] for line in fin: try: fields = line.split(',') data.append({ 'start': int(fields[0]), 'end': int(fields[1]), 'energy': int(1000 * float(fields[2])) }) except Exception: pass if not len(data): raise Exception("No values found in data file!") self.logger.info("Read {} values.".format(len(data))) return data def handleCPULimit(self): self.logger.info('handleCPULimit()') def handleMemLimit(self): self.logger.info('handleMemLimit()' ) def handleNetLimit(self): self.logger.info('handleNetLimit %s' %self.msg_size) self.msg_size = self.min self.logger.info('handled NetLimit %s' %self.msg_size) now = datetime.datetime.now() self.dbase.post(now=now, tag_dict={"resource":"Network", "ID":self.prosumer_id}, seriesName="Waste", value=self.msg_size) def waste_network(self): msg = { 'request': "waste", 'payload': bytearray(self.msg_size) } self.logger.info("WASTE NETWORK") try: self.contractAddr.send_pyobj(msg) self.msg_size = self.msg_size + self.blk # if self.msg_size == self.max: self.msg_size = self.min now = datetime.datetime.now() self.dbase.post(now=now, tag_dict={"resource":"Network", "ID":self.prosumer_id}, seriesName="Waste", value=self.msg_size) except PortError as e: self.logger.info("waste_network:send exception = %d" % e.errno) if e.errno in (PortError.EAGAIN,PortError.EPROTO): self.logger.info("waste_network: try again")