<commit_before>/*
The OpenTRV project licenses this file to you
under the Apache Licence, Version 2.0 (the "Licence");
you may not use this file except in compliance
with the Licence. You may obtain a copy of the Licence at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the Licence is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the Licence for the
specific language governing permissions and limitations
under the Licence.

Author(s) / Copyright (s): <NAME> 2013--2016
*/

/*
 Temperature potentiometer (pot) dial sensor with UI / occupancy outputs.
 */

#ifndef OTV0P2BASE_SENSORTEMPERATUREPOT_H
#define OTV0P2BASE_SENSORTEMPERATUREPOT_H

#include "OTV0P2BASE_Util.h"
#include "OTV0P2BASE_Sensor.h"


namespace OTV0P2BASE
{


// Sensor for temperature potentiometer/dial; 0 is coldest, 255 is hottest.
// Note that if the callbacks are enabled, the following are implemented:
//   * Any operation of the pot calls the occupancy/"UI used" callback.
//   * Force FROST mode when dial turned right down to bottom.
//   * Start BAKE mode when dial turned right up to top.
//   * Cancel BAKE mode when dial/temperature turned down.
//   * Force WARM mode when dial/temperature turned up.
class SensorTemperaturePot : public OTV0P2BASE::SimpleTSUint8Sensor
  {
  public:
    // Maximum 'raw' temperature pot/dial value.
    static const uint16_t TEMP_POT_RAW_MAX = 1023;

    // Minimum change (hysteresis) enforced in normalised/8-bit 'reduced noise' range value; must be greater than 1.
    // Aim to provide reasonable noise immunity, even from an ageing carbon-track pot.
    // Allow reasonable remaining granularity of response, at least 10s of distinct positions (>=5 bits).
    // This is in terms of steps on the non-raw [0,255] nominal output scale.
    // Note that some applications may only see a fraction of full scale movement (eg ~25% for DORM1).
    static const uint8_t RN_HYST = 4;

    // Bottom and top parts of normalised/8-bit reduced noise range reserved for end-stops (forcing FROST or BAKE).
    // Should be big enough to hit easily (and must be larger than RN_HYST)
    // but not so big as to really constrain the temperature range or cause confusion.
    // This is in terms of steps on the non-raw [0,255] nominal output scale.
    // Note that some applications may only see a fraction of full scale movement (eg ~25% for DORM1).
    static const uint8_t RN_FRBO = 2*RN_HYST;

  private:
    // Raw pot value [0,1023] if extra precision is required.
    uint16_t raw;

    // Occupancy callback function (for good confidence of human presence); NULL if not used.
    // Also indicates that the manual UI has been used.
    // If not NULL, is called when this sensor detects indications of occupancy.
    void (*occCallback)();

    // WARM/FROST and BAKE start/cancel callbacks.
    // If not NULL, are called when the pot is adjusted appropriately.
    // Typically at most one of these callbacks would be made on any approriate pot adjustment.
    void (*warmModeCallback)(bool);
    void (*bakeStartCallback)(bool);

    // Compute the real scaled minimum, allowing for reversals.
    inline uint8_t _computeRealMinScaled(uint16_t minExpected_, uint16_t maxExpected_)
      { return(fnmin(minExpected_ >> 2, maxExpected_ >> 2)); }
    // Compute the real scaled maximum, allowing for reversals.
    inline uint8_t _computeRealMaxScaled(uint16_t minExpected_, uint16_t maxExpected_)
      { return(fnmax(minExpected_ >> 2, maxExpected_ >> 2)); }
    // Compute the loEndStop.
    inline uint8_t _computeLoEndStop(uint16_t minExpected_, uint16_t maxExpected_)
      {
      const uint8_t realMinScaled = _computeRealMinScaled(minExpected_, maxExpected_);
      return((realMinScaled >= 255 - RN_FRBO) ? realMinScaled : (realMinScaled + RN_FRBO));
      }
    // Compute the hiEndStop.
    inline uint8_t _computeHiEndStop(uint16_t minExpected_, uint16_t maxExpected_)
      {
      const uint8_t realMaxScaled = _computeRealMaxScaled(minExpected_, maxExpected_);
      return((realMaxScaled < RN_FRBO) ? realMaxScaled : (realMaxScaled - RN_FRBO));
      }

  public:
    // Initialise raw to distinct/special value and all pointers to NULL.
    SensorTemperaturePot(const uint16_t minExpected_ = 0, const uint16_t maxExpected_ = TEMP_POT_RAW_MAX)
      : raw(~0U),
        occCallback(NULL), warmModeCallback(NULL), bakeStartCallback(NULL),
        minExpected(minExpected_), maxExpected(maxExpected_),
        loEndStop(_computeLoEndStop(minExpected_, maxExpected_)), hiEndStop(_computeHiEndStop(minExpected_, maxExpected_))
      { }

    // Lower and upper bounds of expected pot movement/output each in range [0,TEMP_POT_RAW_MAX].
    // The values must be different and further apart at least than the noise threshold (~8).
    // Max is lower than min if the pot value is to be reversed.
    // Conservative values (ie with actual travel outside the specified range) should be specified
    // if end-stop detection is to work (callbacks on hitting the extremes).
    // The output is not rebased based on these values, though is reversed if necessary;
    // whatever uses the pot output should map to the desired values.
    // These read-only values are exposed to assist with any such mapping.
    const uint16_t minExpected, maxExpected;
    // Returns true if the pot output is to be reversed from the natural direction.
    inline bool isReversed() { return(minExpected > maxExpected); }

    // A value below this (scaled) is deemed to be at the low end stop region (allowing for reversed movement).
    const uint8_t loEndStop; // = (realMinScaled >= 255 - RN_FRBO) ? realMinScaled : (realMinScaled + RN_FRBO);
    inline bool isAtLoEndStop() { return(value < loEndStop); }
    // A value above this (scaled) is deemed to be at the high end stop region (allowing for reversed movement).
    const uint8_t hiEndStop; // = (realMaxScaled < RN_FRBO) ? realMaxScaled : (realMaxScaled - RN_FRBO);
    inline bool isAtHiEndStop() { return(value > hiEndStop); }

    // Force a read/poll of the temperature pot and return the value sensed [0,255] (cold to hot).
    // Potentially expensive/slow.<commit_msg>improved comments<commit_after>/*
The OpenTRV project licenses this file to you
under the Apache Licence, Version 2.0 (the "Licence");
you may not use this file except in compliance
with the Licence. You may obtain a copy of the Licence at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the Licence is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the Licence for the
specific language governing permissions and limitations
under the Licence.

Author(s) / Copyright (s): <NAME> 2013--2016
*/

/*
 Temperature potentiometer (pot) dial sensor with UI / occupancy outputs.
 */

#ifndef OTV0P2BASE_SENSORTEMPERATUREPOT_H
#define OTV0P2BASE_SENSORTEMPERATUREPOT_H

#include "OTV0P2BASE_Util.h"
#include "OTV0P2BASE_Sensor.h"


namespace OTV0P2BASE
{


// Sensor for temperature potentiometer/dial; 0 is coldest, 255 is hottest.
// Note that if the callbacks are enabled, the following are implemented:
//   * Any operation of the pot calls the occupancy/"UI used" callback.
//   * Force FROST mode when dial turned right down to bottom.
//   * Start BAKE mode when dial turned right up to top.
//   * Cancel BAKE mode when dial/temperature turned down.
//   * Force WARM mode when dial/temperature turned up.
class SensorTemperaturePot : public OTV0P2BASE::SimpleTSUint8Sensor
  {
  public:
    // Maximum 'raw' temperature pot/dial value.
    static const uint16_t TEMP_POT_RAW_MAX = 1023;

    // Minimum change (hysteresis) enforced in normalised/8-bit 'reduced noise' range value; must be greater than 1.
    // Aim to provide reasonable noise immunity, even from an ageing carbon-track pot.
    // Allow reasonable remaining granularity of response, at least 10s of distinct positions (>=5 bits).
    // This is in terms of steps on the non-raw [0,255] nominal output scale.
    // Note that some applications may only see a fraction of full scale movement (eg ~25% for DORM1).
    static const uint8_t RN_HYST = 4;

    // Bottom and top parts of normalised/8-bit reduced noise range reserved for end-stops (forcing FROST or BAKE).
    // Should be big enough to hit easily (and must be larger than RN_HYST)
    // but not so big as to really constrain the temperature range or cause confusion.
    // This is in terms of steps on the non-raw [0,255] nominal output scale.
    // Note that some applications may only see a fraction of full scale movement (eg ~25% for DORM1).
    static const uint8_t RN_FRBO = 2*RN_HYST;

  private:
    // Raw pot value [0,1023] if extra precision is required.
    uint16_t raw;

    // Occupancy callback function (for good confidence of human presence); NULL if not used.
    // Also indicates that the manual UI has been used.
    // If not NULL, is called when this sensor detects indications of occupancy.
    void (*occCallback)();

    // WARM/FROST and BAKE start/cancel callbacks.
    // If not NULL, are called when the pot is adjusted appropriately.
    // Typically at most one of these callbacks would be made on any approriate pot adjustment.
    void (*warmModeCallback)(bool);
    void (*bakeStartCallback)(bool);

    // Compute the real scaled minimum, allowing for reversals.
    inline uint8_t _computeRealMinScaled(uint16_t minExpected_, uint16_t maxExpected_)
      { return(fnmin(minExpected_ >> 2, maxExpected_ >> 2)); }
    // Compute the real scaled maximum, allowing for reversals.
    inline uint8_t _computeRealMaxScaled(uint16_t minExpected_, uint16_t maxExpected_)
      { return(fnmax(minExpected_ >> 2, maxExpected_ >> 2)); }
    // Compute the loEndStop.
    inline uint8_t _computeLoEndStop(uint16_t minExpected_, uint16_t maxExpected_)
      {
      const uint8_t realMinScaled = _computeRealMinScaled(minExpected_, maxExpected_);
      return((realMinScaled >= 255 - RN_FRBO) ? realMinScaled : (realMinScaled + RN_FRBO));
      }
    // Compute the hiEndStop.
    inline uint8_t _computeHiEndStop(uint16_t minExpected_, uint16_t maxExpected_)
      {
      const uint8_t realMaxScaled = _computeRealMaxScaled(minExpected_, maxExpected_);
      return((realMaxScaled < RN_FRBO) ? realMaxScaled : (realMaxScaled - RN_FRBO));
      }

  public:
    // Initialise raw to distinct/special value and all pointers to NULL.
    SensorTemperaturePot(const uint16_t minExpected_ = 0, const uint16_t maxExpected_ = TEMP_POT_RAW_MAX)
      : raw(~0U),
        occCallback(NULL), warmModeCallback(NULL), bakeStartCallback(NULL),
        minExpected(minExpected_), maxExpected(maxExpected_),
        loEndStop(_computeLoEndStop(minExpected_, maxExpected_)), hiEndStop(_computeHiEndStop(minExpected_, maxExpected_))
      { }

    // Lower and upper bounds of expected pot movement/output each in range [0,TEMP_POT_RAW_MAX].
    // The values must be different and further apart at least than the noise threshold (~8).
    // Max is lower than min if the pot value is to be reversed.
    // Conservative values (ie with actual travel outside the specified range) should be specified
    // if end-stop detection is to work (callbacks on hitting the extremes).
    // The output is not rebased based on these values, though is reversed if necessary;
    // whatever uses the pot output should map to the desired values.
    // These read-only values are exposed to assist with any such mapping.
    const uint16_t minExpected, maxExpected;
    // Returns true if the pot output is to be reversed from the natural direction.
    inline bool isReversed() { return(minExpected > maxExpected); }

    // A value below this (scaled) is deemed to be at the low end stop region (allowing for reversed movement).
    const uint8_t loEndStop; // = (realMinScaled >= 255 - RN_FRBO) ? realMinScaled : (realMinScaled + RN_FRBO);
    // Returns true if at the low end stop: ISR safe.
    inline bool isAtLoEndStop() { return(value < loEndStop); }
    // A value above this (scaled) is deemed to be at the high end stop region (allowing for reversed movement).
    const uint8_t hiEndStop; // = (realMaxScaled < RN_FRBO) ? realMaxScaled : (realMaxScaled - RN_FRBO);
    // Returns true if at the high end stop: ISR safe.
    inline bool isAtHiEndStop() { return(value > hiEndStop); }

    // Force a read/poll of the temperature pot and return the value sensed [0,255] (cold to hot).
    // Potentially expensive/slow.
{'fraction_non_alphanumeric': 0.07650531286894924, 'fraction_numerical': 0.0179456906729634, 'mean_word_length': 3.5606604450825556, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2368095', 'n_tokens_mistral': 3863, 'n_tokens_neox': 3587, 'n_words': 1494}