Beispiel #1
0
    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
Beispiel #2
0
    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
Beispiel #3
0
    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))