Jump to content

schrorg

Members
  • Gesamte Inhalte

    9
  • Benutzer seit

  • Letzter Besuch

schrorg's Achievements

Newbie

Newbie (1/14)

  • One Year In
  • Week One Done
  • One Month Later

Recent Badges

0

Reputation in der Community

  1. Hallo nochmal, da ich das bisher im Netz nirgendwo in der Form finden konnte, hier mein Script. Vielleicht ist es ja für den Ein- oder Anderen ein guter Startpunkt für eigene Implementationen... /* * TinkerForge Wetterstation */ // Configuration: var hosts = ['tf-1', 'tf-2', 'tf-3']; var PORT = 4223; var refresh_secs = 15; // Mindestabstand zwischen Messwerten var ipcon = []; var brick = []; var bricklet = []; refresh_secs *= 1000; var Tinkerforge = require('tinkerforge'); function enumerateHosts() { // Loop over hosts hosts.forEach(function(HOST) { console.log('Host: ' + HOST); // Create connection and connect to brickd ipcon[HOST] = new Tinkerforge.IPConnection(); ipcon[HOST].connect(HOST, PORT); ipcon[HOST].on(Tinkerforge.IPConnection.CALLBACK_CONNECTED, function(connectReason) { // Trigger Enumerate ipcon[HOST].enumerate(); } ); // Register Enumerate Callback ipcon[HOST].on(Tinkerforge.IPConnection.CALLBACK_ENUMERATE, function(uid, connectedUid, position, hardwareVersion, firmwareVersion, deviceIdentifier, enumerationType) { if(enumerationType === Tinkerforge.IPConnection.ENUMERATION_TYPE_DISCONNECTED) { return; } // See https://www.tinkerforge.com/de/doc/Software/Device_Identifier.html for IDs var value = null; switch (deviceIdentifier) { case 216: // Temperature console.log('Temperature: ' + uid); bricklet[uid] = {}; bricklet[uid].host = HOST; bricklet[uid].bricklet = new Tinkerforge.BrickletTemperature(uid, ipcon[bricklet[uid].host]); createState('TinkerForge.' + bricklet[uid].host + '.' + uid + '.name', 'Temperature Bricklet', { type: 'string' }); bricklet[uid].bricklet.getTemperature(function(temperature) { value = temperature / 100.0; createState('TinkerForge.' + bricklet[uid].host + '.' + uid + '.temperature', value, { name: 'Temperature', type: 'number', unit: '°C' }); }); bricklet[uid].bricklet.setTemperatureCallbackPeriod(refresh_secs); bricklet[uid].bricklet.on(Tinkerforge.BrickletTemperature.CALLBACK_TEMPERATURE, function(temperature) { //console.log('T:' + uid + ':' + temperature); setState('TinkerForge.' + bricklet[uid].host + '.' + uid + '.temperature', temperature / 100.0); }); break; case 27: // Humidity console.log('Humidity: ' + uid); bricklet[uid] = {}; bricklet[uid].host = HOST; bricklet[uid].bricklet = new Tinkerforge.BrickletHumidity(uid, ipcon[bricklet[uid].host]); createState('TinkerForge.' + bricklet[uid].host + '.' + uid + '.name', 'Humidity Bricklet', { type: 'string' }); bricklet[uid].bricklet.getHumidity(function(humidity) { value = humidity / 10.0; createState('TinkerForge.' + bricklet[uid].host + '.' + uid + '.humidity', value, { name: 'Humidity', type: 'number', unit: '%RH' }); }); bricklet[uid].bricklet.setHumidityCallbackPeriod(refresh_secs); bricklet[uid].bricklet.on(Tinkerforge.BrickletHumidity.CALLBACK_HUMIDITY, function(humidity) { //console.log('H:' + uid + ':' + humidity); setState('TinkerForge.' + bricklet[uid].host + '.' + uid + '.humidity', humidity / 10.0); }); break; case 221: // Barometer console.log('Barometer: ' + uid); bricklet[uid] = {}; bricklet[uid].host = HOST; bricklet[uid].bricklet = new Tinkerforge.BrickletBarometer(uid, ipcon[bricklet[uid].host]); createState('TinkerForge.' + bricklet[uid].host + '.' + uid + '.name', 'Barometer Bricklet', { type: 'string' }); bricklet[uid].bricklet.getAirPressure(function(airPressure) { value = airPressure / 1000.0; createState('TinkerForge.' + bricklet[uid].host + '.' + uid + '.AirPressure', value, { name: 'AirPressure', type: 'number', unit: 'mbar' }); }); bricklet[uid].bricklet.setAirPressureCallbackPeriod(refresh_secs); bricklet[uid].bricklet.on(Tinkerforge.BrickletBarometer.CALLBACK_AIR_PRESSURE, function(airPressure) { //console.log('BaP:' + uid + ':' + airPressure); setState('TinkerForge.' + bricklet[uid].host + '.' + uid + '.AirPressure', airPressure / 1000.0); }); bricklet[uid].bricklet.getAltitude(function(altitude) { value = altitude / 100.0; createState('TinkerForge.' + bricklet[uid].host + '.' + uid + '.Altitude', value, { name: 'Altitude', type: 'number', unit: 'm' }); }); bricklet[uid].bricklet.setAltitudeCallbackPeriod(refresh_secs); bricklet[uid].bricklet.on(Tinkerforge.BrickletBarometer.CALLBACK_ALTITUDE, function(altitude) { //console.log('Bal:' + uid + ':' + altitude); setState('TinkerForge.' + bricklet[uid].host + '.' + uid + '.Altitude', altitude / 100.0); }); break; } // End switch over brick(let)s } ); }); // End loop over hosts } // End enumerateHosts onStop(function (callback) { console.log('Terminating IPConnections'); hosts.forEach(function(HOST) { ipcon[HOST].disconnect(); }); }, 2000 /* timeout */); // Start with enumeration enumerateHosts(); Darf gerne als Ausgangspunkt für eigene Projekte benutzt werden. Viele Grüße Robin
  2. Ah, sehr gut. Dann hatte ich da also den richtigen Riecher. Ich habe tatsächlich auch noch ein paar weitere Bricklets (Display, IO4), die ich mit dem JavaScript-Code nicht anfasse. Die werden allerdings noch von Perl-Scripten bedient und da nutze ich auch Callbacks. Das würde also irgendwie passen. Danke schonmal für den Fix! Viele Grüße Robin
  3. Hallo zusammen, ich bastle seit ein paar Tagen an einem Skript, welches die Daten meiner Wetterstationen in ioBroker darstellt. Das muss in JavaScript geschehen, weshalb ich mir die Bindings geschnappt und los gelegt habe. Ich mache zunächst ein enumerate und sammle mir bekannte Bricklets (Temperature, Humidity, Barometer) ein. Diese instanziere ich dann und starte die jeweilige Callback. Die Werte bekomme ich alle ordentlich nach ioBroker übermittelt, es funktioniert also eigentlich alles einwandfrei. Das Problem ist, dass alle 2-3 Minuten das Skript abbricht, und zwar mit folgendem Fehler: 2017-09-12 16:00:24.263 - error: javascript.1 TypeError: Cannot read property 'expectedResponses' of undefined at IPConnection.handleResponse (/opt/iobroker/node_modules/iobroker.javascript/node_modules/tinkerforge/lib/IPConnection.js:901:47) at IPConnection.handlePacket (/opt/iobroker/node_modules/iobroker.javascript/node_modules/tinkerforge/lib/IPConnection.js:1025:18) at IPConnection.handleIncomingData (/opt/iobroker/node_modules/iobroker.javascript/node_modules/tinkerforge/lib/IPConnection.js:331:18) at emitOne (events.js:96:13) at Socket.emit (events.js:188:7) at readableAddChunk (_stream_readable.js:176:18) at Socket.Readable.push (_stream_readable.js:134:10) at TCP.onread (net.js:547:20) Ich habe das gequickfixt indem ich in der IPConnection.js in Zeile 899 (also knapp vor dem Fehler) folgendes eingefügt habe: if (handleResponseDevice === undefined) return; Damit läuft alles einwandfrei, mittlerweile seit über 30 Minuten. Hat jemand eine Idee, ob es sich hier um einen Bug in der IPConnection.js handelt oder ob ich eventuell etwas falsch mache? Robin
  4. Habe nur ich das Problem mit mehreren IP Connections in Perl? Oder sehe ich gerade den Wald vor lauter Bäumen nicht und mache irgendwas falsch?
  5. Hallo zusammen, ich habe gerade folgendes Problem bei der Nutzung der Perl bindings: Nach dem connect zu einem zweiten Stapel ist die Verbindung zum ersten Stapel nicht mehr nutzbar. Folgendes Beispiel: #!/usr/bin/perl use lib '../bindings/perl/source/lib'; use strict; use warnings; use Tinkerforge::IPConnection; use Tinkerforge::BrickletTemperature; my $ipcon1 = Tinkerforge::IPConnection->new(); my $b_temp1 = Tinkerforge::BrickletTemperature->new('dHw', $ipcon1); my $ipcon2 = Tinkerforge::IPConnection->new(); my $b_temp2 = Tinkerforge::BrickletTemperature->new('aH3', $ipcon2); $ipcon1->connect('tf-1', 4223); $ipcon2->connect('tf-2', 4223); print "temp1: " . ($b_temp1->get_temperature / 100.0) . "\n"; print "temp2: " . ($b_temp2->get_temperature / 100.0) . "\n"; $ipcon1->disconnect; $ipcon2->disconnect; Die Ausgabe ist folgendermaßen: root@pi-1:/opt/tinkerforge/software/display# ./test2.pl Did not receive response for function 1 in time at ./test2.pl line 18 Perl exited with active threads: 6 running and unjoined 0 finished and unjoined 0 running and detached In C/C++ funktioniert das problemlos. Daten zum System: root@pi-1:/opt/tinkerforge/software/display# perl -v This is perl 5, version 14, subversion 2 (v5.14.2) built for arm-linux-gnueabihf-thread-multi-64int (with 89 registered patches, see perl -V for more detail) [...] root@pi-1:/opt/tinkerforge/software/display# lsb_release -a No LSB modules are available. Distributor ID: Debian Description: Debian GNU/Linux 7.10 (wheezy) Release: 7.10 Codename: wheezy Es ist ein Raspbian Wheezy. Gibt es ein bekanntes Problem mit den Perl Bindings und mehreren IP Connections? Viele Grüße Robin
  6. Hi Ishraq, i think i found a bug in api/Device.pm while playing with my LCD20x4 bricklet: When displaying exactly 20 characters, the last character will not be printed on the display. For me, a fix in the function send_request() in api/Device.pm makes it work: While packing the string (with 'Z20') in line 111, the 20th character will be exchanged with a null character. So my fix is to pack with one more character instead: diff -ur api_orig/Device.pm api/Device.pm --- api_orig/Device.pm 2014-01-05 12:44:59.515125343 +0100 +++ api/Device.pm 2014-01-05 12:47:13.621152531 +0100 @@ -108,7 +108,9 @@ # Strings should be treated different even if its in Z<count> form if($form_data_arr_tmp[0] eq 'Z') { - $packed_data .= pack("$form_data_arr[$i]", @{$data}[$i]); + $form_data_arr[$i] =~ /^Z(\d+)$/; + my $packsize = $1; + $packed_data .= pack("Z" . ($packsize + 1), @{$data}[$i]); next; } @@ -121,7 +123,13 @@ } if(split('', $form_data_arr[$i]) == 1) { - $packed_data .= pack("$form_data_arr[$i]", @{$data}[$i]); + if ($form_data_arr[$i] =~ /^Z(\d+)$/) { + my $packsize = $1; + $packed_data .= pack("Z" . ($packsize + 1), @{$data}[$i]); + } + else { + $packed_data .= pack("$form_data_arr[$i]", @{$data}[$i]); + } } } } I'm not sure if my fix is harmful in any other way, so I would kindly ask you to review the problem. I attached the patch and a small test program. Robin device_pack_length_fix.patch test.pl
  7. Hi Ishraq, very nice work! I quickly tried the enumerate example (without the display code) and it worked like a charm (after I recompiled my perl with "-Dusethreads"...)! I will reimplement the C/C++ part of my weather station (wind measurement with anemometer from Amazon and IO-4 bricklet) in perl in the next days and see, if callbacks and the stuff run stable. The rest of my weather station is already implemented in perl. I use the perl bindings from CPAN (http://search.cpan.org/~joba/TinkerForge-0.01/lib/TinkerForge.pm), but in a newer version from here: https://git.rub.de/gitweb/?p=tinkerforgeperl.git;a=summary The problem with the CPAN perl bindings (which are actually from a friend and me) is, that they use the C/C++ bindings and wrap them in XS. They have only the functionality we need and don't need a perl with thread support (mainly because of stability problems on our machines and with our test suite). Callbacks are not implemented. Your version of the bindings seem to be complete and could be automatically generated like the other bindings. I would prefer them over the version from CPAN, if they would be further developed. I would really like the perl bindings to be official. If I can help in any way, don't hesitate to ask! :-) Robin
  8. Hi! So, jetzt habe ich mal ein bisschen mehr Zeit. Also folgendes: Andreas Jobs und ich (eigentlich viel mehr er als ich) haben neulich mal die TinkerForge C/C++-Bindings genommen und mittels Perl XS Perl-Module daraus gemacht. Dabei haben wir erstmal nur die Funktionen implementiert, die wir (also im Wesentlichen ich) für eine kleine Wetterstation brauchen. Und ein bisschen mehr. Erstmal nur so zum üben. Ich habe mir vor ein paar Wochen mal ein TinkerForge Starter-Kit gekauft und das haben wir erstmal zum Testen genommen. Für folgende Module gibt es jetzt also Funktionen: Master Brick (voltage(), current() und ein paar ungetestete Chibi-Funktionen) Ambient Light (illuminance()) Distance IR (distance()) Humidity (humidity()) Rotary Poti (position()) Temperature (temperature()) Temperature IR (ambient_temperature(), object_temperature(), emissivity()) Voltage (voltage()) Was es noch nicht gibt, sind Callbacks. Und die will man ja eigentlich haben. Da überlegen wir momentan noch, wie wir das am elegantesten hin bekommen. Funktionieren tut das vom Prinzip her, ist aber mit XS ein bisschen blöd zu machen. Mal schauen, was die Tage noch so bringen... Wir wären übrigens auch sehr an einem Ethernet-Brick (mit oder ohne PoE) interessiert, damit könnten wir für unsere Netzwerk-Standorte (in dreistelliger Stückzahl) relativ einfach ein kostengünstiges Monitoring implementieren! Wir haben uns bewusst dagegen entschieden, die Funktionen der C/C++-Bindings 1:1 in Perl abzubilden, weil wir der Meinung sind, dass es zweckdienlicher ist, mit den TinkerForge-Modulen in Perl vom Prinzip her genau so umgehen zu können wie mit jedem anderen Modul. Damit sieht eine Temperatur-Abfrage beispielsweise so aus: #!/opt/perl/bin/perl use TinkerForge::Client; my $tc = new TinkerForge::Client( Hostname => 'yourhostname', Port => 1234 ); my $b_temp = $tc->add_temperature_bricklet('yourBrickletUID'); print 'Temperatur: ' . $b_temp->temperature . ' °C' . "\n"; Ich mache das und ein paar weitere Sachen momentan per Cron-Job alle 5 Minuten und schreibe das Ergebnis in eine Datenbank. Dazu brauche ich erstmal keine Callbacks. Aber für's Display werde ich die später brauchen. Ich werde die Tage mal eins bestellen, damit mein Wetter auch irgendwo angezeigt wird! Es würde uns freuen, wenn die Module allgemeine Zustimmung finden würden. Wir sind auch eigentlich ganz kooperativ und beißen nicht! Wenn es also konstruktive Kritik oder Fragen gibt, sagt bescheid! Gibt es eigentlich irgendwo (vielleicht bei den TinkerForge-Jungs) einen Brick Daemon, an den viele Module angeschlossen sind und den man zum Testen neuer Funktionen verwenden kann? Das würde uns sehr helfen und sicherlich Ansporn geben, weitere Bricks und Bricklets zu implementieren! Viele Grüße Robin Schröder
  9. Hier gibt's welche: http://search.cpan.org/~joba/TinkerForge-0.01/lib/TinkerForge.pm Es sind zwar noch nicht alle Bricks und Bricklets dabei, aber ist schonmal nen guter Anfang!
×
×
  • Neu erstellen...