
////////////////////////////////////
//   DEVICE-SPECIFIC LED SERVICES //
////////////////////////////////////

struct DEV_TempSensor : Service::TemperatureSensor {     // A standalone Temperature sensor

  SpanCharacteristic *temp;                         // reference to the Current Temperature Characteristic
  
  DEV_TempSensor() : Service::TemperatureSensor(){       // constructor() method
    
    // First we instantiate the main Characteristic for a Temperature Sensor, namely the Current Temperature, and set its initial value
    // to 20 degrees.  For a real sensor, we would take a reading and initialize it to that value instead.  NOTE:  HomeKit uses
    // Celsius for all temperature settings.  HomeKit will DISPLAY temperatures in the HomeKit app according to the settings on your iPhone.
    // Though the HAP documentation includes a Characteristic that appears to allow the device to over-ride this setting by specifying a display
    // of Celsius or Fahrenheit for each Service, it does not appear to work as advertised.
    
    temp=new Characteristic::CurrentTemperature(-10.0);        // instantiate the Current Temperature Characteristic
    temp->setRange(-50,100);                                  // expand the range from the HAP default of 0-100 to -50 to 100 to allow for negative temperatures
        
    Serial.print("Configuring Temperature Sensor");           // initialization message
    Serial.print("\n");

  } // end constructor

  // Next we create the loop() method. This method take no arguments and returns no values. In order to simulate a temperature change
  // from an actual sensor we will read the current value of the temp Characteristic using the getVal() function, with <float> as the
  // template parameter; add 0.5 degrees Celsius; and then store the result in a float variable named "temperature."  This will simulate
  // an increment of 0.5 degrees Celsius (a little less than 1 degree F).  We will cap the temperature to 35.0 degrees C, after which
  // it resets to 10.0 and starts over.  Most importantly, we will do this once every 5 seconds by checking the elapsed time since the
  // previous modification using timeVal().

  // All of the action happens in the setVal() line where we set the value of the temp Characteristic to the new value of temperature.
  // This tells HomeKit to send an Event Notification message to all available Controllers making them aware of the new temperature.
  // Note that setVal() is NOT a template function and does not require you to specify <float> as a template parameter.  This is because
  // setVal() can determine the type from the argument you specify.  If there is any chance of ambiguity, you can always specifically
  // cast the argument such: setVal((float)temperature).

  void loop(){

    if(temp->timeVal()>5000){                               // check time elapsed since last update and proceed only if greater than 5 seconds
      float temperature=temp->getVal<float>()+0.5;          // "simulate" a half-degree temperature change...
      if(temperature>35.0)                                  // ...but cap the maximum at 35C before starting over at -30C
        temperature=-30.0;
      
      temp->setVal(temperature);                            // set the new temperature; this generates an Event Notification and also resets the elapsed time
      
      LOG1("Temperature Update: ");
      LOG1(temperature*9/5+32);
      LOG1("\n");            
    }
    
  } // loop
  
};
      
//////////////////////////////////

struct DEV_Voltmeter : Service::BatteryService {     // UPS battery voltmeter
  
  SpanCharacteristic *BatLvl;            	      // reference to the Battery Level, which is a int from 0 to 100
  SpanCharacteristic *LowBat;            	      // reference to the Low Battery Status, which is a int  0 or 1
  DEV_Voltmeter() : Service::BatteryService(){       // constructor() method

	  BatLvl=new Characteristic::BatteryLevel (77);                    // instantiate the Battery Level and set initial value to 77
    LowBat=new Characteristic::StatusLowBattery (0);         		// instantiate the Low Battery Status and set initial value to 0
	
	
    Serial.print("Configuring UPS Bttery Level");   // initialization message
    Serial.print("\n");

  } // end constructor

  void loop(){

    // Note we are NOT updating the Nitrogen Dioxide Density Characteristic.  This should therefore remain steady at its initial value of 700.0

    if(BatLvl->timeVal()>5000){                               // check time elapsed since last update and proceed only if greater than 5 seconds
      int batteryLevel=BatLvl->getVal<int>()-1;          // "simulate" a half-degree temperature change...
      if(batteryLevel<10)                                  // ...but cap the maximum at 35C before starting over at -30C
        batteryLevel=85;
      
      BatLvl->setVal(batteryLevel);                            // set the new temperature; this generates an Event Notification and also resets the elapsed time
      
      LOG1("Battery Lvl Update: ");
      LOG1(batteryLevel);
      LOG1("\n");            
    }

  } // loop

};
      
