def greater_than_tommorow(date): secs = urtc.tuple2seconds(datetime()) + _SECS_IN_DAY year, month, day = date.split('-') curr = urtc.datetime_tuple(int(year), int(month), int(day), 0, 0, 0, 0, 0) curr_sec = urtc.tuple2seconds(curr) return curr_sec > secs
def countdown(now, at): schedule = urtc.datetime_tuple(year=now.year, month=now.month, day=now.day, weekday=now.weekday, hour=at[0], minute=at[1], second=0) return urtc.tuple2seconds(now) - urtc.tuple2seconds(schedule)
def equal_to_today(date): dt = datetime() today = urtc.datetime_tuple(dt.year, dt.month, dt.day, 0, 0, 0, 0, 0) secs = urtc.tuple2seconds(today) year, month, day = date.split('-') curr = urtc.datetime_tuple(int(year), int(month), int(day), 0, 0, 0, 0, 0) curr_sec = urtc.tuple2seconds(curr) return curr_sec == secs
def datetime(): """Get the current timezone date/time from RTC. The result is an 8-tuple of the format (year, month, day, weekday, hour, minute, second, millisecond) """ gmt_secs = urtc.tuple2seconds(gmt()) gmt_secs += config.HOURS_DIFF_FROM_GMT * _SECS_IN_HOUR return urtc.seconds2tuple(int(gmt_secs))
async def run_timer(self): global timestamp_unix # TODO fix this when interval timer becomes a class ds3231.alarm(False, alarm=0) # TODO fix this coupling while True: time_now = urtc.tuple2seconds(ds3231.datetime()) # calculate the next alarm time, aligned to the desired interval # e.g. interval=15mins ==> align to 00, 15, 30, 45 mins time_now += 5 # eliminate risk of timing hazard close to interval boundary wake_time = ((time_now // LOGGING_INTERVAL_IN_SECS) + 1 ) * LOGGING_INTERVAL_IN_SECS # set day-of-week (4th element) to None so alarm uses day-of-month (urtc module API requirement) # some gymnastics needed ... wake_time_tuple = urtc.seconds2tuple(int(wake_time)) wake_time_list = list(wake_time_tuple) wake_time_list[3]=None ds3231.alarm_time(wake_time_list, alarm=0) # TODO fix coupling log.info('TMR:next sensor read at %s', wake_time_list) log.info('TMR:waiting for DS3231 alarm') # loop until the DS3231 alarm is detected while ds3231.alarm(alarm=0) == False: await asyncio.sleep_ms(250) timestamp_unix = epoch_time_upy_to_unix(urtc.tuple2seconds(ds3231.datetime())) # clear alarm ds3231.alarm(False, alarm=0) log.info('TMR:DS3231 alarm -> read all sensors') # dispatch a whole pile of activity # following sequence is deliberately sequential so PM2.5 sensor is powered off when # the Spec Sensor devices are being read await ps.read_pm() await spec_sensors.read_all() await temp_hum.read() await sdcard_logger.run_logger() if modes[operating_mode].mqtt == 1: self.event_mqtt_publish.set() mem_free_before_gc = gc.mem_free() log.debug('TMR:gc mem_free = %d bytes', mem_free_before_gc) gc.collect() log.debug('TMR:gc freed %d bytes', gc.mem_free() - mem_free_before_gc)
def main(): global STATUS global WORKING init() while True: now = rtc.datetime() check(now) if STATUS and WORKING == False: WORKING = True does(urtc.tuple2seconds(now)) elif WORKING and STATUS == False: WORKING = False stop(urtc.tuple2seconds(now)) display.displaytem(now, WORKING) utime.sleep(1.0)
async def run_logger(self): timestamp_local = gmt_to_pst(urtc.tuple2seconds(ds3231.datetime())) ld = urtc.seconds2tuple(timestamp_local) # does log file already exist? Yes->open, append No->create, write header if self.fn == None: self.fn = '/sd/meas-{}-{}-{}-{}-{}-{}.csv'.format(ld.year, ld.month, ld.day, ld.hour, ld.minute, ld.second) s = open(self.fn, 'w+') numwrite = s.write('utc,pm25,o3,o3_vgas,o3_vref,no2,no2_vgas,no2_vref,tdegc,rh,dba_avg,dba_max,' 'vusb_avg,vusb_min,vbat_avg,vbat_min\n') log.info('SD:created new file') else: s = open(self.fn, 'a+') log.info('SD:opened existing file') await asyncio.sleep(0) # write sensor data to the SD Card in CSV format numwrite = s.write('{}, {},' '{:.2f},{:.2f},{:.2f},' '{:.2f},{:.2f},{:.2f},' '{:.1f},{:.1f},' '{:.1f},{:.1f},' '{:.2f},{:.2f},{:.2f},{:.2f}\n'.format( timestamp_unix, repo.get('pm25').current, repo.get('o3').current, repo.get('o3_vgas').current, repo.get('o3_vref').current, repo.get('no2').current, repo.get('no2_vgas').current, repo.get('no2_vref').current, repo.get('tdegc').current, repo.get('rh').current, repo.get('dba').avg, repo.get('dba').max, repo.get('vusb').avg, repo.get('vusb').min, repo.get('vbat').avg, repo.get('vbat').min)) log.info('SD:wrote log and closed') s.close() await asyncio.sleep(0)
def day_of_month(days_in_future=0): """Get the day of the month.""" secs = urtc.tuple2seconds(datetime()) secs += days_in_future * _SECS_IN_DAY future = urtc.seconds2tuple(int(secs)) return future[2]
async def run_mic(self): # dmacount range: 2 to 128 incl # dmalen range: 8 to 1024 incl bck_pin = Pin(13) ws_pin = Pin(12) sdin_pin = Pin(14) audio=I2S(I2S.NUM0, bck=bck_pin, ws=ws_pin, sdin=sdin_pin, mode=I2S.MASTER_RX, samplerate=SAMPLES_PER_SECOND, dataformat=I2S.B32, channelformat=I2S.RIGHT_LEFT, standard=I2S.PHILIPS, dmacount=64, dmalen=256) timer_ms = ms_timer.MillisecTimer() noise = dba.DBA(samples=10000, resolution=dba.B16, coeffa=(1.0, -2.3604841 , 0.83692802, 1.54849677, -0.96903429, -0.25092355, 0.1950274), coeffb=(0.61367941, -1.22735882, -0.61367941, 2.45471764, -0.61367941, -1.22735882, 0.61367941)) logmic.info('opening WAV file') local_timestamp = gmt_to_pst(urtc.tuple2seconds(ds3231.datetime())) ld = urtc.seconds2tuple(local_timestamp) fn = '/sd/mic-{}-{}-{}-{}-{}-{}.wav'.format(ld.year, ld.month, ld.day, ld.hour, ld.minute, ld.second) m=open(fn,'wb') wav_header = wavheader.gen_wav_header(SAMPLES_PER_SECOND, BITS_PER_SAMPLE, 1, SAMPLES_PER_SECOND * RECORD_TIME_IN_SECONDS) logmic.debug('write WAV header') m.write(wav_header) numread = 0 numwrite = 0 bytes_in_dma_memory = 0 overrun_count = 0 sdwrite_over_100ms = 0 sdwrite_50_to_100ms = 0 sdwrite_count = 0 dma_capacity = 64 * 256 * NUM_BYTES_RX # dmacount*dmalen*8 samples = bytearray(NUM_BYTES_IN_SAMPLE_BLOCK) sd_sector = bytearray(NUM_BYTES_IN_SDCARD_SECTOR) bytes_remaining_to_rx = NUM_SAMPLE_BYTES_TO_RX mic_file_open = True logmic.info('recording start') while True: try: start_ticks_us = utime.ticks_us() # read samples from microphone numread = audio.readinto(samples, timeout=0) bytes_remaining_to_rx -= numread if numread == 0: # no samples available in DMA memory # allow lower priority coroutines to run await timer_ms(2) bytes_in_dma_memory = 0 else: bytes_in_dma_memory -= numread # copy sample from left channel and reduce sample resolution to 16 bits num_copied = i2stools.copy(bufin=samples, bufout=sd_sector, channel=i2stools.LEFT, format=i2stools.B16) # feed samples to dBA calculation res = noise.calc(sd_sector) if (res != None): # dba result ready repo.add('dba', res) logmic.debug("noise = {:.1f} dB(A)".format(repo.get('dba').current)) # write samples to SD Card if bytes_remaining_to_rx > 0: start_sd_write = utime.ticks_us() numwrite = m.write(sd_sector) sd_write_time = utime.ticks_diff(utime.ticks_us(), start_sd_write) sdwrite_count += 1 logmic.debug('sd_write_time = %d', sd_write_time) if (sd_write_time) > 100*1000: # 100ms sdwrite_over_100ms += 1 elif (sd_write_time) > 50*1000: # 50ms sdwrite_50_to_100ms += 1 end_ticks_us = utime.ticks_us() bytes_in_dma_memory += (utime.ticks_diff(end_ticks_us, start_ticks_us) * (SAMPLES_PER_SECOND * NUM_BYTES_RX)) // 1000000 if bytes_in_dma_memory > dma_capacity: overrun_count += 1 logmic.debug('Mic: DMA overrun!, count= ', overrun_count) elif mic_file_open == True: m.close() logmic.info('recording done') logmic.info('Stats:\n overrun_count: {}\n' ' sdwrite_50_to_100ms: {}\n' ' sdwrite_over_100ms: {}\n' ' sdwrite_count: {}\n'.format(overrun_count, sdwrite_50_to_100ms, sdwrite_over_100ms, sdwrite_count)) mic_file_open = False # fft TODO coming soon .... ''' num_samples = 256 y = bytearray(num_samples * 4) # (sample / 2) freq bins, 2 floats per bin (real/imag) fft.fft(sd_sector, y) print('fft results') print(ustruct.unpack('>fffff', y)[0]) print(ustruct.unpack('>fffff', y)[1]) print(ustruct.unpack('>fffff', y)[2]) print(ustruct.unpack('>fffff', y)[3]) print(ustruct.unpack('>fffff', y)[4]) ''' except Exception as e: m.close() audio.deinit()