def import_profile_from_workbook( profile, workbook, svg_path, post_calculate=False, ): """Command independent importer""" # Process COMaster for profile COMaster.import_excel(workbook, profile=profile) # Configuration for text representation of events EventText.import_excel(workbook, profile=profile) EventDescription.import_excel(workbook, profile=profile) ComEventKind.import_excel(workbook, profile=profile) Action.import_excel(workbook, profile=profile) # Fabric inspired directory change with cd(svg_path): SVGScreen.import_excel(workbook, profile=profile) SVGElement.import_excel(workbook, screens=profile.screens.all()) Formula.import_excel(workbook, screens=profile.screens.all()) Color.import_excel(workbook, profile=profile) SVGPropertyChangeSet.import_excel(workbook, profile=profile) if post_calculate: ok, error = Formula.calculate() return result_type(ok, error, ok + error) return result_type(0, 0, Formula.objects.all().count())
def import_profile_from_workbook(profile, workbook, svg_path, post_calculate=False,): """Command independent importer""" # Process COMaster for profile COMaster.import_excel(workbook, profile=profile) # Configuration for text representation of events EventText.import_excel(workbook, profile=profile) EventDescription.import_excel(workbook, profile=profile) ComEventKind.import_excel(workbook, profile=profile) Action.import_excel(workbook, profile=profile) # Fabric inspired directory change with cd(svg_path): SVGScreen.import_excel(workbook, profile=profile) SVGElement.import_excel(workbook, screens=profile.screens.all()) Formula.import_excel(workbook, screens=profile.screens.all()) Color.import_excel(workbook, profile=profile) SVGPropertyChangeSet.import_excel(workbook, profile=profile) if post_calculate: ok, error = Formula.calculate() return result_type(ok, error, ok + error) return result_type(0, 0, Formula.objects.all().count())
def test_overrides_existing_value(self): context = { 'di': { 'E4DI00': { 'value': 0 } } } context = bunchify(context) Formula._patch_context(context, {'di.E4DI00.value': 1}) self.assertEqual(context.di.E4DI00.value, 1, "Context should be updted")
def test_overrides_non_existing_tag(self): context = { 'di': { 'E4DI00': { 'value': 0 } } } context = bunchify(context) Formula._patch_context(context, {'di.E4DI01.value': 1}) self.assertEqual(context.di.E4DI00.value, 0) self.assertEqual(context.di.E4DI01.value, 1)
def import_profile_from_workbook(profile, workbook, no_calculate=False,): """Command independent importer""" for comaster in profile.comasters.all(): add_vs_to_comaster(comaster) ieds = IED.objects.filter(co_master__profile=profile) DI.import_excel(workbook, ieds=ieds) AI.import_excel(workbook, ieds=ieds) screens = profile.screens.all() SVGElement.import_excel(workbook, screens=screens) Formula.import_excel(workbook, screens=screens) if not no_calculate: ok, error = Formula.calculate() return result_type(ok, error, ok + error) return result_type(0, 0, Formula.objects.all().count())
def handle_noargs(self, **options): self.options = bunchify(options) self.load_formulas() if self.options['post_calculate']: ok, error = Formula.calculate() print "%s: %s, %s: %s" % ("Calculo OK", green(ok), "Caluclo ERROR", red(error)) for formula in Formula.objects.exclude(last_error=''): print "%s.%s %s %s" % ( yellow(formula.target.tag, True), green(formula.attribute), formula.formula, red(formula.last_error))
def import_profile_from_workbook( profile, workbook, no_calculate=False, ): """Command independent importer""" for comaster in profile.comasters.all(): add_vs_to_comaster(comaster) ieds = IED.objects.filter(co_master__profile=profile) DI.import_excel(workbook, ieds=ieds) AI.import_excel(workbook, ieds=ieds) screens = profile.screens.all() SVGElement.import_excel(workbook, screens=screens) Formula.import_excel(workbook, screens=screens) if not no_calculate: ok, error = Formula.calculate() return result_type(ok, error, ok + error) return result_type(0, 0, Formula.objects.all().count())
def handle_noargs(self, **options): self.options = bunchify(options) self.load_formulas() if self.options['post_calculate']: ok, error = Formula.calculate() print "%s: %s, %s: %s" % ("Calculo OK", green(ok), "Caluclo ERROR", red(error)) for formula in Formula.objects.exclude(last_error=''): print "%s.%s %s %s" % ( yellow(formula.target.tag, True), green(formula.attribute), formula.formula, red(formula.last_error) )
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 test_formula_full_context(self): ctx = Formula.full_context() self.assertEqual(len(ctx.di), 1, "There should be only E4DI00 in DI context") self.assertEqual(len(ctx.ai), 1, "There should be only E4AI00 in AI context") self.assertEqual(len(ctx.eg), 1, "There should be only E4EG00 in EG context")
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