Wenn dies dein erster Besuch hier ist, lies bitte zuerst die Hilfe - Häufig gestellte Fragen durch. Du musst dich vermutlich registrieren, bevor du Beiträge verfassen kannst. Klicke oben auf 'Registrieren', um den Registrierungsprozess zu starten. Du kannst auch jetzt schon Beiträge lesen. Suche dir einfach das Forum aus, das dich am meisten interessiert.
sub hexstr_to_signed32int {
my ($hexstr) = @_;
die "Invalid hex string: $hexstr"
if $hexstr !~ /^[0-9A-Fa-f]{1,8}$/;
my $num = hex($hexstr);
return $num >> 31 ? $num - 2 ** 32 : $num;
}
Ich lese die Zählerwerte mit Perl aus.
Das Perl-Script wird über ein Start-Stop Script in der init.d gestartet.
Es liest alle 2sek. die Werte aus.
Die Augenblickliche Leistung wird alle 2sek. in die rrd und die SQLite DB geschrieben.
Aus der SQLite DB hole ich dann die Werte auf den KNX-BUS.
Gruß NetFritz
Hallo
Ich bin auch dabei meinen Easymeter Q3C mit Perl auszulesen.
Nur mit den Umrechnen der Augenblicklichen Leistung in Abgabe brauche ich mal Hilfe.
Die Umrechnung in Bezug bekomme ich hin.
Der Zähler liefert 32 Bit (4 Byte)
Hex C4653601 bis 3B9AC9FF
das entspricht dann
Dec - 9999999.99 bis + 9999999.99 kW
Der Zähler zeigt mir z.b. zur Zeit als Abgabe "FFFF93B8" an.
Wie bekomme ich da den negativen Wert für Abgabe raus.
Die positiven Werte wandele ich mit hex(3B9AC9FF) zu 999999999 .
Gruß NetFritz
Ich bin gerade auch fleißig am rumexperimentieren mit SML. Hab dabei das Problem, dass ich keine negativen Wirkleistungen erkennen kann. Wenn ich mir den Code des SML-Servers anschaue, dann wird dort auch der integer-Wert einfach auf ein uint8 gelegt, oder?
Der Stand ist: nachdenken und sich was überlegen, im Mittel 2s (0-4) im Plugin warten ist jedenfalls keine brauchbare Option
Als Quickhack würde ich den sml_server per crontab aufrufen mit "sml_server | nc .." auf einen lokalen UDP-Port senden lassen und dort ein Plugin horchen.. oder so ähnlich, aber das bekomm ich halt keinem in 10 minuten erklärt, also muss ich mir was besseres ausdenken wenn mir mal wieder langweilig ist
Zusammenpacken heisst hier: ein gepflegtes Debian-Paket machen, damit das jeder Freakfrei aufm WG benutzen kann ohne zu wissen was C, gcc, automake oder .. bedeutet
Das hört sich gut an!
Bei mir vorhanden:
-nackiches WG
-VZ-OKK
-EMH "Null Brain"-Zähler(vzgl EnBW NB)
So ein ähnliches Projekt hätte ich für einen DELTASOL Solarregler, aber das steht ganz unten auf der Liste. DELTASOL wird unter vielen anderen Namen vertrieben und könnte damit auch einen großen Interessentenkreis haben.
Ein Zähler sendet etwa alle 3-4 Sekunden eine SML Nachricht, solange ist dann geblocked (pro abzufragendem Zähler).
Ich kann Dich gern per WartungsVPN auf mein WG rauflassen, die Zähler (3 Stück) sind alle lokal angebunden (per pl2303 auf Optokopf) und alles zum Bauen (make, gcc, libsml und die modifizierte sml_server.c) sind auch schon drauf.
Zusammenpacken heisst hier: ein gepflegtes Debian-Paket machen, damit das jeder Freakfrei aufm WG benutzen kann ohne zu wissen was C, gcc, automake oder .. bedeutet
1sek wäre Ok, 4 sek zuviel, dann überlege ich mir was anderes..
Testen würde ich halt gerne, obs denn auch wirklich final funzt (eines unserer ElabNET-Motto's: "was nicht getestet ist, funktioniert auch nicht!")
Das Thema ansich wiegesagt finde ich sehr interessant, weil 100% der Haushalte sowas kraft Gesetz bekommen
sieht ja übersichtlich aus, ich würde das die Tage mal zusammenpacken, letzte Frage: wie oft sendet der Zähler freiwillig, ergo wie lange blocked das read(fd .. maximal (im Normalbetrieb) ?
Und wer lässt mich in 1-52 Wochen mit seinem Zähler per VPN testen ?
// Copyright 2011 Juri Glass, Mathias Runge, Nadim El Sayed
// DAI-Labor, TU-Berlin
//
// This is derived from the sample sml_server.c in libSML
//
// libSML is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// libSML is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with libSML. If not, see <http://www.gnu.org/licenses/>.
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <termios.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <math.h>
#include <netdb.h>
#include <sys/socket.h>
#include <signal.h>
#include <sml/sml_file.h>
#include <sml/sml_transport.h>
#include "unit.h"
int i;
int serial_port_open(const char* device) {
int bits;
struct termios config;
memset(&config, 0, sizeof(config));
int fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0) {
printf("error: open(%s): %s\n", device, strerror(errno));
return -1;
}
// set RTS
ioctl(fd, TIOCMGET, &bits);
bits |= TIOCM_RTS;
ioctl(fd, TIOCMSET, &bits);
tcgetattr( fd, &config ) ;
// set 8-N-1
config.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
config.c_oflag &= ~OPOST;
config.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
config.c_cflag &= ~(CSIZE | PARENB | PARODD | CSTOPB);
config.c_cflag |= CS8;
// set speed to 9600 baud
cfsetispeed( &config, B9600);
cfsetospeed( &config, B9600);
tcsetattr(fd, TCSANOW, &config);
return fd;
}
void transport_receiver(unsigned char *buffer, size_t buffer_len) {
// the buffer contains the whole message, with transport escape sequences.
// these escape sequences are stripped here.
sml_file *file = sml_file_parse(buffer + 8, buffer_len - 16);
// the sml file is parsed now
for (i = 0; i < file->messages_len; i++) {
sml_message *message = file->messages[i];
if (*message->message_body->tag == SML_MESSAGE_GET_LIST_RESPONSE) {
sml_list *entry;
sml_get_list_response *body;
body = (sml_get_list_response *) message->message_body->data;
for (entry = body->val_list; entry != NULL; entry = entry->next) { /* linked list */
int unit = (entry->unit) ? *entry->unit : 0;
double value;
switch (entry->value->type) {
case 0x51: value = *entry->value->data.int8; break;
case 0x52: value = *entry->value->data.int16; break;
case 0x54: value = *entry->value->data.int32; break;
case 0x58: value = *entry->value->data.int64; break;
case 0x61: value = *entry->value->data.uint8; break;
case 0x62: value = *entry->value->data.uint16; break;
case 0x64: value = *entry->value->data.uint32; break;
case 0x68: value = *entry->value->data.uint64; break;
default:
// fprintf(stderr, "Unknown value type: %x", entry->value->type);
value = 0;
}
/* apply scaler */
//value *= pow(10, scaler); requires additional includes from obis library that has unmet dependencies
value *= 0.0001; // using fixed scalar for now, works with Hager eHZ
if (value) {
printf("%.2f %s\n", value, dlms_get_unit(unit));
}
}
exit(0); // processed first message - exit
}
}
// free the malloc'd memory
sml_file_free(file);
}
int main(int argc, char **argv) {
// this example assumes that a EDL21 meter sending SML messages via a
// serial device. Use serial device name as input parameter, i.e. /dev/ttyUSB1
char *device = argv[1];
int fd = serial_port_open(device);
if (fd > 0) {
// listen on the serial device, this call is blocking.
sml_transport_listen(fd, &transport_receiver);
close(fd);
}
return 0;
}
Die benötigt noch (für die Einheiten) eine unit.h im gleichen Verzeichnis, die habe ich aus dem vzlogger Projekt genommen:
Code:
/**
* DLMS Units as specified in ISO EN 62056-62 and used by SML
*
* @package vzlogger
* @copyright Copyright (c) 2011, The volkszaehler.org project
* @license http://www.gnu.org/licenses/gpl.txt GNU Public License
* @author Steffen Vogel <info@steffenvogel.de>
*/
/*
* This file is part of volkzaehler.org
*
* volkzaehler.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* volkzaehler.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
*/
typedef struct {
char code;
char *unit;
} dlms_unit_t;
/**
* Static lookup table
*/
dlms_unit_t dlms_units[] = {
// code, unit // Quantity Unit name SI definition (comment)
//=====================================================================================================
{1, "a"}, // time year 52*7*24*60*60 s
{2, "mo"}, // time month 31*24*60*60 s
{3, "wk"}, // time week 7*24*60*60 s
{4, "d"}, // time day 24*60*60 s
{5, "h"}, // time hour 60*60 s
{6, "min."}, // time min 60 s
{7, "s"}, // time (t) second s
{8, "°"}, // (phase) angle degree rad*180/π
{9, "°C"}, // temperature (T) degree celsius K-273.15
{10, "currency"}, // (local) currency
{11, "m"}, // length (l) metre m
{12, "m/s"}, // speed (v) metre per second m/s
{13, "m³"}, // volume (V) cubic metre m³
{14, "m³"}, // corrected volume cubic metre m³
{15, "m³/h"}, // volume flux cubic metre per hour m³/(60*60s)
{16, "m³/h"}, // corrected volume flux cubic metre per hour m³/(60*60s)
{17, "m³/d"}, // volume flux m³/(24*60*60s)
{18, "m³/d"}, // corrected volume flux m³/(24*60*60s)
{19, "l"}, // volume litre 10-3 m³
{20, "kg"}, // mass (m) kilogram
{21, "N"}, // force (F) newton
{22, "Nm"}, // energy newtonmeter J = Nm = Ws
{23, "Pa"}, // pressure (p) pascal N/m²
{24, "bar"}, // pressure (p) bar 10⁵ N/m²
{25, "J"}, // energy joule J = Nm = Ws
{26, "J/h"}, // thermal power joule per hour J/(60*60s)
{27, "W"}, // active power (P) watt W = J/s
{28, "VA"}, // apparent power (S) volt-ampere
{29, "var"}, // reactive power (Q) var
{30, "Wh"}, // active energy watt-hour W*(60*60s)
{31, "VAh"}, // apparent energy volt-ampere-hour VA*(60*60s)
{32, "varh"}, // reactive energy var-hour var*(60*60s)
{33, "A"}, // current (I) ampere A
{34, "C"}, // electrical charge (Q) coulomb C = As
{35, "V"}, // voltage (U) volt V
{36, "V/m"}, // electr. field strength (E) volt per metre
{37, "F"}, // capacitance (C) farad C/V = As/V
{38, "Ω"}, // resistance (R) ohm Ω = V/A
{39, "Ωm²/m"}, // resistivity (ρ) Ωm
{40, "Wb"}, // magnetic flux (Φ) weber Wb = Vs
{41, "T"}, // magnetic flux density (B) tesla Wb/m2
{42, "A/m"}, // magnetic field strength (H) ampere per metre A/m
{43, "H"}, // inductance (L) henry H = Wb/A
{44, "Hz"}, // frequency (f, ω) hertz 1/s
{45, "1/(Wh)"}, // R_W (Active energy meter constant or pulse value)
{46, "1/(varh)"}, // R_B (reactive energy meter constant or pulse value)
{47, "1/(VAh)"}, // R_S (apparent energy meter constant or pulse value)
{48, "V²h"}, // volt-squared hour volt-squaredhours V²(60*60s)
{49, "A²h"}, // ampere-squared hour ampere-squaredhours A²(60*60s)
{50, "kg/s"}, // mass flux kilogram per second kg/s
{51, "S, mho"}, // conductance siemens 1/Ω
{52, "K"}, // temperature (T) kelvin
{53, "1/(V²h)"}, // R_U²h (Volt-squared hour meter constant or pulse value)
{54, "1/(A²h)"}, // R_I²h (Ampere-squared hour meter constant or pulse value)
{55, "1/m³"}, // R_V, meter constant or pulse value (volume)
{56, "%"}, // percentage %
{57, "Ah"}, // ampere-hours ampere-hour
{60, "Wh/m³"}, // energy per volume 3,6*103 J/m³
{61, "J/m³"}, // calorific value, wobbe
{62, "Mol %"}, // molar fraction of mole percent (Basic gas composition unit)
// gas composition
{63, "g/m³"}, // mass density, quantity of material (Gas analysis, accompanying elements)
{64, "Pa s"}, // dynamic viscosity pascal second (Characteristic of gas stream)
{253, "(reserved)"}, // reserved
{254, "(other)"}, // other unit
{255, "(unitless)"}, // no unit, unitless, count
{} // stop condition for iterator
};
char * dlms_get_unit(unsigned char code) {
dlms_unit_t *it = dlms_units;
do { /* linear search */
if (it->code == code) {
return it->unit;
}
} while ((++it)->code);
return NULL; /* not found */
}
Das kompiliert dann mit dem Makefile der libsml/example
liefert dann bei mir folgendes bei Aufruf:
Code:
root@wiregate467:/usr/local/src/libsml/examples# /usr/local/bin/sml_server /dev/ttyUSB-1-4.7
12771.70 Wh
611.28 W
root@wiregate467:/usr/local/src/libsml/examples# /usr/local/bin/sml_server /dev/ttyUSB-1-4.5
6772.06 Wh
35.37 W
root@wiregate467:/usr/local/src/libsml/examples# /usr/local/bin/sml_server /dev/ttyUSB-1-4.6
1587.30 Wh
4.35 W
erste Zeile ist der abolsute Zählerstand und die zweite Zeile ist die Durchschnittslast der letzten (10/15?) Minuten. Es kann sein dass einige Zähler noch mehr ausspucken, dann werden es mehr als 2 Zeilen.
Die Werte brauch auch ich momentan nicht auf dem Bus
RRD-solange wie möglich reicht mir aus.
Es sollte nachher nur auf dem WG weiterlaufen
Ein sei bemerkt: Zähler ist nicht gleich Zähler und NEtzbetreiber nicht gleich Netzbetrieber. Es verhält sich so, wie die Anzahl der nicht gewollten von Uhren in der Küche:Null Brain
Empfehlung: Beim NB nachfragen, ob's eine Zählerauswahl gibt und dann auf HAGER setzen. Denn die sind offen und bieten Doku online an, und aus der Hardware kommt gleich was brauchbares raus.
Wir verarbeiten personenbezogene Daten über die Nutzer unserer Website mithilfe von Cookies und anderen Technologien, um unsere Dienste bereitzustellen. Weitere Informationen findest Du in unserer Datenschutzerklärung.
Indem Du unten auf "ICH stimme zu" klickst, stimmst Du unserer Datenschutzerklärung und unseren persönlichen Datenverarbeitungs- und Cookie-Praktiken zu, wie darin beschrieben. Du erkennst außerdem an, dass dieses Forum möglicherweise außerhalb Deines Landes gehostet wird und bist damit einverstanden, dass Deine Daten in dem Land, in dem dieses Forum gehostet wird, gesammelt, gespeichert und verarbeitet werden.
Einen Kommentar schreiben: