sendMessageHelper(msg, options) {
        return new Promise((resolve, reject) => {
            /*
                The alternative to this in-method function declaration would be some insanity like
                RetryWrapper.sendMessageHelperHelper(msg, options, resolve, reject)
             */
            const doRetry = () => {
                this.retryHandshakeHelper(msg, options).then(() => {
                    this.sendMessageHelper(msg, options).then(response => {
                        resolve(response);
                    }).catch(err => {
                        reject(err);
                    });
                }).catch(err => {
                    reject(err);
                });
            };


            //Make sure that we have a valid recent stamp. Without it, we don't even have to try sending something
            if (this.miioSocket.codec.stamp.isValid()) {
                this.miioSocket.sendMessage(msg, {timeout: options.timeout}).then(response => {
                    resolve(response);
                }).catch(err => {
                    if (err instanceof MiioTimeoutError && !(err instanceof RetryWrapperSurrenderError)) {
                        doRetry();
                    } else {
                        reject(err); //Throw this further up if it's not a timeout
                    }
                });
            } else {
                doRetry();
            }
        });
    }
@param {object} msg JSON object to send to remote
@param {object} options
@param {number=} options.retries
@param {number=} options.timeout custom timeout in milliseconds
@return {Promise<object>}