OpenMQTTGateway/BLE eQ-3 eqiva Heizkörperventil,CC-RT-BLE (RTV) Sollwert senden

Begonnen von Torxgewinde, 18 Februar 2023, 08:19:52

Vorheriges Thema - Nächstes Thema

Torxgewinde

OpenMQTTGateway kann Bluetooth-Low-Energy (BLE) Geräte empfangen und auch ansteuern. Das Ansteuern ist IMHO nicht so einfach, da man sich die Service IDs und Characteristic IDs zusammensuchen muss, und die eQ3 Heizkörperventile dann auch ihren Sollwert in spezieller Form erhalten müssen.

Als Fingerübung und zum Verständnis hier ein paar Befehle wie man ein eQ-3 eqiva Bluetooth CC-RT-BLE Ventil mit MQTT und einem OpenMQTTGateway+BLE auf einem ESP32 steuern kann (ohne FHEM). Das Ventil habe die Adresse "AA:BB:CC:DD:EE:FF", dies kann man recht einfach finden, wenn man dem Gateway zuschaut und ein Gerät mit "CC-RT-BLE" empfangen wird. Einen Pincode brauchte ich übrigens nicht.
##auf 30.0°C stellen = ON (HEX Wert ist 0x3C=60=2*30.0°C, die 0x41 davor ist fix)
mosquitto_pub -t "OpenMQTTGateway/commands/MQTTtoBT/config" -p 1883 -h server.lan -u "Nutzername" -P "passwort123" -m '{
  "ble_write_address":"AA:BB:CC:DD:EE:FF",
  "ble_write_service":"3e135142-654f-9090-134a-a6ff5bb77046",
  "ble_write_char":"3fa4585a-ce4a-3bad-db4b-b8df8179ea09",
  "ble_write_value":"413C",
  "value_type":"HEX",
  "ttl":4,
  "immediate":true }'

##auf 4.5°C stellen = OFF (HEX Wert ist 0x09=9=2*4.5°C, die 0x41 davor ist fix)
mosquitto_pub -t "OpenMQTTGateway/commands/MQTTtoBT/config" -p 1883 -h server.lan -u "Nutzername" -P "passwort123" -m '{
  "ble_write_address":"AA:BB:CC:DD:EE:FF",
  "ble_write_service":"3e135142-654f-9090-134a-a6ff5bb77046",
  "ble_write_char":"3fa4585a-ce4a-3bad-db4b-b8df8179ea09",
  "ble_write_value":"4109",
  "value_type":"HEX",
  "ttl":4,
  "immediate":true }'

##auf 5.5°C stellen (HEX Wert ist 0x0B=11=2*5.5°C, die 0x41 davor ist fix)
mosquitto_pub -t "OpenMQTTGateway/commands/MQTTtoBT/config" -p 1883 -h server.lan -u "Nutzername" -P "passwort123" -m '{
  "ble_write_address":"AA:BB:CC:DD:EE:FF",
  "ble_write_service":"3e135142-654f-9090-134a-a6ff5bb77046",
  "ble_write_char":"3fa4585a-ce4a-3bad-db4b-b8df8179ea09",
  "ble_write_value":"410B",
  "value_type":"HEX",
  "ttl":4,
  "immediate":true }'

usw...


Bildet man das Device in FHEM ab, geht das auch (bei setList muss es alles in einer Zeile sein, die ist dadurch recht lang):
defmod Thermostat.device MQTT2_DEVICE
attr Thermostat.device IODev Mosquitto
attr Thermostat.device alias Thermostat
attr Thermostat.device comment Der Wert in Celsius (auch mit Komma) muss mal zwei gerechnet werden und dann nach uint8_t und dann als zwei Hex-Ziffern an 0x41 anfügen
attr Thermostat.device devicetopic OpenMQTTGateway/BTtoMQTT/AABBCCDDEEFF
attr Thermostat.device group Thermometer
attr Thermostat.device icon sani_heating
attr Thermostat.device readingList $DEVICETOPIC:.* { my $ret=json2nameValue($EVENT);; return $ret }
attr Thermostat.device setList temperaturesetpoint:knob,min:4.5,max:30,width:64,height:64,step:0.5,lineCap:round,angleOffset:180,cursor:3,thickness:.3 {my $id=ReadingsVal($NAME, "id", "???");; my $ret=sprintf("OpenMQTTGateway/commands/MQTTtoBT/config {\"ble_write_address\":\"%s\",\"ble_write_service\":\"3e135142-654f-9090-134a-a6ff5bb77046\",\"ble_write_char\":\"3fa4585a-ce4a-3bad-db4b-b8df8179ea09\",\"ble_write_value\":\"41%x\",\"value_type\":\"HEX\",\"ttl\":4,\"immediate\":true }",$id,$EVTPART1*2.0);; readingsSingleUpdate($defs{"$NAME"}, "temperaturesetpoint", "$EVTPART1", 0);; Log 1, "($NAME): $ret";; return "$ret";;}
attr Thermostat.device webCmd temperaturesetpoint

setstate Thermostat.device 2023-02-18 07:42:26 temperaturesetpoint 30
setstate Thermostat.device 2023-02-18 07:58:29 id AA:BB:CC:DD:EE:FF


HTH und viel Erfolg!

Torxgewinde

Bei der neusten Firmware scheint es nicht mehr ohne Pairing zu funktionieren, schade. Mein "altes" Ventil funktioniert noch 1A mit dem Snippet.

Hier noch ein Snippet, mit dem man den Überblick behalten kann welche BLE Beacons noch senden. Es werden die Beacons der letzten 24h in Form von Readings behalten, die Werte sind JSON codiert:

defmod OpenMQTTGateways.device MQTT2_DEVICE
attr OpenMQTTGateways.device userattr names maxReadingsAge
attr OpenMQTTGateways.device IODev Mosquitto
attr OpenMQTTGateways.device alias Alle OpenMQTTGateways
attr OpenMQTTGateways.device devicetopic OpenMQTTGateway.*/BTtoMQTT/.*
attr OpenMQTTGateways.device event-on-change-reading .*
attr OpenMQTTGateways.device maxReadingsAge 86400
attr OpenMQTTGateways.device names 'AA_BB_CC_DD_EE_FF'=>'ArbeitszimmerThermostat2.device',\
'AA_BB_CC_DD_EE_FE'=>'ThermostatZwei.device',\
'AA_BB_CC_DD_EE_FA'=>'Thermometer.Flur.Unten.device'
attr OpenMQTTGateways.device readingList $DEVICETOPIC:.* { my $ret=json2nameValue($EVENT);; if (defined($ret->{id})) { my $id=makeReadingName($ret->{id});; my $namesAttr = AttrVal($NAME, 'names', '');; my $namesHash = eval "return { $namesAttr };;" || {};; my $Rname = makeReadingName($namesHash->{$id} // $id);; my $old=json2nameValue(ReadingsVal($NAME, $Rname, '{}'));; $old->{counter} = ($old->{counter} // 0) + 1;; return { $Rname => toJSON({ %$old, %$ret }) };; } return }
attr OpenMQTTGateways.device room Global
attr OpenMQTTGateways.device userReadings checkNames:.* {\
    my $hash = $defs{$name};;\
    \
    # Fetch and parse the 'names' attribute\
    my $namesAttr = AttrVal($NAME, 'names', '');;\
    my $namesHash = eval "return { $namesAttr };;" || {};;\
    \
    # Iterate over all names in the namesHash\
    foreach my $key (keys %{$namesHash}) {\
        # Use ReadingsVal to check if the reading exists\
        my $value = ReadingsVal($NAME, $key, undef);;\
        \
        # If the reading exists (not undefined), update it\
        if (defined $value) {\
            # Get the new reading name from namesHash\
            my $newKey = makeReadingName($namesHash->{$key});;\
            \
            # Update the reading with the new name and the same value\
            readingsBulkUpdate($hash, $newKey, $value);;\
            \
            # Delete the old reading with the original key\
            readingsDelete($hash, $key);;\
        }\
    }\
    return;;\
},\
checkReadings:.* {\
    my $newBeacons = "";;\
    \
    foreach my $aReading (keys %{$hash->{READINGS}}) {\
        # Delete beacons not seen for some time\
        if (ReadingsAge($name, $aReading, undef) >= AttrVal($NAME, 'maxReadingsAge', 300)) {\
            readingsDelete($hash, $aReading);;\
            next;;\
        }\
        \
        # Check for counter:1 in the reading value, these are new beacons\
        my $value = ReadingsVal($NAME, $aReading, undef);;\
        if (defined($value) && $value =~ /"counter":1(?:,|\})/ && $value !~ /"reported":"1"(?:,|\})/) {\
            # Concatenate the name of the beacon (reading name)\
            $newBeacons .= "$aReading,";;\
            \
            # Mark as reported\
            my $valueHash = json2nameValue($value);;\
            $value = toJSON({ %$valueHash, "reported" => "1" });;\
            readingsBulkUpdate($hash, $aReading, $value);;\
        }\
    }\
    \
    # Remove trailing comma\
    $newBeacons =~ s/,$//;;\
    \
    return $newBeacons;;\
}
attr OpenMQTTGateways.device widgetOverride names:textField-long

Hier ein Beispiel-Wert in Form eines eQ3 Thermostates:
setstate OpenMQTTGateways.device 2024-11-17 11:26:58 ArbeitszimmerThermostat2.device {"characteristic":"3fa4585a-ce4a-3bad-db4b-b8df8179ea09","counter":5810,"id":"11:22:EE:CC:AA:BB","name":"CC-RT-BLE","reported":"1","rssi":"-65","service":"3e135142-654f-9090-134a-a6ff5bb77046","success":"true","write":"413C"}