Anschließen von Aquastorozh an Smart Home auf Z-Wave



Letztes Jahr habe ich GerĂ€te fĂŒr die Notabschaltung von KrĂ€nen gekauft, als ein Leck von Aquastorozh festgestellt wurde. Lange konnte ich es nicht ausdrĂŒcken. Es gab eine Idee, es in das Z-Wave-Netzwerk zu integrieren und ein Gidrolock-Analogon zu erhalten, aber an Batterien zu arbeiten. Endlich erreichten die HĂ€nde ...

Aquastorozh ist eine Basis mit SteckhĂ€hnen und Lecksensoren. Dieser Komplex kann sowohl von einem 220-V-Netzwerk ĂŒber einen Adapter als auch von Batterien aus betrieben werden. Die Entwickler haben die Möglichkeit bereitgestellt, eine Verbindung zu den Systemen von "Smart Home" herzustellen. Durch Schließen eines Kontaktpaares in einer Ethernet-Steckdose können Sie die Abgriffe öffnen und das andere schließen. Die Relaiskontakte schließen 1 Sekunde lang, wenn ein Leck festgestellt wird. Es gibt einen nicht gelöteten UART-Anschluss auf der Platine, aber in diesem Artikel werde ich ĂŒber die Implementierung dokumentierter Funktionen sprechen.

Entwicklungsaufgaben


  • Remote-Ein / Aus-Abgriffe.
  • Leckinformationen.
  • Zwei WasserzĂ€hler.
  • Unterbrechen Sie nicht die Arbeit von "Aquastorozh".

Beschlossen, auf der Grundlage des ZUNo-Schildes zu tun. Es wird in einem versiegelten GehĂ€use mit Druckdichtung geliefert, verfĂŒgt ĂŒber Klemmenblöcke an Bord und freien Platz fĂŒr die Installation der Batterie und zusĂ€tzlicher elektronischer Komponenten. Arduino ist Ă€hnlich.

Ethernet-Anschluss




Einer der abschließbaren DrĂ€hte ist die „Erde“ des „AquawĂ€chters“. Sie können die LĂ€nder von ZUNo und Aqua-Watch kombinieren und die Krane direkt ĂŒber den GPIO ZUNo steuern. Also habe ich es getan. Bei einem ZUNo-Fehler (z. B. wenn die Batterie leer ist) erhalten die Steuerleitungen „Aquastorozh“ eine „Null“ und beginnen zyklisch neu zu starten. Eine solche Anschlussoption wirkt sich stark auf die ZuverlĂ€ssigkeit des gesamten Systems aus. Da die Schaltung etwas kompliziert war, wechselte ich zu zwei Reed-Relais, die eine galvanische Trennung von Aquastorozh ermöglichten. Relais verbrauchen im eingeschalteten Zustand ca. 7 mA. Um die Krane zu schalten, mĂŒssen Sie ein Relais fĂŒr eine Sekunde einschalten, was durchaus akzeptabel ist. Die Batterieladung reichte fĂŒr mehrere tausend SchaltvorgĂ€nge. (Jetzt habe ich elektromagnetisch gepulste Single-Coil-Relais in meinen HĂ€nden. Um sie zu schalten, mĂŒssen Sie einen 1-ms-Impuls anlegen, der viel energieeffizienter ist. Zur Steuerung benötigen Sie jedoch 4 Transistoren und zwei Eingangs- / Ausgangszweige fĂŒr das Relais.)

Schlaf in Z-Welle


Ich werde ein wenig darĂŒber sprechen, wie Z-Wave-GerĂ€te schlafen und ĂŒber das daraus resultierende Problem.
Z-Wellen-GerĂ€te können inaktiv sein oder hĂ€ufig aufwachen. Das SchlafgerĂ€t ist am energieeffizientesten, es kann jedoch kein Befehl gesendet werden (in meinem Fall zum Wechseln der KrĂ€ne). Der zweite Typ passt zu mir. FLiRS-GerĂ€t - Routing-Slaves hĂ€ufig abhören. Ein fĂŒr diesen Betriebsmodus konfiguriertes GerĂ€t wacht jede Sekunde auf und schlĂ€ft ein, wenn es fĂŒr kurze Zeit kein Signal zum vollstĂ€ndigen Aufwachen von der Steuerung empfĂ€ngt. Zum Beispiel: Ich sende einen Befehl zum Öffnen von KrĂ€nen. Der Controller versteht, dass mein GerĂ€t hĂ€ufig zuhört, und sendet innerhalb einer Sekunde ein spezielles kurzes Paket (Wakeup Beam), damit alle FLIRS-GerĂ€te im Netzwerk aufwachen. Sobald mein GerĂ€t dieses Paket akzeptiert, sendet es einen Bericht, dass es aufgeweckt wurde und bereit ist, den Befehl anzunehmen. Ruft einen Befehl zum Schließen der WasserhĂ€hne ab. Wieder einschlafen. Und so jedes Mal, wenn das GerĂ€t gesteuert wird. Der Nachteil ist, dass das GerĂ€t sowohl am Ende der Sendung durch die Steuerung als auch am Anfang einen Weckstrahl empfangen kann. Der Controller sendet es fĂŒr etwa eine Sekunde. Im schlimmsten Fall wacht das GerĂ€t zu Beginn dieses Newsletters auf und wartet fast eine Sekunde, bis ein Befehl eintrifft. Da das Öffnen und Schließen von WasserhĂ€hnen jedoch hĂ€ufig nicht erforderlich ist, ist dies kein schwerwiegender Nachteil.

Implementierung


ZUNo Shield hat ein kleines Steckbrett, auf dem Sie die erforderlichen Komponenten platzieren können.



Die Schaltung enthÀlt zwei Relais und zwei Transistoren zur Steuerung. Eine einfache kleine Skizze.



Ein paar Worte zum Energieverbrauch.

Die ZUNo-Abschirmung enthĂ€lt einen Treiberchip fĂŒr das RS-485-Protokoll und einen Pull-up-Widerstand fĂŒr Pin "11" am unteren Block fĂŒr das One-Wire-Protokoll. Nach dem Entfernen dieser Komponenten bleibt der Hauptverbraucher ZUNo.



Der Verbrauch im Schlafmodus betrĂ€gt ca. 5-10 ÎŒA und im aktiven Modus bis zu 60 mA (das Relais ist aktiv und ZUNa sendet).

Oszillogramme der Stromaufnahme fĂŒr verschiedene Betriebsarten


Die Richtung der aktuellen Achse ist von oben nach unten.

Das GerÀt wartet auf einen Befehl:



UngefĂ€hr jede Sekunde sind kurze Spitzen sichtbar, wĂ€hrend der das GerĂ€t aufwacht und prĂŒft, ob der WakeUp-Strahl angekommen ist.

Das GerÀt hat den folgenden Befehl erhalten:



Zuerst wachte das GerĂ€t auf, erhielt einen WakeUp-Strahl und wartete auf einen Befehl (von 0 bis 1 Sekunde). Wenn der Befehl zur Steuerung der Krane verwendet wird, schaltet es das entsprechende Relais fĂŒr 1 Sekunde ein (in diesem Stadium mĂŒssen Sie den Controller in den Ruhezustand versetzen, wĂ€hrend Sie die Beine im aktuellen Zustand halten, aber ich Ich hatte Angst und war zu faul) und der Rest der Zeit wird fĂŒr den internen Betrieb des Chips aufgewendet, wonach ZUNo einschlĂ€ft. Insgesamt fast 3,5 Sekunden pro Vorgang des Öffnens oder Schließens durch Tippen. Eine schrecklich lange Zeit, aber aufgrund der Tatsache, dass solche Operationen Ă€ußerst selten ausgefĂŒhrt werden, kann die Optimierung vernachlĂ€ssigt werden. Ja, und es wird wenig geben, denn die Skizze in der Arduino-Idee ist nur ein kleiner Teil dessen, was in diesem kleinen Mikrocontroller geworfen und gedreht wird und was der Hersteller vor Neugierigen sicher verbirgt.

Verbindungsschema zu "Aquastorozh"




Fazit


Es stellte sich heraus, dass „Aquastorozh“ ziemlich genau zum bestehenden Z-Wave-Netzwerk hinzugefĂŒgt wurde. Der Hauptnachteil ist das fehlende Feedback von Aquastorozh. Derzeit warte ich auf eine neue Version der ZUNo-Bibliothek, in der ein Fehler behoben wird, der verhindert, dass ZUNo normal schlĂ€ft. Anstelle eines Fotos mit installiertem und verbundenem Aquastorozh wird daher ein Bild mit dem Debugging-Vorgang angezeigt.



Vielen Dank fĂŒr Ihre Aufmerksamkeit!

Skizze
//#define _DEBUG #define OPEN_PIN 11 #define CLOSE_PIN 12 #define LEAK_PIN 19 #define INT1 18 uint8_t valve_action = 0; #ifdef _DEBUG uint8_t const METER1_PIN = 8; #else uint8_t const METER1_PIN = 7; #endif #define METER2_PIN 8 #include "EEPROM.h" #define MAGIC_VALUE 42 #define ADDR_ACTION 1 #define CH_METER_1 4 #define CH_METER_2 8 #define CNT_ON_OFF_CICL 12 // Global variables byte pin7SwitchBinaryState = 0; DWORD eeprom_buf = 0; #define LEAK_CHANNEL 3 DWORD meter_cnt1; DWORD meter_cnt2; #define ADR_MET1 4 #define ADR_MET2 5 uint8_t alarm_clr = LOW; // Z-Wave channels ZUNO_SETUP_CHANNELS( ZUNO_SWITCH_BINARY(pin7SwitchBinaryGetter, pin7SwitchBinarySetter), ZUNO_SWITCH_BINARY(alarmGetter, alarmSetter), ZUNO_SENSOR_BINARY(ZUNO_SENSOR_BINARY_TYPE_WATER, getterSensorBinary), ZUNO_METER(ZUNO_METER_TYPE_WATER, METER_RESET_ENABLE , ZUNO_METER_WATER_SCALE_PULSECOUNT, 4, 0, getterMETER1, resetterMETER1), ZUNO_METER(ZUNO_METER_TYPE_WATER, METER_RESET_ENABLE , ZUNO_METER_WATER_SCALE_PULSECOUNT, 4, 0, getterMETER2, resetterMETER2) ); ZUNO_SETUP_BATTERY_LEVELS(2700, 3300); ZUNO_SETUP_SLEEPING_MODE(ZUNO_SLEEPING_MODE_FREQUENTLY_AWAKE); void close_water() { #ifdef _DEBUG Serial1.println("close"); #endif digitalWrite(CLOSE_PIN, HIGH); delay(1000); digitalWrite(CLOSE_PIN, LOW); //delay(1000); } void open_water() { #ifdef _DEBUG Serial1.println("open"); #endif digitalWrite(OPEN_PIN, HIGH); delay(1000); digitalWrite(OPEN_PIN, LOW); //delay(1000); } #define LEAK_DETECTED LOW #define LEAK_END HIGH #define ADDR_LEAK_ST_LAST 2 #define ADR_B1_F 3 #define ADR_B2_F 4 #define NZ_ADR_LEAK 5 uint8_t last_leak_st; #define EEPROM_MAGIC 0x11223342 #define EEPROM_ADR_MAGIC 0 void setup() { #ifdef _DEBUG Serial1.begin(9600); Serial1.println("serial init"); #else pinMode(METER1_PIN, INPUT); pinMode(METER2_PIN, INPUT); #endif pinMode(CLOSE_PIN, OUTPUT); pinMode(OPEN_PIN, OUTPUT); pinMode(LEAK_PIN, INPUT_PULLUP); pinMode(INT1, INPUT_PULLUP); digitalWrite(CLOSE_PIN, LOW); digitalWrite(OPEN_PIN, LOW); byte n; NZRAM.get(0x0, &n, 1); if (n == MAGIC_VALUE) { // correct magic value after wake up from sleep mode // trust NZRAM data } else { // incorrect magic, first boot after battery insert ot rebooted due to low battery // initialize NZRAM magic n = MAGIC_VALUE; NZRAM.put(0x0, &n, 1); NZRAM.write(ADDR_ACTION, LOW); NZRAM.write(ADDR_LEAK_ST_LAST, LEAK_END); NZRAM.write(ADR_B1_F, HIGH); NZRAM.write(ADR_B2_F, HIGH); } EEPROM.get(EEPROM_ADR_MAGIC, &eeprom_buf, sizeof(DWORD)); if(eeprom_buf != EEPROM_MAGIC) { eeprom_buf = EEPROM_MAGIC; EEPROM.put(EEPROM_ADR_MAGIC, &eeprom_buf, sizeof(DWORD)); resetterMETER1(); resetterMETER2(); eeprom_buf = 0; EEPROM.put(CNT_ON_OFF_CICL, &eeprom_buf, sizeof(DWORD)); } } uint8_t last_btn_st; void check_btn(uint8_t meter_pin, uint8_t NZ_adr_st) { last_btn_st = NZRAM.read(NZ_adr_st); if(digitalRead(meter_pin) == LOW) { if(last_btn_st != LOW) { for(uint8_t i=0; i<3; ++i) { if(digitalRead(meter_pin) == LOW) delay(5); else return; } last_btn_st = LOW; NZRAM.write(NZ_adr_st, last_btn_st); } } else { if(last_btn_st == LOW) { for(uint8_t i=0; i<3; ++i) { if(digitalRead(meter_pin) == HIGH) delay(5); else return; } last_btn_st = HIGH; NZRAM.write(NZ_adr_st, last_btn_st); if(NZ_adr_st == ADR_B1_F) inc_met(ADR_MET1); else inc_met(ADR_MET2); } } } //=----------------------------------------------------------- void loop() { if(digitalRead(LEAK_PIN) == LEAK_DETECTED) { if(NZRAM.read(ADDR_LEAK_ST_LAST) != LEAK_END) { zunoSendReport(LEAK_CHANNEL); NZRAM.write(ADDR_LEAK_ST_LAST, LEAK_END); } } check_btn(METER1_PIN, ADR_B1_F); check_btn(METER2_PIN, ADR_B2_F); if(zunoGetWakeReason() == ZUNO_WAKEUP_REASON_RADIO) { uint32_t start_time=0; #define ACTION_T_OUT 2000 start_time = millis(); //while(NZRAM.read(ADDR_ACTION)== 0) while(valve_action== 0) if((millis() - start_time) >= ACTION_T_OUT) { #ifdef _DEBUG Serial1.println("T_OUT"); #endif break; } else delay(50); #ifdef _DEBUG Serial1.println(millis() - start_time); #endif if(NZRAM.read(ADDR_ACTION)) { valve_action = 0; NZRAM.write(ADDR_ACTION, LOW); if(pin7SwitchBinaryState == LOW) close_water(); else open_water(); } if(alarm_clr) //      { alarm_clr == LOW; zunoSendReport(LEAK_CHANNEL); } } if(digitalRead(INT1)==0) { zunoSetWUOptions(ZUNO_WUPFLAGS_INT1_HIGH); } else { zunoSetWUOptions(ZUNO_WUPFLAGS_INT1_LOW); } zunoSendDeviceToSleep(); } //----------------------------------------------------------- // Getters and setters void inc_met(uint8_t num_chennel) { uint8_t eeprom_adr_met; if(num_chennel == ADR_MET1) eeprom_adr_met = CH_METER_1; else eeprom_adr_met = CH_METER_2; EEPROM.get(eeprom_adr_met, &eeprom_buf, sizeof(DWORD)); eeprom_buf++; EEPROM.put(eeprom_adr_met, &eeprom_buf, sizeof(DWORD)); zunoSendReport(num_chennel); } DWORD getterMETER1() { EEPROM.get(CH_METER_1, &eeprom_buf, sizeof(DWORD)); return eeprom_buf; } DWORD getterMETER2() { EEPROM.get(CH_METER_2, &eeprom_buf, sizeof(DWORD)); return eeprom_buf; } void resetterMETER1() { eeprom_buf = 0; EEPROM.put(CH_METER_1, &eeprom_buf, sizeof(DWORD)); } void resetterMETER2() { eeprom_buf = 0; EEPROM.put(CH_METER_2, &eeprom_buf, sizeof(DWORD)); } void pin7SwitchBinarySetter(byte value) { valve_action = 1; NZRAM.write(ADDR_ACTION, HIGH); pin7SwitchBinaryState = value; if(value == 255) // if open valve, then off leak alarm { NZRAM.write(ADDR_LEAK_ST_LAST, LOW); zunoSendReport(LEAK_CHANNEL); } } byte pin7SwitchBinaryGetter() { return pin7SwitchBinaryState ? 0xFF : 0; } byte getterSensorBinary() { return digitalRead(LEAK_PIN) ? 0 : 0xFF; } byte alarmGetter() { uint8_t ret; ret = NZRAM.read(ADDR_LEAK_ST_LAST); return ret ? 0xFF : 0; } void alarmSetter(byte value) { alarm_clr = HIGH; NZRAM.write(ADDR_LEAK_ST_LAST, value); } 

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


All Articles