Thread Analyse der Struktur elektrischer Anlagen
(7 answers)
Opened by Ronnie at 2007-10-09 14:53
Hallo miteinander,
ich habe ein wenig gespielt um ein Programm zur Analyse der Struktur elektr. Anlagen zu schreiben. Eine elektr. Anlage ist nichts anderes wie ein Baum (andere Strukturen möglich aber seltener, deshalb ignoriert). Der Baum besteht erstmal aus: - Sicherungen, mit Bezeichnung und einem Bemessungsstrom - Leitungen, mit Bezeichnung, spez. Widerstand, Länge und Querschnitt Interessant sind z.B. die Leitungslängen (wg. des Spannungsfalls), die Querschnitte (sind die Sicherungen darauf abgestimmt), die Selektivität der Sicherungen (es soll immer nur die Sicherung auslösen, die dem Fehler am nächsten ist) u.a. Das ganze kann man relativ gut datentechnisch modellieren: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 #!/usr/bin/perl use strict; use warnings; use Data::Dumper; package EnerTree; use Moose; use List::Util qw /max/; has 'title' => ( is => 'rw' ); has 'follow_ups' => ( is => 'rw', isa => 'ArrayRef', default => sub {[]} ); my %lut_fuse = ( # guessing NYM 2 => 1.5, 4 => 1.5, 6 => 1.5, 10 => 1.5, 13 => 1.5, 16 => 1.5, 20 => 2.5, 25 => 2.5, 35 => 4, 40 => 6, 63 => 10, 80 => 16, ); sub add_follow_up { my $self = shift; my $other = shift; die "add_follow_up(): wrong argument type\n" unless (blessed $other eq 'Wire' or blessed $other eq 'Fuse'); push @{$self->follow_ups}, $other; } sub get_tree_resistance { my $self = shift; my $r = $self->get_resistance; my @fr = map { $_->get_tree_resistance } @{$self->follow_ups}; my $fr = max @fr; $r += $fr if defined($fr) and $fr > 0; return $r; } sub check_selectivity { my $self = shift; my $prev = shift || 100; my $hook = sub { warn $self->title . '/' . $self->rated_current . ' is not selectiv to: ' . $prev }; if (blessed $self eq 'Fuse') { $hook->() if ($self->rated_current > $prev / 1.6); $prev = $self->rated_current; } $_->check_selectivity($prev) for @{$self->follow_ups}; return; } 1; package Fuse; use Data::Dumper; use Moose; extends 'EnerTree'; has 'rated_current' => ( is => 'rw', isa => 'Num' ); sub get_resistance { return 0 }; override 'get_tree_resistance' => sub { my $self = shift; my $r = super(); my $voltage_drop = $r * $self->rated_current; print "voltage_drop: " . $voltage_drop . "\n"; warn "after: " . $self->title . " voltage drop exceeds limit of 3%!\n" if $voltage_drop > 0.03 * 230; return $r; }; sub check_width { my $self = shift; my $hook = sub { warn $self->title .' is to big for : ' . shift }; for (@{$self->follow_ups}) { $hook->($_->width) if $_->width < $lut_fuse{$self->rated_current}; } return; } 1; package Wire; use Moose; extends 'EnerTree'; has 'len' => ( is => 'rw', isa => 'Num' ); has 'width' => ( is => 'rw', isa => 'Num', default => 1.5 ); has 'type' => ( is => 'rw' ); has 'specific_resistance' => ( is => 'rw', isa => 'Num', default => 1/56.0 ); sub get_resistance { my $self = shift; return 2 * (($self->len * $self->specific_resistance) / $self->width); } 1; package main; my $w1 = Wire->new( width => 35, len => 200, specific_resistance => 1/37.8 ); my $w2 = Wire->new( width => 10, len => 12 ); my $w3 = Wire->new( len => 22 ); my $f1 = Fuse->new( title => 'F1', rated_current => 20 ); my $w4 = Wire->new( len => 19 ); $w1->add_follow_up( $w2 ); $w2->add_follow_up( $w3 ); $w2->add_follow_up( $f1 ); $f1->add_follow_up( $w4 ); print Dumper $w1; # # print $w1->get_resistance . "\n"; # print $w2->get_resistance . "\n"; # print $w3->get_resistance . "\n"; # print $w4->get_resistance . "\n"; # my $r_all = $w1->get_tree_resistance; $w1->check_selectivity; $f1->check_width; print $r_all . "\n"; print "max Ik: " . 230 / $r_all . "\n"; Das ist erstmal sehr rudimentär, aber funktioniert wie erwartet. Mein eigentliches Problem ist, dass ich keine Idee habe wie ich das ganze mit einer grafischen Oberfläche versehen könnte. Das liegt einerseits daran, dass ich nie viel GUI-Programmierung gemacht habe, andererseits daran, dass ich mir eine Art Rasteroberfläche vorstelle, in die man die einzelnen Elemente per Drag&Drop plazieren kann: Code: (dl
)
1 +--------------+---------------------------------------------+ Habt ihr Vorschläge wie das am besten zu realisieren wäre, mit TK, WX etc. ? Gruß, Ronnie |