def makeMultipartBody(params): print("makeMultipartBody") mylib.collectMemory() #print(mylib.reportMemory()) # for debug uniq_str = sha1Hash(str(utime.time() * random())) bodyTMPfile = '/sd/' + 'tmp' + uniq_str[5: 10] # make tmp file name (len:3+5) boundary = uniq_str[0:16] # take string (len:16) fp = open(bodyTMPfile, 'wb') for key in params: fp.write(('--' + boundary).encode()) fp.write(CRLF) value = params[key] if key == 'file': if len(value) == 1: file_name = value[0] file_body = None if len(value) == 2: (file_name, file_body) = value else: print("Error in makeMultipartBody") print("file entity illegal") fp.close() return None fp.write(TMPL_CD_FILE.format(file_name).encode()) fp.write(CRLF) fp.write(TMPL_CT_JPEG) fp.write(CRLF * 2) if file_body is None: with open(file_name, "rb") as fp_body: buffer = bytearray(FILEBUFSIZE) while True: if DBG_MEMORY_REPORT: print(mylib.reportMemory()) # for debug size = fp_body.readinto(buffer, FILEBUFSIZE) if size == 0: break else: fp.write(buffer, FILEBUFSIZE) buffer = None else: fp.write(TMPL_CD.format(key).encode()) fp.write(CRLF * 2) if isinstance(value, str): fp.write(value.encode()) else: print("Error in makeMultipartBody") print("entity is not string") fp.close() return None fp.write(CRLF) fp.write(('--' + boundary + '--').encode()) fp.close() return (boundary, bodyTMPfile)
def takePictureAndSaveToFile(self, fileName): ret = self.sendCmd('SNAPSHOT', 0x00, 0x00, 0x00, 0x00) # snap No1 (drop) ret = self.sendCmd('SNAPSHOT', 0x00, 0x00, 0x00, 0x00) # snap No2 if ret == False: print('Error in takePicture; fail to exec SNAPSHOT') return False ret = self.sendCmd('GET_PICTURE', 0x01, 0x00, 0x00, 0x00) if ret == False: print('Error in takePicture; fail to exec GET_PICTURE') return False if self.getPacketType(ret) != 'DATA': print('Error in takePicture, Illegal Response type') return False # get PictSize pictSize = ret[5] pictSize <<= 8 pictSize |= ret[4] pictSize <<= 8 pictSize |= ret[3] if pictSize == 0: print('Error in takePicture, pictSize is 0') return False print("pictSize:{:d}".format(pictSize)) mylib.collectMemory() s = utime.ticks_ms() # for time measurement with open(fileName, 'wb') as f: state = self.getImageDataAndWriteFile(pictSize, f) mylib.collectMemory() e = utime.ticks_ms() # for time measurement diff = utime.ticks_diff(e, s) print("receive picture and save takes:{:d}(ms)".format(diff)) return True
def showQQVGAPicture(self, screenClear=False, drawLines=1): (h_size, v_size) = QQVGASIZE s = utime.ticks_ms() if screenClear: self.tft.fill(self.tft.BLACK) mylib.collectMemory() print("free mem: ", end="") print(mylib.reportMemory()) rectSize = h_size * RGB565BPP * drawLines lineBuf = bytearray(rectSize) self.ov7670.FIFOReadReset() # read data from Top of FIFO for y in range(0, v_size, drawLines): if self.shutterPressed: print("shutter pressed, so stop drawing") break self.ov7670.getPixelFromFIFO(lineBuf, rectSize, False) self.tft.image(0, y, h_size - 1, y + drawLines, lineBuf) e = utime.ticks_ms() print("Preview draw time:{:d}(ms)".format(utime.ticks_diff(e, s))) mylib.collectMemory()
def takePictureAndUpload(self): fileName = None saveState = None mylib.collectMemory() self.ov7670.takePicture() fileName = mylib.getPhotoFileNameWithPath('raw') saveState = self.ov7670.saveVGARawPicture(fileName) if saveState: print("OK! save done") else: print("Error in save Picture") mylib.collectMemory() if saveState: print("send to AWS:{:s}".format(AWSAPIURL)) print("file:{:s}".format(fileName)) s = utime.ticks_ms() (status, info) = uploadFileAWS(fileName, AWSAPIURL, AWSAPIKEY) e = utime.ticks_ms() if status == 200: print("OK! send to AWS done", status) else: print("Error! send to AWS in fail", status) print("upload time:{:d}(ms)".format(utime.ticks_diff(e, s))) mylib.collectMemory()
def takePictureAndUpload(self, uploadMessage=None): # take Picture and save to tmp File mylib.collectMemory() fileName = mylib.getPhotoFileNameWithPath('jpg') state = self.grovecam.takePictureAndSaveToFile(fileName) if state == False: print('Error in takeing a photo') return False else: print('photo is saved: ' + fileName) print('taking a photo ok, upload photo to CloudService') print(mylib.reportMemory()) # for debug # upload picture to Cloudinary Server mylib.collectMemory() s = utime.ticks_ms() # for time measurement (status_code, response) = cloudinaryUploader.uploadPhoto(fileName, CLOUD_NAME, API_KEY, API_SECRET) e = utime.ticks_ms() # for time measurement diff = utime.ticks_diff(e, s) print("upload photo takes:{:d}(ms)".format(diff)) if status_code != 200: print('Error in uploading a photo to the Cloud Album Service') print('StatusCode:[{:d}]'.format(status_code)) return False print('uploading photo is completed') dt = mylib.getLocalTimeJST() timeStamp = '{:d}/{:02d}/{:02d} {:02d}:{:02d}'.format( dt[0], dt[1], dt[2], dt[3], dt[4]) if uploadMessage == None: uploadMessage = 'Photo is Uploaded' uploadMessage = uploadMessage + ' (' + timeStamp + ')' photoURL = response['secure_url'] prevURL = cloudinaryUploader.getResizeURL(photoURL) print('access url(org):' + photoURL) print('access url(prev):' + prevURL) mylib.collectMemory() status_code = lineBOT.postImage(LINE_TOKEN, photoURL, prevURL, uploadMessage) if status_code == 200: print('POST to LineBOT OK') elif status_code == 429: # 429 is 'Too Many Requests' print('Error in lineBOT.postImage') print('LineBOT API Error') print('Too Many Requests') return False else: print('Error in lineBOT.postImage') print('LineBOT API Error') print('status[{:03d}]'.format(status_code)) return False return True
def uploadPhoto(uploadFile, cloudName, apiKey, apiSecret, targetFolder=None): print("uploadPhoto") s = utime.ticks_ms() # for time measurement mylib.collectMemory() #print(mylib.reportMemory()) # for debug if targetFolder is None: (year, month, mday, hour, min, sec, weekday, yearday) = mylib.getLocalTimeJST() targetFolder = "{:04d}{:02d}".format(year, month) params = {} params['api_key'] = apiKey params['timestamp'] = str(int(utime.time()) + EPOCH_2000_1_1) # adjust unix epoch time params['file'] = (uploadFile, None) # load image at makeMultipartBody params['folder'] = targetFolder params['signature'] = makeSignature(params, apiSecret) (boundary, postBodyTMPFile) = makeMultipartBody(params) headers = {} headers['Content-Type'] = 'multipart/form-data; boundary={:s}'.format( boundary) url = CLO_URL_TEMPLATE.format(cloudName, RESOURCE_TYPE) e = utime.ticks_ms() # for time measurement diff = utime.ticks_diff(e, s) print("create BodyPart takes:{:d}(ms)".format(diff)) s = utime.ticks_ms() # for time measurement resp = postBodyFromFile(url, file=postBodyTMPFile, headers=headers) status_code = resp.status_code postInfo = resp.json() resp.close() print("remove tmpfile:" + postBodyTMPFile) uos.remove(postBodyTMPFile) e = utime.ticks_ms() # for time measurement diff = utime.ticks_diff(e, s) print("data transfer takes:{:d}(ms)".format(diff)) return (status_code, postInfo)
def mainLoop(self): self.tft.fill(self.tft.BLACK) self.shutterPressed = False while True: print("-------------") self.ov7670.takePicture() self.showQQVGAPicture() if self.shutterPressed: self.tft.text((10, 120), "!! Shutter Pressed !!", self.tft.RED, terminalfont) self.tft.text((11, 120), "!! Shutter Pressed !!", self.tft.PURPLE, terminalfont) self.ov7670.setVGABayerMode() # change to VGA_RAW Mode self.takePictureAndUpload() # self.shutterPressed = False # clear flag self.ov7670.setQQVGARGB565Mode() # change to QQVGA_RGB565 self.tft.fillrect((0, 120), (160, 128), self.tft.BLACK) print(mylib.collectMemory())
def postBodyFromFile(url, headers, file): print("postBodyFromFile") mylib.collectMemory() #print(mylib.reportMemory()) # for debug try: proto, dummy, host, path = url.split("/", 3) except ValueError: proto, dummy, host = url.split("/", 2) path = "" if proto == "https:": port = 443 else: raise ValueError("Unsupported protocol: " + proto) if ":" in host: host, port = host.split(":", 1) port = int(port) ai = usocket.getaddrinfo(host, port, 0, usocket.SOCK_STREAM) ai = ai[0] s = usocket.socket(ai[0], ai[1], ai[2]) try: s.connect(ai[-1]) s = wrap_socket(s, server_hostname=host) s.write(b"%s /%s HTTP/1.0\r\n" % ('POST', path)) if not "Host" in headers: s.write(b"Host: %s\r\n" % host) # Iterate over keys to avoid tuple alloc for k in headers: s.write(k) s.write(b": ") s.write(headers[k]) s.write(b"\r\n") size = mylib.getFileSize(file) if size == None: raise ValueError("FileSize is None") s.write(b"Content-Length: %d\r\n" % size) s.write(b"\r\n") with open(file, 'rb') as fp: buffer = bytearray(FILEBUFSIZE) while True: if DBG_MEMORY_REPORT: print(mylib.reportMemory()) # for debug size = fp.readinto(buffer, FILEBUFSIZE) if size == 0: break else: s.write(buffer, FILEBUFSIZE) buffer = None l = s.readline() l = l.split(None, 2) status = int(l[1]) reason = "" if len(l) > 2: reason = l[2].rstrip() while True: l = s.readline() if not l or l == b"\r\n": break if l.startswith(b"Transfer-Encoding:"): if b"chunked" in l: raise ValueError("Unsupported " + l) elif l.startswith(b"Location:") and not 200 <= status <= 299: raise NotImplementedError("Redirects not yet supported") except OSError: s.close() raise resp = Response(s) resp.status_code = status resp.reason = reason return resp
def exec10MJobs(self): print('-------------10M-----') status_code = lineBOT.postText(LINE_TOKEN, 'mem:' + mylib.collectMemory()) print(mylib.collectMemory())
def exec1MJobs(self): print('-------------1M-----') print(mylib.collectMemory())
def mainLoop(self): lastPhotoTakeTime = 0 mylib.collectMemory() # setup CRON self.setupCRON() # setup IRQ(shutter, humanSensor) self.setupIRQ() msg = 'ESP32 WiFi Camera Started(' + ESPCAM_VERSION + ')' print('*** main loop start ***') print(msg) status_code = lineBOT.postText(LINE_TOKEN, msg) if status_code == 200: print('POST to LineBOT OK') elif status_code == 429: # 429 is 'Too Many Requests' print('LineBOT API Error') print('Too Many Requests') else: print('Error in lineBOT.postText') print('status[{:03d}]'.format(status_code)) while True: #print('.',end='') utime.sleep(WAITTIME_IN_MAINLOOP) if self.shutterPressed: currentTime = utime.time() print(mylib.getTimeStampJST(enableSecond=True)) if (currentTime - lastPhotoTakeTime) < NONRESPONSIVETIME_FOR_BUTTON: print('avoid too many take photo') self.shutterPressed = False else: print( 'take a photo because the shutter button was pressed') self.deleteIRQ() status_code = lineBOT.postText(LINE_TOKEN, 'pressed shutter button') if status_code == 200: print('POST to LineBOT OK') elif status_code == 429: # 429 is 'Too Many Requests' print('LineBOT API Error') print('Too Many Requests') else: print('LineBOT API Error') print('status[{:03d}]'.format(status_code)) self.takePictureAndUpload() lastPhotoTakeTime = currentTime self.shutterPressed = False self.setupIRQ() status_code = lineBOT.postText( LINE_TOKEN, 'mem:' + mylib.collectMemory()) print('mem:' + mylib.collectMemory()) mylib.collectMemory() if self.sensorDetected: currentTime = utime.time() print(mylib.getTimeStampJST(enableSecond=True)) if (currentTime - lastPhotoTakeTime ) < NONRESPONSIVETIME_FOR_HUMAN_SENSOR: print('avoid rensya form sensor') self.sensorDetected = False else: print('take a photo because the sensor detects some obj.') status_code = lineBOT.postText(LINE_TOKEN, 'sensor detection') if status_code == 200: print('POST to LineBOT OK') elif status_code == 429: # 429 is 'Too Many Requests' print('LineBOT API Error') print('Too Many Requests') else: print('LineBOT API Error') print('status[{:03d}]'.format(status_code)) self.deleteIRQ() for i in range(NOFPHOTOINDETECT): self.takePictureAndUpload() # take N photos lastPhotoTakeTime = currentTime self.sensorDetected = False self.setupIRQ() memSize = mylib.collectMemory() print('mem:' + memSize) status_code = lineBOT.postText(LINE_TOKEN, 'mem:' + memSize) mylib.collectMemory() if status_code != 200: print('Error in lineBOT.postText') print('status[{:03d}]'.format(status_code)) self.checkAndRunCRON()
def setup(self): screen_pos_y = 0 print('*** camera Setup ***') from sys import implementation print(implementation) mylib.setGCThreshold(GC_THRESHOLD_SIZE) mylib.collectMemory() self.setupGlovecam = False self.setupSDFileSystem = False # # setup TFT # # SPI FOR TFT self.hspi = SPI(1, baudrate=HSPI_BAUDRATE, polarity=0, phase=0, sck=Pin(TFT_SPI_SCK), mosi=Pin(TFT_SPI_MOSI), miso=Pin(TFT_SPI_MISO)) # # setup TFT Unit # self.tft = self.TFT_setup(self.hspi, TFT_DC, TFT_RESET, TFT_CS) self.tft.fill(self.tft.BLACK) msg = ESPCAM_VERSION self.tft.text((5, screen_pos_y), msg, self.tft.WHITE, terminalfont) msg = 'py:' + str(implementation[1]).replace(' ', '') screen_pos_y += 8 self.tft.text((5, screen_pos_y), msg, self.tft.WHITE, terminalfont) mylib.collectMemory() # # setup SD Card # screen_pos_y += 8 self.tft.text((5, screen_pos_y), 'SD Setup', self.tft.WHITE, terminalfont) self.vspi = SPI(2, baudrate=VSPI_BAUDRATE, polarity=1, phase=0, sck=Pin(SD_SPI_SCK), mosi=Pin(SD_SPI_MOSI), miso=Pin(SD_SPI_MISO)) self.sd = self.SD_setup(self.vspi, SD_CS) if self.sd is None: self.stat_sd = False else: self.stat_sd = True # # # setup WiFi and NTP # mylib.collectMemory() screen_pos_y += 8 self.tft.text((5, screen_pos_y), 'Wifi Connect', self.tft.WHITE, terminalfont) mylib.wlan_connect(SSID, PASS) self.stat_ntp = mylib.ntp_setup() mylib.collectMemory() screen_pos_y += 8 if self.stat_ntp: self.tft.text((5, screen_pos_y), 'NTP Setup OK', self.tft.WHITE, terminalfont) else: self.tft.text((5, screen_pos_y), 'NTP Setup Error', self.tft.WHITE, terminalfont) mylib.collectMemory() screen_pos_y += 8 mylib.collectMemory() if self.stat_sd and self.stat_ntp: if mylib.setupSDFileSystem(self.sd): self.tft.text((5, screen_pos_y), 'SD Setup OK', self.tft.WHITE, terminalfont) setupSDFileSystem = True else: setupSDFileSystem = False self.tft.text((5, screen_pos_y), 'SD Setup Error', self.tft.WHITE, terminalfont) else: print('Initialization failed, so skip setupSDFileSystem()') mylib.collectMemory() dt = mylib.getLocalTimeJST() timeStamp = '{:d}/{:02d}/{:02d} {:02d}:{:02d}'.format( dt[0], dt[1], dt[2], dt[3], dt[4]) screen_pos_y += 8 self.tft.text((5, screen_pos_y), 'NOW:' + timeStamp, self.tft.WHITE, terminalfont) # # setup GroveCAM # screen_pos_y += 8 self.uart = UART(1, CAM_UART_HIGH_SPEED) self.uart.init(CAM_UART_HIGH_SPEED, bits=8, parity=None, stop=1, tx=CAM_TX, rx=CAM_RX) self.grovecam = GroveCAM(self.uart) status = self.grovecam.setup() if status: self.tft.text((5, screen_pos_y), 'Camera Setup OK', self.tft.WHITE, terminalfont) self.stat_glovecam = True else: self.tft.text((5, screen_pos_y), 'Camera Setup Error', self.tft.WHITE, terminalfont) self.stat_glovecam = False mylib.collectMemory() if self.stat_sd and self.stat_ntp and self.stat_glovecam: screen_pos_y += 8 self.tft.text((5, screen_pos_y), 'Ready! Take to a Photo', self.tft.WHITE, terminalfont) self.shutter = Pin(SHUTTERBUTTON, Pin.IN) # 36 is assigned for ShutterButton self.humanSensor = Pin(HUMANSENSOR, Pin.IN) # 35 is assigned for HumanSensor else: screen_pos_y += 8 self.tft.text((5, screen_pos_y), 'Error in Setup', self.tft.WHITE, terminalfont) return self.stat_sd and self.stat_ntp and self.stat_glovecam
def setup(self): mylib.collectMemory() # SPI FOR TFT/OV7670 FIFO self.hspi = SPI(1, baudrate=HSPI_BAUDRATE, polarity=0, phase=0, sck=Pin(TFT_SPI_SCK), mosi=Pin(TFT_SPI_MOSI), miso=Pin(TFT_SPI_MISO)) # # setup TFT Unit # self.tft = self.TFT_setup(self.hspi, TFT_DC, TFT_RESET, TFT_CS) # # SPI FOR SD Card # self.vspi = SPI(2, baudrate=VSPI_BAUDRATE, polarity=1, phase=0, sck=Pin(SD_SPI_SCK), mosi=Pin(SD_SPI_MOSI), miso=Pin(SD_SPI_MISO)) # # setup SD Unit # self.sd = self.SD_setup(self.vspi, SD_CS) if self.sd is None: self.stat_sd = False else: self.stat_sd = True mylib.wlan_connect(SSID, PASS) self.stat_ntp = mylib.ntp_setup() mylib.collectMemory() if self.stat_sd and self.stat_ntp: mylib.setupSDFileSystem(self.sd) else: print("Initialization failed, so skip setupSDFileSystem()") mylib.collectMemory() # # setup ImageSensor(OV7670) Unit # self.ov7670 = OV7670(I2C_SCL, I2C_SDA) self.stat_ov7670 = self.ov7670.getStatus() # setup FIFO if self.stat_ov7670: self.ov7670.setupFIFO(self.hspi, FIFO_VSYNC, FIFO_RDCLK, FIFO_WE, FIFO_RRST, FIFO_WRST, FIFO_PL) # setup shutter button and IRQ self.shutter = Pin(SHUTTER_BUTTON, Pin.IN) # 36 is assigned for ShutterButton self.shutter.irq(trigger=Pin.IRQ_FALLING, handler=self.cb_shutterPressed) return self.stat_sd and self.stat_ntp and self.stat_ov7670