рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдЕрдиреБрдХреВрд▓ рд╕реНрдорд╛рд░реНрдЯ рд╣реЛрдо рдкрд╛рд╡рд░ рдкреНрд░рдмрдВрдзрди: рдбреЛрдореЛрдЯрд┐рдХрдЬрд╝ + рдореИрдиреБрдЕрд▓ рд╕реНрд╡рд┐рдЪ

рд╣рд╛рдп рдЧреАрдХрдЯрд╛рдЗрдореНрд╕!

рдореИрдВ рдЕрдкрдиреЗ рд╕реНрдорд╛рд░реНрдЯ рд╣реЛрдо рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдХреБрдЫ рдХрдард┐рди рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред

рд╕реНрдорд╛рд░реНрдЯ рд╣реЛрдо рдХреЗ рдореЗрд░реЗ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдХреЗрдВрджреНрд░реАрдп рдирд┐рдпрдВрддреНрд░рдХ рдХреЗ рд░реВрдк рдореЗрдВ, рдореИрдВ рд╕реНрдерд╛рдкрд┐рдд рдбреЛрдореЛрдЯрд┐рдХрдЬрд╝ рдФрд░ рдПрдордХреНрдпреВрдЯреАрдЯреА рдмреНрд░реЛрдХрд░ рдордЪреНрдЫрд░ рдХреЗ рд╕рд╛рде рд░рд╛рд╕реНрдкрдмреЗрд░реА рдкрд╛рдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред рдХреЗрдВрджреНрд░реАрдп рдирд┐рдпрдВрддреНрд░рдХ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рднрд╛рд░ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЕрдХреНрд╕рд░ рдореБрдЦреНрдп рднрд╡рди рд╕реЗ рдХрд╛рдлреА рджреВрд░ рд╕реНрдерд┐рдд рд╣реЛрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдЧреИрд░реЗрдЬ рдпрд╛ рдЧреНрд░реАрдирд╣рд╛рдЙрд╕ рдореЗрдВред рдРрд╕реА рджреВрд░рд╕реНрде рд╕рд╛рдЗрдЯреЛрдВ рдореЗрдВ, рдореИрдВ рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣ рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдИрдерд░рдиреЗрдЯ рд╢реАрд▓реНрдб рдХреЗ рд╕рд╛рде рд▓реЛрдбрд┐рдВрдЧ рдФрд░ Arduino рдХреЗ рд▓рд┐рдП рд╕рд╕реНрддреА KMTronic UDP рд░рд┐рд▓реЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореИрдВ рд╕реНрд╡рд┐рдЪрд┐рдВрдЧ рд╕реНрдХреАрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВ, рддрд╛рдХрд┐ рдХрд┐рд╕реА рднреА рд╕рдордп, рдЬрд┐рд╕рдореЗрдВ рд╕реНрдорд╛рд░реНрдЯ рд╣реЛрдо рдЗрдиреНрдлреНрд░рд╛рд╕реНрдЯреНрд░рдХреНрдЪрд░ рдХреЗ рддрддреНрд╡ рд╡рд┐рдлрд▓ рд╣реЛрдВ, рдореИрдВ рд▓реЛрдб рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╕реНрд╡рд┐рдЪ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред рдореЗрд░реЗ рд▓рд┐рдП, рд╡рд┐рд╢реНрд╡рд╕рдиреАрдпрддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдорд╛рдзреНрдпрдорд┐рдХ рд╣реИ - рдореБрдЦреНрдп рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдореЗрд░реА рдкрддреНрдиреА рдХреЗ рдкрд╛рд╕ рд╣рдореЗрд╢рд╛ рдкрд░рд┐рдЪрд┐рдд рдкреНрд░рдмрдВрдзрди рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИ, рдЬреЛ рдореБрдЭреЗ рдЕрдкрдиреЗ рдкрд░рд┐рд╡рд╛рд░ рдореЗрдВ рд╢рд╛рдВрддрд┐ рдмрдирд╛рдП рд░рдЦрдиреЗ рдФрд░ рдореБрдЭреЗ рдЕрдкрдиреЗ рдкрд╕рдВрджреАрджрд╛ рд╢реМрдХ рдХреЛ рдЬрд╛рд░реА рд░рдЦрдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рджреЗрдЧрд╛ред

рд╡рд┐рдЪрд╛рд░


рдпрд╣ рд╡рд┐рдЪрд╛рд░ рд╕рд░рд▓ рд╣реИ: рджреЛ рд╕реНрдерд╛рдиреЛрдВ рд╕реЗ рдХреНрд▓рд╛рд╕рд┐рдХ рд╕реНрд╡рд┐рдЪрд┐рдВрдЧ рд╕рд░реНрдХрд┐рдЯ рдХрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ:



SA1 рд╕реНрд╡рд┐рдЪ KMTronic рд░рд┐рд▓реЗ рдЖрдЙрдЯрдкреБрдЯ (NO-C-NC) рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ, SA2 рд╕реНрд╡рд┐рдЪ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдШрд░реЗрд▓реВ рдПрдХрд▓-рдХреБрдВрдЬреА рд╕реНрд╡рд┐рдЪ рд╣реИред рд╕рдм рдХреБрдЫ рдареАрдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рдЪреЗрддрд╛рд╡рдиреА рд╣реИ - рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ рд▓реЛрдб рдХреА рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕реНрдерд┐рддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рд╣реИред рдЗрд╕рд╕реЗ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ - рдПрдХ рд▓реЛрдб рдХреЗ рд░реВрдк рдореЗрдВ рд╕рд░реНрдХрд┐рдЯ рдореЗрдВ рдПрдХ 24V рдХреЙрдЗрд▓ рдХреЗ рд╕рд╛рде рдПрдХ рдордзреНрдпрд╡рд░реНрддреА рд░рд┐рд▓реЗ рдпрд╛ рдХреЗрдПрдо рд╕рдВрдкрд░реНрдХрдХрд░реНрддрд╛ рдЬреЛрдбрд╝реЗрдВ:


рдЗрд╕рд▓рд┐рдП рд╣рдо рдПрдХ рдкрддреНрдерд░ рд╕реЗ рдХрдИ рдкрдХреНрд╖рд┐рдпреЛрдВ рдХреЛ рдорд╛рд░ рджреЗрдВрдЧреЗ:
  • рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд KM рд░рд┐рд▓реЗ рд╕рдВрдкрд░реНрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рдорд┐рд▓рддрд╛ рд╣реИ;
  • рд╣рдо рд╡рд┐рджреНрдпреБрдд рд╕реБрд░рдХреНрд╖рд╛ рдореЗрдВ рд╡реГрджреНрдзрд┐ рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЧреАрд▓реЗ рдХрдорд░реЛрдВ рдореЗрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ;
  • рд╣рдо KMTronic рд░рд┐рд▓реЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдП рдЧрдП рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рднрд╛рд░ рдХреЛ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдВрдЧреЗред

рдордзреНрдпрд╡рд░реНрддреА рд░рд┐рд▓реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдореБрдЭреЗ рдордЬрдмреВрд░ рдореИрдиреБрдЕрд▓ рдирд┐рдпрдВрддреНрд░рдг (OFF, AUTO, ON) рдХреЗ рд╕рд╛рде 24V рдкрд░ рд╣реИрдЧрд░ рдПрд░реНрдХреНрд╕рдПрдХреНрд╕рдПрдХреНрд╕рдПрдХреНрд╕рдПрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдкрд╕рдВрдж рд╣реИред



рдбрд┐рдмрдЧрд┐рдВрдЧ рдФрд░ рдЖрдЧреЗ рдХреЗ рдСрдкрд░реЗрд╢рди рдХреЗ рджреМрд░рд╛рди рдпрд╣ рд╡рд┐рдХрд▓реНрдк рдмрд╣реБрдд рдорджрдж рдХрд░рддрд╛ рд╣реИред

рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди


рд░рд╛рд╕реНрдкрдмреЗрд░реА рдкрд╛рдИ рдкрд░ рдХреЗрдореЛрдЯрд┐рдХ рдХреНрд░реЙрдирд┐рдХ рдпреВрдбреАрдкреА рд░рд┐рд▓реЗ рдХрдиреЗрдХреНрд╢рди рдбреЛрдореЛрдЯрд┐рдХреЛрдЬ рдХреЗ рд▓рд┐рдП



  • рдпреВрдбреАрдкреА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рдЬ рд╕реЗрдЯ рдХрд░реЗрдВ:

    sudo apt-get install socat
    

  • ~ / Domoticz / рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ, UDP рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ KMTronic рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдмрдирд╛рдПрдВред рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, rudp.sh:

    #!/bin/bash
    RelayIP="$1"
    RelayNumber="$2"
    Status=$(echo FF0000 | socat - udp-datagram:192.168.100.${RelayIP}:12345)
    StatusBit=${Status:RelayNumber-1:1}
    CommandON=FF0${RelayNumber}01
    CommandOFF=FF0${RelayNumber}00
    if [ "$StatusBit" = "1" ]; then
    echo ${CommandOFF} | socat - udp-datagram:192.168.100.${RelayIP}:12345
    else
    echo ${CommandON} | socat - udp-datagram:192.168.100.${RelayIP}:12345
    fi
    

  • рд╣рдо rudp.sh рдлрд╝рд╛рдЗрд▓ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдмрдирд╛рддреЗ рд╣реИрдВ:

    chmod +x rudp.sh
    

  • рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рд╕реЗ рдЬрд╛рдВрдЪреЗрдВ:

    rudp.sh 199 1
    


    рдЗрд╕ рдХрдорд╛рдВрдб рдХреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдкреЛрд░реНрдЯ 12345 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрддрд╛ 192.168.100.199 рдХреЗ рд╕рд╛рде KMTronic рдбрд┐рд╡рд╛рдЗрд╕ рдХреЗ рд░рд┐рд▓реЗ # 1 рдХреЛ рд╕реНрд╡рд┐рдЪ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

  • рдбреЛрдореЛрдЯрд┐рдХреЛрдЬрд╝ рдореЗрдВ, рдПрдХреНрд╢рди рдФрд░ рдСрдл рдПрдХреНрд╢рди рдлрд╝реАрд▓реНрдб рдореЗрдВ рдбрдореА рд╕реНрд╡рд┐рдЪ рдмрдирд╛рдПрдВ, рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ:

    script:///home/pi/domoticz/scripts/rudp.sh 199 1
    


    рдЕрдм, рдЬрдм рдЖрдк рд╕реНрд╡рд┐рдЪ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпреВрдбреАрдкреА рд░рд┐рд▓реЗ рд╕рдВрдкрд░реНрдХ рд╕реНрд╡рд┐рдЪ рдХрд░рддрд╛ рд╣реИред
    рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ, рд╣рдо рдореИрдиреБрдЕрд▓ рд╕реНрд╡рд┐рдЪ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓реЛрдб рдХреЛ рд╕реНрд╡рд┐рдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


Arduino рдкреНрд░реЛрдЯреЛрдХреЙрд▓ MQTT рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рднрд╛рд░ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдХрд╛ рд╕рдВрдЧреНрд░рд╣


  • рд╣рдо Arduino рдореЗрдВ MQTT рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдХреЗрдЪ рдореЗрдВ рднрд░рддреЗ рд╣реИрдВ (рдзреНрдпрд╛рди рджреЗрдВ, рд╕реНрдХреЗрдЪ рдореЗрдВ рдЖрдкрдХреЛ domoticz_Idx [рд╕рд░рдгреА] рдореЗрдВ рднрд░рдХрд░ Arduino рдирд┐рд╡рд┐рд╖реНрдЯрд┐рдпрд╛рдБ рдФрд░ рд╣рдорд╛рд░реЗ рдбрдореА рд╕реНрд╡рд┐рдЪ рдХреЗ Idx рд╕реВрдЪрдХрд╛рдВрдХ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
    рд╕реНрдХреЗрдЪ
    #include <SPI.h>
    #include <Ethernet.h>
    #include <Bounce2.h>
    #include <PubSubClient.h>
    
    byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
    byte server[] = { 192, 168, 100, 250};
    byte ip[]     = { 192, 168, 100, 199};
    
    // I/O ports on board, 20 for UNO and Leonardo (14 DI + 6 AI) 
    static const int ioPorts = 20; 
    
    // all pins                           0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19
    static const uint8_t arduinoPins[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,A0,A1,A2,A3,A4,A5};
    static const int availablePin[]    = {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1}; //  pins available for general I/O. 1 - available, 0 - not available
    static const int domoticz_Idx[]    = {5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //
    
    // Buffers for sending data
    char  statusBuffer[ioPorts+1] = "0";           
    char  prevStatusBuffer[ioPorts+1] = "0"; 
    
    // Instantiate a Bounce object
    Bounce debouncer[ioPorts] = Bounce();
    
    // Function headers
    void callback(char* topic, byte* payload, unsigned int length);
    char pinToChar(int value);
    int compareCharArrays(char  array1[ioPorts+1], char array2[ioPorts+1]);
    void readAllPins();
    void publishPins(boolean all);
    void setup();
    void loop();
    
    EthernetClient ethClient;
    PubSubClient clientMQTT(server, 1883, callback, ethClient);
    
    void callback(char* topic, byte* payload, unsigned int length) {
      byte* p = (byte*)malloc(length);
      memcpy(p,payload,length);
      publishPins(true); 
      free(p);
    }
    
    char pinToChar(int value) {
      char result = 'X';
      if (value==HIGH) {
        result = '0';  // if pin opened, send 0
      }  
      if (value==LOW) {
         result = '1';  // if pin closed to GND, send 1
      }   
      return result; 
    }
    
    int compareCharArrays(char  array1[ioPorts+1], char array2[ioPorts+1]) {
      int result = 0;
      for (int i =0; i <= (ioPorts); i++) {
        if (array1[i]!=array2[i]) {
          result = 1;
          break;
        }  
      }  
      return result;    
    }
    
    void readAllPins() {
      for (int i =0; i < (ioPorts); i++)
      {
        if (availablePin[i]) 
        {
          debouncer[i].update();
          statusBuffer[i] =  pinToChar(debouncer[i].read());
        }  
      }  
    }
    
    void publishPins(boolean all) {
      char topic[]="domoticz/in";
      String data;
      char jsonStr[200];
      for (int i =0; i < (ioPorts); i++)
      {
        if ((all) || (prevStatusBuffer[i]!=statusBuffer[i]))
        {
          if ((availablePin[i]) && (domoticz_Idx[i])) 
          {
            data="{\"idx\":";
            data+=(int)domoticz_Idx[i];
            data+=",\"nvalue\":";
            data+=(char)statusBuffer[i];
            data+="}";
            data.toCharArray(jsonStr,200);
            clientMQTT.publish(topic,jsonStr); 
            Serial.print(topic);
            Serial.print(" ");
            Serial.println(jsonStr);
          }
        }  
      }  
    }
    
    void setup() {  
      // initialize serial port over USB  
      Serial.begin(9600);
      
      Ethernet.begin(mac, ip);
      
      // initialize the digital pins as an input.
      for (int i =0; i < ioPorts; i++)
      {
        if (availablePin[i]) { 
          pinMode(i, INPUT_PULLUP);
          debouncer[i].attach(arduinoPins[i]);       // setup the Bounce instance
          debouncer[i].interval(100);   // interval in ms
        }  
        statusBuffer[i]='0';  
        prevStatusBuffer[i]='0'; 
      }
      statusBuffer[ioPorts]='\0';      // EOL
      prevStatusBuffer[ioPorts]='\0';  // EOL
    
      readAllPins();
      
      if (clientMQTT.connect("myhome-ino-id1")) {
        clientMQTT.subscribe("myhome/ino/id1/in/#");
        publishPins(true);
      }
    }
    
    void loop(){
      clientMQTT.loop();
      readAllPins();
      if (compareCharArrays(statusBuffer,prevStatusBuffer)==1)
      // time for send information to the server
      {
          if (!clientMQTT.connected()){
            if (clientMQTT.connect("myhome-ino-id1")) {
              clientMQTT.subscribe("myhome/ino/id1/in/#");
            }  
          } 
          
          if (clientMQTT.connected()) { 
            publishPins(false);
          }  
        
        for (int i =0; i < (ioPorts); i++) {
          prevStatusBuffer[i]=statusBuffer[i]; 
        }
      }    
    }
    


  • рд╣рдо Arduino рдХреЗ Gnd рдФрд░ DIxx рдХреЗ рд╕рдВрдкрд░реНрдХ рдореЗрдВ рдЕрдкрдиреЗ рдордзреНрдпрд╡рд░реНрддреА рд░рд┐рд▓реЗ рдХрд╛ рдПрдХ рдореБрдлреНрдд рд╕рдВрдкрд░реНрдХ рдХрдиреЗрдХреНрдЯ рдХрд░рддреЗ рд╣реИрдВред

  • рдбреЙрдореЛрдЯрд┐рдХрдЬрд╝ рдореЗрдВ рдПрдордХреНрдпреВрдЯреАрдЯреА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдордХреНрдпреВрдЯреАрдЯреАрд╡реЙрдХрд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВред

  • рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд▓реЛрдб рдХреЛ рдЪрд╛рд▓реВ рдФрд░ рдмрдВрдж рдХрд░реЗрдВ рдФрд░ рдбреЛрдореЛрдЯрд┐рдХрд┐рдЬрд╝ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ рд▓реЛрдб рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХрд╛ рдирд┐рд░реАрдХреНрд╖рдг рдХрд░реЗрдВред


рдЖрдкрдХреЗ рдзреНрдпрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдХреЛрдИ рдореЗрд░реЗ рдЕрдиреБрднрд╡ рдХреЛ рдЙрдкрдпреЛрдЧреА рдкрд╛рдПрдЧрд╛ред

Source: https://habr.com/ru/post/hi397621/


All Articles