load('api_config.js'); load('api_events.js'); load('api_gpio.js'); load('api_http.js'); load('api_net.js'); load('api_sys.js'); load('api_timer.js'); load('api_esp32.js'); load('api_dht.js'); load('api_adc.js'); load('api_rpc.js'); load('api_mqtt.js'); let esp_sleep_enable_ext0_wakeup = ffi("void esp_sleep_enable_ext0_wakeup(int, int)"); // (GpioPin, 0=LOW, 1=HIGH) // Pins let resetPin = 0; let statusLightPin = 16; let dhtPin = 22; let moisturePin = 32; // Turn on status led GPIO.set_mode(statusLightPin, GPIO.MODE_OUTPUT); GPIO.write(statusLightPin, 0); // Reset Handler GPIO.set_mode(resetPin, GPIO.MODE_INPUT); GPIO.set_int_handler(resetPin, GPIO.INT_EDGE_NEG, function(resetPin) { print('Pin', resetPin, 'got interrupt'); for (let i=0; i<=5; i++) { GPIO.toggle(statusLightPin); Sys.usleep(200000); } GPIO.write(statusLightPin, 1); // enable bluetooth Cfg.set({bt:{enable:true}}); // disable wifi Cfg.set({wifi:{sta:{enable:true}}}); Cfg.set({wifi:{ap:{enable:false}}}); // clear wifi-config // Cfg.set({wifi:{sta:{ssid:'',pass:''}}}); Sys.reboot(1000); }, null); print("Starting..."); GPIO.enable_int(resetPin); ADC.enable(moisturePin); let dht = DHT.create(dhtPin, DHT.DHT11); let deviceId = Cfg.get("device.id"); if (deviceId === "") { deviceId = Cfg.get("higrow.deviceId"); Cfg.set("device.id", deviceId); } let mqttTopic = deviceId + '/sample'; let mqttPowerOnTopic = deviceId + '/poweron'; let sendMqtt = Cfg.get("higrow.send_mqtt"); let sendHttp = Cfg.get("higrow.send_http"); let sendHttpUrl = Cfg.get("higrow.send_http_url"); print("HTTP: ", sendHttp, "URL:", sendHttpUrl); print("MQTT:", sendMqtt, "Topic:", mqttTopic, "PowerOn Topic:", mqttPowerOnTopic); let netConnected = false; let mqttConnected = false; let sampleTime_ms = Cfg.get("higrow.sample_time") * 1000; let httpReadyForDeepSleep = false; let mqttReadyForDeepSleep = false; let lastActionBeforeSleep = Sys.uptime(); // tracked to be able to wait some time after last action to be sure it is completed let waitAfterLastActionBeforeSleep = Cfg.get("higrow.wait_after_last_action_before_sleep"); esp_sleep_enable_ext0_wakeup(resetPin, 0); function enterDeepSleepMode() { print("Entering deep sleep mode for", sampleTime_ms/1000, "seconds"); ESP32.deepSleep(sampleTime_ms * 1000); // never reaches this here, except for a couple of milliseconds Sys.usleep(300000); // 300ms print("DID NOT ENTER DEEP SLEEP!"); } let readSensors = Timer.set(/*sampleTime_ms*/ 1000, Timer.REPEAT, function() { if ((!sendHttp || (sendHttp && httpReadyForDeepSleep)) && (!sendMqtt || (sendMqtt && mqttReadyForDeepSleep))) { if (Sys.uptime() > lastActionBeforeSleep + waitAfterLastActionBeforeSleep) { enterDeepSleepMode(); } print("wait after last action before deep sleep"); return; // do nothing for some time, but RPC still is available } let t = dht.getTemp(); let h = dht.getHumidity(); let m = ADC.read(moisturePin); print("DeviceId:", deviceId, "Temperature:", t, "Humidity:", h, "Moisture:", m, "DeepSleep:", httpReadyForDeepSleep, "/", mqttReadyForDeepSleep); if (deviceId !== "" && (!sendHttp || (sendHttp && netConnected)) && (!sendMqtt || (sendMqtt && mqttConnected))) { GPIO.write(statusLightPin, 0); let jsonData = {'DeviceId': deviceId, 'Temperature': t, 'Humidity': h, 'Moisture': m}; if (sendHttp) { HTTP.query({ headers: {'Content-Type' : 'application/json'}, url: sendHttpUrl, data: jsonData, success: function(body, full_http_msg) { print(body); httpReadyForDeepSleep = true; lastActionBeforeSleep = Sys.uptime(); }, error: function(err) { print("ERROR!", err); httpReadyForDeepSleep = true; lastActionBeforeSleep = Sys.uptime(); }, }); print("Sent HTTP message: ", jsonData); } if (sendMqtt) { let jsonDataString = JSON.stringify(jsonData); // print("Try to send MQTT message: ", jsonDataString, "To:", mqttTopic); MQTT.pub(mqttTopic, jsonDataString, 1, true); mqttReadyForDeepSleep = true; lastActionBeforeSleep = Sys.uptime(); } GPIO.write(statusLightPin, 1); //Timer.del(readSensors); } else { print("DeviceId:", deviceId, "Net-Con:", netConnected, "MQTT-Con:", mqttConnected); GPIO.write(statusLightPin, 1); } }, null); // RPC Handlers RPC.addHandler('HG.Temp.Read', function(args){ lastActionBeforeSleep = Sys.uptime(); return { value: dht.getTemp() }; }); RPC.addHandler('HG.Humidity.Read', function(args){ lastActionBeforeSleep = Sys.uptime(); return { value: dht.getHumidity() }; }); RPC.addHandler('HG.Moisture.Read', function(args){ lastActionBeforeSleep = Sys.uptime(); return { value: ADC.read(moisturePin) }; }); RPC.addHandler('HG.StatusLED.Read', function(args){ lastActionBeforeSleep = Sys.uptime(); return { value: GPIO.read(statusLightPin) }; }); RPC.addHandler('HG.StatusLED.On', function(args){ lastActionBeforeSleep = Sys.uptime(); GPIO.write(statusLightPin, 0); print("LED On"); if (GPIO.read(statusLightPin) !== 0) { return false; } return true; }); RPC.addHandler('HG.StatusLED.Off', function(args){ lastActionBeforeSleep = Sys.uptime(); GPIO.write(statusLightPin, 1); if (GPIO.read(statusLightPin) !== 1) { return false; } return true; }); // Monitor network connectivity. Event.addGroupHandler(Net.EVENT_GRP, function(ev, evdata, arg) { let status = true && netConnected; let evs = '???'; if (ev === Net.STATUS_DISCONNECTED) { evs = 'DISCONNECTED'; netConnected = false; } else if (ev === Net.STATUS_CONNECTING) { evs = 'CONNECTING'; netConnected = false; } else if (ev === Net.STATUS_CONNECTED) { evs = 'CONNECTED'; netConnected = false; } else if (ev === Net.STATUS_GOT_IP) { evs = 'GOT_IP'; netConnected = true; } print(evs); }, null); let publishedMessageCount = 0; let subscribedMessageCount = 0; // Monitor MQTT connectivity. MQTT.setEventHandler(function(conn, ev, evdata) { let mqttStatus = '???'; if (ev === MQTT.EV_CONNACK) { mqttStatus = 'CONNECTED'; if (!mqttConnected) { MQTT.pub(mqttPowerOnTopic, "HiGrow sensor booted", 1, true); } mqttConnected = true; } else if (ev === MQTT.EV_PUBLISH) { lastActionBeforeSleep = Sys.uptime(); subscribedMessageCount++; } else if (ev === MQTT.EV_PUBACK) { publishedMessageCount++; } else if (ev === MQTT.EV_CLOSE) { mqttStatus = 'DISCONNECTED'; netConnected = false; } if (mqttStatus !== '???') { print("MQTT-Status:", mqttStatus, "Msg-Sub:", subscribedMessageCount, "Msg-Pub:", publishedMessageCount); } }, null);