class SpiAdc: _CHANNELS = C.ADC_CHANNELS() _VREFS = C.ADC_VREFS() def __init__(self): self._log = LOGGER_FACTORY.get_logger('ipa.adc') self._spi = spidev.SpiDev() self._spi.open(0, 0) if len(SpiAdc._CHANNELS) != len(SpiAdc._VREFS): raise config.InvalidConfigException( 'config has %d channels, but %d vrefs' % (len(SpiAdc._CHANNELS), len(SpiAdc._VREFS))) self._log.info('initialized (channels: %s; vrefs: %s)' % (SpiAdc._CHANNELS, SpiAdc._VREFS)) def _read(self, channel): """Reads ADC channel 0..7""" response = self._spi.xfer2([1, (8 + channel) << 4, 0]) value = ((response[1] & 3) << 8) + response[2] return value / 1023.0 # 10 bit resolution def get_sample(self): sample = {} for i, channel in enumerate(SpiAdc._CHANNELS): vref = SpiAdc._VREFS[i] sample[channel] = (common.timestamp(), self._read(channel) * vref) return 'adc', sample
def _upload(self): """Returns True if data was uploaded, False if (likely) not.""" data_json = json.dumps(self._queue) data_bz2 = bz2.compress(data_json) data_bz2_size = len(data_bz2) self._failed_uploads += 1 # assume failure; will reset to zero on success if data_bz2_size > C.UPLOAD_MAX_SIZE_KB() * 1024: self._queue = {} self._log.critical( 'discarded upload buffer of size %d after %d failed uploads' % (data_bz2_size, self._failed_uploads)) return try: request = urllib2.Request( ARGS.server_url() + 'ul.php', data_bz2, {'Content-Type': 'application/octet-stream'}) if ARGS.server_username(): user_colon_pass = '******' % (ARGS.server_username(), ARGS.server_password()) auth_string = base64.encodestring(user_colon_pass).replace( '\n', '') request.add_header('Authorization', 'Basic %s' % auth_string) self._log.debug('uploading %d bytes...' % data_bz2_size) response = urllib2.urlopen( request, timeout=C.TIMEOUT_HTTP_REQUEST_SECONDS()) if response.getcode() != 200: self._log.error('failed to upload data: HTTP status code %d' % response.getcode()) return except Exception: self._log.error('failed to upload data: %s' % traceback.format_exc()) return response_content = response.read() try: response_dict = json.loads(response_content) except Exception: # This might be the 3G stick's error/"no network" (or rather: "no javascript" :-) page, to # which it redirects when offline. self._log.error( 'failed to parse server response: %sserver response begins with: "%s"' % (traceback.format_exc(), response_content[:10240])) # return first 10kB return if response_dict.setdefault('status', 'n/a') != 'ok': self._log.error('upload failed; status: %s' % response_dict['status']) else: self._log.debug('upload OK; response: %s' % response_content) self._log.debug('datos enviados: %s' % data_json) self._queue = {} self._failed_uploads = 0 # Add commands to main command queue. This also happens on failure; an outdated client might be # causing the failure in the first place. del response_dict['status'] server_commands = [] for k, v in response_dict.items(): server_commands.append((k, v)) return server_commands
def _shutdown(self): """Deregister GPIO callbacks and attempt to shut down all threads gracefully.""" self._uploader_termination_event.set() threads_left = common.join_all_threads(C.TIMEOUT_SHUTDOWN_SECONDS()) if threads_left: self._log.warning('%d thread(s) failed to shutdown' % threads_left) else: self._log.info('all threads shutdown successfully') if not C.DEMO_MODE_ENABLED(): GPIO.cleanup( ) # Do this last, otherwise GPIO may fail in running threads.
def get_sample(self): ticks = self._ticks.get_and_reset() wide = C.RAIN_SIZE_WIDE_MM() long = C.RAIN_SIZE_LONG_MM() drops = C.RAIN_DROPS() area_mm2 = wide * long area_m2 = area_mm2 / 1000000 drops_m2 = drops / area_m2 l_m2 = drops_m2 * 0.001 / 20 rain = ticks * l_m2 return 'rain', (common.timestamp(), rain)
def __init__(self): self._log = LOGGER_FACTORY.get_logger('weather.rain') self._ticks = rain_ticks.Ticks() # self._startup_time = common.timestamp() # TODO: Consider removing start timestamp and only use sample start/end timestamps. self._register_callback(self._ticks.add_edge) self._log.info('initialized') self._log.info( 'pin=%d debounce=%dms Wide=%g Long=%g Drops=%d' % (C.RAIN_INPUT_PIN(), C.RAIN_DEBOUNCE_MILLIS(), C.RAIN_SIZE_WIDE_MM(), C.RAIN_SIZE_LONG_MM(), C.RAIN_DROPS()))
class Door: """Monitors the shed door via GPIO.""" _PIN = C.DOOR_INPUT_PIN() _OPEN_STATE = C.DOOR_OPEN_STATE() # TODO: Make these configurable? They might depend on cable layout etc. _STABLE_READ_INTERVAL_MILLIS = 25 _STABLE_READ_COUNT = 5 # 20 was OK, but I believe sometimes too slow. def __init__(self): self._log = LOGGER_FACTORY.get_logger('weather.door') self._lock = threading.Lock() self._events = [] self._previous_door_open = None GPIO.setup(Door._PIN, GPIO.IN, pull_up_down=C.DOOR_PUD()) GPIO.add_event_detect(Door._PIN, GPIO.BOTH, callback=self._read_door_callback, bouncetime=C.DOOR_DEBOUNCE_MILLIS()) door_open = self._read_door_callback(0) self._log.info('initialized (pin=%d open=%d debounce=%d)' % (Door._PIN, door_open, C.DOOR_DEBOUNCE_MILLIS())) def _read_door_callback(self, pin_ignored): read_stable = raspisys.read_stable(Door._PIN, Door._STABLE_READ_COUNT, Door._STABLE_READ_INTERVAL_MILLIS, self._log) door_open = 1 if read_stable == Door._OPEN_STATE else 0 self._log.debug('door_open in callback: %d' % door_open) with self._lock: self._consider_door_open_locked(door_open) return door_open def get_sample(self): # We don't want to rely on the callback; if we miss one edge (e.g. because the switch is # bouncing) we'd be stuck with an incorrect state until the next callback happens. So we do a # simple read here, accepting that we may be unlucky and hit noise on the cable, but that seems # much less likely that the first case. It would also very likely be corrected in the next call. door_open = 1 if GPIO.input(Door._PIN) == Door._OPEN_STATE else 0 self._log.debug('door_open in get_sample: %d' % door_open) with self._lock: self._consider_door_open_locked(door_open) events = self._events self._events = [] return 'door', events def _consider_door_open_locked(self, door_open): """Append new door_open state if it differs from the previous state. Must hold lock.""" if door_open != self._previous_door_open: self._events.append((common.timestamp(), door_open)) self._previous_door_open = door_open
def _register_callback(self, callback): GPIO.setup(C.WIND_INPUT_PIN(), GPIO.IN, pull_up_down=C.WIND_PUD()) # Up to (at least) GPIO 0.5.9 edge detection is partly broken. RISING always behaves like BOTH, # FALLING sometimes behaves like BOTH. Since BOTH is the only mode that works as expected, we # use BOTH even though that makes computation of revolution time more complicated. # (Unfortunately the callback isn't passed the value that triggered it, so we can't just skip # edges we don't want.) # Bug report: https://sourceforge.net/p/raspberry-gpio-python/tickets/79/ GPIO.add_event_detect(C.WIND_INPUT_PIN(), GPIO.BOTH, callback=callback, bouncetime=C.WIND_DEBOUNCE_MILLIS())
def __init__(self): self._log = LOGGER_FACTORY.get_logger('weather.count') # Only one blinking thread at a time. self._blink_semaphore = threading.Semaphore() # Synchronize access in _read_callback() and get_sample(). self._lock = threading.Lock() self._count = 0 self._pilots = [] self._last_reset_yday = time.localtime(time.time()).tm_yday self._log.info(('initialized (plus: pin=%d trigger=%d debounce=%d; ' + 'minus: pin=%d trigger=%d debounce=%d)') % (PilotCount._PLUS_PIN, PilotCount._PLUS_TRIGGER_STATE, C.PILOTS_PLUS_DEBOUNCE_MILLIS(), PilotCount._MINUS_PIN, PilotCount._MINUS_TRIGGER_STATE, C.PILOTS_MINUS_DEBOUNCE_MILLIS())) # Read previous count if it's fresh. try: mtime = os.stat(_STATE_FILE).st_mtime if (time.time() - mtime) / 60.0 < _STATE_LIFETIME_MINUTES: with open(_STATE_FILE) as f: self._count = int(f.read()) with self._lock: # not really necessary at this point self._append_count_locked() self._log.info('read pilot count from file: %d @ %s' % (self._count, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(mtime)))) except Exception: self._log.warning('could not read state from file %s' % _STATE_FILE) GPIO.setup(PilotCount._PLUS_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN if PilotCount._PLUS_TRIGGER_STATE else GPIO.PUD_UP) GPIO.setup(PilotCount._MINUS_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN if PilotCount._MINUS_TRIGGER_STATE else GPIO.PUD_UP) GPIO.setup(PilotCount._LED_PIN, GPIO.OUT) GPIO.add_event_detect(PilotCount._PLUS_PIN, GPIO.BOTH, callback=self._read_callback, bouncetime=C.PILOTS_PLUS_DEBOUNCE_MILLIS()) GPIO.add_event_detect(PilotCount._MINUS_PIN, GPIO.BOTH, callback=self._read_callback, bouncetime=C.PILOTS_MINUS_DEBOUNCE_MILLIS())
def __init__(self): self._log = LOGGER_FACTORY.get_logger('ipa.main') self._log.info(K.CLIENT_GREETING) auth_info = ((' (authenticated as user "%s")' % ARGS.server_username()) if ARGS.server_username() else '') self._log.info('URL: %s%s' % (ARGS.server_url(), auth_info)) self._log.info('client version: %s' % C.CLIENT_VERSION()) if C.DEMO_MODE_ENABLED(): self._log.warn('DEMO MODE ENABLED') # Create main command queue. self._main_cq = Queue.Queue() # Create thread termination Event for Uploader. self._uploader_termination_event = threading.Event()
def get_logger(self, name): """Return the logger with the specified name, creating it if required.""" if not self._initialized: from config import C self.initialize(C.LOGGING_LEVEL(), C.LOGGING_MAX_FILE_SIZE_KB(), C.LOGGING_BACKUP_COUNT()) i = name.find('.') if i < 0: return self._get_toplevel_logger(name) self._get_toplevel_logger(name[:i]) # make sure it exists return logging.getLogger(name)
def __init__(self): self._log = LOGGER_FACTORY.get_logger('weather.door') self._lock = threading.Lock() self._events = [] self._previous_door_open = None GPIO.setup(Door._PIN, GPIO.IN, pull_up_down=C.DOOR_PUD()) GPIO.add_event_detect(Door._PIN, GPIO.BOTH, callback=self._read_door_callback, bouncetime=C.DOOR_DEBOUNCE_MILLIS()) door_open = self._read_door_callback(0) self._log.info('initialized (pin=%d open=%d debounce=%d)' % (Door._PIN, door_open, C.DOOR_DEBOUNCE_MILLIS()))
def _register_callback(self, callback): GPIO.setup(C.WIND_INPUT_PIN(), GPIO.IN, pull_up_down=C.WIND_PUD()) # readded pull_up_down as, even though I've hardwared a pull_down 47Kohm resistor, it keeps on having wrong lectures # from time to time. # GPIO.setup(C.WIND_INPUT_PIN(), GPIO.IN) # Up to (at least) GPIO 0.5.9 edge detection is partly broken. RISING always behaves like BOTH, # FALLING sometimes behaves like BOTH. Since BOTH is the only mode that works as expected, we # use BOTH even though that makes computation of revolution time more complicated. # (Unfortunately the callback isn't passed the value that triggered it, so we can't just skip # edges we don't want.) # Bug report: https://sourceforge.net/p/raspberry-gpio-python/tickets/79/ # Original: GPIO.add_event_detect(C.WIND_INPUT_PIN(), GPIO.BOTH, callback=callback, bouncetime=C.WIND_DEBOUNCE_MILLIS()) # Removed software debounce as I have hardwared debounce with a capacitor GPIO.add_event_detect(C.WIND_INPUT_PIN(), GPIO.BOTH, callback=callback)
def main(): args = arg_parse() # ---- setup device ---- device = 'cuda' if torch.cuda.is_available() else 'cpu' print('==> Using device ' + device) # ---- setup configs ---- C.merge_from_file(args.cfg) C.freeze() seed.set_seed(C.SOLVER.SEED) # ---- setup logger and output ---- output_dir = os.path.join(C.OUTPUT_DIR, C.DATASET.NAME, args.output) os.makedirs(output_dir, exist_ok=True) logger = lu.construct_logger('gripnet', output_dir) logger.info('Using ' + device) logger.info(C.dump()) # ---- setup dataset ---- data = construct_dataset(C) device = torch.device(device) data = data.to(device) # ---- setup model ---- print('==> Building model..') model = GripNet(C.GRIPN.GG_LAYERS, C.GRIPN.GD_LAYERS, C.GRIPN.DD_LAYERS, data.n_d_node, data.n_g_node, data.n_dd_edge_type).to(device) # TODO Visualize model # ---- setup trainers ---- optimizer = torch.optim.Adam(model.parameters(), lr=C.SOLVER.BASE_LR) # TODO trainer = Trainer(C, device, data, model, optimizer, logger, output_dir) if args.resume: # Load checkpoint print('==> Resuming from checkpoint..') cp = torch.load(args.resume) trainer.model.load_state_dict(cp['net']) trainer.optim.load_state_dict(cp['optim']) trainer.epochs = cp['epoch'] trainer.train_auprc = cp['train_auprc'] trainer.val_auprc = cp['val_auprc'] trainer.train_auroc = cp['train_auroc'] trainer.val_auroc = cp['val_auroc'] trainer.train_ap = cp['train_ap'] trainer.val_ap = cp['val_ap'] trainer.train()
class Picture: """Takes Picture and stores it""" _RESOLUTION_HOR = C.CAMERA_RESOLUTION_HOR() _RESOLUTION_VER = C.CAMERA_RESOLUTION_VER() def __init__(self): self._log = LOGGER_FACTORY.get_logger('weather.camera') self._log.info('Resolution: Horizontal=%d Vertical=%d' % (Picture._RESOLUTION_HOR, Picture._RESOLUTION_VER)) def get_sample(self): camera.resolution = (Picture._RESOLUTION_HOR, Picture._RESOLUTION_VER) camera.start_preview() sleep(2) timestamp = common.timestamp() camera.capture('/var/www/html/pictures/picture%s.jpg' % timestamp) camera.stop_preview() return 'picture', timestamp
class Dht: """Reads DHT11/DHT22/AM2302 sensor.""" _SENSOR = C.DHT_SENSOR() _PIN = C.DHT_PIN() _RETRIES = C.DHT_RETRIES() def __init__(self): self._log = LOGGER_FACTORY.get_logger('ipa.dht') self._log.info('sensor=%d pin=%d retries=%d' % (Dht._SENSOR, Dht._PIN, Dht._RETRIES)) def get_sample(self): humidity, temperature = Adafruit_DHT.read_retry(Dht._SENSOR, Dht._PIN, retries=Dht._RETRIES) if humidity == None or temperature == None: self._log.warning('failed to read temperature/humidity') return 'temp_hum', (common.timestamp(), temperature, humidity)
class Dht(): """Reads DHT11/DHT22/AM2302 sensor.""" _SENSOR = C.DHT_SENSOR() _PIN = C.DHT_PIN() _RETRIES = C.DHT_RETRIES() def __init__(self): self._log = LOGGER_FACTORY.get_logger('weather.dht') self._log.info('sensor=%d pin=%d retries=%d' % (Dht._SENSOR, Dht._PIN, Dht._RETRIES)) def get_sample(self): humidity, temperature = Adafruit_DHT.read_retry(Dht._SENSOR, Dht._PIN, retries=Dht._RETRIES) if humidity == None or temperature == None: self._log.warning('failed to read temperature/humidity') if humidity > 100: #Humidity can't be higer than 100% self._log.warning('Temp & humidity wrong value. Reading again') while humidity > 100: #Read new humidity data as the sensor failed humidity, temperature = Adafruit_DHT.read_retry(Dht._SENSOR, Dht._PIN, retries=Dht._RETRIES) return 'temp_hum', (common.timestamp(), temperature, humidity)
class Pressure: """Reads BMP183 sensor for preasure / Temp """ _CS = C.PRESSURE_CS() _SCK = C.PRESSURE_SCK() _SDI = C.PRESSURE_SDI() _SDO = C.PRESSURE_SDO() def __init__(self): self._log = LOGGER_FACTORY.get_logger('weather.pressure') self._log.info( 'CS=%d SCK=%d SDI=%d SDO=%d' % (Pressure._CS, Pressure._SCK, Pressure._SDI, Pressure._SDO)) def get_sample(self): bmp = bmp183() bmp.measure_pressure() pre = bmp.pressure / 100.0 if pre == None: self._log.warning('failed to read Pressure') return 'press', (common.timestamp(), pre)
class Measures: """Stores the values of temperature and humidity and gets the average""" _SENSOR = C.DHT_SENSOR() _PIN = C.DHT_PIN() _RETRIES = C.DHT_RETRIES() def __init__(self): self._count = 0 self._temp = 0 self._hum = 0 self._lock = threading.RLock() def get_and_reset(self): """Return the average temperature and humidity and turns counter to 0""" with self._lock: count = self._count temp = self._temp hum = self._hum self._count = 0 self._temp = 0 self._hum = 0 humidity = hum / count temperature = temp / count return humidity, temperature def add_measure(self): """Add one measure of temperature and humidity""" with self._lock: self._count = self._count + 1 humidity, temperature = Adafruit_DHT.read_retry( Measures._SENSOR, Measures._PIN, retries=Measures._RETRIES) if humidity == None or temperature == None: self._log.warning('failed to read temperature/humidity') if humidity > 100: #Humidity can't be higer than 100% self._log.warning('Temp & humidity wrong value. Reading again') while humidity > 100: #Read new humidity data as the sensor failed humidity, temperature = Adafruit_DHT.read_retry( Measures._SENSOR, Measures._PIN, retries=Measures._RETRIES) self._hum = self._hum + humidity self._temp = self._temp + temperature
def __init__(self, calibration_mode=False): self._log = LOGGER_FACTORY.get_logger('weather.wind') self._revolutions = wind_revolutions.Revolutions( C.WIND_EDGES_PER_REV()) self._startup_time = common.timestamp() # TODO: Consider removing start timestamp and only use sample start/end timestamps. self._calibration_mode = calibration_mode if calibration_mode: self._calibration_logger = calibration_logger.CalibrationLogger() self._revolutions.calibration_init(self._calibration_logger) self._register_callback( self._revolutions.calibration_add_edge_and_log) else: self._register_callback(self._revolutions.add_edge) self._stats = wind_stats.WindStats(C.WIND_HSF(), C.WIND_LSF(), C.WIND_MAX_ROTATION(), self._startup_time) self._log.info('initialized - CALIBRATION MODE' if calibration_mode else 'initialized') self._log.info('pin=%d edges=%d debounce=%dms LSF=%g HSF=%g max=%dms' % (C.WIND_INPUT_PIN(), C.WIND_EDGES_PER_REV(), C.WIND_DEBOUNCE_MILLIS(), C.WIND_LSF(), C.WIND_HSF(), C.WIND_MAX_ROTATION()))
def run(self): try: self._log.info('starting (upload interval: %ds)' % C.UPLOAD_INTERVAL_SECONDS()) wait_seconds = C.UPLOAD_INTERVAL_SECONDS() while True: if self._termination_event.wait( wait_seconds): # returns immediately if <= 0 return start_time = time.time() self._poll_data_sources() client_command = interceptor.process(self._queue) server_commands = self._upload() commands = [] if client_command: commands = [client_command] elif server_commands: commands = server_commands for command in commands: self._main_cq.put(command) wait_seconds = C.UPLOAD_INTERVAL_SECONDS() - (time.time() - start_time) except Exception: self._log.critical(traceback.format_exc())
def _register_callback(self, callback): GPIO.setup(C.RAIN_INPUT_PIN(), GPIO.IN, pull_up_down=C.RAIN_PUD()) GPIO.add_event_detect(C.RAIN_INPUT_PIN(), GPIO.RISING, callback=callback, bouncetime=C.RAIN_DEBOUNCE_MILLIS())
def get_sample(self): return 'meta', {'stratum': raspisys.get_stratum(), # TODO: Avoid subprocess? 'client_version': C.CLIENT_VERSION(), 'cts': common.timestamp()}
def _initialize(self): # Create state directory. if not os.path.exists(K.STATE_DIR): os.mkdir(K.STATE_DIR) # Create upload thread (started in run() below). self._uploader = uploader.Uploader(self._main_cq, self._uploader_termination_event) # Create data sources. GPIO.setmode(GPIO.BCM) # required before Wind() self._uploader.add_data_source(temperature.Temperature(), True) self._uploader.add_data_source(metadata.Metadata(), False) # Import modules only when enabled, since some again import optional libraries (e.g. DHT). # In demo mode, enable all and import demo instances. if C.WIND_ENABLED() or C.DEMO_MODE_ENABLED(): # NEW: Wind Optional. if C.DEMO_MODE_ENABLED(): import demo.demo_wind as wind # @UnusedImport else: import wind # @Reimport self._uploader.add_data_source(wind.Wind(), True) if C.DHT_ENABLED() or C.DEMO_MODE_ENABLED(): if C.DEMO_MODE_ENABLED(): import demo.demo_dht as dht # @UnusedImport else: import dht # @Reimport self._uploader.add_data_source(dht.Dht(), True) if C.PRESSURE_ENABLED() or C.DEMO_MODE_ENABLED(): if C.DEMO_MODE_ENABLED(): import demo.demo_pressure as pressure # @UnsuedImport else: import pressure # @Reimport self._uploader.add_data_source(pressure.Pressure(), True) if C.CAMERA_ENABLED(): import camera self._uploader.add_data_source(camera.Picture(), True) if C.RAIN_ENABLED() or C.DEMO_MODE_ENABLED(): if C.DEMO_MODE_ENABLED(): import demo.demo_rain as rain # @UnusedImport else: import rain self._uploader.add_data_source(rain.Rain(), True) if C.WIND_VANE_ENABLED() or C.DEMO_MODE_ENABLED(): if C.DEMO_MODE_ENABLED(): import demo.demo_vane as vane # @UnusedImport else: import vane self._uploader.add_data_source(vane.Direction(), True) if C.ADC_ENABLED() or C.DEMO_MODE_ENABLED(): if C.DEMO_MODE_ENABLED(): import demo.demo_spi_adc as spi_adc # @UnusedImport else: import spi_adc # @Reimport self._uploader.add_data_source(spi_adc.SpiAdc(), True) if C.HUAWEI_ENABLED() or C.DEMO_MODE_ENABLED(): if C.DEMO_MODE_ENABLED(): import demo.demo_huawei_status as huawei_status # @UnusedImport else: import huawei_status # @Reimport self._uploader.add_data_source(huawei_status.HuaweiStatus(), True) if C.DOOR_ENABLED() or C.DEMO_MODE_ENABLED(): if C.DEMO_MODE_ENABLED(): import demo.demo_door as door # @UnusedImport else: import door # @Reimport self._uploader.add_data_source(door.Door(), True) if C.PILOTS_ENABLED() or C.DEMO_MODE_ENABLED(): if C.DEMO_MODE_ENABLED(): import demo.demo_pilot_count as pilot_count # @UnusedImport else: import pilot_count # @Reimport self._uploader.add_data_source(pilot_count.PilotCount(), True)
def main(options): C.update(options) model = ResnetModel() x_train, y_train, x_validate, y_validate, x_test, y_test, train_size, validate_size, test_size = \ pre_process_CIFAR10_data() learning_rate = 0.1 for epoch in range(C['num_epoch']): start_time = time.time() kf = get_minibatches_idx(train_size, C['batch_size'], shuffle=True) train_loss = 0.0 train_batches = 0 for _, train_index in kf: inputs = x_train[train_index] targets = y_train[train_index] inputs, targets = prepare_CIFAR10_data(inputs, targets) loss = model.f_grad_shared(inputs, targets) model.f_update(learning_rate) train_loss += loss train_batches += 1 kf_valid = get_minibatches_idx(validate_size, C['valid_batch_size'], shuffle=False) valid_loss = 0.0 valid_accuracy = 0.0 valid_batches = 0 for _, valid_index in kf_valid: inputs = x_validate[valid_index] targets = y_validate[valid_index] inputs, targets = prepare_CIFAR10_data(inputs, targets) loss, accuracy = model.f_validate(inputs, targets) valid_loss += loss valid_accuracy += accuracy valid_batches += 1 print( '''\ Epoch {} of {} took {:.3f}s training loss: {:.6f} validation loss: {:.6f} validation accuracy: {:.2f} %'''.format( epoch, C['num_epoch'], time.time() - start_time, train_loss / train_batches, valid_loss / valid_batches, valid_accuracy / valid_batches * 100.0, ) ) if epoch + 1 == 41 or epoch + 1 == 61: learning_rate *= 0.1 print('Discount learning rate to', learning_rate) print('Saving model...', end='') np.savez('cifar10_deep_residual_model.npz', *lasagne.layers.get_all_param_values(model.network)) print('Done')
class PilotCount: """Count pilots by manually pressing a button connected to GPIO.""" _PLUS_PIN = C.PILOTS_PLUS_INPUT_PIN() _MINUS_PIN = C.PILOTS_MINUS_INPUT_PIN() _PLUS_TRIGGER_STATE = C.PILOTS_PLUS_TRIGGER_STATE() _MINUS_TRIGGER_STATE = C.PILOTS_MINUS_TRIGGER_STATE() _LED_PIN = C.PILOTS_LED_OUTPUT_PIN() _RESET_HOUR = C.PILOTS_RESET_HOUR() # TODO: Make these configurable? They might depend on cable layout etc. _STABLE_READ_INTERVAL_MILLIS = 20 _STABLE_READ_COUNT = 5 _LED_ON_MILLIS = 200 _LED_OFF_MILLIS = 300 _LED_ON_SHORT_MILLIS = 20 _LED_OFF_SHORT_MILLIS = 40 def __init__(self): self._log = LOGGER_FACTORY.get_logger('ipa.count') # Only one blinking thread at a time. self._blink_semaphore = threading.Semaphore() # Synchronize access in _read_callback() and get_sample(). self._lock = threading.Lock() self._count = 0 self._pilots = [] self._last_reset_yday = time.localtime(time.time()).tm_yday self._log.info(('initialized (plus: pin=%d trigger=%d debounce=%d; ' + 'minus: pin=%d trigger=%d debounce=%d)') % (PilotCount._PLUS_PIN, PilotCount._PLUS_TRIGGER_STATE, C.PILOTS_PLUS_DEBOUNCE_MILLIS(), PilotCount._MINUS_PIN, PilotCount._MINUS_TRIGGER_STATE, C.PILOTS_MINUS_DEBOUNCE_MILLIS())) # Read previous count if it's fresh. try: mtime = os.stat(_STATE_FILE).st_mtime if (time.time() - mtime) / 60.0 < _STATE_LIFETIME_MINUTES: with open(_STATE_FILE) as f: self._count = int(f.read()) with self._lock: # not really necessary at this point self._append_count_locked() self._log.info('read pilot count from file: %d @ %s' % (self._count, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(mtime)))) except Exception: self._log.warning('could not read state from file %s' % _STATE_FILE) GPIO.setup(PilotCount._PLUS_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN if PilotCount._PLUS_TRIGGER_STATE else GPIO.PUD_UP) GPIO.setup(PilotCount._MINUS_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN if PilotCount._MINUS_TRIGGER_STATE else GPIO.PUD_UP) GPIO.setup(PilotCount._LED_PIN, GPIO.OUT) GPIO.add_event_detect(PilotCount._PLUS_PIN, GPIO.BOTH, callback=self._read_callback, bouncetime=C.PILOTS_PLUS_DEBOUNCE_MILLIS()) GPIO.add_event_detect(PilotCount._MINUS_PIN, GPIO.BOTH, callback=self._read_callback, bouncetime=C.PILOTS_MINUS_DEBOUNCE_MILLIS()) def _read_callback(self, pin): read_stable = raspisys.read_stable(pin, PilotCount._STABLE_READ_COUNT, PilotCount._STABLE_READ_INTERVAL_MILLIS, self._log) delta = 0 if pin == PilotCount._PLUS_PIN: if read_stable == PilotCount._PLUS_TRIGGER_STATE: delta = 1 elif pin == PilotCount._MINUS_PIN: if read_stable == PilotCount._MINUS_TRIGGER_STATE: delta = -1 if not delta: return with self._lock: if self._blink_semaphore.acquire(False): # If we're currently blinking, ignore this event. self._reset_at_night_locked() self._count = max(0, self._count + delta) self._log.debug('count += %d -> %d' % (delta, self._count)) self._update_pilots_locked() BlinkThread(self._count, self._blink_semaphore).start() def _reset_at_night_locked(self): t = time.localtime(time.time()) if t.tm_hour >= PilotCount._RESET_HOUR and t.tm_yday != self._last_reset_yday: if self._count: self._log.debug('resetting counter to 0 (was: %d)' % self._count) self._count = 0 self._update_pilots_locked() # Avoid long blanks in the DB. self._last_reset_yday = t.tm_yday def _update_pilots_locked(self): self._append_count_locked() with open(_STATE_FILE, 'w') as f: f.write(str(self._count)) def _append_count_locked(self): self._pilots.append((common.timestamp(), self._count)) def get_sample(self): with self._lock: self._reset_at_night_locked() pilots = self._pilots self._pilots = [] return 'pilots', pilots
#!/usr/bin/env python import RPi.GPIO as GPIO #@UnresolvedImport import subprocess import traceback import common from config import C from logger import LOGGER_FACTORY from wind import Wind if __name__ == "__main__": log = LOGGER_FACTORY.get_logger('wind_calibrate') try: log.info('--- wind_calibrate started, waiting for ntpd ---') if subprocess.call('../await_clock_sync.sh'): log.critical('--- failed to sync clock ---') else: log.info('--- clock in sync ---') GPIO.setmode(GPIO.BCM) wind = Wind(calibration_mode=True) raw_input('Press ENTER to quit...\n' ) # just in case there's a kb and a screen GPIO.cleanup() wind.terminate_calibration() threads_left = common.join_all_threads(C.TIMEOUT_SHUTDOWN_SECONDS()) print '--- exiting - threads left: %d ---' % threads_left except Exception: log.critical(traceback.format_exc())
from config import Config as C config = C( seed=42, env="Pong-v0", episodes=100000, log_interval=100, transforms=[ C(type="grayscale"), C(type="stack", k=4, dim=0), C(type="skip", k=4), C(type="normalize"), ], gamma=0.99, entropy_weight=1e-2, horizon=8, workers=32, model=C(size=128, encoder=C(type="conv", size=16)), opt=C(type="adam", lr=1e-3), )
# TODO: Make this a class. import common from config import C from logger import LOGGER_FACTORY MAX_TEMP = C.TEMPERATURE_SHUTDOWN_AT() LOG = LOGGER_FACTORY.get_logger('ipa.intcpt') def process(queue): """Process the queue, possibly modifying it. May return a command.""" command = None last_temp = _get_last_sample(queue, 'temp') if last_temp and last_temp[1] >= MAX_TEMP: LOG.info( 'shutting down since temperature of %s exceeds maximum of %s' % (last_temp[1], MAX_TEMP)) queue['status'] = (common.timestamp(), 'shutdown: CPU temp = %s (max: %s)' % (last_temp[1], MAX_TEMP)) command = ('exit', 100) # 100 = shutdown else: queue['status'] = (common.timestamp(), 'ok') return command def _get_last_sample(queue, type_key): samples = queue.get(type_key, []) return samples[-1] if samples else None
class bmp183: """Class for Bosch BMP183 pressure and temperature sensor with SPI interface as sold by Adafruit""" # BMP183 registers _CS = C.PRESSURE_CS() _SCK = C.PRESSURE_SCK() _SDI = C.PRESSURE_SDI() _SDO = C.PRESSURE_SDO() BMP183_REG = { #@ Calibration data 'CAL_AC1': 0xAA, 'CAL_AC2': 0xAC, 'CAL_AC3': 0xAE, 'CAL_AC4': 0xB0, 'CAL_AC5': 0xB2, 'CAL_AC6': 0xB4, 'CAL_B1': 0xB6, 'CAL_B2': 0xB8, 'CAL_MB': 0xBA, 'CAL_MC': 0xBC, 'CAL_MD': 0xBE, #@ Chip ID. Value fixed to 0x55. Useful to check if communication works 'ID': 0xD0, 'ID_VALUE': 0x55, #@ VER Undocumented 'VER': 0xD1, #@ SOFT_RESET Write only. If set to 0xB6, will perform the same sequence as power on reset. 'SOFT_RESET': 0xE0, #@ CTRL_MEAS Controls measurements 'CTRL_MEAS': 0xF4, #@ DATA 'DATA': 0xF6, } # BMP183 commands BMP183_CMD = { #@ Chip ID Value fixed to 0x55. Useful to check if communication works 'ID_VALUE': 0x55, # SPI bit to indicate READ or WRITE operation 'READWRITE': 0x80, # Read TEMPERATURE, Wait time 4.5 ms 'TEMP': 0x2E, 'TEMP_WAIT': 0.0045, # Read PRESSURE 'PRESS': 0x34, # 001 # PRESSURE reading modes # Example usage: (PRESS || (OVERSAMPLE_2 << 4) 'OVERSAMPLE_0': 0x0, # ultra low power, no oversampling, wait time 4.5 ms 'OVERSAMPLE_0_WAIT': 0.0045, 'OVERSAMPLE_1': 0x1, # standard, 2 internal samples, wait time 7.5 ms 'OVERSAMPLE_1_WAIT': 0.0075, 'OVERSAMPLE_2': 0x2, # high resolution, 4 internal samples, wait time 13.5 ms 'OVERSAMPLE_2_WAIT': 0.0135, 'OVERSAMPLE_3': 0x3, # ultra high resolution, 8 internal samples, Wait time 25.5 ms 'OVERSAMPLE_3_WAIT': 0.0255, } def __init__(self): self.temperature = 0 self.pressure = 0 # Setup Raspberry PINS, as numbered on BOARD self.SCK = bmp183._SCK # GPIO for SCK, other name SCLK. ORIGINAL=14 self.SDO = bmp183._SDO # GPIO for SDO, other name MISO. ORIGINAL=15 self.SDI = bmp183._SDI # GPIO for SDI, other name MOSI. ORIGINAL=18 self.CS = bmp183._CS # GPIO for CS, other name CE. ORIGINAL=23 self._log = LOGGER_FACTORY.get_logger('weather.bmp183') # SCK frequency 1 MHz self.delay = 1 / 1000000.0 self.set_up_gpio() # Check comunication / read ID ret = self.read_byte(self.BMP183_REG['ID']) if ret != self.BMP183_CMD['ID_VALUE']: self._log.critical( 'BMP183 returned %d instead of 0x55. Communication failed, expect problems.' % (ret)) self.read_calibration_data() # Proceed with initial pressure/temperature measurement self.measure_pressure() #def __del__(self): #self.cleanup_gpio() def set_up_gpio(self): # GPIO initialisation GPIO.setmode(GPIO.BCM) GPIO.setup(self.SCK, GPIO.OUT, initial=GPIO.HIGH) GPIO.setup(self.CS, GPIO.OUT, initial=GPIO.HIGH) GPIO.setup(self.SDI, GPIO.OUT) GPIO.setup(self.SDO, GPIO.IN) def cleanup_gpio(self): # GPIO clean up GPIO.cleanup(self.SCK) GPIO.cleanup(self.CS) GPIO.cleanup(self.SDI) GPIO.cleanup(self.SDO) def read_byte(self, addr): # Read byte from SPI interface from address "addr" ret_value = self.spi_transfer(addr, 0, 1, 8) return ret_value def read_word(self, addr, extra_bits=0): # Read word from SPI interface from address "addr", option to extend read by up to 3 bits ret_value = self.spi_transfer(addr, 0, 1, 16 + extra_bits) return ret_value def write_byte(self, addr, value): # Write byte of "value" to SPI interface at address "addr" self.spi_transfer(addr, value, 0, 8) def spi_transfer(self, addr, value, rw, length): # Bit banging at address "addr", "rw" indicates READ (1) or WRITE (1) operation ret_value = 0 if (rw == 0): spi_addr = addr & (~self.BMP183_CMD['READWRITE']) else: spi_addr = addr | self.BMP183_CMD['READWRITE'] GPIO.output(self.CS, 0) time.sleep(self.delay) for i in range(8): bit = spi_addr & (0x01 << (7 - i)) if (bit): GPIO.output(self.SDI, 1) else: GPIO.output(self.SDI, 0) GPIO.output(self.SCK, 0) time.sleep(self.delay) GPIO.output(self.SCK, 1) time.sleep(self.delay) if (rw == 1): for i in range(length): GPIO.output(self.SCK, 0) time.sleep(self.delay) bit = GPIO.input(self.SDO) GPIO.output(self.SCK, 1) ret_value = (ret_value << 1) | bit time.sleep(self.delay) if (rw == 0): for i in range(length): bit = value & (0x01 << (length - 1 - i)) if (bit): GPIO.output(self.SDI, 1) else: GPIO.output(self.SDI, 0) GPIO.output(self.SCK, 0) time.sleep(self.delay) GPIO.output(self.SCK, 1) time.sleep(self.delay) GPIO.output(self.CS, 1) return ret_value def read_calibration_data(self): # Read calibration data self.AC1 = numpy.int16(self.read_word(self.BMP183_REG['CAL_AC1'])) self.AC2 = numpy.int16(self.read_word(self.BMP183_REG['CAL_AC2'])) self.AC3 = numpy.int16(self.read_word(self.BMP183_REG['CAL_AC3'])) self.AC4 = numpy.uint16(self.read_word(self.BMP183_REG['CAL_AC4'])) self.AC5 = numpy.uint16(self.read_word(self.BMP183_REG['CAL_AC5'])) self.AC6 = numpy.uint16(self.read_word(self.BMP183_REG['CAL_AC6'])) self.B1 = numpy.int16(self.read_word(self.BMP183_REG['CAL_B1'])) self.B2 = numpy.int16(self.read_word(self.BMP183_REG['CAL_B2'])) self.MB = numpy.int16(self.read_word(self.BMP183_REG['CAL_MB'])) self.MC = numpy.int16(self.read_word(self.BMP183_REG['CAL_MC'])) self.MD = numpy.int16(self.read_word(self.BMP183_REG['CAL_MD'])) def measure_temperature(self): # Start temperature measurement self.write_byte(self.BMP183_REG['CTRL_MEAS'], self.BMP183_CMD['TEMP']) # Wait time.sleep(self.BMP183_CMD['TEMP_WAIT']) # Read uncmpensated temperature self.UT = numpy.int32(self.read_word(self.BMP183_REG['DATA'])) self.calculate_temperature() def measure_pressure(self): # Measure temperature - required for calculations self.measure_temperature() # Read 3 samples of uncompensated pressure UP = {} for i in range(3): # Start pressure measurement self.write_byte( self.BMP183_REG['CTRL_MEAS'], self.BMP183_CMD['PRESS'] | (self.BMP183_CMD['OVERSAMPLE_3'] << 4)) # Wait for conversion time.sleep(self.BMP183_CMD['OVERSAMPLE_3_WAIT']) # Store uncmpensated pressure for averaging UP[i] = numpy.int32(self.read_word(self.BMP183_REG['DATA'], 3)) self.UP = (UP[0] + UP[1] + UP[2]) / 3 self.calculate_pressure() def calculate_pressure(self): # Calculate atmospheric pressure in [Pa] self.B6 = self.B5 - 4000 X1 = (self.B2 * (self.B6 * self.B6 / 2**12)) / 2**11 X2 = self.AC2 * self.B6 / 2**11 X3 = X1 + X2 self.B3 = (((numpy.uint32(self.AC1 * 4 + X3)) << self.BMP183_CMD['OVERSAMPLE_3']) + 2) / 4 X1 = self.AC3 * self.B6 / 2**13 X2 = (self.B1 * (self.B6 * self.B6 / 2**12)) / 2**16 X3 = ((X1 + X2) + 2) / 2**2 self.B4 = numpy.uint32(self.AC4 * (X3 + 32768) / 2**15) self.B7 = (numpy.uint32(self.UP) - self.B3) * (50000 >> self.BMP183_CMD['OVERSAMPLE_3']) p = numpy.uint32((self.B7 * 2) / self.B4) X1 = (p / 2**8) * (p / 2**8) X1 = int(X1 * 3038) / 2**16 X2 = int(-7357 * p) / 2**16 self.pressure = p + (X1 + X2 + 3791) / 2**4 def calculate_temperature(self): #Calculate temperature in [degC] X1 = (self.UT - self.AC6) * self.AC5 / 2**15 X2 = self.MC * 2**11 / (X1 + self.MD) self.B5 = X1 + X2 self.T = (self.B5 + 8) / 2**4 self.temperature = self.T / 10.0