HowTo: Integration of Daikin Air Conditioning over Wifi

Einklappen
X
 
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge
  • TomekWaw
    LoxBus Spammer
    • 25.07.2019
    • 436

    #1

    HowTo: Integration of Daikin Air Conditioning over Wifi

    Hallo zusammen,

    Ich habe Daikin AC mit Loxone integriert Wahrscheinlich etwas anders als andere zuvor. Der Vorteil dieser Integration ist die relative Einfachheit und bidirektionale Kommunikation (Duplex). Ich habe die gesamte Integration bei LoxWiki auf Englisch beschrieben:

    https://www.loxwiki.eu/display/LOXEN...ning+over+WiFi

    Dies ist der erste Teil der Integration - nur remote control.
    Ich arbeite immer noch an der Kühllogik.
    Bleib dran.

    ------------ english ------------

    Hi everyone,

    I have integrated Daikin AC with Loxone. Probably in a slightly different way than others before me. The advantage of that integration is its relative simplicity and bidirectional communication (duplex). I described the integration on LoxWiki:

    https://www.loxwiki.eu/display/LOXEN...ning+over+WiFi

    This is the first part of integration - only remote control.
    I'm still working on the cooling logic.
    Stay tuned.



    Teaser:

    Klicke auf die Grafik für eine vergrößerte Ansicht

Name: 03_app-screens.png
Ansichten: 4754
Größe: 172,0 KB
ID: 256352
    Zuletzt geändert von TomekWaw; 28.06.2020, 05:19.
    Noch ein oder zwei Jahre mit Loxone und ich werde Deutsch sprechen
  • christian288
    Dumb Home'r
    • 29.12.2015
    • 23

    #2
    Hallo
    Ich habe mit Raspberry ioBroker angefangen. Ich habe 3 DAIKIN-Klimaanlagen installiert und weiß nicht, wie ich vorgehen soll. Ich weiß nicht, wie ich Loxone dazu bringen kann, ioBroker-Daten von Klimaanlagen zu empfangen. Ich habe MQTT in ioBroker installiert und wie in Abbildung (4) gezeigt eingerichtet. Ich weiß nicht, wie ich es machen soll. Ich verwende auch Raspberry on, LoxBerry, auf dem das MQTT-Gateway installiert ist, aber irgendwie möchte ich keine Daten senden.
    Vielen Dank im Voraus für die Informationen.

    Kommentar

    • dasrockt
      Extension Master
      • 01.06.2017
      • 136

      #3
      Hmm wo hast du dein MQTT Gateway laufen? Die Einstellungen sehen komisch aus...
      Mch doch das Gateway am Loxberry dann brauchst du nur die IP im Loxberry auf localhost ändern und dann im iobroker gibst die ip vom loxberry ein.. dann bei subscribe #/ rein und schaust was kommt.
      Loxone: so ziemlich alles was es gibt
      Loxberry: Alexa<->Lox, CamStream4Lox, FHEM, MQTT Gateway, Weather4Loxone, Zigbee2Mqtt
      Other: Node-Red, IObroker, Zehnder Comfoair 350, Tasmota, usw.

      Kommentar


      • christian288
        christian288 kommentierte
        Kommentar bearbeiten
        Hallo, es funktioniert.
    • christian288
      Dumb Home'r
      • 29.12.2015
      • 23

      #4
      Zitat von dasrockt
      ​​Hmm wo hast du dein MQTT Gateway laufen? Die Einstellungen sehen komisch aus...
      Mch doch das Gateway am Loxberry dann brauchst du nur die IP im Loxberry auf localhost ändern und dann im iobroker gibst die ip vom loxberry ein.. dann bei subscribe #/ rein und schaust was kommt.
      ​​​ ​
      Hallo,
      Ich habe zwei Himbeeren, 1 loxberry und 2 ist ioBroker.
      LoxBery hat die Adresse XXX.XXX.XX.107: 8084
      ioBrok hat jase XXX.XXX.XX.208: 8081
      Aber irgendwie möchte ioBrok nicht mit LoxBery kommunizieren, weil ich immer noch die gleichen Werte von ☹ habe
      Zuletzt geändert von christian288; 11.03.2021, 13:06.

      Kommentar

      • dasrockt
        Extension Master
        • 01.06.2017
        • 136

        #5
        Funktioniert es jetzt?
        Loxone: so ziemlich alles was es gibt
        Loxberry: Alexa<->Lox, CamStream4Lox, FHEM, MQTT Gateway, Weather4Loxone, Zigbee2Mqtt
        Other: Node-Red, IObroker, Zehnder Comfoair 350, Tasmota, usw.

        Kommentar


        • christian288
          christian288 kommentierte
          Kommentar bearbeiten
          Now yes, now I will program into Loxone
      • christian288
        Dumb Home'r
        • 29.12.2015
        • 23

        #6
        Hallo, alle miteinander,
        Ich kann nach der Loxon-Konfiguration fragen. Irgendwie kann ich das nicht machen. Ich wollte auch fragen, ob ich Daten eingeben muss (Text-zu-Wert-Konvertierung in MQTT Gateway), da ich immer noch ein orangefarbenes Symbol habe (siehe Bild). Vielleicht besser helfen.

        Danke im Voraus.

        Klicke auf die Grafik für eine vergrößerte Ansicht

Name: 2021-03-11 (8111.png
Ansichten: 3199
Größe: 257,0 KB
ID: 295809

        Kommentar

        • Iksi
          Lox Guru
          • 27.08.2015
          • 1111

          #7
          How do you want to get the data into Loxone?
          Over UDP or directly to the virtual inputs?

          The symbol tells you that the virtual input dows not exist. You must have an virtual input which name is exactly like the topic.

          Kommentar

          • christian288
            Dumb Home'r
            • 29.12.2015
            • 23

            #8
            Hi to all,

            I wanted to ask how to set up virtual output, thank you in advance for your help.

            Zuletzt geändert von christian288; 12.03.2021, 19:09.

            Kommentar

            • Paul Sinnema
              Smart Home'r
              • 29.12.2015
              • 54

              #9
              Diese Lösungen sind alle ziemlich complex. Ich glaube ik habe eine einfachere gefunden mit Picoc. Es ist noch nicht fertig aber der erste Ansatz funktioniert gut.
              Ik habe ein kleines Picoc Programm geschrieben mit denem ich die Kommandozeile zusammensetze. Hier ist das Programm

              Die Einbindung is supereinfach. Eine (nicht digitale) virtuele Ausgang mit <v> im Kommandozeile is alles was man benötigt.

              Klicke auf die Grafik für eine vergrößerte Ansicht  Name: 2021-09-21_21-10-41.jpg Ansichten: 0 Größe: 35,6 KB ID: 318342

              Klicke auf die Grafik für eine vergrößerte Ansicht  Name: 2021-09-21_21-14-25.jpg Ansichten: 0 Größe: 119,4 KB ID: 318343

              Klicke auf die Grafik für eine vergrößerte Ansicht

Name: 2021-09-21_21-17-07.jpg
Ansichten: 2608
Größe: 25,0 KB
ID: 318344

              Code:
              int ftoi(float f)
              {
                char fbuf[20];
              
                sprintf(fbuf, "%f", f);
              
                return batoi(fbuf);
              }
              
              ///
              /// Main loop.
              ///
              while(TRUE)
              {
                int event = getinputevent();
                int power = 0;
                int mode = 0;
                int temp = 0;
                char buffer[256];
              
                if(event & 0x2C) // bits 3, 4 and 5
                {
                  // power, mode or temp changed
              
                  power = ftoi(getinput(0));
                  mode = ftoi(getinput(1));
                  temp = ftoi(getinput(2));
              
                  sprintf(buffer, "/aircon/set_control_info?pow=%d&mode=%d&stemp=%d&shum=50&f _rate=B&f_dir=0", power, mode, temp);
              
                  setoutputtext(0, buffer);
                }
              
                // Slow the loop down 1 second
                int sleepTime = 1 * 1000;
                sleep(sleepTime);
              }
              Zuletzt geändert von Paul Sinnema; 21.09.2021, 21:18.

              Kommentar

              • HIS-Loxone
                MS Profi
                • 26.08.2015
                • 547

                #10
                Die Idee find ich gut

                Kommentar

                • Paul Sinnema
                  Smart Home'r
                  • 29.12.2015
                  • 54

                  #11
                  Ich habe dem Programm erweitert. Hier ist was jetzt bei mir aktiv ist

                  Code:
                  // -----------------------------------------------------------------------------
                  // This little program is capable of reading values for up to 3 units
                  // and compose the command to steer each of them
                  //
                  // Parameters read are
                  //                  unit 0      unit 1      unit 2        value     description
                  // power on/off     AI1         AI5         AI9           0/1        0 = off, 1 = on power on/off
                  // mode             AI2         AI6         AI10          0/1        0 = heat, 1=cool
                  // temperature      AI3         AI7         AI11
                  //
                  // output           TQ1         TQ2         TQ3            Command
                  // -----------------------------------------------------------------------------
                  
                  
                  // Port offsets
                  #define unit0PortOffset 0
                  #define unit1PortOffset 4
                  #define unit2PortOffset 8
                  
                  // Event masks
                  // 0000 0000 0111 1000
                  #define unit0mask 0x0078
                  // 0000 0111 1000 0000
                  #define unit1mask 0x0780
                  // 0111 1000 0000 0000
                  #define unit2mask 0x7800
                  
                  // Convert float to int.
                  // Removes the fraction! (i.e. 1.9 will become 1)
                  // Float value should not exceed 99 digits.
                  int ftoi(float f)
                  {
                    char fbuf[100];
                  
                    sprintf(fbuf, "%f", f);
                  
                   return batoi(fbuf);
                  }
                  
                  // Sends the command string to the unit
                  void SendCommand(int unit)
                  {
                   char buffer[256];
                   int startInput;
                   int output;
                  
                   switch(unit)
                   {
                    case 0:
                      startInput = unit0PortOffset;
                      output = 0;
                      break;
                    case 1:
                      startInput = unit1PortOffset;
                      output = 1;
                      break;
                    case 2:
                      startInput = unit2PortOffset;
                      output = 2;
                      break;
                    default:
                      printf("Wrong unit %d", unit);
                      break;
                    }
                  
                    int   power = ftoi(getinput(startInput + 0));
                    int   mchoice = ftoi(getinput(startInput + 1));
                    float temp = getinput(startInput + 2);
                  
                     temp = round(temp * 10.0) / 10.0;
                  
                    int   mode = 4; // Heat
                  
                    if(mchoice == 1) mode = 3; // Cool
                  
                    sprintf(buffer, "/aircon/set_control_info?pow=%d&mode=%d&stemp=%f&shum=50&f _rate=B&f_dir=0", power, mode, temp);
                    printf("Sending to output %d for unit %d: %s", output, unit, buffer);
                    setoutputtext(output, buffer);
                  }
                  
                  // Main loop.
                  while(TRUE)
                  {
                    int event = getinputevent();
                  
                    if(event != 0)
                    {
                      if(event & unit0mask) SendCommand(0);
                      if(event & unit1mask) SendCommand(1);
                      if(event & unit2mask) SendCommand(2);
                    }
                  
                  /  / Slow the loop down 1 second
                    int sleepTime = 1 * 1000;
                    sleep(sleepTime);
                  }
                  Layout im Loxone Config

                  Klicke auf die Grafik für eine vergrößerte Ansicht  Name: 2021-09-22_20-24-07.jpg Ansichten: 23 Größe: 61,7 KB ID: 318464
                  Zuletzt geändert von Paul Sinnema; 24.09.2021, 09:49. Grund: Code verbessert

                  Kommentar

                  • HIS-Loxone
                    MS Profi
                    • 26.08.2015
                    • 547

                    #12
                    Jetzt noch die lüfterdrehzahl. Die rluftstrom Richtung. Und denn silentmode integrieren. Und noch eine Unit dazu und es währe Perfekt

                    Kommentar


                    • Paul Sinnema
                      Paul Sinnema kommentierte
                      Kommentar bearbeiten
                      Kann man machen. Es gibt auch die getio(). Mit dem kann man virtuelle inputs abfragen. Ist vielleicht eine schönere Lösung. Dann ist man nicht eingeschränkt durch die AIn inputs. Nachteil ist dass es keine direkte Verbinding hat mit dem Programm-baustein. Mann muss es wissen und siehts nicht. Noch eine Unit dazu geht leider nicht. Man hat 'nur' 16 Ports und 3 davon sind nicht floats also bleiben 'nur' 13 übrig.
                      Zuletzt geändert von Paul Sinnema; 24.09.2021, 09:48.
                  • Paul Sinnema
                    Smart Home'r
                    • 29.12.2015
                    • 54

                    #13
                    Hallo Leute,
                    Es war eine Streit aber ich glaube es ist mir gelungen ein Programm zusamen zu setzen dass unendlich viele AC Units (ok, ok, max 99 :-) ) steuern kann. PicoC is wirklich sehr mühsam zu programmieren. Ich habe das Programm jetzt auf die getio() function bassiert. Das bedeutet dass es keine Verbindungen mehr gibt zum Programmblock. Alles wird aus Markers und Virtuele Eingänge gehohlt.

                    Das Programm erwartet folgendes:
                    Typ Name Wert Bemerkung
                    Virtuelle Eingang oder Marker AC_MAX n Maximum n Units werden gehandelt
                    Marker ACnn_Address_p IP Address part Es müssen 4 Address Teile erfasst werden pro AC Unit. nn = Unit, p=Teil (part). Z.b. AC01_Address_1 = 192, AC01_Address_2 = 168, AC01_Address_3 = 1, AC01_Address_4 = 20,
                    Marker ACnn_Mode Mode Mode: 0 = Heating, 1 = Cooling
                    Marker ACnn_Power OnOff OnOff: 0 = Off, 1 = On
                    Marker ACnn_Temperature Temperature Temperature: Erwünschte Temperatur
                    Virtuelle Eingag oder Marker ACnn_Direction Direction Direction: Wert zwischen 0 und 3
                    Virtuelle Eingang oder Marker ACnn_Humidity Humidity Humidity: Luftveuchtigkeit: Wert zwischen 0 und 100.
                    Virtuelle Eingang oder Marker ACnn_Rate Rate Rate: Ventilator geschwindigkeit. Wert zwischen 0 und 7. 0 = Auto, 1 = Silent, 2 bis 7 = lvl_1 bis lvl_5
                    Hier ist die Einbindung in Config.

                    Klicke auf die Grafik für eine vergrößerte Ansicht  Name: 2021-10-17_13-04-32.jpg Ansichten: 0 Größe: 187,1 KB ID: 321287


                    Was mir geholfen hat is die PicoC Repository on GitHub. Ich konnte es herunterladen und sogar met Visual Studio 2019 Professional compilieren. Nachdem kannst du met ‘picoc -s ac.c’ das Programm lokal laufen lassen. Die Syntax ist nicht 100% gleich an PicoC im Miniserver aber jetzt muss ich nicht jede Änderung hochladen und die Fehlermeldungen im Miniserver beseitigen sondern geht Lokal.
                    Es gibt 2 files: ac.c und loxone.h. In der Letzte stehen dummy Funktionen für fehlende Loxone Erweiterungen.

                    Code:
                    // Remove or comment this define before uploading to the miniserver
                    #define LOXONE_DUMMIES
                    // In the headerfile below there are LOXONE functions that are not present in PicoC.
                    #ifdef LOXONE_DUMMIES
                    #include "loxone.h"
                    #endif
                    Bevor mann das Program Hochläd muss der #define LOXONE_DUMMIES inaktiv gemacht werden (Z.b. Löschen).

                    Code:
                    // ---------------------------------------------------------------------------------
                    // This little program is capable of reading values for an unlimited number of units
                    // and compose the command to steer each of them
                    // ---------------------------------------------------------------------------------
                    
                    // Remove or comment this define before uploading to the miniserver
                    #define LOXONE_DUMMIES
                    // In the headerfile below there are LOXONE functions that are not present in PicoC.
                    #ifdef LOXONE_DUMMIES
                    #include "loxone.h"
                    #endif
                    
                    struct IO_Unit
                    {
                      char address[20];
                      int power;
                      int oldpower;
                      int mode;
                      int oldmode;
                      float temperature;
                      float oldtemperature;
                      int humidity;
                      int oldhumidity;
                      int rate;
                      int oldrate;
                      int direction;
                      int olddirection;
                    };
                    
                    struct IO_Unit *iounits;
                    
                    // Convert float to int.
                    // Removes the fraction! (i.e. 1.9 will become 1)
                    // Float value should not exceed 99 digits.
                    int ftoi(float f)
                    {
                      char fbuf[100];
                    
                      sprintf(fbuf, "%f", f);
                    
                      return atoi(fbuf);
                    }
                    
                    float getioForUnit(int unit, char* template)
                    {
                      char buffer[100];
                    
                      sprintf(buffer, template, unit);
                    
                      return getio(buffer);
                    }
                    
                    void getIoAddressForUnit(int unit, char* template)
                    {
                      struct IO_Unit *iounit = &iounits[unit];
                    
                      float address_part[4];
                      char buffer[100];
                    
                      for(int part = 0; part < 4; part++)
                      {
                        sprintf(buffer, template, unit + 1, part + 1);
                    
                        address_part[part] = getio(buffer);
                      }
                    
                      sprintf(iounit->address, "%d.%d.%d.%d", address_part[0], address_part[1], address_part[2], address_part[3]);
                    }
                    
                    float roundit(float f)
                    {
                      return (floor(f) + (round((f - floor(f)) * (1.0 / 0.5)) * 0.5));
                    }
                    
                    int hasIoValueChanged(int index)
                    {
                      int unit = index + 1;
                      struct IO_Unit *iounit = &iounits[index];
                    
                      getIoAddressForUnit(index, "AC%02d_Address_%d");
                    
                      iounit->power = ftoi(getioForUnit(unit, "AC%02d_Power"));
                      iounit->mode = ftoi(getioForUnit(unit, "AC%02d_Mode"));
                      iounit->temperature = roundit(getioForUnit(unit, "AC%02d_Temperature"));
                      iounit->humidity = ftoi(getioForUnit(unit, "AC%02d_Humidity"));
                      iounit->rate = ftoi(getioForUnit(unit, "AC%02d_Rate"));
                      iounit->direction = ftoi(getioForUnit(unit, "AC%02d_Direction"));
                    
                      // PicoC does not like && a lot. Had to create this long nested if.
                      if(iounit->power == iounit->oldpower)
                        if(iounit->mode == iounit->oldmode)
                          if(iounit->temperature == iounit->oldtemperature)
                            if(iounit->humidity == iounit->oldhumidity)
                              if(iounit->rate == iounit->oldrate)
                                if(iounit->direction == iounit->olddirection)
                                  return 0;
                    
                      iounit->oldpower = iounit->power;
                      iounit->oldmode = iounit->mode;
                      iounit->oldtemperature = iounit->temperature;
                      iounit->oldhumidity = iounit->humidity;
                      iounit->oldrate = iounit->rate;
                      iounit->olddirection = iounit->direction;
                    
                      return 1;
                    }
                    
                    // Sends the command string to the unit
                    void SendCommand(int unit)
                    {
                      char buffer[256];
                      char rate[5];
                      char *response;
                      struct IO_Unit *iounit = &iounits[unit];
                    
                      int mode = 4; // Heat
                    
                      if(iounit->mode == 1) mode = 3; // Cool
                    
                      switch(iounit->rate)
                      {
                        case 1:
                          strcpy(rate, "A");
                          break;
                        case 2:
                          strcpy(rate, "B");
                          break;
                        case 3:
                        case 4:
                        case 5:
                        case 6:
                        case 7:
                          sprintf(rate, "%s", iounit.rate);
                          break;
                    
                        case 0:
                        default:
                          printf("***** ERROR: Wrong rate %d\n", iounit->rate);
                          return;
                      }
                    
                      sprintf(buffer, "/aircon/set_control_info?pow=%d&mode=%d&stemp=%f&shum=%d&f _rate=%s&f_dir=%d",
                      iounit->power,
                      mode,
                      iounit->temperature,
                      iounit->humidity,
                      rate,
                      iounit->direction);
                      printf("Sending for unit %d to %s: %s\n", unit+1, iounit->address, buffer);
                    
                      response = httpget(iounit->address, buffer);
                    
                      printf("Response: %s\n", response);
                    
                      free(response);
                    }
                    
                    int acMax = ftoi(getio("AC_MAX"));
                    iounits = calloc(sizeof(struct IO_Unit), acMax);
                    
                    printf("Starting mainloop, number of units: %d (AC_MAX)\n", acMax);
                    
                    // Main loop.
                    while(true)
                    {
                      for(int unit = 0; unit < acMax; unit++)
                      {
                        if(hasIoValueChanged(unit) == 1)
                        {
                          SendCommand(unit);
                        }
                      }
                    
                      // Slow the loop down 10 second
                      int sleepTime = 10 * 1000;
                      sleep(sleepTime);
                    }
                    Zuletzt geändert von Paul Sinnema; 17.10.2021, 14:34.

                    Kommentar


                    • HIS-Loxone
                      HIS-Loxone kommentierte
                      Kommentar bearbeiten
                      Perfect
                      Hast du einen Modus Vergleich der Units vorgesehen z.b. Unit 1 bis 3 Modus kühlen. Wenn Unit 4 noch auf heizen steht würde Unit 4 auf Konflikt schalten
                  • Martin1234
                    LoxBus Spammer
                    • 18.01.2020
                    • 288

                    #14
                    Hallo Paul Sinnema ,
                    großartige Arbeit. Herzlichen Dank für deinen Beitrag zu diesem Thema.

                    Ich hätte eine grundsätzliche Frage: Voraussetzung ist ja eine lokale API der Innengeräte, oder? Funktioniert diese wieder? Mein letzter Stand war, dass diese von Daikin nicht mehr zur Verfügung steht.

                    Kommentar


                    • Paul Sinnema
                      Paul Sinnema kommentierte
                      Kommentar bearbeiten
                      Nein, die neusten Innenmodulen haben eine neue Wifi welche man nur ueber Cloud erreigen kann.. Mit dem geht es nicht. Du kansst aber die Alte noch immer kaufen und an den S21 Port anschliessen. BRP069B45 ist ein alter Modul mit dem mein Programm functionieren wuerde. Es gibt noch mehrere Variationen von diesem Modul. Ich habe mal Intesis gekauft. Die sind sehr teuer (250+ Euro). Die Intesis Module verwenden Web Sockets, die werden von Loxone her nicht unterstuetzt. Die alte Wifi Modulen sind viel geunstiger. Suche mal im Internet auf ‘Daikin GitHub’ und du findest die Inoffizielle Dokus des Daikins.
                      Zuletzt geändert von Paul Sinnema; 17.10.2021, 23:26.

                    • Martin1234
                      Martin1234 kommentierte
                      Kommentar bearbeiten
                      Danke für deine Bestätigung. Ich hätte Angst, dass ich die neuen Innenmodule bekomme, wenn ich mir eine neue Daikin Klimaanlage kaufe.

                    • Martin1234
                      Martin1234 kommentierte
                      Kommentar bearbeiten
                      Hi Paul, Ich hab bei Daikin Österreich direkt nachgefragt und mir wurde gesagt, dass die neuen Innengeräte nicht kompatibel mit den alten Wifi Modulen, z.B. BRP069B45 wären. Wenn das stimmt, dann würde ja für alle neuen Daikin Anlagen nur mehr die Cloud-Lösung bleiben.
                  • HIS-Loxone
                    MS Profi
                    • 26.08.2015
                    • 547

                    #15
                    Paul Sinnema hast du bei deinen Script etwas erweitert? kannst du mal deine Config mir schicken. ich denke ein Wiki Beitrag währe super


                    Ich komme irgendwie nicht zusammen. Das Programme schickt mir keine werte.

                    Klicke auf die Grafik für eine vergrößerte Ansicht

Name: Daikin Programm 1.png
Ansichten: 2263
Größe: 39,0 KB
ID: 342567
                    Code:
                    // ---------------------------------------------------------------------------------
                    // This little program is capable of reading values for an unlimited number of units
                    // and compose the command to steer each of them
                    // ---------------------------------------------------------------------------------
                    
                    // Remove or comment this define before uploading to the miniserver
                    //#define LOXONE_DUMMIES
                    // In the headerfile below there are LOXONE functions that are not present in PicoC.
                    //#ifdef LOXONE_DUMMIES
                    //#include "loxone.h"
                    //#endif
                    
                    struct IO_Unit
                    {
                    char address[20];
                    int power;
                    int oldpower;
                    int mode;
                    int oldmode;
                    float temperature;
                    float oldtemperature;
                    int humidity;
                    int oldhumidity;
                    int rate;
                    int oldrate;
                    int direction;
                    int olddirection;
                    };
                    
                    struct IO_Unit *iounits;
                    
                    // Convert float to int.
                    // Removes the fraction! (i.e. 1.9 will become 1)
                    // Float value should not exceed 99 digits.
                    int ftoi(float f)
                    {
                    char fbuf[100];
                    
                    sprintf(fbuf, "%f", f);
                    
                    return atoi(fbuf);
                    }
                    
                    float getioForUnit(int unit, char* template)
                    {
                    char buffer[100];
                    
                    sprintf(buffer, template, unit);
                    
                    return getio(buffer);
                    }
                    
                    void getIoAddressForUnit(int unit, char* template)
                    {
                    struct IO_Unit *iounit = &iounits[unit];
                    
                    float address_part[4];
                    char buffer[100];
                    
                    for(int part = 0; part < 4; part++)
                    {
                    sprintf(buffer, template, unit + 1, part + 1);
                    
                    address_part[part] = getio(buffer);
                    }
                    
                    sprintf(iounit->address, "%d.%d.%d.%d", address_part[0], address_part[1], address_part[2], address_part[3]);
                    }
                    
                    float roundit(float f)
                    {
                    return (floor(f) + (round((f - floor(f)) * (1.0 / 0.5)) * 0.5));
                    }
                    
                    int hasIoValueChanged(int index)
                    {
                    int unit = index + 1;
                    struct IO_Unit *iounit = &iounits[index];
                    
                    getIoAddressForUnit(index, "AC%02d_Address_%d");
                    
                    iounit->power = ftoi(getioForUnit(unit, "AC%02d_Power"));
                    iounit->mode = ftoi(getioForUnit(unit, "AC%02d_Mode"));
                    iounit->temperature = roundit(getioForUnit(unit, "AC%02d_Temperature"));
                    iounit->humidity = ftoi(getioForUnit(unit, "AC%02d_Humidity"));
                    iounit->rate = ftoi(getioForUnit(unit, "AC%02d_Rate"));
                    iounit->direction = ftoi(getioForUnit(unit, "AC%02d_Direction"));
                    
                    // PicoC does not like && a lot. Had to create this long nested if.
                    if(iounit->power == iounit->oldpower)
                    if(iounit->mode == iounit->oldmode)
                    if(iounit->temperature == iounit->oldtemperature)
                    if(iounit->humidity == iounit->oldhumidity)
                    if(iounit->rate == iounit->oldrate)
                    if(iounit->direction == iounit->olddirection)
                    return 0;
                    
                    iounit->oldpower = iounit->power;
                    iounit->oldmode = iounit->mode;
                    iounit->oldtemperature = iounit->temperature;
                    iounit->oldhumidity = iounit->humidity;
                    iounit->oldrate = iounit->rate;
                    iounit->olddirection = iounit->direction;
                    
                    return 1;
                    }
                    
                    // Sends the command string to the unit
                    void SendCommand(int unit)
                    {
                    char buffer[256];
                    char rate[5];
                    char *response;
                    struct IO_Unit *iounit = &iounits[unit];
                    
                    int mode = 4; // Heat
                    
                    if(iounit->mode == 1) mode = 3; // Cool
                    
                    switch(iounit->rate)
                    {
                    case 1:
                    strcpy(rate, "A");
                    break;
                    case 2:
                    strcpy(rate, "B");
                    break;
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    sprintf(rate, "%s", iounit.rate);
                    break;
                    
                    case 0:
                    default:
                    printf("***** ERROR: Wrong rate %d\n", iounit->rate);
                    return;
                    }
                    
                    sprintf(buffer, "/aircon/set_control_info?pow=%d&mode=%d&stemp=%f&shum=%d&f _rate=%s&f_dir=%d",
                    iounit->power,
                    mode,
                    iounit->temperature,
                    iounit->humidity,
                    rate,
                    iounit->direction);
                    printf("Sending for unit %d to %s: %s\n", unit+1, iounit->address, buffer);
                    
                    response = httpget(iounit->address, buffer);
                    
                    printf("Response: %s\n", response);
                    
                    free(response);
                    }
                    
                    int acMax = ftoi(getio("AC_MAX"));
                    iounits = calloc(sizeof(struct IO_Unit), acMax);
                    
                    printf("Starting mainloop, number of units: %d (AC_MAX)\n", acMax);
                    
                    // Main loop.
                    while(true)
                    {
                    for(int unit = 0; unit < acMax; unit++)
                    {
                    if(hasIoValueChanged(unit) == 1)
                    {
                    SendCommand(unit);
                    }
                    }
                    
                    // Slow the loop down 10 second
                    int sleepTime = 10 * 1000;
                    sleep(sleepTime);
                    }// write program here in PicoC
                    Angehängte Dateien
                    Zuletzt geändert von HIS-Loxone; 27.03.2022, 11:05.

                    Kommentar


                    • Paul Sinnema
                      Paul Sinnema kommentierte
                      Kommentar bearbeiten
                      Ist es dir gelungen? Kann ich noch irgendwie helfen?
                  Lädt...