diff --git a/apps/abs/models.py b/apps/abs/models.py index 0dd94fa..3890f46 100644 --- a/apps/abs/models.py +++ b/apps/abs/models.py @@ -1,10 +1,878 @@ 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 change_beam_for_multiprocessing(module): + + for i in range (1,50): + beam_pos = 0 + 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.2) + + + beam_pos = 1 + 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.2) + + + class ABSConfiguration(Configuration): - + beams = models.CharField(verbose_name='Beams', 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' - \ No newline at end of file + + 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 = ast.literal_eval(self.beams) + b=1 + for beam in beams: + absbeam = ABSBeam.objects.get(pk=beams[beam]) + parameters['beams']['beam'+str(b)] = absbeam.parms_to_dict() + b+=1 + + return parameters + + + 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] = beam.module_6bits(module_num) + i=i+1 + + beams = bs + + parameters = {} + 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 + 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() + message = answer['message'] + module_bits = answer['allbits'] + except: + message = "Could not read ABS parameters" + return 0 + + return module_bits + + + def write_device(self): + """ + This function sends the beams list to every abs module. + """ + + beams_list = ast.literal_eval(self.beams) + beams = [] + + 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--- + beams_status = ast.literal_eval(self.module_status) + for i in range(62,65): + try: + 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() + #return 0 + + #self.device.status = 1 + 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 = ast.literal_eval(self.beams) + 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 = ast.literal_eval(self.beams) + 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)<300: + t2 = time.time() + self.send_beam_num(1) + time.sleep(0.04) + self.send_beam_num(2) + time.sleep(0.04) + return + + def change_procs_test1(self, module): + + for i in range (1,300): + beam_pos = 0 + 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.2) + + + beam_pos = 1 + 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.2) + + + def multi_procs_test1(self): + + #if __name__ == "__main__": + size = 10000000 # Number of random numbers to add + procs = 65 # (Number-1) of processes to create + + # 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(62, 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 status_device(self): + + 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 change_beam(self, beam_pos=0): + + module_63 = ('192.168.1.63', 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_63) + sock.send(message_tx) + sock.close() + return message_tx + + def change_module_beam(self, module=61,beam_pos=0): + + 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 + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.connect(module_address) + sock.send(message_tx) + sock.close() + except: + return 0 + return message_tx + + def write_device(self): + + parameters = {} + + module_ip = '192.168.1.63' + write_route = 'http://192.168.1.63:8080/configure' + + header = 'JROABSCeCnModCnMod01000108SNDFexperimento1.ab1' + module = 'ABS_63' + 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 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 add_beam2list(self): + """ + This function adds a beam to the beams list of ABS Configuration. + """ + beams = ast.literal_eval(self.abs_conf.beams) + if any(beams): + for beam in beams: + if beams[beam] == self.id: + return + i = len(beams)+1 + beams['beam'+str(i)] = self.id + else: + beams['beam1'] = self.id + + self.abs_conf.beams = json.dumps(beams) + self.abs_conf.save() + + return + + def remove_beamfromlist(self): + """ + This function removes current beam from the beams list of ABS Configuration. + """ + beams = ast.literal_eval(self.abs_conf.beams) + dict_position = '' + + if any(beams): + for beam in beams: + if beams[beam] == self.id: + dict_position = beam + if dict_position != '': + beams.pop(str(dict_position),None) + else: + return + + self.abs_conf.beams = json.dumps(beams) + 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_rx(self): + """ + This function shows the rx-values of one beam + """ + data = json.loads(self.rx) + + return data