Camera surveillance

A project that combines camera surveillance and a monitor for the heating system to be controlled by the same RPi.

[pastacode lang=”python” manual=”%23This%20program%20drives%20the%20RPi%20for%20the%20heating%20system%20and%20camera%0Aimport%20os%0Aimport%20glob%0Aimport%20time%0Aimport%20commands%0Aimport%20threading%0Afrom%20time%20import%20sleep%0Aimport%20gdata.spreadsheet%0Aimport%20gdata.spreadsheet.service%0Afrom%20ftplib%20import%20FTP%0Aimport%20ftplib%0Afrom%20time%20import%20sleep%0Aimport%20picamera%0Aimport%20RPi.GPIO%20as%20GPIO%0Aimport%20subprocess%0Aimport%20datetime%20as%20dt%0Aimport%20smtplib%20%23for%20sending%20mails%0A%20%0AGPIO.setmode(GPIO.BCM)%0AGPIO.setup(17%2C%20GPIO.IN%2C%20GPIO.PUD_UP)%0A%20%0An%3D1%0Aupld%3D1%20%23determines%20if%20image%20will%20be%20uploaded%20as%20well%0Afilename%20%3D%20’%2Fhome%2Fpi%2FDesktop%2Fcamera%2F’%20%2B%20str(n)%20%2B%20′.jpg’%0A%20%0A%23%20load%20the%20kernel%20modules%20needed%20to%20handle%20the%20sensor%0Aos.system(‘modprobe%20w1-gpio’)%0Aos.system(‘modprobe%20w1-therm’)%0A%20%0Atemperature%20%3D%200.00%0A%20%0A%23FTP%20information%0AFTPhost%20%3D%20’zzzzzzzzzzz’%0AFTPdomain%20%3D%20’zzzzzzzzzzzzz’%0AFTPpass%20%3D%20’zzzzzzzzzzzzzzzzzzzzzz’%0A%20%0A%23ALL%20GOOGLE%20SERVICES%20ARE%20NOW%20DISABLED%20DUE%20TO%20THEIR%20OAUTH%20PARANOIA%0A%23GOOGLE%3A%0A%23account%20details%0Agmail%20%3D%20’zzzzzz’%0Agpass%20%3D%20’qqqqqqqqqqqqqq’%0Aghost%20%3D%20’vvvvvvvvvvvvvvvvvv’%0A%20%0A%23Spreadsheets%0Aspr_client%20%3D%20gdata.spreadsheet.service.SpreadsheetsService()%0Aspr_client.email%20%3D%20gmail%0Aspr_client.password%20%3D%20gpass%0Aspr_client.source%20%3D%20’Example%20Spreadsheet%20Writing%20Application’%0Aspr_client.ProgrammaticLogin()%0A%20%0A%23%20ID’s%20of%20the%20different%20spreadsheets%20used%20for%20storing%20data%0Aspr_key_event%20%3D%20’1QNmkzUWZKyZ6BYDu0B7UBJCcdiC9bLrg_vxXxBZIhtk’%20%23Event%20log%0Aspr_key_rainy_day%20%3D%20’1sidW4BTGui7frjRxehZlySCPe4oo_lSshNmGQDP0v3k’%20%23%20Rain%20last%2024H%20in%2010%20min%20intervals%0Aspr_key_rainy_week%20%3D%20’1EFfRVuUIYqD9QObG0M_AgSmYjHYMd3kv2yvmHUrNSZM’%20%23%20Rain%20last%202%20weeks%20in%201H%20intervals%0Aspr_key_rainy_year%20%3D%20’16R1nxxtNsrQNKULwiFXLzkvZUYaRc_N2XbgqcoVFnKE’%20%23Rain%20last%20year%20with%20once%20daily%20updates%0Aspr_key_temp_out%20%3D%20’1EflJUkzfxBI5vPTSAMh5Ds8Y01O63RGd5hCg2IFM50w’%20%23Outside%20temperature%20the%20last%2024h%20(Temp%20out)%0Aspr_key_temp_now%20%3D%20’1iyAU5eHBeYHG3XHisUlPSWFEFM4dnc8_RkOR7AU108g’%20%23Outside%20temperature%20right%20now%20(Temp%20now)%0Aspr_key_temp_all%20%3D%20’1srQPRg9ZUfFLY_5z8m6DLgbz-Cz833S2HRz2alsWrRo’%20%23All%20temperature%20sensors%20(Temp%20all)%20for%20internal%20use%0Aspr_key_temp_extremes%20%3D%20’1Oe3DlM4uobJMgSfJw8Fucyd4qgDt7WgXn0BVFZRuFRw’%20%23Outside%20temperature%20extremes%0A%20%0Aworksheet_id%20%3D%20’od6’%20%23%20worksheet%20%231%20by%20default%20always%20has%20a%20value%20of%20’od6’%20if%20necessary%0A%20%0ATEMP_ALL_UPDATE%20%3D%20True%0AONLINE_SENSORS%20%3D%20True%20%23Used%20for%20checking%20the%20online%20sensors%20once%20every%2010%20mins%0A%20%0Adef%20LogFile%20(func)%3A%20%23Generic%20function%20to%20write%20to%20logfile%20if%20spreadsheet%20updates%20fail%0A%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20f%20%3D%20open(‘%2Fhome%2Fpi%2FDesktop%2Fheat.txt’%2C%20’a’)%0A%20%20%20%20%20%20%20%20f.write(%22%20Event%20registered%20for%20%22%20%2B%20func%20%2B%20%22%20at%20%22%20%2B%20str(time.strftime(‘%25d%2F%25m%2F%25Y%20%25H%3A%25M%3A%25S’)))%0A%20%20%20%20%20%20%20%20f.close()%0A%20%20%20%20%20%0Adef%20SprUpdate%20()%3A%0A%20%20%20%20%20%20%20%20global%20spr_key_sensors%0A%20%20%20%20%20%20%20%20global%20dict%0A%20%20%20%20%20%20%20%20entry%20%3D%20spr_client.InsertRow(dict%2C%20spr_key_sensors)%0A%20%20%20%20%20%20%20%20print%20dict%0A%20%20%20%20%20%20%20%20sleep%20(0.1)%20%23wait%20for%20the%20update%20before%20deleting%20the%20first%20line%0A%20%20%20%20%20%20%20%20delfeed%20%3D%20spr_client.GetListFeed(spr_key_sensors)%0A%20%20%20%20%20%20%20%20spr_client.DeleteRow(delfeed.entry%5B0%5D)%0A%20%0Adef%20SprUpdateCell%20(value%2C%20cellno%2C%20spr_key)%3A%20%23Function%20to%20update%20single%20cells%20(temp%2C%20cell%20number%20and%20spreadsheet)%0A%20%20%20%20%20%20%20%20try%3A%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%20query%20%3D%20gdata.spreadsheet.service.CellQuery()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20query.return_empty%20%3D%20%22true%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cells%20%3D%20spr_client.GetCellsFeed(spr_key%2C%20query%3Dquery)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20batchRequest%20%3D%20gdata.spreadsheet.SpreadsheetsCellsFeed()%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cells.entry%5Bint(str(cellno))%5D.cell.inputValue%20%3D%20str(value)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20batchRequest.AddUpdate(cells.entry%5Bint(str(cellno))%5D)%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20updated%20%3D%20spr_client.ExecuteBatch(batchRequest%2C%20cells.GetBatchLink().href)%0A%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%20except%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20LogFile%20(%22%20SprUpdateCell%20had%20a%20problem.%20Temperature%3A%20%22%20%2B%20str(value)%20%2B%20%22%20Cell%3A%20%22%20%2B%20str(cellno)%20%2B%20%22%20Key%3A%20%22%20%2B%20str(spr_key)%20%2B%20%22%20%22)%0A%20%0Adef%20termo%20(tID)%3A%20%23Read%20the%20temperature%20of%20a%20thermometer%0A%20%20%20%20%20%20%20%20global%20temperature%0A%20%0A%20%20%20%20%20%20%20%20file%20%3D%20open(%22%2Fsys%2Fbus%2Fw1%2Fdevices%2F%22%20%2B%20tID%20%2B%20%22%2Fw1_slave%22)%20%23%20Path%20of%20the%20sensor%0A%20%20%20%20%20%20%20%20%23%20Read%20all%20of%20the%20text%20in%20the%20file.%20%0A%20%20%20%20%20%20%20%20text%20%3D%20file.read()%20%0A%20%20%20%20%20%20%20%20%23%20Close%20the%20file%20now%20that%20the%20text%20has%20been%20read.%20%0A%20%20%20%20%20%20%20%20file.close()%20%0A%20%20%20%20%20%20%20%20%23%20Split%20the%20text%20with%20new%20lines%20(%5Cn)%20and%20select%20the%20second%20line.%20%0A%20%20%20%20%20%20%20%20secondline%20%3D%20text.split(%22%5Cn%22)%5B1%5D%20%0A%20%20%20%20%20%20%20%20%23%20Split%20the%20line%20into%20words%2C%20referring%20to%20the%20spaces%2C%20and%20select%20the%2010th%20word%20(counting%20from%200).%20%0A%20%20%20%20%20%20%20%20temperaturedata%20%3D%20secondline.split(%22%20%22)%5B9%5D%20%0A%20%20%20%20%20%20%20%20%23%20The%20first%20two%20characters%20are%20%22t%3D%22%2C%20so%20get%20rid%20of%20those%20and%20convert%20the%20temperature%20from%20a%20string%20to%20a%20number.%20%0A%20%20%20%20%20%20%20%20temperature%20%3D%20float(temperaturedata%5B2%3A%5D)%20%0A%20%20%20%20%20%20%20%20%23%20Put%20the%20decimal%20point%20in%20the%20right%20place%20and%20display%20it.%20%0A%20%20%20%20%20%20%20%20temperature%20%3D%20temperature%20%2F%201000%0A%20%0Adef%20termoRead(spr_key)%3A%0A%20%0A%20%20%20%20%20%20%20%20global%20dict%0A%20%20%20%20%20%20%20%20global%20TempIDs%0A%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%23Open%20the%20CSV%20and%20write%20the%20header%20instead%20of%20old%20content%0A%20%20%20%20%20%20%20%20r%20%3D%20open(‘%2Fhome%2Fpi%2FDesktop%2Fcsv%2Fheat.csv’%2C%20’w’)%0A%20%20%20%20%20%20%20%20r.write%20(time.strftime(‘Date%20%25d-%25m-%25Y%20Time%20%25H%3A%25M%3A%25S’)%20%2B%20%22%2C%22%20%2B%20%22Degrees%20(C)%22%20%2B%20’%5Cr%5Cn’)%0A%20%20%20%20%20%20%20%20r.close()%0A%20%0A%20%20%20%20%20%20%20%20%23Compare%20the%20two%20arrays%20in%20order%20to%20know%20which%20sensors%20to%20use%0A%20%20%20%20%20%20%20%20dict%20%3D%20%7B%7D%20%23Prepare%20data%20for%20spreadsheet%0A%20%20%20%20%20%20%20%20for%20i%20in%20range(len(OnlineIDs))%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%3DOnlineIDs%5Bi%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20t%20in%20range(len(TempIDs))%3A%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%20b%3DTempIDs%5Bt%5D%5B1%5D%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%20a%3D%3Db%3A%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%20termo%20(str(TempIDs%5Bt%5D%5B1%5D))%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%23print%20str(TempIDs%5Bt%5D%5B0%5D)%20%2B%20%22%20is%20%22%20%2B%20str(temperature)%20%2B%20%22%20deg%20C%22%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%20dict%5Bstr(TempIDs%5Bt%5D%5B2%5D)%5D%20%3D%20str(temperature)%20%23Build%20the%20list%20for%20each%20run%20if%20it%20should%20be%20used%20at%20a%20later%20stage%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%20r%20%3D%20open(‘%2Fhome%2Fpi%2FDesktop%2Fcsv%2Fheat.csv’%2C%20’a’)%20%23Append%20the%20readings%20to%20the%20CSV%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%20r.write%20(str(TempIDs%5Bt%5D%5B3%5D)%20%2B%20%22%2C%22%20%2B%20str(temperature)%20%2B%20’%5Cr%5Cn’)%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%20r.close()%0A%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%20%20%20%20%20%20%20%20%23print%20str(TempIDs%5Bt%5D%5B1%5D)%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%23print%20str(TempIDs%5Bt%5D%5B2%5D)%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%23print%20str(TempIDs%5Bt%5D%5B3%5D)%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%23print%20str(TempIDs%5Bt%5D%5B4%5D)%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%23SprUpdateCell%20(temperature%2C%20str(TempIDs%5Bt%5D%5B4%5D)%2C%20spr_key)%0A%20%20%20%20%20%20%20%20Upload%20(‘heat’)%0A%20%0Adef%20Upload%20(filename)%3A%20%23Uploads%20the%20specified%20CSV%20file%20to%20the%20domain%0A%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20global%20FTPhost%2C%20FTPdomain%2C%20FTPpass%0A%20%20%20%20%20%20%20%20fileup%20%3D%20’%2Fhome%2Fpi%2FDesktop%2Fcsv%2F’%20%2B%20str(filename)%20%2B%20′.csv’%0A%20%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20session%20%3D%20ftplib.FTP(str(FTPhost)%2C%20str(FTPdomain)%2C%20str(FTPpass))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20file%20%3D%20open(str(fileup)%2C’rb’)%20%20%23%20file%20to%20send%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20session.cwd(‘%2Fwp-content%2Fuploads%2F’)%20%23change%20directory%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20session.storbinary(‘STOR%20’%20%2B%20str(filename)%20%2B%20%22.csv%22%2C%20file)%20%23%20send%20the%20file%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20file.close()%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%23%20close%20file%20and%20FTP%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20session.quit()%0A%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%20except%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print%20%22FTP%20upload%20failed%20%22%0A%20%0Adef%20shootusb%20()%3A%0A%23%20%20%20%20%20%20%20print%20%22%20shooting%20image%20with%20fswebcam%20%22%0A%20%20%20%20os.system(‘fswebcam%20-r%201280×720%20%2Fhome%2Fpi%2FDesktop%2Fcamera%2F%25H%25M%25S.jpg’)%0A%23%20%20%20%20%20%20%20%20fswebcam%20-r%201280×720%20%2Fhome%2Fpi%2FDesktop%2Fcamera%2Fusbcam.jpg%0A%23%20%20%20%20%20%20%20print%20%22USB%20shot%20with%20fswebcam%20went%20fine%22%0A%20%0Adef%20shootrpi%20()%3A%0A%23%20Shooting%20image%20with%20RPI%20cam%0A%20%0A%20%20%20%20global%20n%0A%20%20%20%20global%20upld%0A%20%20%20%20global%20filename%0A%20%20%20%20filename%20%3D%20’%2Fhome%2Fpi%2FDesktop%2Fcamera%2F’%20%2B%20str(n)%20%2B%20′.jpg’%0A%20%20%20%20with%20picamera.PiCamera()%20as%20camera%3A%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20camera.led%20%3D%20False%0A%20%20%20%20%20%20%20%20%20%20%20%20camera.resolution%20%3D%20(2592%2C%201944)%0A%20%20%20%20%20%20%20%20%20%20%20%20camera.framerate%20%3D%201%0A%20%20%20%20%20%20%20%20%20%20%20%20camera.exposure_mode%20%3D%20’auto’%0A%20%20%20%20%23%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20camera.iso%20%3D%200%0A%20%20%20%20%23%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20camera.shutter_speed%20%3D%205000000%0A%20%20%20%20%20%20%20%20%20%20%20%20camera.start_preview()%0A%20%20%20%20%20%20%20%20%20%20%20%20camera.annotate_background%20%3D%20True%0A%20%20%20%20%20%20%20%20%20%20%20%20camera.annotate_text%20%3D%20’Ferskenvej%2034%2C%20Copenhagen%20’%20%2B%20dt.datetime.now().strftime(‘%25Y-%25m-%25d%20%25H%3A%25M%3A%25S’)%0A%20%20%20%20%20%20%20%20%20%20%20%20camera.exif_tags%5B’IFD0.Artist’%5D%20%3D%20’Webcam%20at%20Ferskenvej%2034%2C%20Copenhagen’%0A%20%20%20%20%20%20%20%20%20%20%20%20camera.exif_tags%5B’IFD0.UserComment’%5D%20%3D%20’Made%20with%20Rapberry%20Pi%20Cam’%0A%20%20%20%20%20%20%20%20%20%20%20%20camera.exif_tags%5B’IFD0.Copyright’%5D%20%3D%20’Copyright%20(c)%202017%20Jesper%20Bonde%20Petersen’%0A%20%20%20%20%20%20%20%20%20%20%20%20sleep(4)%0A%20%20%20%20%20%20%20%20%20%20%20%20camera.capture(filename%2C%20resize%3D(1280%2C%20960))%0A%20%20%20%20%20%20%20%20%20%20%20%20sleep(2)%0A%20%20%20%20%20%20%20%20%20%20%20%20camera.close%0A%23%20%20%20%20%20%20%20%20%20%20%20print%20%22RPI%20shot%20%22%20%2B%20str(n)%20%2B%20%22%20was%20made%22%0A%20%20%20%20%20%20%20%20%20%20%20%20n%3Dn%2B1%0A%20%20%20%20%20%20%20%20%20%20%20%20upld%3Dupld%2B1%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20upld%3D%3D60%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20upld%3D1%20%23’Upload%20one%20copy%20to%20http%3A%2F%2Fjesperbonde.dk%2Fwp-content%2Fuploads%2Fwebcam.jpg%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20n%3D%3D3500%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20n%3D1%0A%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20except%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print%20%22Capture%20failed%20for%20pix%20no%20%22%20%2B%20str(n)%0A%20%0Adef%20shootftp%20()%3A%0A%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20session%20%3D%20ftplib.FTP(‘zzzzzzzzzzzzzzzzzzz’%2C’vvvvvvvvvvvvvvvv’%2C’qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq’)%0A%20%20%20%20%20%20%20%20file%20%3D%20open(str(filename)%2C’rb’)%20%20%23%20file%20to%20send%0A%20%20%20%20%20%20%20%20session.cwd(‘%2Fwp-content%2Fuploads%2F’)%20%23change%20directory%0A%20%20%20%20%20%20%20%20session.storbinary(‘STOR%20webcam.jpg’%2C%20file)%20%20%20%20%20%23%20send%20the%20file%0A%20%20%20%20%20%20%20%20file.close()%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%20%20%20%20%23%20close%20file%20and%20FTP%0A%20%20%20%20%20%20%20%20session.quit()%0A%23%20%20%20%20%20%20%20print%20%22——-%3E%20%20Shot%20%22%20%2B%20str(n)%20%2B%20%22%20was%20uploaded%22%0A%20%20%20%20%20%20%20%20%20%0A%20%20%20%20except%3A%0A%20%20%20%20%20%20%20%20print%20%22FTP%20upload%20failed%20for%20pix%20no.%20%22%20%2B%20str(n)%0A%20%0A%23Array%20with%20information%20about%20all%20tested%20sensors%20incl.%20color%20code%2C%20sensor%20ID%2C%20spreadsheet%20name%2C%20function%20and%20spreadsheet%20cell%0ATempIDs%20%3D%20%5B%22BLACK%22%2C%20%2228-000005b16567%22%2C%20%22out%22%2C%20%22Outside%20temperature%22%2C%20%2216%22%2C%20%22X%22%5D%2C%5C%0A%20%20%20%20%20%20%20%20%20%20%5B%22BROWN%22%2C%20%2228-000005b226ae%22%2C%20%22water%22%2C%20%22Water%20tank%20temp%22%2C%20%2217%22%2C%20%22A%22%5D%2C%20%5C%0A%20%20%20%20%20%20%20%20%20%20%5B%22RED%22%2C%20%2228-000005b217e2%22%2C%20%22radf%22%2C%20%22Radiators%20forward%20temp%22%2C%20%2218%22%2C%20%22B%22%5D%2C%5C%0A%20%20%20%20%20%20%20%20%20%20%5B%22ORANGE%22%2C%20%2228-000005b23020%22%2C%20%22radr%22%2C%20%22Radiators%20return%20temp%22%2C%20%2219%22%2C%20%22C%22%5D%2C%5C%0A%20%20%20%20%20%20%20%20%20%20%5B%22YELLOW%22%2C%20%2228-000005b21d0d%22%2C%20%22heatf%22%2C%20%22Received%20power%20heating%20temp%22%2C%20%2220%22%2C%20%22D%22%5D%2C%20%5C%0A%20%20%20%20%20%20%20%20%20%20%5B%22GREEN%22%2C%20%2228-000005b1b646%22%2C%20%22heatr%22%2C%20%22Returned%20power%20heating%20temp%22%2C%20%2221%22%2C%20%22E%22%20%5D%2C%5C%0A%20%20%20%20%20%20%20%20%20%20%5B%22BLUE%22%2C%20%2228-000005b1d70e%22%2C%20%22floorf%22%2C%20%22Floor%20heating%20forward%20temp%22%2C%20%2222%22%2C%20%22F%22%5D%2C%20%5C%0A%20%20%20%20%20%20%20%20%20%20%5B%22PURPLE%22%2C%20%2228-000005b217eb%22%2C%20%22floorr%22%2C%20%22Floor%20heating%20return%20temp%22%2C%20%2223%22%2C%20%22G%22%5D%2C%5C%0A%20%20%20%20%20%20%20%20%20%20%5B%22BLACK%20-%20LOST%20BROWN%22%2C%20%2228-000005b1a9e9%22%2C%20%22xx%22%2C%20%22xx%22%2C%20%2224%22%2C%20%22X%22%5D%2C%5C%0A%20%20%20%20%20%20%20%20%20%20%5B%22BROWN%22%2C%20%2228-000005bxxxxx%22%2C%20%22XX%22%2C%20%22xx%22%2C%20%2225%22%2C%20%22Y%22%5D%2C%5C%0A%20%20%20%20%20%20%20%20%20%20%5B%22RED%22%2C%20%2228-000005b22544%22%2C%20%22dining%22%2C%20%22Dining%20Room%22%2C%20%2226%22%2C%20%22Z%22%5D%2C%5C%0A%20%20%20%20%20%20%20%20%20%20%5B%22ORANGE%22%2C%20%2228-000005b1725b%22%2C%20%22living%22%2C%20%22Living%20Room%22%2C%20%2227%22%2C%20%22Q%22%5D%0A%20%0A%23Read%20the%20sensors%20that%20are%20connected%20when%20booting%0AOnlineIDs%20%3D%20commands.getoutput(‘%20ls%20%2Fsys%2Fbus%2Fw1%2Fdevices%2F%20%7C%20grep%20-e%20%2228-%22’).splitlines()%20%20%23%20Ids%20for%20sensors%20online%0Aprint%20%22Total%20amount%20of%20installed%20sensors%3A%20%22%20%2B%20str(len(TempIDs))%0Aprint%20%22Amount%20of%20online%20temp%20sensors%3A%20%22%20%2B%20str(len(OnlineIDs))%0Aprint%20%22ID%20of%20online%20sensors%3A%20%22%20%2B%20str(OnlineIDs)%0A%20%0A%23termoRead(spr_key_temp_all)%0Awhile%20True%3A%0A%20%0A%20%20%20%20shootrpi()%0A%20%20%20%20sleep(3)%0A%20%20%20%20if%20upld%3D%3D2%3A%0A%20%20%20%20%20%20%20%20shootftp()%0A%20%20%20%20%20%20%20%20sleep(5)%0A%20%0A%20%20%20%20minw%20%3D%20str(time.strftime%20(%22%25M%22))%23%20Watching%20minutes%0A%20%0A%20%20%20%20if%20minw%5B-1%3A%5D%20%3D%3D%20%220%22%3A%20%23Update%20the%20sensor%20csv%20spreadsheet%20every%2010%20min%0A%20%20%20%20%20%20%20%20if%20TEMP_ALL_UPDATE%20%3D%3D%20True%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20a%3Dthreading.Thread(target%3DtermoRead(spr_key_temp_all))%0A%20%20%20%20%20%20%20%20%20%20%20%20a.start()%0A%20%20%20%20%20%20%20%20%20%20%20%20TEMP_ALL_UPDATE%20%3D%20False%0A%20%0A%20%20%20%20if%20minw%5B-1%3A%5D%20%3D%3D%20%225%22%3A%20%23Check%20for%20active%20online%20sensors%20every%2010%20min%0A%20%20%20%20%20%20%20%20if%20ONLINE_SENSORS%20%3D%3D%20True%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20OnlineIDs%20%3D%20commands.getoutput(‘%20ls%20%2Fsys%2Fbus%2Fw1%2Fdevices%2F%20%7C%20grep%20-e%20%2228-%22’).splitlines()%20%20%23%20Ids%20for%20sensors%20online%0A%20%20%20%20%20%20%20%20%20%20%20%20sleep%20(20)%0A%20%20%20%20%20%20%20%20%20%20%20%20ONLINE_SENSORS%20%3D%20False%0A%20%0A%20%20%20%20if%20minw%5B-1%3A%5D%20%3D%3D%20%229%22%3A%20%0A%20%20%20%20%20%20%20%20%23Prepare%20for%20next%20Update%20%0A%20%20%20%20%20%20%20%20TEMP_ALL_UPDATE%20%3D%20True%0A%20%20%20%20%20%20%20%20ONLINE_SENSORS%20%3D%20True” message=”” highlight=”” provider=”manual”/]