async reconfigure(cb, options) {
        await new Promise((resolve) => {
            this.mutexes.reconfigure.take(() => {
                resolve();
            });
        });

        const reconfOptions = {
            reconfigState: HomieCommonAttributes.STATE.INIT,
            targetState: HomieCommonAttributes.STATE.READY,
            errorState: HomieCommonAttributes.STATE.ALERT
        };

        if (options !== undefined) {
            Object.assign(reconfOptions, options);
        }

        const previousState = this.state;

        try {
            await this.setState(reconfOptions.reconfigState);
            await cb();

            // Since the ready state is used by the handles to determine whether they should publish stuff,
            // we must never exit reconfigure in the READY state if we are in fact not READY
            if (reconfOptions.targetState === HomieCommonAttributes.STATE.READY && !this.isConnected) {
                Logger.debug(`Overriding reconfigure target state '${reconfOptions.targetState}' with '${previousState}' since we're not connected.`);

                reconfOptions.targetState = previousState;
            }

            await this.setState(reconfOptions.targetState);

            this.mutexes.reconfigure.leave();
        } catch (err) {
            Logger.error("MQTT reconfiguration error", err);
            await this.setState(reconfOptions.errorState);

            this.mutexes.reconfigure.leave();

            throw err;
        }
    }
Set the controller in reconfiguration mode, then call the callback cb. Attributes, devices and properties can be
safely reconfigured or changed  while inside the callback.

@param {reconfigureCb} cb
@param {object} [options]
@param {string} [options.reconfigState]
@param {string} [options.targetState]
@param {string} [options.errorState]
@return {Promise<void>}