Pflanzensensor Parrot Flower Power in FHEM // BT4.0

Begonnen von snowball7g, 25 Januar 2015, 18:51:31

Vorheriges Thema - Nächstes Thema

hive2015

Zitat von: emilio20 am 29 Dezember 2016, 12:54:09
Hallo ich habe mir auch einen Flower Power Pflanzensensor zugelegt.
Fhem lauf bei mir auf einem rasberry pi3 .
Ich würde gerne mit dem rasberry die live Daten des Pflanzensensors logen. Funktioniert dies schon oder kann ich nur auf die cloud zugreifen?

kennt jemand dieses Projekt ? Hier müssen die Livedaten ja auch vom rasberry erfasst werden
https://github.com/Parrot-Developers/node-flower-bridge

Das ging mal eine ganze Weile recht gut in Kombination von node-flower-bridge (damit scannte mein pi immer meine Pflanzen und pushte die Daten in die Cloud) sowie FlowerPowerTools, mit dem ich dann die Daten aus der Cloud mittels cronjob wieder aus der Cloud ausgelesen und in ein CSV gepumpt habe.

Leider hat Parrot vor einigen Monaten die API, Firmware und Software grundsätzlich geändert und dann ging quasi nix mehr. Es gab dann von dem node-flower-bridge eine V2  Version, welche aber ebenfalls seit nem guten Jahr nicht mehr weiterentwickelt wurde, mit der ging es wenigstens wieder nen kleines bisschen. Sie haben auch beim Parrot-Support gestanden, das sie momentan Probleme haben mit mehr als einem Sensor und überhaupt, aber das sie "energisch dran seien" das zu fixen. Das ist nun glaub 4 Monate her und es hat sich nichts getan. Daher werde ich meine FlowerPower-Sensoren in naher Zukunft wegschmeissen und durch z.B. die "xiaomi flower monitor" ersetzen, falls die mal irgendwo in annehmbarer Zeit lieferbar sind.

Gruss,
Hive

mumpitzstuff

#46
Nachdem ich mich einige Zeit mit irgendwelchen Bridges und anderem Zeugs rumgeschlagen habe und alles nur halblebig funktioniert, habe ich mal ein kleines Perl Script gebastelt, das die Daten direkt auslesen kann. Das sind wenige zeilen Code, die gern als Grundlage für ein FHEM Modul dienen können.
Schaut es euch doch mal bitte an und sagt mir, ob es bei euch funktioniert. Die komischen Formeln im Code habe ich von den Git Sourcen der Parrot Entwickler. Warum oder weshalb die so ausehen müssen, entzieht sich meiner Kenntnis. Am genauesten scheinen mir die Calibrated Werte zu sein (macht irgendwie auch Sinn). Leider sind bei meinem Sensor nur 3 der ansonsten 6 Werte auslesbar. Vielleicht gibts andere Sensoren die alle Werte haben. Außerdem ist das hier verwendete Gatttool auf 20 Byte Daten beschränkt. Die Firmware und Hardware Version wird deshalb nur teilweise angezeigt. Vielleicht hat dazu noch jemand eine Idee?

1.) Damit das Ganze funktioniert muss Bluez z.B. auf eurem Raspberry installiert sein und ordnungsgemäß funktionieren!
2.) Weiterhin müsst ihr im Script die Mac Adresse für euren Parrot Flower Power Sensor eintragen!
3.) Denkt bitte daran, dass das Script ausführbar sein muss (chmod +x ...).

Der Output sieht bei mir dann so aus:

Name: Flower power 43F8
System ID: f8438400003d14a0
Serial Number: PI040297AD5I204905
Firmware Revision: 2016-09-14_hawaii-2
Hardware Revision: 2013-07-26_hawaiiPr
Color: 4
Battery Level: 95
Calibrated Soil Moisture: 40.7666854858398
Calibrated Air Temperature: 18.6852474212646
Calibrated Sunlight: 0.100000001490116
Calibrated EA: 0
Calibrated ECB: 0
Calibrated EC Porous: 0
Sunlight: 0.129691229016778
Soil Electrical Conductivity: 3.87916431394692
Soil Temperature: 19.364238285
Air Temperature: 17.74524974592
Soil Moisture: 29.5134248813477


#!/usr/bin/perl

use strict;
use warnings;

sub readSensorValue($$);
sub convertStringToFloat($);
sub convertStringToU8($);
sub convertStringToU16($);
sub convertHexToString($);



my $mac = "AA:BB:CC:DD:EE:FF";
my $result;

# Name
$result = readSensorValue($mac, "00002a00-0000-1000-8000-00805f9b34fb");
print "Name: ".convertHexToString($result)."\n";

# Device Name
#$result = readSensorValue($mac, "39e1fe03-84a8-11e2-afba-0002a5d5c51b");
#print "Device Name: ".convertHexToString(substr($result, 0, -4))."\n";

# System ID
$result = readSensorValue($mac, "00002a23-0000-1000-8000-00805f9b34fb");
print "System ID: ".$result."\n";

# Serial Number
$result = readSensorValue($mac, "00002a25-0000-1000-8000-00805f9b34fb");
print "Serial Number: ".convertHexToString($result)."\n";

# Firmware Revision (gatttool is limited to 20 bytes of data)
$result = readSensorValue($mac, "00002a26-0000-1000-8000-00805f9b34fb");
print "Firmware Revision: ".convertHexToString($result)."\n";

# Hardware Revision (gatttool is limited to 20 bytes of data)
$result = readSensorValue($mac, "00002a27-0000-1000-8000-00805f9b34fb");
print "Hardware Revision: ".convertHexToString($result)."\n";

# Color
$result = readSensorValue($mac, "39e1fe04-84a8-11e2-afba-0002a5d5c51b");
print "Color: ".convertStringToU16($result)."\n";

# Battery Level in %
$result = readSensorValue($mac, "00002a19-0000-1000-8000-00805f9b34fb");
print "Battery Level: ".convertStringToU8($result)."\n";

# Calibrated Soil Moisture in %
$result = readSensorValue($mac, "39e1fa09-84a8-11e2-afba-0002a5d5c51b");
print "Calibrated Soil Moisture: ".convertStringToFloat($result)."\n";

# Calibrated Air Temperature in °C
$result = readSensorValue($mac, "39e1fa0a-84a8-11e2-afba-0002a5d5c51b");
print "Calibrated Air Temperature: ".convertStringToFloat($result)."\n";

# Calibrated Sunlight in mol/m^2
$result = readSensorValue($mac, "39e1fa0b-84a8-11e2-afba-0002a5d5c51b");
print "Calibrated Sunlight: ".convertStringToFloat($result)."\n";

# Calibrated EA (not available?)
$result = readSensorValue($mac, "39e1fa0c-84a8-11e2-afba-0002a5d5c51b");
print "Calibrated EA: ".convertStringToFloat($result)."\n";

# Calibrated ECB in dS/m (not available?)
$result = readSensorValue($mac, "39e1fa0d-84a8-11e2-afba-0002a5d5c51b");
print "Calibrated ECB: ".convertStringToFloat($result)."\n";

# Calibrated EC Porous in dS/m (not available?)
$result = readSensorValue($mac, "39e1fa0e-84a8-11e2-afba-0002a5d5c51b");
print "Calibrated EC Porous: ".convertStringToFloat($result)."\n";

# reference: https://github.com/Parrot-Developers/node-flower-power/blob/master/index.js
# reference: FlowerPower-BLE.pdf
# Sunlight in mol/m^2
$result = readSensorValue($mac, "39e1fa01-84a8-11e2-afba-0002a5d5c51b");
$result = 0.08640000000000001 * (192773.17000000001 * (convertStringToU16($result) ** -1.0606619));
print "Sunlight: ".$result."\n";

# Soil Electrical Conductivity in dS/m
$result = readSensorValue($mac, "39e1fa02-84a8-11e2-afba-0002a5d5c51b");
$result = (convertStringToU16($result) * 10.0) / 1771.0;
print "Soil Electrical Conductivity: ".$result."\n";

# Soil Temperature in °C
$result = readSensorValue($mac, "39e1fa03-84a8-11e2-afba-0002a5d5c51b");
$_ = convertStringToU16($result) * 1.0;
$result = (0.00000003044 * ($_ ** 3.0)) - (0.00008038 * ($_ ** 2.0)) + ($_ * 0.1149) - 30.449999999999999;
if ($result < -10.0)
{
  $result = -10.0;
}
elsif ($result > 55.0)
{
  $result = 55.0;
}
print "Soil Temperature: ".$result."\n";

# Air Temperature in °C
$result = readSensorValue($mac, "39e1fa04-84a8-11e2-afba-0002a5d5c51b");
$_ = convertStringToU16($result) * 1.0;
$result = (0.00000003044 * ($_ ** 3.0)) - (0.00008038 * ($_ ** 2.0)) + ($_ * 0.1149) - 30.449999999999999;
if ($result < -10.0)
{
  $result = -10.0;
}
elsif ($result > 55.0)
{
  $result = 55.0;
}
print "Air Temperature: ".$result."\n";

# Soil Moisture in % (seems to be incorrect)
$result = readSensorValue($mac, "39e1fa05-84a8-11e2-afba-0002a5d5c51b");
$_ = convertStringToU16($result) * 1.0;
$result = 11.4293 + ((0.0000000010698 * $_**4.0) - (0.00000152538 * $_**3.0) + (0.000866976 * $_**2.0) - (0.169422 * $_));
$result = 100.0 * ((0.0000045 * $result**3.0) - (0.00055 * $result**2.0) + (0.0292 * $result) - 0.053);
if ($result < 0.0)
{
  $result = 0.0;
}
elsif ($result > 60.0)
{
  $result = 60.0;
}
print "Soil Moisture: ".$result."\n";




sub readSensorValue($$)
{
  my $mac = shift;
  my $uuid = shift;
  my @result;
  my $repeatCounter = 0;

  do
  {
    # try to read the value from sensor
    @result = split(": ", qx(gatttool -b $mac --char-read --uuid=$uuid 2>/dev/null));
    $repeatCounter++;
  }
  while (($repeatCounter < 10) && (not defined($result[0])));

  if (defined($result[0]))
  {
    # remove spaces
    $result[2] =~ s/\s//g;

    return $result[2];
  }
  else
  {
    # return 0 in case of an error
    return "0";
  }
}


sub convertStringToFloat($)
{
  $_ = shift;

  # switch endianess of string
  $_ = unpack("H*", reverse(pack("H*", $_)));

  # convert string to float
  return unpack("f", pack("L", hex($_)));
}


sub convertStringToU8($)
{
  $_ = shift;

  # convert string to U8
  return hex($_);
}


sub convertStringToU16($)
{
  $_ = shift;

  # switch endianess of string
  $_ = unpack("H*", reverse(pack("H*", $_)));

  # convert string to U16
  return hex($_);
}


sub convertHexToString($)
{
  $_ = shift;

  # convert hex string into string
  return pack("H*", $_);
}

CoolTux

Das scheint ein und die selbe uuid zu sein. Kann mir da einer den char für geben. Ist irgendwie Recht viel Code um ein paar Werte aus dem Hex Telegramm zu bekommen.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

mumpitzstuff

Nein das sind immer andere oder übersehe ich da etwas? Ist leider nicht so einfach wie beim Xiaomi Sensor, bei dem in einer Antwort alle Werte hintereinander stehen. Die Doku von Parrot findest du hier. Gibt aber ehrlich gesagt nicht viel her. Andere Anhaltspunkte bietet die Bridge von Parrot. Die Berechnungen daraus habe ich Beispielsweise übernommen.

https://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=0ahUKEwjclMf989bRAhWCHxoKHatEB4IQFggaMAA&url=http%3A%2F%2Fdeveloper.parrot.com%2Fdocs%2FFlowerPower%2FFlowerPower-BLE.pdf&usg=AFQjCNHHPSPY-9n7gJDPUixOVj_nh-Q6Qw&sig2=N2071_Mxl2OY4qj61laiVg&bvm=bv.144686652,d.d2s

CoolTux

Mist hast Recht. Habe eben erst den Anfang mir mal genau angeschaut.
Das sind dann aber ne Menge Anfragen, die arme Batterie  :)
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

hive2015

@mumpitzstuff

Danke für da Script. Ich habe es bei mir mal laufen gelassen mit einem meiner Sensoren, aber die Ergebnisse sind ... hmm ... seltsam. Zum einen kommt kaum was zurück an Daten, zum anderen ist die Ausgabe bei jedem Aufruf etwas anders. Manchmal sind es ein paar mehr Infos, manchmal weniger.

Name: Flower power A70F
System ID: 466c6f77657220706f7765722041373046
Serial Number: ?
                =?
Firmware Revision: PI040307AA4C024330
Hardware Revision:
Color: 0
Battery Level: 0
Calibrated Soil Moisture: 0
Calibrated Air Temperature: 0
Calibrated Sunlight: 0
Calibrated EA: 0
Calibrated ECB: 0
Calibrated EC Porous: 0
Sunlight: inf
Soil Electrical Conductivity: 0
Soil Temperature: -10
Air Temperature: -10
Soil Moisture: 21.5608151743303


dann mal:

Name: Flower power A70F
System ID: 0
Serial Number:
Firmware Revision:
Hardware Revision:
Color: 0
Battery Level: 0
Calibrated Soil Moisture: 0
Calibrated Air Temperature: 0
Calibrated Sunlight: 0
Calibrated EA: 0
Calibrated ECB: 0
Calibrated EC Porous: 0
Sunlight: inf
Soil Electrical Conductivity: 0
Soil Temperature: -10
Air Temperature: -10
Soil Moisture: 21.5608151743303


oder:

Name:
System ID: 0
Serial Number:
Firmware Revision:
Hardware Revision:
Color: 0
Battery Level: 0
Calibrated Soil Moisture: 0
Calibrated Air Temperature: 0
Calibrated Sunlight: 0
Calibrated EA: 0
Calibrated ECB: 0


Was könnte das sein?

Danke und Gruss,
Hive

mumpitzstuff

#51
0 wird normalerweise zurück gegeben, wenn irgend etwas schief läuft und das Script es nach 10 Versuchen es nicht schafft den entsprechenden Wert zu lesen. Leg mal den Sensor relativ nahe an deinen Bluetooth Dongle und probier mal folgendes:

Such mal im Skript nach: 2>/dev/null
Und entferne den Teil.

Danach solltest du die Fehlermeldungen vom Gatttool sehen.

Ansonsten hier eine Version mit mehr Debugausgaben:


#!/usr/bin/perl

use strict;
use warnings;

sub readSensorValue($$);
sub convertStringToFloat($);
sub convertStringToU8($);
sub convertStringToU16($);
sub convertHexToString($);



my $mac = "AA:BB:CC:DD:EE:FF";
my $result;

# Name
$result = readSensorValue($mac, "00002a00-0000-1000-8000-00805f9b34fb");
print "Name (raw): ".$result."\n";
print "Name: ".convertHexToString($result)."\n";

# Device Name
#$result = readSensorValue($mac, "39e1fe03-84a8-11e2-afba-0002a5d5c51b");
#print "Device Name: ".convertHexToString(substr($result, 0, -4))."\n";

# System ID
$result = readSensorValue($mac, "00002a23-0000-1000-8000-00805f9b34fb");
print "System ID (raw): ".$result."\n";
print "System ID: ".$result."\n";

# Serial Number
$result = readSensorValue($mac, "00002a25-0000-1000-8000-00805f9b34fb");
print "Serial Number (raw): ".$result."\n";
print "Serial Number: ".convertHexToString($result)."\n";

# Firmware Revision (gatttool is limited to 20 bytes of data)
$result = readSensorValue($mac, "00002a26-0000-1000-8000-00805f9b34fb");
print "Firmware Revision (raw): ".$result."\n";
print "Firmware Revision: ".convertHexToString($result)."\n";

# Hardware Revision (gatttool is limited to 20 bytes of data)
$result = readSensorValue($mac, "00002a27-0000-1000-8000-00805f9b34fb");
print "Hardware Revision (raw): ".$result."\n";
print "Hardware Revision: ".convertHexToString($result)."\n";

# Color
$result = readSensorValue($mac, "39e1fe04-84a8-11e2-afba-0002a5d5c51b");
print "Color (raw): ".$result."\n";
print "Color: ".convertStringToU16($result)."\n";

# Battery Level in %
$result = readSensorValue($mac, "00002a19-0000-1000-8000-00805f9b34fb");
print "Battery Level (raw): ".$result."\n";
print "Battery Level: ".convertStringToU8($result)."\n";

# Calibrated Soil Moisture in %
$result = readSensorValue($mac, "39e1fa09-84a8-11e2-afba-0002a5d5c51b");
print "Calibrated Soil Moisture (raw): ".$result."\n";
print "Calibrated Soil Moisture: ".convertStringToFloat($result)."\n";

# Calibrated Air Temperature in °C
$result = readSensorValue($mac, "39e1fa0a-84a8-11e2-afba-0002a5d5c51b");
print "Calibrated Air Temperature (raw): ".$result."\n";
print "Calibrated Air Temperature: ".convertStringToFloat($result)."\n";

# Calibrated Sunlight in mol/m^2
$result = readSensorValue($mac, "39e1fa0b-84a8-11e2-afba-0002a5d5c51b");
print "Calibrated Sunlight (raw): ".$result."\n";
print "Calibrated Sunlight: ".convertStringToFloat($result)."\n";

# Calibrated EA (not available?)
$result = readSensorValue($mac, "39e1fa0c-84a8-11e2-afba-0002a5d5c51b");
print "Calibrated EA (raw): ".$result."\n";
print "Calibrated EA: ".convertStringToFloat($result)."\n";

# Calibrated ECB in dS/m (not available?)
$result = readSensorValue($mac, "39e1fa0d-84a8-11e2-afba-0002a5d5c51b");
print "Calibrated ECB (raw): ".$result."\n";
print "Calibrated ECB: ".convertStringToFloat($result)."\n";

# Calibrated EC Porous in dS/m (not available?)
$result = readSensorValue($mac, "39e1fa0e-84a8-11e2-afba-0002a5d5c51b");
print "Calibrated EC Porous (raw): ".$result."\n";
print "Calibrated EC Porous: ".convertStringToFloat($result)."\n";

# reference: https://github.com/Parrot-Developers/node-flower-power/blob/master/index.js
# reference: FlowerPower-BLE.pdf
# Sunlight in mol/m^2
$result = readSensorValue($mac, "39e1fa01-84a8-11e2-afba-0002a5d5c51b");
print "Sunlight (raw): ".$result."\n";
$result = 0.08640000000000001 * (192773.17000000001 * (convertStringToU16($result) ** -1.0606619));
print "Sunlight: ".$result."\n";

# Soil Electrical Conductivity in dS/m
$result = readSensorValue($mac, "39e1fa02-84a8-11e2-afba-0002a5d5c51b");
print "Soil Electrical Conductivity (raw): ".$result."\n";
$result = (convertStringToU16($result) * 10.0) / 1771.0;
print "Soil Electrical Conductivity: ".$result."\n";

# Soil Temperature in °C
$result = readSensorValue($mac, "39e1fa03-84a8-11e2-afba-0002a5d5c51b");
print "Soil Temperature (raw): ".$result."\n";
$_ = convertStringToU16($result) * 1.0;
$result = (0.00000003044 * ($_ ** 3.0)) - (0.00008038 * ($_ ** 2.0)) + ($_ * 0.1149) - 30.449999999999999;
if ($result < -10.0)
{
  $result = -10.0;
}
elsif ($result > 55.0)
{
  $result = 55.0;
}
print "Soil Temperature: ".$result."\n";

# Air Temperature in °C
$result = readSensorValue($mac, "39e1fa04-84a8-11e2-afba-0002a5d5c51b");
print "Air Temperature (raw): ".$result."\n";
$_ = convertStringToU16($result) * 1.0;
$result = (0.00000003044 * ($_ ** 3.0)) - (0.00008038 * ($_ ** 2.0)) + ($_ * 0.1149) - 30.449999999999999;
if ($result < -10.0)
{
  $result = -10.0;
}
elsif ($result > 55.0)
{
  $result = 55.0;
}
print "Air Temperature: ".$result."\n";

# Soil Moisture in % (seems to be incorrect)
$result = readSensorValue($mac, "39e1fa05-84a8-11e2-afba-0002a5d5c51b");
print "Soil Moisture (raw): ".$result."\n";
$_ = convertStringToU16($result) * 1.0;
$result = 11.4293 + ((0.0000000010698 * $_**4.0) - (0.00000152538 * $_**3.0) + (0.000866976 * $_**2.0) - (0.169422 * $_));
$result = 100.0 * ((0.0000045 * $result**3.0) - (0.00055 * $result**2.0) + (0.0292 * $result) - 0.053);
if ($result < 0.0)
{
  $result = 0.0;
}
elsif ($result > 60.0)
{
  $result = 60.0;
}
print "Soil Moisture: ".$result."\n";




sub readSensorValue($$)
{
  my $mac = shift;
  my $uuid = shift;
  my @result;
  my $repeatCounter = 0;

  do
  {
    # try to read the value from sensor
    @result = split(": ", qx(gatttool -b $mac --char-read --uuid=$uuid));
    $repeatCounter++;
  }
  while (($repeatCounter < 10) && (not defined($result[0])));

  if (defined($result[0]))
  {
    # remove spaces
    $result[2] =~ s/\s//g;

    return $result[2];
  }
  else
  {
    print "Error: max retries reached (return 0)\n";
   
    # return 0 in case of an error
    return "0";
  }
}


sub convertStringToFloat($)
{
  $_ = shift;

  # switch endianess of string
  $_ = unpack("H*", reverse(pack("H*", $_)));

  # convert string to float
  return unpack("f", pack("L", hex($_)));
}


sub convertStringToU8($)
{
  $_ = shift;

  # convert string to U8
  return hex($_);
}


sub convertStringToU16($)
{
  $_ = shift;

  # switch endianess of string
  $_ = unpack("H*", reverse(pack("H*", $_)));

  # convert string to U16
  return hex($_);
}


sub convertHexToString($)
{
  $_ = shift;

  # convert hex string into string
  return pack("H*", $_);
}


Die Ausgabe ist dann bei mir wie folgt:


Name (raw): 466c6f77657220706f7765722034334638
Name: Flower power 43F8
System ID (raw): f8438400003d14a0
System ID: f8438400003d14a0
Serial Number (raw): 50493034303239374144354932303439303500
Serial Number: PI040297AD5I204905
Firmware Revision (raw): 323031362d30392d31345f6861776169692d32
Firmware Revision: 2016-09-14_hawaii-2
Hardware Revision (raw): 323031332d30372d32365f6861776169695072
Hardware Revision: 2013-07-26_hawaiiPr
Color (raw): 0400
Color: 4
Battery Level (raw): 5a
Battery Level: 90
Calibrated Soil Moisture (raw): c4803f42
Calibrated Soil Moisture: 47.8757476806641
Calibrated Air Temperature (raw): 9f979c41
Calibrated Air Temperature: 19.5740337371826
Calibrated Sunlight (raw): cdcccc3d
Calibrated Sunlight: 0.100000001490116
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Error: max retries reached (return 0)
Calibrated EA (raw): 0
Calibrated EA: 0
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Error: max retries reached (return 0)
Calibrated ECB (raw): 0
Calibrated ECB: 0
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Read characteristics by UUID failed: No attribute found within the given range
Error: max retries reached (return 0)
Calibrated EC Porous (raw): 0
Calibrated EC Porous: 0
Sunlight (raw): ffff
Sunlight: 0.129691229016778
Soil Electrical Conductivity (raw): 1805
Soil Electrical Conductivity: 7.3630717108978
Soil Temperature (raw): aa02
Soil Temperature: 20.18114432992
Air Temperature (raw): 8a02
Air Temperature: 18.634035
Soil Moisture (raw): fa01
Soil Moisture: 34.9378398850164



Ich habe auch noch mal etwas recherchiert. Es ist leider tatsächlich so, dass man nur die Calibrated Werte verwenden kann, weil diese direkt den Werten in der App entsprechen. Alle anderen Werte werden erst auf dem Server umgerechnet. Parrot macht aus dem Wie leider ein Geheimnis, so dass man hier nur irgendwelche Berechnungen im Web findet, die sich jemand aus den Fingern gesogen hat und deshalb relativ ungenau sein dürften. Übrig bleiben deshalb nur:

Batterie
Feuchtigkeit
Licht
Lufttemperatur
und noch ein paar andere unwichtige wie Name, Firmware, Farbe usw.

Den Düngergehalt zum Beispiel bekommt man nur als Raw Wert. Und da niemand die Formel zur Umrechnung kennt, ist der relativ nutzlos. Vielleicht gibt es aber auch neuere Sensoren als meinen, die den Düngergehalt auch als Calibrated Wert abgelegt haben. Laut Parrot Doku soll es das geben, nur mein Sensor spuckt da nix aus.

gandy

#52
Zitat von: CoolTux am 23 Januar 2017, 04:36:49
Mist hast Recht. Habe eben erst den Anfang mir mal genau angeschaut.
Das sind dann aber ne Menge Anfragen, die arme Batterie  :)

Die Daten einzeln aus den Characteristics zu lesen ist in der Tat nicht sehr höflich ggü der Batterie  ;D  Parrot sieht dafür den History Service vor, über den man alle seit dem letzten Auslesen im viertelstunden Takt angefallenen Messdaten beschaffen kann. In den Advertising Daten kann man sogar sehen, ob überhaupt neue Daten hinzugekommen sind, was die Sache noch batterieschonender gestaltet.

Das Problem dabei wie auch mumpitzstuff schreibt: Die Daten liegen in der History im Rohformat vor und sind nicht wie die Life-Daten in physikalische Größen umgerechnet. Das Format ist nicht dokumentiert, entsprechende Anfragen im Parrot-Forum wurden bislang geblockt. Für eine Umrechnung der Rohdaten muss also ein wenig Reverse Engineering herhalten.

Dazu habe ich auf Github mit https://github.com/gandy92/pyflowerpower ein paar Python-Scripten eingestellt, um mit den Flower Power Sensoren ein wenig spielen zu können. Auslesen des History Buffers funktioniert und auch die Datenstruktur ist schon gut verstanden. Für den Reverse-Engineering Teil gibt es ein Script, das die Rohdaten mit den umgerechneten Sensordaten aus der Cloud anreichert (alte und neue API).

Dadurch lassen sich leicht die umgerechneten Daten gegen Rohdaten plotten und für einfache 1:1 Relationen konnte ich auch geeignete Funktionen finden (Temperatur, Licht und Batterie). Wie Bodenfeuchtigkeit und Düngergehalt zu berechnen sind, ist im Moment noch unklar, aber vielleicht findet sich jemand, der hier mithelfen kann. Wenn uns das gelingt, steht einer batterieschonenden Cloud-freien Lösung für FHEM nichts im Weg.

Grüße,
Andy.
fhem (svn) auf i5-4210U NUC
2x HMLAN, 19x HM-SEC-RHS, 15x HM-LC-Bl1PBU-FM, etc.
ODYS Neron Tablet / Android 4.2
Samsung Galaxy Tab 2 10.1N / Android 4.1.2
Samsung Galaxy Note / Android 6.0.1

mumpitzstuff

Wow interessant. Das hatte ich noch nicht gefunden bei meiner Suche...

Grundsätzlich ist es richtig, dass es Batterieschonender ist die History Werte auszulesen, wenn man wirklich alle Werte haben möchte. Aber mal ganz ehrlich, brauche ich von einem Pflanzensensor alle 15min Werte? Hinzu kommt, dass ich die Daten ebenfalls scheibchenweise in 20Byte Blöcken runterladen muss bzw. den Protokolloverhead mitschleppe. Mir persönlich würde es ausreichen 3-4x am Tag die Werte zu erhalten und dann relativiert sich der Batterieverbrauch glaube ich wieder. Weiterhin würde ich lieber auf die kalibrierten Werte setzen, da diese wirklich richtig sind. Aus den Rohwerten die richtigen Werte rauslesen zu wollen, würde bedeuten, dass man die gesamte Skala aller Werte schrittweise abfahren müsste, was nicht unbedingt einfach ist. Hinzu kommt, dass die Sensoren mit hoher Wahrscheinlichkeit kalibriert sind. Solange man diese Werte nicht kennt, ist jede Berechnung sinnlos (siehe dazu die UUID: FE01 (calibration service)).

Wenn man sich beim Auslesen auf 4 Werte beschränkt (batterie, licht (fragwürdig ob man das braucht in der wohnung, das sind eh mondwerte...), feuchtigkeit, temperatur), dann ist der Aufwand ebenfalls überschaubar. Man könnte weiterhin verschiedene Intervalle definieren, um den Aufwand weiterhin zu senken.

gandy

Konntest Du bei Deiner Suche nicht finden, hab das erst gestern auf Github eingestellt, nachdem ich endlich den Zugriff auf den neuen Cloud-Dienst eingebaut habe.

Sicher, die Anforderungen und Vorstellungen unterscheiden sich von User zu User. Ich für meinen Teil finde die 1/4-stündliche Samplingrate nicht so schlecht und der Sensor nimmt die Daten ohnehin, warum sie also nicht auslesen und weiterverarbeiten. Wenn z.B. in den ersten 2-3 Stunden nach dem Gießen die gemessene Bodenfeuchtigkeit nicht wieder deutlich abnimmt, deutet das auf Staunässe hin, manche Pflanzen wollen dann schnelle Hilfe. Kurzum, ich will den vollen Funktionsumfang der Sensoren nutzen können, dazu gehören die History-Daten.

Aktuell lese ich die wie viele andere auch per cloud-bridge aus, die sie dann umgehend in die Cloud pumpt. Von Cloud-Diensten möchte ich aber aus verschiedenen Gründen unabhängig sein, hierher kommt der Wunsch, die History-Daten selbst konvertieren zu können.

Der Calibration Service hat mich zunächst auch schwer beeindruckt, bis ich gesehen habe, dass der alte Cloud-Dienst die Temperatur-Werte für alle Sensoren schon mal identisch umrechnet. Ob das auch der neue Cloud-Service so macht, habe ich mir noch nicht angesehen. Zumindest in den ersten Wochen lieferte der ja z.T. andere Werte als der Alte, den ich immer noch parallel mit Daten füttere. Für die Umrechnung des Lichtwertes hingegen wird eine sensortypischer Kalibrierwert benötigt, der sich aber bequem einmalig aus den Life-Daten des betreffenden Sensors berechnen lässt, ohne die Werte aus dem Calibration Service verstanden haben zu müssen.
fhem (svn) auf i5-4210U NUC
2x HMLAN, 19x HM-SEC-RHS, 15x HM-LC-Bl1PBU-FM, etc.
ODYS Neron Tablet / Android 4.2
Samsung Galaxy Tab 2 10.1N / Android 4.1.2
Samsung Galaxy Note / Android 6.0.1

mumpitzstuff

In dem Skript von mir sind für die Temperaturen und auch Licht Formeln hinterlegt, die bereits im Netz rum schwirren und auch relativ gut die Werte aus der Cloud treffen. Die beiden entscheidenden Werte wie Feuchtigkeit und Dünger liefern allerdings Mondwerte. Die Formel die ich im Netz gefunden habe stimmt bei mir gar nicht. Um wirklich verwertbare Werte zu bekommen, bräuchte man mind. 2 Sensoren in einem Topf ohne Pflanze, den man mit Folie umwickelt und dann alle 15 min. ein wenig Wasser zuführt und den Rohwert und den Wert aus der Cloud ermittelt (liefert die Cloud Nachkommawerte, welche die App nur nicht anzeigt?). Um genügend Werte zu bekommen sitzt man dann aber etliche Stunden vor dem Topf. Wenn man die beiden Sensoren miteinander vergleicht, findet man vielleicht auch den richtigen Kalibrierwert raus. Beim Dünger wirds dann noch komplizierter. Hier muss man, wenn man der Literatur trauen kann, alles auf 25 Grad normieren. Schätzungsweise geht auch noch die Feuchtigkeit mit ein. Keine Ahnung wie man das ermitteln soll.
Mir fällt auch grad ein, dass es auch interessant wäre die Werte zu ermitteln wenn sich der Sensor nicht in der Erde befindet, also vollkommen trocken ist. Vielleicht erhält man dann ja die kalibrierwerte direkt. Ach und bei der Feuchtigkeit hat man ja noch den kalibrierten wert. Wenn man den kalibrierten und unkalibrierten wert in einer Schleife ausließt und den Sensor mit extrem langsamen Bewegungen im Wasser unterschiedlich eintaucht, müsste man die Kurve ebenfalls nachstellen können (hoffe der Sensor misst kapazitiv)

Ich hab zwar extrem wenig Zeit aber ich versuche mal mit so wenig Readings wie möglich ein fhem Modul zu machen (wird noch etwas dauern) und dann schaue ich mir den Batteriverbrauch mal genau an.

gandy

Zwischenzeitlich habe ich mal die historischen Daten meiner 8 Sensoren verglichen: Die Daten, die jeweils vom alten und vom neuen Cloud-Dienst ausgeliefert werden, stimmen bis auf einen minimalen Unterschied überein.

Demgegenüber weichen sie aber deutlich von den historischen Daten ab, die in der App angezeigt werden, und auch von den Life-Daten. So bekomme ich zB für die Bodenfeuchte eines der Sensoren:

  • 26.8% vom Cloud-Server (historische Daten)
  • 32.7% vom Life Service (Sensor, Calibrated VWC)
  • 33% in der App (aktueller Wert)
  • 33.8% in der App (Datenplot aus historischen Daten vom Server)
Augenscheinlich nimmt hier die App nochmal eine Umrechnung der in der Cloud gespeicherten Werte vor, kommt aber nicht auf die gleichen 'kalibrierten' Werte wie der Sensor selbst.

Zwei meiner Sensoren stecken seit einiger Zeit dicht nebeneinander im selben Topf, die Cloud-Daten der beiden zeigen aber unterschiedliche Werte für Temperatur und Bodenfeuchtigkeit. Im nächsten Schritt versuche ich, die Life-Daten und die App-Daten miteinander zu vergleichen.


fhem (svn) auf i5-4210U NUC
2x HMLAN, 19x HM-SEC-RHS, 15x HM-LC-Bl1PBU-FM, etc.
ODYS Neron Tablet / Android 4.2
Samsung Galaxy Tab 2 10.1N / Android 4.1.2
Samsung Galaxy Note / Android 6.0.1

mumpitzstuff

Ich vermute, dass der erste Wert der Rohwert ist, ohne die Calibrierung des Sensors mit einzubeziehen. Der aktuelle Wert wird wahrscheinlich einfach gerundet. Warum der Datenplot anders ist verstehe ich allerdings auch nicht. Es könnte höchstens sein, dass der Zeitpunkt der Messung anders war, da die historischen Werte ja in einem bestimmten Zeitraster aufgezeichnet werden. Beim Life Service springt bei mir die Anzeige auch manchmal um 1-2 Prozent in der App hin und her.

Sind bei den beiden Sensoren die nebeneinander stehen nur die Cloud Werte anders und die Werte vom Life Service ähnlich? Wenn ja, dann werden tatsächlich die unkalibrierten Werte in der Cloud hinterlegt.

mumpitzstuff

Hallo,

ich habe das Ganze mal in eine erste Version eines fhem Moduls gegossen. Ich muss darauf hinweisen, dass noch einige Fehler enthalten sein können. Ich habe bisher nur das Anlegen des Devices und das Verändern des Intervalls getestet. Ich würde mich freuen, wenn das der ein oder andere mal testen könnte:

https://github.com/mumpitzstuff/fhem-ParrotFlowerPower

Wenn es Fehler oder Probleme gibt, dann könnt ihr im Device das Attribut verbose auf 5 setzen und dann im Logfile nachvollziehen, was genau innerhalb des Moduls passiert.

Viel Spaß.

emilio_35

Hallo
ich habe einen Flower Power Sensor und möchte diesen gerne in Fhem einbinden.
Kannst du mir kurz erklären wie ich das machen muss ? Dann könnte ich dein Modul testen
Fhem Raspberry Pi, SPS, S7 315PN,VU+