/*
 * THIS FILE IS AUTOMATICALLY GENERATED
 *
 * Generator:     sensirion-driver-generator 0.40.0
 * Product:       sht4x
 * Model-Version: 2.1.1
 */
/*
 * Copyright (c) 2024, Sensirion AG
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of Sensirion AG nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef SENSIRIONI2CSHT4X_H
#define SENSIRIONI2CSHT4X_H

#include <SensirionCore.h>
#include <Wire.h>

#define SHT40_I2C_ADDR_44 0x44
#define SHT40_I2C_ADDR_45 0x45
#define SHT41_I2C_ADDR_44 0x44
#define SHT41_I2C_ADDR_45 0x45
#define SHT45_I2C_ADDR_44 0x44
#define SHT45_I2C_ADDR_45 0x45

typedef enum {
    SHT4X_MEASURE_HIGH_PRECISION_TICKS_CMD_ID = 0xfd,
    SHT4X_MEASURE_MEDIUM_PRECISION_TICKS_CMD_ID = 0xf6,
    SHT4X_MEASURE_LOWEST_PRECISION_TICKS_CMD_ID = 0xe0,
    SHT4X_ACTIVATE_HIGHEST_HEATER_POWER_LONG_TICKS_CMD_ID = 0x39,
    SHT4X_ACTIVATE_HIGHEST_HEATER_POWER_SHORT_TICKS_CMD_ID = 0x32,
    SHT4X_ACTIVATE_MEDIUM_HEATER_POWER_LONG_TICKS_CMD_ID = 0x2f,
    SHT4X_ACTIVATE_MEDIUM_HEATER_POWER_SHORT_TICKS_CMD_ID = 0x24,
    SHT4X_ACTIVATE_LOWEST_HEATER_POWER_LONG_TICKS_CMD_ID = 0x1e,
    SHT4X_ACTIVATE_LOWEST_HEATER_POWER_SHORT_TICKS_CMD_ID = 0x15,
    SHT4X_SERIAL_NUMBER_CMD_ID = 0x89,
    SHT4X_SOFT_RESET_CMD_ID = 0x94,
} SHT4xCmdId;

class SensirionI2cSht4x {
  public:
    SensirionI2cSht4x();
    /**
     * @brief Initializes the SHT4x class.
     *
     * @param i2cBus Arduino stream object to be used for communication.
     */
    void begin(TwoWire& i2cBus, uint8_t i2cAddress);

    /**
     * @brief Run measurement with high precision
     *
     * SHT4x command for a single shot measurement with high repeatability.
     *
     * @param[out] aTemperature Converted from ticks to degrees celsius by (175
     * * ticks_value / 65535) - 45
     * @param[out] aHumidity Converted from ticks to percent relative humdity by
     * (125 * ticks_value / 65535) - 6
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t measureHighPrecision(float& aTemperature, float& aHumidity);

    /**
     * @brief Run measurement with medium precision
     *
     * SHT4x command for a single shot measurement with medium repeatability.
     *
     * @param[out] aTemperature Converted from ticks to degrees celsius by (175
     * * ticks_value / 65535) - 45
     * @param[out] aHumidity Converted from ticks to percent relative humdity by
     * (125 * ticks_value / 65535) - 6
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t measureMediumPrecision(float& aTemperature, float& aHumidity);

    /**
     * @brief Run measurement with low precision
     *
     * SHT4x command for a single shot measurement with low repeatability.
     *
     * @param[out] aTemperature Converted from ticks to degrees celsius by (175
     * * ticks_value / 65535) - 45
     * @param[out] aHumidity Converted from ticks to percent relative humdity by
     * (125 * ticks_value / 65535) - 6
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t measureLowestPrecision(float& aTemperature, float& aHumidity);

    /**
     * @brief Run measurement with high precision and the highest power heater
     * for 1s
     *
     * SHT4x command to activate highest heater power and perform a single shot
     * high precision measurement for 1s.
     *
     * @param[out] aTemperature Converted from ticks to degrees celsius by (175
     * * ticks_value / 65535) - 45
     * @param[out] aHumidity Converted from ticks to percent relative humdity by
     * (125 * ticks_value / 65535) - 6
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t activateHighestHeaterPowerLong(float& aTemperature,
                                           float& aHumidity);

    /**
     * @brief Run measurement with high precision and the highest power heater
     * for 0.1s
     *
     * SHT4x command to activate highest heater power and perform a single shot
     * high precision measurement for 0.1s.
     *
     * @param[out] aTemperature Converted from ticks to degrees celsius by (175
     * * ticks_value / 65535) - 45
     * @param[out] aHumidity Converted from ticks to percent relative humdity by
     * (125 * ticks_value / 65535) - 6
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t activateHighestHeaterPowerShort(float& aTemperature,
                                            float& aHumidity);

    /**
     * @brief Run measurement with high precision and the medium power heater
     * for 1s
     *
     * SHT4x command to activate medium heater power and perform a single shot
     * high precision measurement for 1s.
     *
     * @param[out] aTemperature Converted from ticks to degrees celsius by (175
     * * ticks_value / 65535) - 45
     * @param[out] aHumidity Converted from ticks to percent relative humdity by
     * (125 * ticks_value / 65535) - 6
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t activateMediumHeaterPowerLong(float& aTemperature,
                                          float& aHumidity);

    /**
     * @brief Run measurement with high precision and the medium power heater
     * for 0.1s
     *
     * SHT4x command to activate medium heater power and perform a single shot
     * high precision measurement for 0.1s.
     *
     * @param[out] aTemperature Converted from ticks to degrees celsius by (175
     * * ticks_value / 65535) - 45
     * @param[out] aHumidity Converted from ticks to percent relative humdity by
     * (125 * ticks_value / 65535) - 6
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t activateMediumHeaterPowerShort(float& aTemperature,
                                           float& aHumidity);

    /**
     * @brief Run measurement with high precision and the lowest power heater
     * for 1s
     *
     * SHT4x command to activate lowest heater power and perform a single shot
     * high precision measurement for 1s.
     *
     * @param[out] aTemperature Converted from ticks to degrees celsius by (175
     * * ticks_value / 65535) - 45
     * @param[out] aHumidity Converted from ticks to percent relative humdity by
     * (125 * ticks_value / 65535) - 6
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t activateLowestHeaterPowerLong(float& aTemperature,
                                          float& aHumidity);

    /**
     * @brief Run measurement with high precision and the lowest power heater
     * for 0.1s
     *
     * SHT4x command to activate lowest heater power and perform a single shot
     * high precision measurement for 0.1s.
     *
     * @param[out] aTemperature Converted from ticks to degrees celsius by (175
     * * ticks_value / 65535) - 45
     * @param[out] aHumidity Converted from ticks to percent relative humdity by
     * (125 * ticks_value / 65535) - 6
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t activateLowestHeaterPowerShort(float& aTemperature,
                                           float& aHumidity);

    /**
     * @brief measureHighPrecisionTicks
     *
     * SHT4x command for a single shot measurement with high repeatability.
     *
     * @param[out] temperatureTicks Temperature ticks. Convert to degrees
     * celsius by (175 * value / 65535) - 45
     * @param[out] humidityTicks Humidity ticks. Convert to degrees celsius by
     * (125
     * * value / 65535) - 6
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t measureHighPrecisionTicks(uint16_t& temperatureTicks,
                                      uint16_t& humidityTicks);

    /**
     * @brief measureMediumPrecisionTicks
     *
     * SHT4x command for a single shot measurement with medium repeatability.
     *
     * @param[out] temperatureTicks Temperature ticks. Convert to degrees
     * celsius by (175 * value / 65535) - 45
     * @param[out] humidityTicks Humidity ticks. Convert to degrees celsius by
     * (125
     * * value / 65535) - 6
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t measureMediumPrecisionTicks(uint16_t& temperatureTicks,
                                        uint16_t& humidityTicks);

    /**
     * @brief measureLowestPrecisionTicks
     *
     * SHT4x command for a single shot measurement with lowest repeatability.
     *
     * @param[out] temperatureTicks Temperature ticks. Convert to degrees
     * celsius by (175 * value / 65535) - 45
     * @param[out] humidityTicks Humidity ticks. Convert to degrees celsius by
     * (125
     * * value / 65535) - 6
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t measureLowestPrecisionTicks(uint16_t& temperatureTicks,
                                        uint16_t& humidityTicks);

    /**
     * @brief activateHighestHeaterPowerLongTicks
     *
     * SHT4x command to activate highest heater power and perform a single shot
     * high precision measurement for 1s.
     *
     * @param[out] temperatureTicks Temperature ticks. Convert to degrees
     * celsius by (175 * value / 65535) - 45
     * @param[out] humidityTicks Humidity ticks. Convert to degrees celsius by
     * (125
     * * value / 65535) - 6
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t activateHighestHeaterPowerLongTicks(uint16_t& temperatureTicks,
                                                uint16_t& humidityTicks);

    /**
     * @brief activateHighestHeaterPowerShortTicks
     *
     * SHT4x command to activate highest heater power and perform a single shot
     * high precision measurement for 0.1s.
     *
     * @param[out] temperatureTicks Temperature ticks. Convert to degrees
     * celsius by (175 * value / 65535) - 45
     * @param[out] humidityTicks Humidity ticks. Convert to degrees celsius by
     * (125
     * * value / 65535) - 6
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t activateHighestHeaterPowerShortTicks(uint16_t& temperatureTicks,
                                                 uint16_t& humidityTicks);

    /**
     * @brief activateMediumHeaterPowerLongTicks
     *
     * SHT4x command to activate medium heater power and perform a single shot
     * high precision measurement for 1s.
     *
     * @param[out] temperatureTicks Temperature ticks. Convert to degrees
     * celsius by (175 * value / 65535) - 45
     * @param[out] humidityTicks Humidity ticks. Convert to degrees celsius by
     * (125
     * * value / 65535) - 6
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t activateMediumHeaterPowerLongTicks(uint16_t& temperatureTicks,
                                               uint16_t& humidityTicks);

    /**
     * @brief activateMediumHeaterPowerShortTicks
     *
     * SHT4x command to activate medium heater power and perform a single shot
     * high precision measurement for 0.1s.
     *
     * @param[out] temperatureTicks Temperature ticks. Convert to degrees
     * celsius by (175 * value / 65535) - 45
     * @param[out] humidityTicks Humidity ticks. Convert to degrees celsius by
     * (125
     * * value / 65535) - 6
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t activateMediumHeaterPowerShortTicks(uint16_t& temperatureTicks,
                                                uint16_t& humidityTicks);

    /**
     * @brief activateLowestHeaterPowerLongTicks
     *
     * SHT4x command to activate lowest heater power and perform a single shot
     * high precision measurement for 1s.
     *
     * @param[out] temperatureTicks Temperature ticks. Convert to degrees
     * celsius by (175 * value / 65535) - 45
     * @param[out] humidityTicks Humidity ticks. Convert to degrees celsius by
     * (125
     * * value / 65535) - 6
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t activateLowestHeaterPowerLongTicks(uint16_t& temperatureTicks,
                                               uint16_t& humidityTicks);

    /**
     * @brief activateLowestHeaterPowerShortTicks
     *
     * SHT4x command to activate lowest heater power and perform a single shot
     * high precision measurement for 0.1s.
     *
     * @param[out] temperatureTicks Temperature ticks. Convert to degrees
     * celsius by (175 * value / 65535) - 45
     * @param[out] humidityTicks Humidity ticks. Convert to degrees celsius by
     * (125
     * * value / 65535) - 6
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t activateLowestHeaterPowerShortTicks(uint16_t& temperatureTicks,
                                                uint16_t& humidityTicks);

    /**
     * @brief serialNumber
     *
     * Read out the serial number
     *
     * @param[out] serialNumber Unique serial number
     *
     * @note Each sensor has a unique serial number that is assigned by
     * Sensirion during production.It is stored in the one-time-programmable
     * memory and cannot be manipulated after production.
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t serialNumber(uint32_t& serialNumber);

    /**
     * @brief softReset
     *
     * Perform a soft reset.
     *
     * @note A reset of the sensor can be achieved in three ways: • Soft reset:
     * use this function • I2C general call: all devices on the I2C bus are
     * reset by sending the command 0x06 to the I2C address 0x00. • Power down
     * (incl.pulling SCL and SDA low)
     *
     * @return error_code 0 on success, an error code otherwise.
     */
    int16_t softReset();

    /**
     * @brief signalTemperature
     *
     * @param[in] temperatureTicks
     *
     * @return Converted from ticks to degrees celsius by (175 * ticks_value /
     * 65535) - 45
     */
    static float signalTemperature(uint16_t temperatureTicks);

    /**
     * @brief signalHumidity
     *
     * @param[in] humidityTicks
     *
     * @return Converted from ticks to percent relative humdity by (125 *
     * ticks_value / 65535) - 6
     */
    static float signalHumidity(uint16_t humidityTicks);

  private:
    TwoWire* _i2cBus = nullptr;
    uint8_t _i2cAddress = 0;
};

#endif  // SENSIRIONI2CSHT4X_H