FHEM Integration Ulanzi TC001 mit AWTRIX

Begonnen von Saphora, 31 Dezember 2024, 13:48:21

Vorheriges Thema - Nächstes Thema

Saphora

Hallo Community
Habe eine Ulanzi TC001 geschenkt bekommen.
Sehr schönes Panel, was super geeignet ist, um in FHEM zu integrieren.
Zumindest dachte ich mir das.
Dies scheint aber nur über MQTT zu funktionieren, womit ich aber bisher weniger zu tun hatte.
Daher habe ich die Grundlagen angeschaut und soweit verstanden, wie MQTT arbeitet.
Aber das jetzt anzuwenden, um die Ulanzi im FHEM zu integrieren, fällt mir extrem schwer.
Habe zwei Einträge im FHEM Forum gefunden, wo AWTRIX angesprochen wird.
Aber das funktioniert so bei mir nicht.
Hat jemand Erfahrung wie die Ulanzi mit der AWTRIX Firmware sinnvoll in FHEM integriert werden kann?
Für IObroker oder Home Asssiatant gibt es viel Dokumentation mit Templates.
Für FHEM leider nicht ganz so viel.
Da das Thema MQTT für mich eher neu ist, befürchte ich die zusammenhänge nicht zu verstehen (Grundlagen vs. FHEM Integration).
Es gibt soweit ich gelesen habe eine direkte Integration oder über einen externen MQTT-Server (z.B. Mosquitto).
Wäre über jede Hilfe dankbar wie ich mich dem Thema sinnvoll nähren kann.

Grüße Martin

Beta-User

Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

vbs

Ich kann mal einfach in den Raum schmeißen, was ich mir mal gebastelt hatte. Betonung auf "gebastelt", aber vielleicht nutzt es ja irgendwem.

Ein Device für tc001:
defmod wz_tc001 MQTT2_DEVICE wz_tc001
attr wz_tc001 cmdIcon false:on true:off
attr wz_tc001 devicetopic home/wz_tc001
attr wz_tc001 event-on-change-reading tc001_lux
attr wz_tc001 group Geräte
attr wz_tc001 icon display_dot
attr wz_tc001 readingList home/wz_tc001/stats/currentApp:.* ulanzi_currentApp\
home/wz_tc001/stats:.* { json2nameValue($EVENT, "tc001_") }
attr wz_tc001 room Wohnzimmer
attr wz_tc001 setList on:noArg $DEVICETOPIC/power {"power": true}\
off:noArg $DEVICETOPIC/power {"power": false}\
brightness:colorpicker,BRI,0,1,255 $DEVICETOPIC/settings {"BRI":"$EVTPART1"}\
kelvin:colorpicker,CT,2500,1,6000 $DEVICETOPIC/moodlight {"$EVTPART0":"$EVTPART1"}\
color:colorpicker,RGB $DEVICETOPIC/moodlight {"$EVTPART0":"$EVTPART1"}\
text $DEVICETOPIC/notify {"$EVTPART0":"$EVTPART1"}\
progress $DEVICETOPIC/notify {"$EVTPART0":"$EVTPART1"}\
notify $DEVICETOPIC/notify\
switch:TempOutDoor,Temp,Energy,Date,Time,CO2,Humidity,Ett $DEVICETOPIC/switch {"name": "$EVTPART1"}\
nextapp $DEVICETOPIC/nextapp\
deleteapp $DEVICETOPIC/custom/$EVTPART1\
custom $DEVICETOPIC/custom/$EVTPART1 $EVTPART2\
pause:noArg $DEVICETOPIC/settings {"ATRANS": false}\
play:noArg $DEVICETOPIC/settings {"ATRANS": true}\
notifytext1 $DEVICETOPIC/notify {"icon": "$EVTPART2","text": [{"t": "$EVTPART5","c":"$EVTPART3"},{"t": "$EVTPART6","c": "$EVTPART4"}]}\
reboot:noArg $DEVICETOPIC/reboot\
dismiss:noArg $DEVICETOPIC/notify/dismiss\
setting_brightness:colorpicker,BRI,0,1,255 $DEVICETOPIC/settings {"BRI":"$EVTPART1"}
attr wz_tc001 stateFormat Batterie: tc001_bat App: tc001_app
attr wz_tc001 verbose 2

So ein DOIF Device:
defmod sys_di_wz_tc001 DOIF ([env_thpl:temperature]) {VBSUtils_AwtrixSetCustomTempOutside("wz_tc001")}\
DOELSEIF ([wz_hmTcClimate:measured-temp]) {VBSUtils_AwtrixSetCustomTemp("wz_tc001", ReadingsVal("wz_hmTcClimate", "measured-temp", 99))}\
DOELSEIF ([wz_hmTcClimate:humidity]) {VBSUtils_Awtrix_SetCustomHumidity("wz_tc001", ReadingsVal("wz_hmTcClimate", "humidity", 999))}\
DOELSEIF ([env_electricMeter_Sen:power]) {VBSUtils_AwtrixSetCustomPower("wz_tc001")}\
DOELSEIF ([wz_co2:co2]) {VBSUtils_Awtrix_SetCo2("wz_tc001", ReadingsVal("wz_co2", "co2", 0))}\
DOELSEIF ([+30]) {VBSUtils_AwtrixSetCustomAnim("wz_tc001")}\
DOELSEIF ([+45]) {VBSUtils_AwtrixSetRandTrans("wz_tc001")}\
DOELSEIF ([wz_motion:illuminance]) {VBSUtils_Awtrix_SetBrightness("wz_tc001", ReadingsVal("wz_motion", "illuminance", 99))}\
DOELSEIF ([env_ett:data_attributes_elo]) {VBSUtils_AwtrixSetCustomEtt("wz_tc001")}\
DOELSEIF ([env_quest3_pres:presence]) (set env_ett reread)\
\

attr sys_di_wz_tc001 do always
attr sys_di_wz_tc001 event-on-update-reading .
attr sys_di_wz_tc001 group Logik
attr sys_di_wz_tc001 room System

Und einiges an Perl-Funktionen:
package main;

use strict;
use JSON;
use warnings;
use POSIX;
use Data::Dumper;
use Time::Local;
use List::Util qw(first max min);

# Borrowed from 59_GSI, thanks! :)
my sub VBSUtils_Awtrix_linearInterpolate {
    my ($x, $x1, $x2, $y1, $y2) = @_;
    my $m = ($x - $x1) / ($x2 - $x1);
    my $r = ($y1 * (1 - $m) + $y2 * $m);
    # negativ clipping
    $r = 0 if ($r < 0);
    return $r;
};

sub VBSUtils_Awtrix_GetWeatherIcond
{
    my $wettericon01 = '11201';     # klarer Himmel Tag
    my $wettericon02 = '52163';     # klarer Himmel Nacht
    my $wettericon03 = '22315';     # ein paar Wolken Tag (11-25% Wolken)
    my $wettericon04 = '26088';     # ein paar Wolken Nacht (11-25% Wolken)
    my $wettericon05 = '22378';     # aufgelockerte Bewölkung Tag (25-50% Wolken)
    my $wettericon06 = '21907';     # aufgelockerte Bewölkung Nacht (25-50% Wolken)
    my $wettericon07 = '13852';     # bewölkt Tag (51-100%)
    my $wettericon08 = '52159';     # bewölkt Nacht (51-100%)
    my $wettericon09 = '43706';     # Regenschauer Tag
    my $wettericon10 = '43739';     # Regenschauer Nacht
    my $wettericon11 = '22257';     # Regen Tag
    my $wettericon12 = '72';        # Regen Nacht
    my $wettericon13 = '43733';     # Gewitter Tag
    my $wettericon14 = '43748';     # Gewitter Nacht
    my $wettericon15 = '43732';     # Schnee Tag
    my $wettericon16 = '26090';     # Schnee Nacht
    my $wettericon17 = '43708';     # Nebel Tag
    my $wettericon18 = '43741';     # Nebel Nacht

    my %map = (
        "01d" => $wettericon01,
        "01n" => $wettericon02,
        "02d" => $wettericon03,
        "02n" => $wettericon04,
        "03d" => $wettericon05,
        "03n" => $wettericon06,
        "04d" => $wettericon07,
        "04n" => $wettericon08,
        "09d" => $wettericon09,
        "09n" => $wettericon10,
        "10d" => $wettericon11,
        "10n" => $wettericon12,
        "11d" => $wettericon13,
        "11n" => $wettericon14,
        "13d" => $wettericon15,
        "13n" => $wettericon16,
        "50d" => $wettericon17,
        "50n" => $wettericon18,
    );
    return \%map;
}


sub lerp_rgb3 {
  my ($color_low, $color_mid, $color_high, $low, $mid, $high, $target) = @_;

  if ($target >= $mid) {
    return lerp_rgb($color_mid, $color_high, $mid, $high, $target);
  }
  else {
    return lerp_rgb($color_low, $color_mid, $low, $mid, $target);
  }
}

sub lerp_rgb4 {
  my ($color_low, $color_mid1, $color_mid2, $color_high, $low, $mid1, $mid2, $high, $target) = @_;

  if ($target >= $mid2) {
    return lerp_rgb($color_mid2, $color_high, $mid2, $high, $target);
  }
  elsif ($target >= $mid1) {
    return lerp_rgb($color_mid1, $color_mid2, $mid1, $mid2, $target);
  }
  else {
    return lerp_rgb($color_low, $color_mid1, $low, $mid1, $target);
  }
}


sub lerp_rgb {
  my ($color_low, $colorh_high, $low, $high, $target) = @_;

  return $color_low if $target <= $low;
  return $colorh_high if $target >= $high;

  # Calculate total range for interpolation
  my $total_range = $high - $low;

  # Handle zero range case (return starting or ending color)
  return $color_low if ($total_range == 0);

  # Normalize interpolation weight (t) by total range (avoid division by zero)
  my $t = ($target - $low) / $total_range;

  my %color = (
    r => $color_low->{r} + ($colorh_high->{r} - $color_low->{r}) * $t,
    g => $color_low->{g} + ($colorh_high->{g} - $color_low->{g}) * $t,
    b => $color_low->{b} + ($colorh_high->{b} - $color_low->{b}) * $t,
  );

  return \%color;
}

sub rgb_to_hex {
  my ($color) = @_;

  # Convert each color value to a two-digit hex string with leading zeros
  my $hex_r = sprintf("%02x", $color->{r});
  my $hex_g = sprintf("%02x", $color->{g});
  my $hex_b = sprintf("%02x", $color->{b});

  # Combine hex strings and return the complete hex color string
  return "#" . $hex_r . $hex_g . $hex_b;
}


sub lerp_rgb_temp {
    my ($start, $mid, $end, $target) = @_;

    my %color1 = (r => 0, g => 0, b => 255);  # Blue
    my %color2 = (r => 0, g => 255, b => 0);  # Green
    my %color3 = (r => 255, g => 0, b => 0);  # Red

    my $new_color = lerp_rgb3(\%color1, \%color2, \%color3, $start, $mid, $end, $target);
    return rgb_to_hex($new_color);
}

sub lerp_rgb_power {
    my ($start, $mid, $end, $target) = @_;

    my %color1 = (r => 0, g => 0, b => 255);  # Blue
    my %color2 = (r => 255, g => 255, b => 0);  # Yellow
    my %color3 = (r => 255, g => 0, b => 0);  # Red

    my $new_color = lerp_rgb3(\%color1, \%color2, \%color3, $start, $mid, $end, $target);
    return rgb_to_hex($new_color);
}

sub lerp_rgb_co2 {
    my ($start, $mid, $end, $target) = @_;

    my %color1 = (r => 0, g => 255, b => 0);  # Green
    my %color2 = (r => 255, g => 255, b => 0);  # Yellow
    my %color3 = (r => 255, g => 0, b => 0);  # Red

    my $new_color = lerp_rgb3(\%color1, \%color2, \%color3, $start, $mid, $end, $target);
    return rgb_to_hex($new_color);
}

sub VBSUtils_Awtrix_publish {
    my ($name, $topic, $payload) = @_;

    my $hash = $defs{$name};

    my $devtopic = AttrVal($name, "devicetopic", undef);
    my $payload_str = JSON->new->encode($payload);
    IOWrite($hash, "publish", "$devtopic/$topic " . $payload_str);
}

sub VBSUtils_AwtrixSetCustom {
    my ($name, $appname, $payload) = @_;

    my $hash = $defs{$name};

    VBSUtils_Awtrix_publish($name, "custom/$appname", $payload);
}

sub VBSUtils_AwtrixSetCustomTempOutside {
    my ($name) = @_;

    my $temp = ReadingsVal("env_thpl", "temperature", 99);

    my %data = (
        text  => "$temp°C",
        icon => "555",
    );

    my $weatherMap = VBSUtils_Awtrix_GetWeatherIcond();
    my $iconId = ReadingsVal("env_weatherOpenWeatherMap", "iconAPI", undef);

    if (defined($iconId)) {
        $data{"icon"} = $weatherMap->{$iconId};
    }

    my $color = lerp_rgb_temp(-10, 12, 35, $temp);
    $data{"color"} = $color;

    VBSUtils_AwtrixSetCustom($name, "TempOutdoor", \%data);
}

sub VBSUtils_Awtrix_Update {
    VBSUtils_Awtrix_SetBrightness("sz_tc001", ReadingsVal("sz_motion", "illuminance", 99));
    VBSUtils_Awtrix_SetModeSz();
}

sub VBSUtils_Awtrix_SetModeSz {
    Log3 "VBSUtils_Awtrix_SetModeSz", 5, "VBSUtils_Awtrix_SetMode";

    my $name = "sz_tc001";

    my $presence = Value("env_presence");
    my $sz_kodi = Value("sz_kodi");
    my $sz_illu = ReadingsVal("sz_motion", "illuminance", 0);

    my $ambPct = ReadingsVal("sz_lightAmbient", "pct", 0);
    my $spotPct = ReadingsVal("sz_lightSpot", "pct", 0);

    my $pctCombined = max($ambPct, $spotPct);

    if (($presence eq "sleep") && ($pctCombined < 30)) {
        VBSUtils_Awtrix_SetNightMode($name);
    }
    else {
        VBSUtils_Awtrix_SetDayMode($name);
    }
}

sub VBSUtils_Awtrix_SetNightMode {
    my ($name) = @_;

    my @tcol = (255, 0, 0);

    my %data = (
        "WD" => JSON::false,
        "TIME_COL" => \@tcol,
        "TMODE" => 0,
        "ABRI" => JSON::false,
        "ATRANS" => JSON::false,
    );

    VBSUtils_Awtrix_publish($name, "settings", \%data);

    fhem("set $name switch Time", 1);

    fhem("set $name pause", 1);
}

sub VBSUtils_Awtrix_SetDayMode {
    my ($name) = @_;

    my @tcol = (255, 255, 0);

    my %data = (
        "WD" => JSON::true,
        "TIME_COL" => \@tcol,
        "TMODE" => 1,
        "BRI" => 3,
        "TCOL" => \@tcol,
        "ABRI" => JSON::false,
        "ATRANS" => JSON::true,
    );

    VBSUtils_Awtrix_publish($name, "settings", \%data);

    fhem("set $name play", 1);
}


sub VBSUtils_Awtrix_DeleteApp {
    my ($name, $appname) = @_;

    VBSUtils_AwtrixSetCustom($name, $appname, \%data);
}

sub VBSUtils_AwtrixSetCustomTemp {
    my ($name, $temp) = @_;

    #my $temp = ReadingsVal("wz_hmTcClimate", "measured-temp", 99);

    my %data = (
        text  => "$temp°C",
        icon => "2355",
    );

    my $color = lerp_rgb_temp(12,21,30, $temp);
    #my $color = vbsColor(16,21,30, $temp);
    #$color = "#FF0000";
   
    $data{"color"} = $color;

    VBSUtils_AwtrixSetCustom($name, "TempWz", \%data);
}

sub Awtrix_SetDefaults {
    my ($name) = @_;

    my %data = (
        TIM  => JSON::true,
        DAT => JSON::false,
        HUM => JSON::false,
        TEMP => JSON::false,
        BAT => JSON::false,
        TEFF => 1,
    );

    VBSUtils_Awtrix_publish($name, "settings", \%data);
}   

sub VBSUtils_Awtrix_SetCustomHumidity {
    my ($name, $humidity) = @_;

    #my $humidity = ReadingsVal("wz_hmTcClimate", "humidity", 999);

    my %data = (
        text  => "$humidity %",
        icon => "3359",
        #icon => "humidityroundsmall",
        color => "#00FF00"
    );

    VBSUtils_AwtrixSetCustom($name, "Humidity", \%data);
}

sub vbcolor {
    my ($temp) = @_;
    my $color = vbsColor(16,21,30, $temp);

    my %data = (
        text  => "$temp°C",
        icon => "2355",
        color  => $color,   
    );

    VBSUtils_AwtrixSetCustom("wz_tc001", "TempWz", \%data);
}

sub VBSUtils_AwtrixSetCustomEtt {
    my ($name) = @_;

    my $elo = ReadingsVal("env_ett", "data_attributes_elo", 99);
    my $color = lerp_rgb_power(1600, 2100, 2500, $elo);

    my %data = (
        text  => "$elo",
        icon => "59285",
        color => $color,
    );


    VBSUtils_AwtrixSetCustom($name, "Ett", \%data);
}

sub VBSUtils_AwtrixSetCustomPower {
    my ($name) = @_;

    my $power = ReadingsVal("env_electricMeter_Sen", "power", 99);
    my $color = lerp_rgb_power(0, 200, 1500, $power);

    my %data = (
        text  => "$power W",
        icon => "21256",
        color => $color,
    );


    VBSUtils_AwtrixSetCustom($name, "Power", \%data);
}

sub VBSUtils_AwtrixSetRandTrans {
    my ($name) = @_;

    my @anims = (1,
                2,
                6,
                9,
                10
                );

    my $num = int(rand(scalar @anims));
    my %data = (
        TEFF => $anims[$num],
    );

    VBSUtils_Awtrix_publish($name, "settings", \%data);
}

sub VBSUtils_AwtrixSetCustomAnim {
    my ($name) = @_;

    my @anims = ("yoshi", "SuperMario", "Pika32", "nyan", "matrixcode", "mario&luigi", "Firepit");

    my $num = int(rand(scalar @anims));
    my %data = (
        icon => $anims[$num],
    );

    VBSUtils_AwtrixSetCustom($name, "Anim", \%data);
}


sub VBSUtils_Awtrix_Notify {
    my ($name, $message, $duration, $hold) = @_;

    $duration = 30 if !defined($duration);
    $hold = 1 if !defined($hold);

    my $holdJson = $hold ? JSON::true : JSON::false;

    my %data = (
        text  => $message,
        duration => $duration,
        hold => $hold,
        icon => "attentionwarning",
    );

    my $hash = $defs{$name};
    VBSUtils_Awtrix_publish($name, "notify", \%data);
}

sub VBSUtils_Awtrix_SetBrightness {
    my ($name, $illuminance) = @_;

    #my $illuminance = ReadingsVal("wz_motion", "illuminance", 99);

    my $bri = VBSUtils_Awtrix_linearInterpolate($illuminance, 0, 1000, 3, 100);


    if ($name eq "sz_tc001" && Value("sz_kodi") ne "opened") {
        $bri = 1;
    }

    Log3 "VBSUtils_Awtrix_SetBrightness", 5, "VBSUtils_Awtrix_SetBrightness: Illu: $illuminance -> Brightness: $bri";

    fhem("set $name setting_brightness $bri", 1)
}

#sub vbsColor
#{
#    my $color = Color::pahColor(@_);
#    return "#" . substr $color, 0, 6;
#}

sub VBSUtils_Awtrix_SetCo2 {
    my ($name, $co2) = @_;

    #my $co2 = ReadingsVal("wz_co2", "co2", 99);

    my %data = (
        text  => "$co2",
    );

    my $icon;
    if ($co2 > 2000) {
        $icon = "39320";
    }
    elsif ($co2 > 1000) {
        $icon = "39321";
    }
    else {
        $icon = "39322";
    }
    $data{"icon"} = $icon;

    my $progress = VBSUtils_Awtrix_linearInterpolate($co2, 300, 2000, 0, 100);

    my $color = lerp_rgb_co2(0, 300, 2000, $co2);
    $data{"color"} = "$color";

    $data{"progress"} = $progress;

    $data{"progressC"} = "$color";

    VBSUtils_AwtrixSetCustom($name, "CO2", \%data);
}

Saphora

Vielen Dank @vbs für den bereitgestellten Code.
Hatte von dir auch schon einen anderen Post gefunden, wo ich bereits versucht hatte das Vorgehen zu verstehen.
Aber irgendwie klappt es noch nicht ganz.

Habe mich wie im Forum geschrieben für FHEM als MQTT-Server netschieden (MQTT2_SERVER).
Der FHEM-MQTT-Server ist wie folgt eingerichtet:
defmod MQTT2_SERVER MQTT2_SERVER 1883 global
Internals:
   CFGFN     
   CONNECTS   32
   Clients    :MQTT2_DEVICE:MQTT_GENERIC_BRIDGE:
   ClientsKeepOrder 1
   DEF        1883 global
   FD         112
   FUUID      677323f4-f33f-f166-dddf-7fdc22ca9f5c8207
   NAME       MQTT2_SERVER
   NR         1286
   PORT       1883
   STATE      Initialized
   TYPE       MQTT2_SERVER
   eventCount 64
   MatchList:
     1:MQTT2_DEVICE ^.
     2:MQTT_GENERIC_BRIDGE ^.
   READINGS:
     2025-01-02 16:03:21   nrclients       0
     2024-12-30 23:51:32   state           Initialized
   clients:
     MQTT2_SERVER_192.168.0.24_56198 1
   hmccu:
   retain:
Attributes:



Die Ulanzi mit der Firmware AWTRIX ist hat den MQTT Server eingetragen und hat sich auch eingecheckt.
Das Device awtrix_54a1ab habe ich mit deinen Attributen angereichert.

Internals:
   CFGFN     
   CID        awtrix_54a1ab
   DEF        awtrix_54a1ab
   FUUID      67766cc7-f33f-f166-5a05-520a9b36b305e0db
   IODev      MQTT2_SERVER
   LASTInputDev MQTT2_SERVER
   MQTT2_SERVER_CONN MQTT2_SERVER_192.168.0.24_64755
   MQTT2_SERVER_MSGCNT 1508
   MQTT2_SERVER_TIME 2025-01-02 16:02:53
   MSGCNT     1508
   NAME       awtrix_54a1ab
   NR         1307
   STATE      Batterie: awtrix_54a1ab_bat App: awtrix_54a1ab_app
   TYPE       MQTT2_DEVICE
   eventCount 1481
   READINGS:
     2025-01-02 15:51:32   1               Random
     2025-01-02 15:51:32   10              Reload
     2025-01-02 15:51:32   11              Fade
     2025-01-02 15:51:32   12              TheaterChase
     2025-01-02 15:51:32   13              Plasma
     2025-01-02 15:51:32   14              Matrix
     2025-01-02 15:51:32   15              SwirlIn
     2025-01-02 15:51:32   16              SwirlOut
     2025-01-02 15:51:32   17              LookingEyes
     2025-01-02 15:51:32   18              TwinklingStars
     2025-01-02 15:51:32   19              ColorWaves
     2025-01-02 15:51:32   2               Slide
     2025-01-02 15:51:32   3               Dim
     2025-01-02 15:51:32   4               Zoom
     2025-01-02 15:51:32   5               Rotate
     2025-01-02 15:51:32   6               Pixelate
     2025-01-02 15:51:32   7               Curtain
     2025-01-02 15:51:32   8               Ripple
     2025-01-02 15:51:32   9               Blink
     2025-01-02 15:25:17   Battery         3
     2025-01-02 15:25:17   Date            1
     2025-01-02 15:25:17   Humidity        2
     2025-01-02 15:53:28   IODev           MQTT2_SERVER
     2025-01-02 15:25:17   Time            0
     2025-01-02 16:02:51   app             Date
     2025-01-02 16:02:51   bat             70
     2025-01-02 16:02:51   bat_raw         609
     2025-01-02 16:02:51   bri             2
     2025-01-02 16:02:53   buttonLeft      1
     2025-01-02 16:02:53   buttonRight     1
     2025-01-02 15:24:29   buttonSelect    1
     2025-01-02 16:02:53   currentApp      Humidity
     2025-01-02 16:02:51   hum             29
     2025-01-02 16:02:51   indicator1      false
     2025-01-02 16:02:51   indicator2      false
     2025-01-02 16:02:51   indicator3      false
     2025-01-02 16:02:51   ip_address      192.168.0.24
     2025-01-02 16:02:51   ldr_raw         155
     2025-01-02 16:02:51   lux             0
     2025-01-02 16:02:51   matrix          true
     2025-01-02 15:25:17   meineTolleCustomApp 4
     2025-01-02 16:02:51   messages        0
     2025-01-02 16:02:51   ram             137924
     2025-01-02 15:56:31   state           off
     2025-01-02 15:53:27   subscriptions   awtrix_54a1ab/apps awtrix_54a1ab/brightness awtrix_54a1ab/custom/# awtrix_54a1ab/dateformat awtrix_54a1ab/doupdate awtrix_54a1ab/indicator1 awtrix_54a1ab/indicator2 awtrix_54a1ab/indicator3 awtrix_54a1ab/moodlight awtrix_54a1ab/nextapp awtrix_54a1ab/notify awtrix_54a1ab/notify/dismiss awtrix_54a1ab/power awtrix_54a1ab/previousapp awtrix_54a1ab/r2d2 awtrix_54a1ab/reboot awtrix_54a1ab/rtttl awtrix_54a1ab/sendscreen awtrix_54a1ab/settings awtrix_54a1ab/sleep awtrix_54a1ab/sound awtrix_54a1ab/switch awtrix_54a1ab/timeformat
     2025-01-02 16:02:51   temp            24
     2025-01-02 16:02:51   type            0
     2025-01-02 16:02:51   uid             awtrix_54a1ab
     2025-01-02 16:02:51   uptime          693
     2025-01-02 16:02:51   version         0.97
     2025-01-02 16:02:51   wifi_signal     -51
   hmccu:
Attributes:
   cmdIcon    false:on true:off
   devicetopic home/awtrix_54a1ab
   icon       display_dot
   readingList home/awtrix_54a1ab/stats/currentApp:.* ulanzi_currentApp
home/awtrix_54a1ab/stats:.* { json2nameValue($EVENT, "awtrix_54a1ab") }
awtrix_54a1ab:awtrix_54a1ab/stats:.* { json2nameValue($EVENT) }
awtrix_54a1ab:awtrix_54a1ab/stats/currentApp:.* currentApp
awtrix_54a1ab:awtrix_54a1ab/stats/effects:.* { json2nameValue($EVENT) }
awtrix_54a1ab:awtrix_54a1ab/stats/transitions:.* { json2nameValue($EVENT) }
awtrix_54a1ab:awtrix_54a1ab/stats/currentApp:.* currentApp
awtrix_54a1ab:awtrix_54a1ab/stats:.* { json2nameValue($EVENT) }
awtrix_54a1ab:awtrix_54a1ab/stats/buttonRight:.* buttonRight
awtrix_54a1ab:awtrix_54a1ab/stats/buttonLeft:.* buttonLeft
   setList    on:noArg $DEVICETOPIC/power {"power": true}
off:noArg $DEVICETOPIC/power {"power": false}
brightness:colorpicker,BRI,0,1,255 $DEVICETOPIC/settings {"BRI":"$EVTPART1"}
kelvin:colorpicker,CT,2500,1,6000 $DEVICETOPIC/moodlight {"$EVTPART0":"$EVTPART1"}
color:colorpicker,RGB $DEVICETOPIC/moodlight {"$EVTPART0":"$EVTPART1"}
text $DEVICETOPIC/notify {"$EVTPART0":"$EVTPART1"}
progress $DEVICETOPIC/notify {"$EVTPART0":"$EVTPART1"}
notify $DEVICETOPIC/notify
switch:TempOutDoor,Temp,Energy,Date,Time,CO2,Humidity,Ett $DEVICETOPIC/switch {"name": "$EVTPART1"}
nextapp $DEVICETOPIC/nextapp
deleteapp $DEVICETOPIC/custom/$EVTPART1
custom $DEVICETOPIC/custom/$EVTPART1 $EVTPART2
pause:noArg $DEVICETOPIC/settings {"ATRANS": false}
play:noArg $DEVICETOPIC/settings {"ATRANS": true}
notifytext1 $DEVICETOPIC/notify {"icon": "$EVTPART2","text": [{"t": "$EVTPART5","c":"$EVTPART3"},{"t": "$EVTPART6","c": "$EVTPART4"}]}
reboot:noArg $DEVICETOPIC/reboot
dismiss:noArg $DEVICETOPIC/notify/dismiss
setting_brightness:colorpicker,BRI,0,1,255 $DEVICETOPIC/settings {"BRI":"$EVTPART1"}
   stateFormat Batterie: awtrix_54a1ab_bat App: awtrix_54a1ab_app
   verbose    2


Internals:
   BUF       
   FD         119
   NAME       MQTT2_SERVER_192.168.0.24_56198
   NR         10040619
   PEER       192.168.0.24
   PORT       56198
   SNAME      MQTT2_SERVER
   SSL       
   STATE      Connected
   TEMPORARY  1
   TYPE       MQTT2_SERVER
   WBCallback
   cflags     2
   cid        awtrix_54a1ab
   keepalive  15
   lastMsgTime 1735844230.16947
   protoNum   4
   protoTxt   MQTT
   READINGS:
     2025-01-02 19:56:46   state           Connected
   subscriptions:
     awtrix_54a1ab/apps 1735844208.2869
     awtrix_54a1ab/brightness 1735844206.67649
     awtrix_54a1ab/custom/# 1735844206.77703
     awtrix_54a1ab/dateformat 1735844208.28804
     awtrix_54a1ab/doupdate 1735844206.94382
     awtrix_54a1ab/indicator1 1735844208.28742
     awtrix_54a1ab/indicator2 1735844208.28756
     awtrix_54a1ab/indicator3 1735844208.2877
     awtrix_54a1ab/moodlight 1735844208.28832
     awtrix_54a1ab/nextapp 1735844208.28632
     awtrix_54a1ab/notify 1735844206.74285
     awtrix_54a1ab/notify/dismiss 1735844206.71024
     awtrix_54a1ab/power 1735844208.2871
     awtrix_54a1ab/previousapp 1735844206.87751
     awtrix_54a1ab/r2d2 1735844208.28891
     awtrix_54a1ab/reboot 1735844208.28817
     awtrix_54a1ab/rtttl 1735844208.2886
     awtrix_54a1ab/sendscreen 1735844208.28876
     awtrix_54a1ab/settings 1735844206.8438
     awtrix_54a1ab/sleep 1735844208.28729
     awtrix_54a1ab/sound 1735844208.28846
     awtrix_54a1ab/switch 1735844206.81065
     awtrix_54a1ab/timeformat 1735844208.28783
Attributes:

Was mir nicht ganz klar ist, wie das Zusammenspiel zwischen den Devices MQTT2_SERVER, MQTT2_SERVER_192.168.0.24_56198 und awtrix_54a1ab ist?
Würde denken, dass die MQTT-Nachrichten über den MQTT2_SERVER reinkommen und dann verarbeitet werden. Wenn an das Device awtrix_54a1ab etwas gesendet werden soll, dann wird dies hierüber gemacht?

Habe auch mal einer deiner Funktionen aufgerufen, die ich in meiner Utils übernommen habe. Aber es kommt einfach nichts bei der Ulanzi (awtrix_54a1ab) an:
{return VBSUtils_Awtrix_SetDayMode("awtrix_54a1ab")}
FHEM ist aktuell und es sind keine Allowed Listen gepflegt.
Wird die ulanzi ausgeschaltet, verschwindet das Device MQTT2_SERVER_192.168.0.24_56198.
Wird es wieder eingeschaltet, ist es wieder da.
Daher gehe ich davon aus, dann die kommunikation über FHEM generell steht.

vbs

ZitatWas mir nicht ganz klar ist, wie das Zusammenspiel zwischen den Devices MQTT2_SERVER, MQTT2_SERVER_192.168.0.24_56198 und awtrix_54a1ab ist?
Würde denken, dass die MQTT-Nachrichten über den MQTT2_SERVER reinkommen und dann verarbeitet werden. Wenn an das Device awtrix_54a1ab etwas gesendet werden soll, dann wird dies hierüber gemacht?

Klingt generell nich so falsch, aber dein Device "MQTT2_SERVER_192.168.0.24_56198" verstehe ich nicht. Ich denke, das brauchst du nicht (?). Das scheint ja ein zweiter MQTT2_SERVER zu sein. Ich benutze einen separaten MQTT-Server (mosquitto) und nutze dann in FHEM entsprechend MQTT2_CLIENT statt MQTT2_SERVER.
Das verschwindet, wenn du die Ulanzi ausschaltest? Das versteh ich nicht.

Was mir in dem Zusammenhang noch auffällt:
An dem MQTT2_DEVICE (also bei dir "awtrix_54a1ab") sollte ja in dem Reading "IODev" der Name des FHEM-Devices stehen, über das die MQTT-Nachrichten verschickt und empfangen werden. Also in meinem Fall ist das "sys_mqtt" (das ist mein MQTT2_CLIENT-Device). Bei dir steht da MQTT2_SERVER. Also ein Modul-Name und kein Device-Name! Also das kommt mir an deiner Config auch komisch vor und da würde ich mal ein Fragezeichen dran machen, ob das so korrekt ist. Ich denke, da steckt ein Fehler drin.

Du solltest dir mal einen separaten Desktop-MQTT-Client installieren, um erstmal gucken zu können, ob die MQTT-Nachrichten, die da verschickt werden, sinnvoll aussehen. Ich benutze "MQTTX". Wenn du dich mit dem Server verbindest, solltest du erstmal die Nachrichten sehen, die die Ulanzi von sich aus versendet.
Und wenn du dann in FHEM z.B. machst "set awtrix_54a1ab switch Time", dann solltest du in dem Client sehen, was FHEM versendet hat.
Damit würde ich erstmal anfangen, um zu sehen, was da überhaupt vor sich geht in der MQTT-Kommunikation und dann wird vieles vermutlich klarer und dann kannst du auch gezielter forschen, wenn irgendwo was klemmt.

Beta-User

Die temporären MQTT2_SERVER-Instanzen sind kein Problem, für jede aktive Verbindung wird da halt eine Instanz aufgemacht, macht z.B. FHEMWEB auch so...

Und die IODev-Namensgebung paßt auch.

Man braucht auch kein externes Tool, um den MQTT-Verkehr sichtbar zu machen - "show MQTT traffic" im IO geht genauso (ich nutze aber auch gerne mosquitto_sub, um den MQTT2_SERVER abzuhören...).

Nach den "subscriptions" ist das "home/" in devicetopic zu viel, vermutlich wurde da was geändert; jedenfalls sieht auch die readingList so aus, als hätte sich das jemand dann anders überlegt...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

vbs

Ahh ok, danke für Aufklärung. Aber mal aus Interesse: warum steht da bei IODev kein Device-Name, sondern ein Typ-Name drin? Was passiert, wenn man mehrere MQTT2_SERVER hätte?

Ich würde aber weiterhin, dabei bleiben, für das Mitlesen von MQTT eine UI-Anwendung zu nutzen, da die meistens weitgehend selbsterklärend sind. Ist für die meisten Leute einfacher, als textbasierte Befehle oder Anwendungen zu nutzen mit manchmal nicht sehr intuitiven Kommando-Parametern, die man sich dann alle merken muss ;) Aber kann natürlich jeder halten, wie er möchte.


rudolfkoenig

Zitatwarum steht da bei IODev kein Device-Name, sondern ein Typ-Name drin?
Ist kein Typ: der MQTT2_SERVER heisst hier MQTT2_SERVER.

vbs

Ach Mensch, danke, ja, hätte ich auch sehen können...   :(

juergen012

Schon gesehen??
[url=https://blueforcer.github.io/awtrix3/#/README]https://blueforcer.github.io/awtrix3/#/README[/url]
Es gibt auch eine App für das iPhone. Android??.

Ich hatte meine Ulazi über die MQTT GENERIC BRIDGE eingebunden.

Gruß
Jürgen K.
Fhem unter Proxmox

Saphora

Hatte jetzt etwas herumgespielt und jetzt scheint alles soweit zu laufen.
Entscheidender Hinweis warum gar keine Kommunikation zustande kam, war

Zitat von: Beta-User am 03 Januar 2025, 07:30:01Nach den "subscriptions" ist das "home/" in devicetopic zu viel, vermutlich wurde da was geändert; jedenfalls sieht auch die readingList so aus, als hätte sich das jemand dann anders überlegt...

Hatte mich dann als FHEM für den MQTT-Server entschieden.

Auch gut zu wissen war:
Zitat von: Beta-User am 03 Januar 2025, 07:30:01Die temporären MQTT2_SERVER-Instanzen sind kein Problem, für jede aktive Verbindung wird da halt eine Instanz aufgemacht, macht z.B. FHEMWEB auch so...

@Beta-User: Großen Dank für den Hinweis

Auch einen Mega Dank an @vbs für deinen bereitgestellten Code.
Dadurch habe ich die Funktionsweise jetzt gut verstanden und kann selbst Anpassungen vornehmen.

Danke Danke Danke  :D

Falls noch Fragen aufkommen solten, würde ich mich noch einmal melden.