from django.db import models from apps.main.models import Configuration from django.core.urlresolvers import reverse # Create your models here. import ast import socket import json import requests import struct import sys, time import multiprocessing antenna_default = json.dumps({ "antenna_up": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5], [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5], [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5], [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5], [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0], [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0], [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0], [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0] ] , "antenna_down": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5], [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5], [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5], [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5], [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0], [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0], [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0], [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0]], }) tx_default = json.dumps({ "up": [[1,1,1,1,0,0,0,0], [1,1,1,1,0,0,0,0], [1,1,1,1,0,0,0,0], [1,1,1,1,0,0,0,0], [0,0,0,0,1,1,1,1], [0,0,0,0,1,1,1,1], [0,0,0,0,1,1,1,1], [0,0,0,0,1,1,1,1]], "down": [[1,1,1,1,0,0,0,0], [1,1,1,1,0,0,0,0], [1,1,1,1,0,0,0,0], [1,1,1,1,0,0,0,0], [0,0,0,0,1,1,1,1], [0,0,0,0,1,1,1,1], [0,0,0,0,1,1,1,1], [0,0,0,0,1,1,1,1]], }) rx_default = json.dumps({ "up": [[1,1,1,1,0,0,0,0], [1,1,1,1,0,0,0,0], [1,1,1,1,0,0,0,0], [1,1,1,1,0,0,0,0], [0,0,0,0,1,1,1,1], [0,0,0,0,1,1,1,1], [0,0,0,0,1,1,1,1], [0,0,0,0,1,1,1,1]], "down": [[1,1,1,1,0,0,0,0], [1,1,1,1,0,0,0,0], [1,1,1,1,0,0,0,0], [1,1,1,1,0,0,0,0], [0,0,0,0,1,1,1,1], [0,0,0,0,1,1,1,1], [0,0,0,0,1,1,1,1], [0,0,0,0,1,1,1,1]], }) conf_default = {} status_default = {} for i in range(1,65): conf_default[str(i)] = "" status_default[str(i)] = 0 ues_default = json.dumps({ "up": [0.533333,0.00000,1.06667,0.00000], "down": [0.533333,0.00000,1.06667,0.00000] }) onlyrx_default = json.dumps({ "up": False, "down": False }) def up_convertion(cadena): valores = [] for c in cadena: if c == 1.0: valores=valores+['000'] if c == 2.0: valores=valores+['001'] if c == 3.0: valores=valores+['010'] if c == 0.0: valores=valores+['011'] if c == 0.5: valores=valores+['100'] if c == 1.5: valores=valores+['101'] if c == 2.5: valores=valores+['110'] if c == 3.5: valores=valores+['111'] return valores def up_conv_bits(value): if value == 1.0: bits="000" if value == 2.0: bits="001" if value == 3.0: bits="010" if value == 0.0: bits="011" if value == 0.5: bits="100" if value == 1.5: bits="101" if value == 2.5: bits="110" if value == 3.5: bits="111" return bits def down_convertion(cadena): valores = [] for c in cadena: if c == 1.0: valores=valores+['000'] if c == 2.0: valores=valores+['001'] if c == 3.0: valores=valores+['010'] if c == 0.0: valores=valores+['011'] if c == 0.5: valores=valores+['100'] if c == 1.5: valores=valores+['101'] if c == 2.5: valores=valores+['110'] if c == 3.5: valores=valores+['111'] return valores def down_conv_bits(value): if value == 1.0: bits="000" if value == 2.0: bits="001" if value == 3.0: bits="010" if value == 0.0: bits="011" if value == 0.5: bits="100" if value == 1.5: bits="101" if value == 2.5: bits="110" if value == 3.5: bits="111" return bits def ip2position(module_number): j=0 i=0 for x in range(0,module_number-1): j=j+1 if j==8: i=i+1 j=0 pos = [i,j] return pos def fromBinary2Char(binary_string): number = int(binary_string, 2) #Plus 33 to avoid more than 1 characters values such as: '\x01'-'\x1f' number = number + 33 char = chr(number) return char def fromChar2Binary(char): number = ord(char) - 33 #Minus 33 to get the real value bits = bin(number)[2:] #To ensure we have a string with 6bits if len(bits) < 6: bits = bits.zfill(6) return bits class ABSConfiguration(Configuration): active_beam = models.CharField(verbose_name='Active Beam', max_length=20000, default="{}") module_status = models.CharField(verbose_name='Module Status', max_length=10000, default=json.dumps(status_default)) class Meta: db_table = 'abs_configurations' def get_absolute_url_plot(self): return reverse('url_plot_abs_patterns', args=[str(self.id)]) def parms_to_dict(self): parameters = {} parameters['device_id'] = self.device.id parameters['name'] = self.name parameters['beams'] = {} beams = ABSBeam.objects.get(pk=self.id) b=1 for beam in beams: #absbeam = ABSBeam.objects.get(pk=beams[beam]) parameters['beams']['beam'+str(b)] = beam.parms_to_dict()#absbeam.parms_to_dict() b+=1 return parameters def get_beams(self, **kwargs): ''' This function returns ABS Configuration beams ''' return ABSBeam.objects.filter(abs_conf=self.pk, **kwargs) def clone(self, **kwargs): beams = self.get_beams() self.pk = None self.id = None for attr, value in kwargs.items(): setattr(self, attr, value) self.save() for beam in beams: beam.clone(abs_conf=self) return self def module_conf(self, module_num, beams): """ This function creates beam configurations for one abs module. """ ip_address = self.device.ip_address ip_address = ip_address.split('.') module_seq = (ip_address[0],ip_address[1],ip_address[2]) dot = '.' module_ip = dot.join(module_seq)+'.'+str(module_num) module_port = self.device.port_address write_route = 'http://'+module_ip+':'+str(module_port)+'/configure' header = 'JROABSCeCnModCnMod01000108SNDFexperimento1.ab1' module = 'ABS_'+str(module_num) bs = '' #{} i=1 #beams = {1: '001000', 2: '010001', 3: '010010', 4: '000011', 5: '101100', 6: '101101', # 7: '110110', 8: '111111', 9: '000000', 10: '001001', 11: '010010', 12: '011011'} for beam in beams: #bs[i] = fromBinary2Char(beam.module_6bits(module_num)) bs = bs + fromBinary2Char(beam.module_6bits(module_num)) i=i+1 beams = bs parameters = {} parameters['header'] = header parameters['module'] = module parameters['beams'] = beams #json.dumps(beams) print parameters['beams'] answer = '' try: r_write = requests.post(write_route, parameters, timeout=0.5) answer = r_write.json() self.message = answer['message'] except: self.message = "Could not write ABS parameters" return 0 return 1 def read_module(self, module): """ Read out-bits (up-down) of 1 abs module NOT for Configuration """ parameters = {} ip_address = self.device.ip_address ip_address = ip_address.split('.') module_seq = (ip_address[0],ip_address[1],ip_address[2]) dot = '.' module_ip = dot.join(module_seq)+'.'+str(module) module_port = self.device.port_address read_route = 'http://'+module_ip+':'+str(module_port)+'/read' print(read_route) answer = '' module_bits = '' try: r_write = requests.get(read_route, timeout=0.7) answer = r_write.json() self.message = answer['message'] module_bits = answer['allbits'] except: #message = "Could not read ABS parameters" return 0 return module_bits def status_device(self): """ This function gets the status of each abs module. It sends GET method to Web Application in Python Bottle. """ ip_address = self.device.ip_address ip_address = ip_address.split('.') module_seq = (ip_address[0],ip_address[1],ip_address[2]) dot = '.' module_port = self.device.port_address modules_status = json.loads(self.module_status) for i in range(1,65): module_ip = dot.join(module_seq)+'.'+str(i) print module_ip route = 'http://'+module_ip+':'+str(module_port)+'/hello' try: r = requests.get(route, timeout=0.7) modules_status[str(i)] = 1 except: modules_status[str(i)] = 0 pass self.message = 'ABS modules Status have been updated.' self.module_status=json.dumps(modules_status) self.save() return def write_device(self): """ This function sends the beams list to every abs module. It needs 'module_conf' function """ ###beams_list = ast.literal_eval(self.beams) ###beams = [] beams = ABSBeam.objects.filter(abs_conf=self) ###for bl in range(1,len(beams_list)+1): ### b = ABSBeam.objects.get(pk=beams_list['beam'+str(bl)]) ### beams.append(b) #---Write each abs module--- if beams: beams_status = ast.literal_eval(self.module_status) for i in range(62,65): #(62,65) try: answer = self.module_conf(i, beams) beams_status[str(i)] = 1 self.module_status = json.dumps(beams_status) self.save() #self.module_conf(63,beams) #beams_status[str(63)] = 1 #self.module_status = json.dumps(beams_status) except: beams_status[str(i)] = 0 self.module_status = json.dumps(beams_status) self.save() answer = 0 return 0 else: self.message = "ABS Configuration does not have beams" return 0 #self.device.status = 1 ## if answer==1: self.message = "ABS Beams List have been sent to ABS Modules" else: self.message = "Could not read ABS parameters" ## self.save() return 1 def write_module(self, module): """ Send configuration to one abs module """ parameters = {} ip_address = self.abs_conf.device.ip_address ip_address = ip_address.split('.') module_seq = (ip_address[0],ip_address[1],ip_address[2]) dot = '.' module_ip = dot.join(module_seq)+'.'+str(module) module_port = self.abs_conf.device.port_address write_route = 'http://'+module_ip+':'+str(module_port)+'/configure' #print write_route header = 'JROABSCeCnModCnMod01000108SNDFexperimento1.ab1' module = 'ABS_'+str(module) beams = {1: '001000', 2: '010001', 3: '010010', 4: '000011', 5: '101100', 6: '101101', 7: '110110', 8: '111111', 9: '000000', 10: '001001', 11: '010010', 12: '011011'} parameters['header'] = header parameters['module'] = module parameters['beams'] = json.dumps(beams) answer = '' try: r_write = requests.post(write_route, parameters, timeout=0.5) answer = r_write.json() self.message = answer['message'] except: self.message = "Could not write ABS parameters" return 0 #self.device.status = int(answer['status']) return 1 def beam_selector(self, module, beam_pos): """ This function selects the beam number for one absmodule. """ if beam_pos > 0: beam_pos = beam_pos - 1 else: beam_pos = 0 #El indice del apunte debe ser menor que el numero total de apuntes #El servidor tcp en el embebido comienza a contar desde 0 beams_list = ABSBeam.objects.filter(abs_conf=self) if len(beams_list) < beam_pos: return 0 flag = 1 if beam_pos>9: flag = 2 module_address = ('192.168.1.'+str(module), 5500) header = 'JROABSCeCnModCnMod0100000' numbers = len(str(beam_pos)) function = 'CHGB' message_tx = header+str(numbers)+function+str(beam_pos)+'0' # Create the datagram socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #sock.connect(module_address) try: sock.connect(module_address) sock.send(message_tx) sock.close() print("Writing abs module:"+module_address[0]+"...") except: sock = None print("Problem writing abs module:"+module_address[0]) return 0 return 1 def change_beam(self, beam_pos): """ This function selects the beam number for all absmodules. """ for i in range(1,65): try: self.beam_selector(i,beam_pos) except: print("Problem with module: 192.168.1."+str(i)) self.message = "Problem with module: 192.168.1."+str(i) #return 0 return 1 def send_beam_num(self, beam_pos): """ This function connects to a multicast group and sends the beam number to all abs modules. """ if beam_pos > 0: beam_pos = beam_pos - 1 else: beam_pos = 0 #El indice del apunte debe ser menor que el numero total de apuntes #El servidor tcp en el embebido comienza a contar desde 0 beams_list = ABSBeam.objects.filter(abs_conf=self) if len(beams_list) < beam_pos: return 0 flag = 1 if beam_pos>9: flag = 2 header = 'JROABSCeCnModCnMod0100000' flag = str(flag) function = 'CHGB' message_tx = header+flag+function+str(beam_pos)+'0' multicast_group = '224.3.29.71' server_address = ('',10000) # Create the socket sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Bind to the server address sock.bind(server_address) # Telling the OS add the socket to the multicast on all interfaces group = socket.inet_aton(multicast_group) mreq = struct.pack('4sL', group, socket.INADDR_ANY) sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) #print 'sending acknowledgement to all: \n' + message_tx sock.sendto(message_tx, (multicast_group, 10000)) sock.close() sock = None return 1 def test1(self): t1 = time.time() t2 = 0 while (t2-t1)<100:#300 t2 = time.time() self.send_beam_num(2) time.sleep(0.04) self.send_beam_num(1) time.sleep(0.04) return def change_procs_test1(self, module): for i in range (1,300):#300 beam_pos = 1 module_address = ('192.168.1.'+str(module), 5500) header = 'JROABSCeCnModCnMod0100000' numbers = len(str(beam_pos)) function = 'CHGB' message_tx = header+str(numbers)+function+str(beam_pos)+'0' # Create the datagram socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(module_address) sock.send(message_tx) #t = sock.recv(1024) sock.close() sock = None time.sleep(0.04) beam_pos = 0 numbers = len(str(beam_pos)) message_tx = header+str(numbers)+function+str(beam_pos)+'0' # Create the datagram socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(module_address) sock.send(message_tx) sock.close() sock = None time.sleep(0.04) def multi_procs_test1(self): """ This function sends the beam number to all abs modules using multiprocessing. """ #if __name__ == "__main__": size = 10000000 # Number of random numbers to add procs = 65 # (Number-1) of processes to create (absmodule) # Create a list of jobs and then iterate through # the number of processes appending each process to # the job list jobs = [] for i in range(1, procs): process = multiprocessing.Process(target=self.change_procs_test1,args=(i,)) jobs.append(process) #print jobs # Start the processes (i.e. calculate the random number lists) for j in jobs: #time.sleep(0.4) #print j j.start() # Ensure all of the processes have finished for j in jobs: j.join() print("List processing complete.") return 1 def multi_procs_test2(self): """ This function use multiprocessing python library. Importing Pool we can select the number of cores we want to use After 'nproc' linux command, we know how many cores computer has. NOT WORKING """ import multiprocessing pool = multiprocessing.Pool(3) # cores tasks = [] procs = 65 for i in range(62, procs): tasks.append( (i,)) #print tasks #pool.apply_async(self.change_procs_test1, 62) results = [pool.apply( self.change_procs_test1, t ) for t in tasks] #for result in results: #result.get() #(plotNum, plotFilename) = result.get() #print("Result: plot %d written to %s" % (plotNum, plotFilename) ) return 1 def multi_procs_test3(self): """ This function use multiprocessing python library. Importing Pool we can select the number of cores we want to use After 'nproc' linux command, we know how many cores computer has. """ from multiprocessing import Pool import time def f(x): return x*x tasks = [] procs = 65 pool = Pool(processes=4) #for i in range(62, procs): #result = pool.map(f, range(62,65)) it = pool.imap(self.change_procs_test1, range(62,65)) #result.get(timeout=5) return 1 def f(x): print x return def multi_procs_test4(self): import multiprocessing as mp num_workers = mp.cpu_count() pool = mp.Pool(num_workers) procs = 65 for i in range(62, procs): #for task in tasks: pool.apply_async(self.f, args = (i,)) pool.close() pool.join() return 1 class ABSBeam(models.Model): name = models.CharField(max_length=60, default='Beam') antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default) abs_conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration') tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default) rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default) s_time = models.TimeField(verbose_name='Star Time', default='00:00:00') e_time = models.TimeField(verbose_name='End Time', default='23:59:59') modules_conf = models.CharField(verbose_name='Modules', max_length=2000, default=json.dumps(conf_default)) ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default) only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default) class Meta: db_table = 'abs_beams' def __unicode__(self): return u'%s' % (self.name) def parms_to_dict(self): #Update data self.modules_6bits() parameters = {} parameters['name'] = self.name parameters['antenna'] = ast.literal_eval(self.antenna) parameters['abs_conf'] = self.abs_conf.name parameters['tx'] = ast.literal_eval(self.tx) parameters['rx'] = ast.literal_eval(self.rx) parameters['s_time'] = self.s_time.strftime("%H:%M:%S") parameters['e_time'] = self.e_time.strftime("%H:%M:%S") parameters['configuration'] = ast.literal_eval(self.modules_conf) parameters['ues'] = ast.literal_eval(self.ues) parameters['only_rx'] = json.loads(self.only_rx) return parameters def dict_to_parms(self, parameters): self.name = parameters['name'] self.antenna = json.dumps(parameters['antenna']) #self.abs_conf = parameters['abs_conf'] self.tx = json.dumps(parameters['tx']) self.rx = json.dumps(parameters['rx']) #parameters['s_time'] #parameters['e_time'] self.ues = json.dumps(parameters['ues']) self.only_rx = json.dumps(parameters['only_rx']) self.modules_6bits() self.save() return parameters def clone(self, **kwargs): self.pk = None self.id = None for attr, value in kwargs.items(): setattr(self, attr, value) self.save() return self def set_activebeam(self): """ This function change de active beam of ABS Configuration """ conf = self.abs_conf active_beam = {} active_beam['active_beam'] = self.id conf.active_beam = json.dumps(active_beam) conf.save() return def module_6bits(self, module): """ This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module """ if module > 64: beam_bits = "" return beam_bits data = ast.literal_eval(self.antenna) up_data = data['antenna_up'] down_data = data['antenna_down'] pos = ip2position(module) up_value = up_data[pos[0]][pos[1]] down_value = down_data[pos[0]][pos[1]] up_bits = up_conv_bits(up_value) down_bits = down_conv_bits(down_value) beam_bits = up_bits+down_bits return beam_bits def modules_6bits(self): """ This function returns 6bits from every abs module (1-64) in a dict """ modules_configuration = ast.literal_eval(self.modules_conf) for i in range(1,65): modules_configuration[str(i)] = self.module_6bits(i) self.modules_conf = json.dumps(modules_configuration) self.save() return self.modules_conf def active_beam(self): """ This function set this beam as the active beam of its ABS Configuration. """ self.abs_conf.active_beam = json.dumps({'active_beam': self.id}) self.abs_conf.save() return @property def get_upvalues(self): """ This function reads antenna pattern and show the up-value of one abs module """ data = ast.literal_eval(self.antenna) up_data = data['antenna_up'] up_values = [] for data in up_data: for i in range(0,8): up_values.append(data[i]) return up_values @property def antenna_upvalues(self): """ This function reads antenna pattern and show the up - values of one abs beam in a particular order """ data = ast.literal_eval(self.antenna) up_data = data['antenna_up'] return up_data @property def antenna_downvalues(self): """ This function reads antenna pattern and show the down - values of one abs beam in a particular order """ data = ast.literal_eval(self.antenna) down_data = data['antenna_down'] return down_data @property def get_downvalues(self): """ This function reads antenna pattern and show the down-value of one abs module """ data = ast.literal_eval(self.antenna) down_data = data['antenna_down'] down_values = [] for data in down_data: for i in range(0,8): down_values.append(data[i]) return down_values @property def get_up_ues(self): """ This function shows the up-ues-value of one beam """ data = ast.literal_eval(self.ues) up_ues = data['up'] return up_ues @property def get_down_ues(self): """ This function shows the down-ues-value of one beam """ data = ast.literal_eval(self.ues) down_ues = data['down'] return down_ues @property def get_up_onlyrx(self): """ This function shows the up-onlyrx-value of one beam """ data = json.loads(self.only_rx) up_onlyrx = data['up'] return up_onlyrx @property def get_down_onlyrx(self): """ This function shows the down-onlyrx-value of one beam """ data = json.loads(self.only_rx) down_onlyrx = data['down'] return down_onlyrx @property def get_tx(self): """ This function shows the tx-values of one beam """ data = json.loads(self.tx) return data @property def get_uptx(self): """ This function shows the up-tx-values of one beam """ data = json.loads(self.tx) up_data = data['up'] up_values = [] for data in up_data: for i in range(0,8): up_values.append(data[i]) return up_values @property def get_downtx(self): """ This function shows the down-tx-values of one beam """ data = json.loads(self.tx) down_data = data['down'] down_values = [] for data in down_data: for i in range(0,8): down_values.append(data[i]) return down_values @property def get_rx(self): """ This function shows the rx-values of one beam """ data = json.loads(self.rx) return data @property def get_uprx(self): """ This function shows the up-rx-values of one beam """ data = json.loads(self.rx) up_data = data['up'] up_values = [] for data in up_data: for i in range(0,8): up_values.append(data[i]) return up_values @property def get_downrx(self): """ This function shows the down-rx-values of one beam """ data = json.loads(self.rx) down_data = data['down'] down_values = [] for data in down_data: for i in range(0,8): down_values.append(data[i]) return down_values