enrich() {
		if(! this.id) {
			throw new Error('Device has no identifier yet, handshake needed');
		}

		if(this.model && ! this.tokenChanged && this.packet.token) {
			// This device has model info and a valid token
			return Promise.resolve();
		}

		if(this.enrichPromise) {
			// If enrichment is already happening
			return this.enrichPromise;
		}

		// Check if there is a token available, otherwise try to resolve it
		let promise;
		if(! this.packet.token) {
			// No automatic token found - see if we have a stored one
			this.debug('Loading token from storage, device hides token and no token set via options');
			this.autoToken = false;
			promise = tokens.get(this.id)
				.then(token => {
					this.debug('Using stored token:', token);
					this.packet.token = Buffer.from(token, 'hex');
					this.tokenChanged = true;
				});
		} else {
			if(this.tokenChanged) {
				this.autoToken = false;
			} else {
				this.autoToken = true;
				this.debug('Using automatic token:', this.packet.token.toString('hex'));
			}
			promise = Promise.resolve();
		}

		return this.enrichPromise = promise
			.then(() => this.call('miIO.info'))
			.then(data => {
				this.enriched = true;
				this.model = data.model;
				this.tokenChanged = false;

				this.enrichPromise = null;
			})
			.catch(err => {
				this.enrichPromise = null;
				this.enriched = true;

				if(err.code === 'missing-token') {
					// Rethrow some errors
					err.device = this;
					throw err;
				}

				if(this.packet.token) {
					// Could not call the info method, this might be either a timeout or a token problem
					const e = new Error('Could not connect to device, token might be wrong');
					e.code = 'connection-failure';
					e.device = this;
					throw e;
				} else {
					const e = new Error('Could not connect to device, token needs to be specified');
					e.code = 'missing-token';
					e.device = this;
					throw e;
				}
			});
	}
Enrich this device with detailed information about the model. This will
simply call miIO.info.