Electric IMP小惡魔,除了可以在ElectricIMP的網頁上進行coding與上傳資料,我們還能在agent code pane(代理人程式碼區),撰寫程式碼,將我們感測到的溫度數字上傳到一般網頁中。
如果想深入了解IMP小惡魔可以看下列幾篇文章
認識 Electric Imp 線上開發環境、環境建置與 BlinkUp app、溫濕度感應計
在執行程式之後,在agent code pane(代理人程式碼區),點選這個device(裝置)專用的網址,我們不僅可以將IMP的數值顯示在開發網頁中,IMP也可以將數值呈現在一個獨立的頁面
IMP的程式是以C語言、JAVESCRIPT與HTML的語法為基礎做撰寫,要達成下列效果,必須下列使用IMP專屬的函式,將agent code pane(代理人程式碼區)、device code pane(裝置程式碼區)之間做連結,進行資料傳遞。
我們在device code pane(裝置程式碼區)使用agent.on(string, function)、agent.send(string, object)這兩個函式,裝置接險與程式碼可以參考這篇溫濕度感應計,文章最下方有附device code pane的完整程式碼,主要傳遞訊息的部分在176-213行,讓我們先直接看這個部分。
1、我們使用agent.on(“pong”, returnFromImp)等待從agent code pane(代理人程式碼區)傳來的識別資訊”pong”,並將資訊的數值傳送到副函式returnFromImp之中。
2、將溫度感應器的溫度數值藉由agent.send(“ping”, data_temp)函式,將一個識別資訊”ping”,以及想要傳送的溫度資訊data_temp,傳送至agent code pane(代理人程式碼區)
[pastacode lang=”javascript” message=”” highlight=”” provider=”manual” manual=”function%20loop()%20%7B%0A%20%20%20%20imp.wakeup(INTERVAL%2C%20loop)%3B%0A%20%20%20%20local%20data%20%3D%20dht11.read()%3B%0A%20%20%20%20local%20data_hum%2Cdata_temp%3B%0A%20%20%20%20server.log(%22Running%20%22%2Bimp.getsoftwareversion()%2B%22%2C%20Free%20Memory%3A%20%22%2Bimp.getmemoryfree())%3B%0A%20%20%20%20data_hum%3D%20data.rh%3B%0A%20%20%20%20server.log(format(%22Relative%20Humidity%3A%20%250.1f%22%2Cdata_hum)%2B%22%20%25%22)%3B%0A%20%20%20%20%2F%2Fserver.log(format(%22Relative%20Humidity%3A%20%250.1f%22%2Cdata.rh)%2B%22%20%25%22)%3B%0A%20%20%20%20data_temp%3D%20data.temp%3B%0A%20%20%20%20server.log(format(%22Temperature%3A%20%250.1f%20C%22%2Cdata_temp))%3B%0A%20%20%20%20%2F%2Fserver.log(format(%22Temperature%3A%20%250.1f%20C%22%2Cdata.temp))%3B%0A%20%20%20%20ping(data_temp)%3B%0A%7D%0A%0Aspi%20%20%20%20%20%20%20%20%20%3C-%20hardware.spi257%3B%0Aclkspeed%20%20%20%20%3C-%20spi.configure(MSB_FIRST%2C%20SPICLK)%3B%0A%0Adht11%20%3C-%20DHT11(spi%2C%20clkspeed)%3B%0A%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%0Afunction%20ping(data_temp)%20%0A%7B%0A%20%20%20%20%2F%2F%20Send%20a%20’ping’%20message%20to%20the%20server%20with%20the%20current%20millis%20counter%0A%20%20%20%20%0A%20%20%20%20agent.send(%22ping%22%2C%20data_temp)%3B%0A%7D%0A%0Afunction%20returnFromImp(startMillis)%0A%7B%0A%7D%0A%0Aagent.on(%22pong%22%2C%20returnFromImp)%3B%0A%20%0A%2F%2F%20Start%20the%20ping-pong%0A%0A%2F%2Fping()%3B%0A%0A%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%0Aloop()%3B”/]
接著在agent code pane(代理人程式碼區)使用device.on(string, function)、http.onrequest(function)這兩個函式,
1、使用device.on(“ping”, startTime)函式等待從device code pane(裝置程式碼區)傳來的識別資訊”ping”並將溫度資訊data_temp傳送至副函式startTime
2、副函式startTime會先在網頁下方的 log pane(記錄區)顯示一次接收到的溫度數值
3、http.onrequest(requestHandler)會更新這個裝置專屬網頁的內容,每當我們對網頁進行重新整理,http.onrequest(requestHandler),便會到副函式requestHandler抓取最新數值response.send(200, format(“Temperature: %0.1f C”,global_data_temp));
agent code pane(代理人程式碼區)的完整程式碼
[pastacode lang=”javascript” message=”” highlight=”” provider=”manual” manual=”global_data_temp%20%3C-%2045.5%3B%0Aglobal_data_hum%20%3C-%2045.5%3B%0A%0Afunction%20startTime(data_temp)%0A%7B%0A%20%20%20%20server.log(format(%22agent%20Temperature%3A%20%250.1f%20C%22%2Cdata_temp))%3B%0A%20%20%20%20server.log(data_temp)%3B%0A%20%20%20%20%0A%20%20%20%20global_data_temp%20%3D%20data_temp%3B%0A%20%20%20%20%2F%2F%20Send%20the%20device%20a%20’pong’%20message%20immediately%0A%20%20%20%20%2F%2Fdevice.send(%22pong%22%2C%20time)%3B%0A%7D%0A%0A%0Afunction%20requestHandler(request%2C%20response)%20%7B%0A%20%20%2F%2F%20send%20a%20response%20back%20to%20whoever%20made%20the%20request%0A%20%20server.log(%22http%20refresh%22)%3B%0A%20%20response.send(200%2C%20format(%22Temperature%3A%20%250.1f%20C%22%2Cglobal_data_temp))%3B%0A%20%20%2F%2Fresponse.send(200%2C%20%22LED%20OK%20%22)%3B%0A%7D%0Ahttp.onrequest(requestHandler)%3B%0A%0A%0Adevice.on(%22ping%22%2C%20startTime)%3B”/]
device code pane(裝置程式碼區)的完整程式碼
[pastacode lang=”javascript” message=”” highlight=”” provider=”manual” manual=”%0A%2F%2F%20Copyright%20(c)%202014%20Electric%20Imp%0A%2F%2F%20This%20file%20is%20licensed%20under%20the%20MIT%20License%0A%2F%2F%20http%3A%2F%2Fopensource.org%2Flicenses%2FMIT%0A%2F%2F%20Class%20for%20DHT11%2FRHT03%20Temp%2FHumidity%20Sensor%0A%0Aconst%20SPICLK%20%3D%20937.5%3B%0Aconst%20INTERVAL%20%3D%205%3B%20%2F%2F%20time%20between%20readings%20in%20seconds%0A%0A%0A%2F%2F%20Class%20to%20read%20the%20DHT11%2FDHT22%20family%20of%20temperature%2Fhumidity%20sensors%0A%2F%2F%20See%20http%3A%2F%2Fakizukidenshi.com%2Fdownload%2Fds%2Faosong%2FDHT11.pdf%0A%2F%2F%20These%20sensors%20us%20a%20proprietary%20one-wire%20protocol.%20The%20imp%0A%2F%2F%20emulates%20this%20protocol%20with%20SPI.%20%0A%2F%2F%20To%20use%3A%0A%2F%2F%20%20-%20tie%20MOSI%20to%20MISO%20with%20a%2010k%20resistor%0A%2F%2F%20%20-%20tie%20MISO%20to%20the%20data%20line%20on%20the%20sensor%0Aclass%20DHT11%20%7B%0A%20%20%20%20static%20STARTTIME_LOW%20%20%20%20%20%3D%200.020000%3B%20%20%20%20%2F%2F%2020%20ms%20low%20time%20for%20start%0A%20%20%20%20static%20STARTTIME_HIGH%20%20%20%20%3D%200.000020%3B%20%20%2F%2F%2020%20us%20min%20high%20time%20for%20start%0A%20%20%20%20static%20STARTTIME_SENSOR%20%20%3D%200.000080%3B%20%20%2F%2F%2080%20us%20low%20%2F%2080%20us%20high%20%22ACK%22%20from%20sensor%20on%20START%0A%20%20%20%20static%20MARKTIME%20%20%20%20%20%20%20%20%20%20%3D%200.000050%3B%20%20%2F%2F%2050%20us%20low%20pulse%20between%200%20or%201%20marks%0A%20%20%20%20static%20ZERO%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%200.000026%3B%20%2F%2F%2026%20us%20high%20for%20%220%22%0A%20%20%20%20static%20ONE%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%200.000075%3B%20%20%2F%2F%2070%20us%20high%20for%20%221%22%0A%20%20%20%20%0A%20%20%20%20_spi%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20null%3B%0A%20%20%20%20_clkspeed%20%20%20%20%20%20%20%20%20%20%20%20%3D%20null%3B%0A%20%20%20%20_bittime%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20null%3B%0A%20%20%20%20_bytetime%20%20%20%20%20%20%20%20%20%20%20%20%3D%20null%3B%0A%20%20%20%20_start_low_bits%20%20%20%20%20%20%3D%20null%3B%0A%20%20%20%20_start_low_bytes%20%20%20%20%20%3D%20null%3B%0A%20%20%20%20_start_high_bits%20%20%20%20%20%3D%20null%3B%0A%20%20%20%20_start_high_bytes%20%20%20%20%3D%20null%3B%0A%20%20%20%20_start_ack_bits%20%20%20%20%20%20%3D%20null%3B%0A%20%20%20%20_start_ack_bytes%20%20%20%20%20%3D%20null%3B%0A%20%20%20%20_mark_bits%20%20%20%20%20%20%20%20%20%20%20%3D%20null%3B%0A%20%20%20%20_mark_bytes%20%20%20%20%20%20%20%20%20%20%3D%20null%3B%0A%20%20%20%20_zero_bits%20%20%20%20%20%20%20%20%20%20%20%3D%20null%3B%0A%20%20%20%20_zero_bytes%20%20%20%20%20%20%20%20%20%20%3D%20null%3B%0A%20%20%20%20_one_bits%20%20%20%20%20%20%20%20%20%20%20%20%3D%20null%3B%0A%20%20%20%20_one_bytes%20%20%20%20%20%20%20%20%20%20%20%3D%20null%3B%0A%20%20%20%20%0A%20%20%20%20%2F%2F%20class%20constructor%0A%20%20%20%20%2F%2F%20Input%3A%20%0A%20%20%20%20%2F%2F%20%20%20%20%20%20_spi%3A%20a%20pre-configured%20SPI%20peripheral%20(e.g.%20spi257)%0A%20%20%20%20%2F%2F%20%20%20%20%20%20_clkspeed%3A%20the%20speed%20the%20SPI%20has%20been%20configured%20to%20run%20at%0A%20%20%20%20%2F%2F%20Return%3A%20(None)%0A%20%20%20%20constructor(spi%2C%20clkspeed)%20%7B%0A%20%20%20%20%20%20%20%20_spi%20%3D%20spi%3B%0A%20%20%20%20%20%20%20%20_clkspeed%20%3D%20clkspeed%3B%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20_bittime%20%20%20%20%20%3D%201.0%20%2F%20(_clkspeed%20*%201000)%3B%0A%20%20%20%20%20%20%20%20_bytetime%20%20%20%20%3D%208.0%20*%20_bittime%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20_start_low_bits%20%20%20%20%20%20%3D%20STARTTIME_LOW%20%2F%20_bittime%3B%0A%20%20%20%20%20%20%20%20_start_low_bytes%20%20%20%20%20%3D%20(_start_low_bits%20%2F%208)%3B%0A%20%20%20%20%20%20%20%20_start_high_bits%20%20%20%20%20%3D%20STARTTIME_HIGH%20%2F%20_bittime%3B%0A%20%20%20%20%20%20%20%20_start_high_bytes%20%20%20%20%3D%20(_start_high_bits%20%2F%208)%3B%0A%20%20%20%20%20%20%20%20_start_ack_bits%20%20%20%20%20%20%3D%20STARTTIME_SENSOR%20%2F%20_bittime%3B%0A%20%20%20%20%20%20%20%20_start_ack_bytes%20%20%20%20%20%3D%20(_start_ack_bits%20%2F%208)%3B%0A%20%20%20%20%20%20%20%20_mark_bits%20%20%20%20%20%20%20%20%20%20%20%3D%20MARKTIME%20%2F%20_bittime%3B%0A%20%20%20%20%20%20%20%20_mark_bytes%20%20%20%20%20%20%20%20%20%20%3D%20(_mark_bits%20%2F%208)%3B%0A%20%20%20%20%20%20%20%20_zero_bits%20%20%20%20%20%20%20%20%20%20%20%3D%20ZERO%20%2F%20_bittime%3B%0A%20%20%20%20%20%20%20%20_zero_bytes%20%20%20%20%20%20%20%20%20%20%3D%20(_zero_bits%20%2F%208)%3B%0A%20%20%20%20%20%20%20%20_one_bits%20%20%20%20%20%20%20%20%20%20%20%20%3D%20ONE%20%2F%20_bittime%3B%0A%20%20%20%20%20%20%20%20_one_bytes%20%20%20%20%20%20%20%20%20%20%20%3D%20(_one_bits%20%2F%208)%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%2F%2F%20%2F%2F%20Pull%20the%20signal%20line%20up%0A%20%20%20%20%20%20%20%20_spi.writeread(%22%5Cxff%22)%3B%0A%20%20%20%20%20%20%20%20imp.sleep(STARTTIME_LOW)%3B%0A%20%20%20%20%7D%0A%20%20%20%20%0A%20%20%20%20%2F%2F%20helper%20function%0A%20%20%20%20%2F%2F%20given%20a%20long%20blob%2C%20find%20times%20between%20transitions%20and%20parse%20to%20%0A%20%20%20%20%2F%2F%20temp%20and%20humidity%20values.%20Assumes%2040-bit%20return%20value%20(16%20humidity%20%2F%2016%20temp%20%2F%208%20checksum)%0A%20%20%20%20%2F%2F%20Input%3A%20%0A%20%20%20%20%2F%2F%20%20%20%20%20%20hexblob%20(blob%20of%20arbitrary%20length)%0A%20%20%20%20%2F%2F%20Return%3A%20%0A%20%20%20%20%2F%2F%20%20%20%20%20%20table%20containing%3A%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20%20%20%20%22rh%22%3A%20relative%20humidity%20(float)%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20%20%20%20%22temp%22%3A%20temperature%20in%20celsius%20(float)%0A%20%20%20%20%2F%2F%20%20%20%20%20%20if%20read%20fails%2C%20rh%20and%20temp%20will%20return%200%0A%20%20%20%20function%20parse(hexblob)%20%7B%0A%20%20%20%20%20%20%20%20local%20laststate%20%20%20%20%20%3D%200%3B%0A%20%20%20%20%20%20%20%20local%20lastbitidx%20%20%20%20%3D%200%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20local%20gotack%20%20%20%20%20%20%20%20%3D%20false%3B%0A%20%20%20%20%20%20%20%20local%20rawidx%20%20%20%20%20%20%20%20%3D%200%3B%0A%20%20%20%20%20%20%20%20local%20result%20%20%20%20%20%20%20%20%3D%20blob(5)%3B%20%2F%2F%202-byte%20humidity%2C%202-byte%20temp%2C%201-byte%20checksum%0A%20%20%20%20%0A%20%20%20%20%20%20%20%20local%20humid%20%20%20%20%20%20%20%20%20%3D%200%3B%0A%20%20%20%20%20%20%20%20local%20temp%20%20%20%20%20%20%20%20%20%20%3D%200%3B%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%2F%2F%20iterate%20through%20each%20bit%20of%20each%20byte%20of%20the%20returned%20signal%0A%20%20%20%20%20%20%20%20for%20(local%20byte%20%3D%200%3B%20byte%20%3C%20hexblob.len()%3B%20byte%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(local%20bit%20%3D%207%3B%20bit%20%3E%3D%200%3B%20bit–)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20local%20thisbit%20%3D%20(hexblob%5Bbyte%5D%20%26%20(0x01%20%3C%3C%20bit))%20%3F%201%3A0%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(thisbit%20!%3D%20laststate)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(thisbit)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20low-to-high%20transition%3B%20watch%20to%20see%20how%20long%20it%20is%20high%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20laststate%20%3D%201%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lastbitidx%20%3D%20(8%20*%20byte)%20%2B%20(7%20-%20bit)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20high-to-low%20transition%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20laststate%20%3D%200%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20local%20idx%20%3D%20(8%20*%20byte)%20%2B%20(7%20-%20bit)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20local%20hightime%20%3D%20(idx%20-%20lastbitidx)%20*%20_bittime%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20we%20now%20have%20one%20valid%20bit%20of%20info.%20Figure%20out%20what%20symbol%20it%20is.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20local%20resultbyte%20%3D%20(rawidx%20%2F%208)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20local%20resultbit%20%3D%20%207%20-%20(rawidx%20%25%208)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2Fserver.log(format(%22bit%20%25d%20of%20byte%20%25d%22%2Cresultbit%2C%20resultbyte))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(hightime%20%3C%20ZERO)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20this%20is%20a%20zero%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(gotack)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20don’t%20record%20any%20data%20before%20the%20ACK%20is%20seen%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result%5Bresultbyte%5D%20%3D%20result%5Bresultbyte%5D%20%26%20~(0x01%20%3C%3C%20resultbit)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20rawidx%2B%2B%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(hightime%20%3C%20ONE)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20this%20is%20a%20one%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(gotack)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result%5Bresultbyte%5D%20%3D%20result%5Bresultbyte%5D%20%7C%20(0x01%20%3C%3C%20resultbit)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20rawidx%2B%2B%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20this%20is%20a%20START%20ACK%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20gotack%20%3D%20true%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%2F%2Fserver.log(format(%22parsed%3A%200x%20%2502x%2502x%20%2502x%2502x%20%2502x%22%2Cresult%5B0%5D%2Cresult%5B1%5D%2Cresult%5B2%5D%2Cresult%5B3%5D%2Cresult%5B4%5D))%3B%0A%20%20%20%20%20%20%20%20humid%20%3D%20(result%5B0%5D%20*%201.0)%20%2B%20(result%5B1%5D%20%2F%201000.0)%3B%0A%20%20%20%20%20%20%20%20if%20(result%5B2%5D%20%26%200×80)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20negative%20temperature%0A%20%20%20%20%20%20%20%20%20%20%20%20result%5B2%5D%20%3D%20((~result%5B2%5D)%20%2B%201)%20%26%200xff%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20temp%20%3D%20(result%5B2%5D%20*%201.0)%20%2B%20(result%5B3%5D%20%2F%201000.0)%3B%0A%20%20%20%20%20%20%20%20if%20(((result%5B0%5D%20%2B%20result%5B1%5D%20%2B%20result%5B2%5D%20%2B%20result%5B3%5D)%20%26%200xff)%20!%3D%20result%5B4%5D)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%22rh%22%3A0%2C%22temp%22%3A0%7D%3B%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%22rh%22%3Ahumid%2C%22temp%22%3Atemp%7D%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20%0A%20%20%20%20%2F%2F%20read%20the%20sensor%0A%20%20%20%20%2F%2F%20Input%3A%20(none)%0A%20%20%20%20%2F%2F%20Return%3A%0A%20%20%20%20%2F%2F%20%20%20%20%20%20table%20containing%3A%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20%20%20%20%22rh%22%3A%20relative%20humidity%20(float)%0A%20%20%20%20%2F%2F%20%20%20%20%20%20%20%20%20%20%22temp%22%3A%20temperature%20in%20celsius%20(float)%0A%20%20%20%20%2F%2F%20%20%20%20%20%20if%20read%20fails%2C%20rh%20and%20temp%20will%20return%200%0A%20%20%20%20function%20read()%20%7B%0A%20%20%20%20%20%20%20%20local%20bloblen%20%3D%20_start_low_bytes%20%2B%20_start_high_bytes%20%2B%20(40%20*%20(_mark_bytes%20%2B%20_one_bytes))%3B%0A%20%20%20%20%20%20%20%20local%20startblob%20%3D%20blob(bloblen)%3B%0A%20%20%20%20%20%20%20%20for%20(local%20i%20%3D%200%3B%20i%20%3C%20_start_low_bytes%3B%20i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20startblob.writen(0x00%2C’b’)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20for%20(local%20j%20%3D%20_start_low_bytes%3B%20j%20%3C%20bloblen%3B%20j%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20startblob.writen(0xff%2C’b’)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%2F%2Fserver.log(format(%22Sending%20%25d%20bytes%22%2C%20startblob.len()))%3B%0A%20%20%20%20%20%20%20%20local%20result%20%3D%20_spi.writeread(startblob)%3B%0A%20%20%20%20%20%20%20%20return%20parse(result)%3B%0A%20%20%20%20%7D%0A%7D%0A%0A%0A%0Afunction%20loop()%20%7B%0A%20%20%20%20imp.wakeup(INTERVAL%2C%20loop)%3B%0A%20%20%20%20local%20data%20%3D%20dht11.read()%3B%0A%20%20%20%20local%20data_hum%2Cdata_temp%3B%0A%20%20%20%20server.log(%22Running%20%22%2Bimp.getsoftwareversion()%2B%22%2C%20Free%20Memory%3A%20%22%2Bimp.getmemoryfree())%3B%0A%20%20%20%20data_hum%3D%20data.rh%3B%0A%20%20%20%20server.log(format(%22Relative%20Humidity%3A%20%250.1f%22%2Cdata_hum)%2B%22%20%25%22)%3B%0A%20%20%20%20%2F%2Fserver.log(format(%22Relative%20Humidity%3A%20%250.1f%22%2Cdata.rh)%2B%22%20%25%22)%3B%0A%20%20%20%20data_temp%3D%20data.temp%3B%0A%20%20%20%20server.log(format(%22Temperature%3A%20%250.1f%20C%22%2Cdata_temp))%3B%0A%20%20%20%20%2F%2Fserver.log(format(%22Temperature%3A%20%250.1f%20C%22%2Cdata.temp))%3B%0A%20%20%20%20ping(data_temp)%3B%0A%7D%0A%0Aspi%20%20%20%20%20%20%20%20%20%3C-%20hardware.spi257%3B%0Aclkspeed%20%20%20%20%3C-%20spi.configure(MSB_FIRST%2C%20SPICLK)%3B%0A%0Adht11%20%3C-%20DHT11(spi%2C%20clkspeed)%3B%0A%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%0Afunction%20ping(data_temp)%20%0A%7B%0A%20%20%20%20%2F%2F%20Send%20a%20’ping’%20message%20to%20the%20server%20with%20the%20current%20millis%20counter%0A%20%20%20%20%0A%20%20%20%20agent.send(%22ping%22%2C%20data_temp)%3B%0A%7D%0A%0Afunction%20returnFromImp(startMillis)%0A%7B%0A%7D%0A%0Aagent.on(%22pong%22%2C%20returnFromImp)%3B%0A%20%0A%2F%2F%20Start%20the%20ping-pong%0A%0A%2F%2Fping()%3B%0A%0A%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%0Aloop()%3B”/]







