def saveInDatabase(self): from apps.mara.models import DI, AI from apps.hmi.models import Formula try: payload = self.input.payload_10 if not payload: print "No se detecto payload!!!" pprint(self.input) return di_count, ai_count, sv_count = 0, 0, 0 t0, timestamp = time(), datetime.now() comaster = self.factory.comaster for value, di in zip(iterbits(payload.dis), comaster.dis): di.update_value(value, timestamp=timestamp) di_count += 1 for value, ai in zip(payload.ais, comaster.ais): ai.update_value(value, timestamp=timestamp) ai_count += 1 variable_widths = [v.width for v in comaster.svs] #print variable_widths, len(variable_widths) for value, sv in zip(worditer(payload.varsys, variable_widths), self.factory.comaster.svs): sv.update_value(value, timestamp=timestamp) sv_count += 1 for event in payload.event: if event.evtype == 'DIGITAL': # Los eventos digitales van con una DI try: di = DI.objects.get(ied__rs485_address = event.addr485, port=event.port, bit=event.bit) fecha = container_to_datetime(event) di.events.create( timestamp=container_to_datetime(event), q=event.q, value=event.status ) except DI.DoesNotExist: print "Evento para una DI que no existe!!!" elif event.evtype == 'ENERGY': try: query = dict(ied__rs485_address = event.addr485, channel=event.channel) ai = AI.objects.get(**query) ai.energy_set.create( timestamp=event.timestamp, code=event.code, q=event.q, hnn=event.hnn, ) except AI.DoesNotExist: print "Medicion de energia no reconcible", event except AI.MultipleObjectsReturned: print "No se pudo identificar la DI con ", query print "Recalculo de las formulas" Formula.calculate() transaction.commit() print "Update DB: DI: %d AI: %d SV: %d in %sS" % (di_count, ai_count, sv_count, time() - t0) except Exception as e: print e
def process_frame(self, mara_frame, update_states=True, update_di=True, update_ai=True, update_sv=True, create_events=True, create_ev_digital=True, create_ev_energy=True, create_ev_comsys=True, calculate=True, logger=None): """Takes a Mara frame (from construct) and saves its components in related COMaster models (DI, AI, SV) and Events. It accepts flags for processing. There are two general flags called update_states and create_events, that when false disable processing of states and events acordingly. There are 3 fine grained flags for states and 3 for event types""" if not logger: logger = logging.getLogger('commands') # Flags for states update_di = update_di and update_states update_ai = update_ai and update_states update_sv = update_sv and update_states # Flags for events create_ev_digital = create_ev_digital and create_events create_ev_energy = create_ev_energy and create_events create_ev_comsys = create_ev_comsys and create_events try: payload = mara_frame.payload_10 except AttributeError as e: raise AttributeError( "Mara payload not present. %s does not look like a frame" % mara_frame ) # Some counters di_count, ai_count, sv_count, event_count = 0, 0, 0, 0 timestamp = datetime.now() if update_di: for value, di in zip(iterbits(payload.dis, length=16), self.dis): # Update value takes care of maskinv di.update_value(value, q=0, last_update=timestamp) di_count += 1 else: if len(payload.dis): logger.info("Skipping DI") if update_ai: for value, ai in zip(payload.ais, self.ais): value = value & 0x0FFF q = (value & 0xC000) >> 14 ai.update_value(value, last_update=timestamp, q=q) ai_count += 1 if update_sv: for value, sv in zip(payload.varsys, self.svs): sv.update_value(value, last_update=timestamp) sv_count += 1 logger.info(_("Processing %s events") % len(payload.event)) for event in payload.event: if event.evtype == 'DIGITAL' and create_ev_digital: # Los eventos digitales van con una DI try: di = DI.objects.get(ied__rs485_address=event.addr485, ied__co_master=self, port=event.port, bit=event.bit) ev = di.events.create( timestamp=container_to_datetime(event), q=event.q, value=event.status ^ di.maskinv ) logger.info(_("Digital event created %s") % ev) except DI.DoesNotExist: logger.warning( "DI does not exist for %s:%s", event.port, event.bit) elif event.evtype == 'ENERGY' and create_ev_energy: try: query = dict( ied__rs485_address=event.addr485, ied__co_master=self, channel=event.channel, ) ai = AI.objects.get(**query) timestamp = container_to_datetime(event) # Parsing construct arrray bogus data value = event.data[ 1] + (event.data[0] << 8) + (event.data[2] << 16) ev = ai.energy_set.create( timestamp=timestamp, code=event.code, q=event.q, hnn=event.hnn, value=value ) logger.info(_("Energy created: %s") % ev) except AI.DoesNotExist: logger.warning(_("AI for energy does not exist")) except AI.MultipleObjectsReturned: logger.warning(_("AI for energy has multiple matches")) elif event.evtype == 'COMSYS' and create_ev_comsys: try: ied = self.ieds.get(rs485_address=event.addr485) timestamp = container_to_datetime(event) ev = ied.comevent_set.create( motiv=event.motiv, timestamp=timestamp ) logger.info("ComEvent created: %s" % ev) except ComEvent.DoesNotExist: logger.warning(_("Cannot create COMSYS event")) if calculate: from apps.hmi.models import Formula logger.info("Starting formula update") try: Formula.calculate() logger.info("Formula update OK") except Exception as e: logger.error(unicode(e), exc_info=True) return di_count, ai_count, sv_count, event_count
def saveInDatabase(self): print "Acutalizando DB" # print self.input from models import DI, AI, VarSys, Energy, Event payload = self.input.payload_10 # Iterar de a bit def iterdis(): # Iterar ieds for ied in self.factory.comaster.ied_set.order_by('offset'): # Ordenar por puerto y por bit for di in DI.filter(ied=ied).order_by(('port', 'asc'), ('bit', 'asc')): yield di def iterais(): # Iterar ieds for ied in self.factory.comaster.ied_set.order_by('offset'): # Itera por ais for ai in AI.filter(ied=ied).order_by('offset'): yield ai def itervarsys(): # Iterar ieds for ied in self.factory.comaster.ied_set.order_by('offset'): for varsys in VarSys.filter(ied=ied).order_by('offset'): yield varsys #======================================================================= # Guardando... #======================================================================= for varsys, value in zip(itervarsys(), payload.varsys): varsys.value = value varsys.save() for di, value in zip(iterdis(), iterbits(payload.dis)): di.value = value di.save() for ai, value in zip(iterais(), payload.ais): ai.value = value ai.save() if self.save_events: for ev in payload.event: if ev.evtype == "DIGITAL": ied = self.factory.comaster.ied_set.get(addr_485_IED=ev.addr485) di = DI.get(ied=ied, port=ev.port, bit=ev.bit) # di = comaster.dis.get(port = ev.port, bit = ev.bit) timestamp = datetime( ev.year + 2000, ev.month, ev.day, ev.hour, ev.minute, ev.second, int(ev.subsec * 100000)) Event(di=di, timestamp=timestamp, subsec=ev.subsec, q=0, value=ev.status).save() elif ev.evtype == "ENERGY": timestamp = datetime(ev.year + 2000, ev.month, ev.day, ev.hour, ev.minute, ev.second) ied = self.factory.comaster.ied_set.get(addr_485_IED=ev.addr485) Energy(ied=ied, q=ev.value.q, timestamp=timestamp, address=ev.addr485, channel=ev.channel, value=ev.value.val,).save() print ("Guardados %d eventos" % len(payload.event))