#ifdef ENABLE_SENSORS_ONEWIRE #define DALLAS_TEMPERATURE_PRECISION 12 void oneWireSensors_setup() { oneWireSensors.begin(); //Serial.print("Locating devices..."); //Serial.print("Found "); //Serial.print(oneWireSensors.getDeviceCount(), DEC); //Serial.println(" devices."); snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: found %d devices", oneWireSensors.getDeviceCount()); sendLog(logBuf, LOGLEVEL_INFO); // report parasite power requirements //Serial.print("Parasite power is: "); //if (oneWireSensors.isParasitePowerMode()) Serial.println("ON"); //else Serial.println("OFF"); // Search for devices on the bus and assign based on an index. Ideally, // you would do this to initially discover addresses on the bus and then // use those addresses and manually assign them (see above) once you know // the devices on your bus (and assuming they don't change). // // method 1: by index //if (!oneWireSensors.getAddress(oneWireSensor0, 0)) Serial.println("Unable to find address for Device 0"); //if (!oneWireSensors.getAddress(oneWireSensor1, 1)) Serial.println("Unable to find address for Device 1"); //if (!oneWireSensors.getAddress(oneWireSensor2, 2)) Serial.println("Unable to find address for Device 1"); for (uint8_t i=0; i < oneWireSensors.getDeviceCount(); i++) { if (!oneWireSensors.getAddress(oneWireSensors_IndexToAddress[i], i)) { snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: Unable to find address for Device %d", i); sendLog(logBuf, LOGLEVEL_ERROR); //Serial.print("Unable to find address for Device"); //Serial.println(i); } } // method 2: search() // search() looks for the next device. Returns 1 if a new address has been // returned. A zero might mean that the bus is shorted, there are no devices, // or you have already retrieved all of them. It might be a good idea to // check the CRC to make sure you didn't get garbage. The order is // deterministic. You will always get the same devices in the same order // // Must be called before search() //oneWire.reset_search(); // assigns the first address found to insideThermometer //if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer"); // assigns the seconds address found to outsideThermometer //if (!oneWire.search(outsideThermometer)) Serial.println("Unable to find address for outsideThermometer"); // show the addresses we found on the bus for (uint8_t i=0; i < oneWireSensors.getDeviceCount(); i++) { //Serial.print("Device "); //Serial.print(i); //Serial.print(" Address: "); //oneWireSensors_printAddress(oneWireSensors_IndexToAddress[i]); //Serial.println(); snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: Device: %d, Address: %02x%02x%02x%02x%02x%02x%02x%02x", i, oneWireSensors_IndexToAddress[i][0], oneWireSensors_IndexToAddress[i][1], oneWireSensors_IndexToAddress[i][2], oneWireSensors_IndexToAddress[i][3], oneWireSensors_IndexToAddress[i][4], oneWireSensors_IndexToAddress[i][5], oneWireSensors_IndexToAddress[i][6], oneWireSensors_IndexToAddress[i][7]); sendLog(logBuf, LOGLEVEL_INFO); } //Serial.print("Device 0 Address: "); //oneWireSensors_printAddress(oneWireSensor0); //Serial.println(); // //Serial.print("Device 1 Address: "); //oneWireSensors_printAddress(oneWireSensor1); //Serial.println(); // //Serial.print("Device 2 Address: "); //oneWireSensors_printAddress(oneWireSensor2); //Serial.println(); // set the resolution to 9 bit per device //oneWireSensors.setResolution(oneWireSensor0, DALLAS_TEMPERATURE_PRECISION); //oneWireSensors.setResolution(oneWireSensor1, DALLAS_TEMPERATURE_PRECISION); //oneWireSensors.setResolution(oneWireSensor2, DALLAS_TEMPERATURE_PRECISION); for (uint8_t i=0; i < oneWireSensors.getDeviceCount(); i++) { oneWireSensors.setResolution(oneWireSensors_IndexToAddress[i], DALLAS_TEMPERATURE_PRECISION); } //Serial.print("Device 0 Resolution: "); //Serial.print(oneWireSensors.getResolution(oneWireSensor0), DEC); //Serial.println(); // //Serial.print("Device 1 Resolution: "); //Serial.print(oneWireSensors.getResolution(oneWireSensor1), DEC); //Serial.println(); // //Serial.print("Device 2 Resolution: "); //Serial.print(oneWireSensors.getResolution(oneWireSensor2), DEC); //Serial.println(); } // // function to print a device address // void oneWireSensors_printAddress(DeviceAddress deviceAddress) // { // for (uint8_t i = 0; i < 8; i++) // { // // zero pad the address if necessary // if (deviceAddress[i] < 16) Serial.print("0"); // Serial.print(deviceAddress[i], HEX); // } // } // // // function to print the temperature for a device // void oneWireSensors_printTemperature(DeviceAddress deviceAddress) // { // float tempC = oneWireSensors.getTempC(deviceAddress); // if (tempC == DEVICE_DISCONNECTED_C) // { // Serial.println("Error: Could not read temperature data"); // return; // } // Serial.print("Temp C: "); // Serial.print(tempC); // } // // // function to print a device's resolution // void oneWireSensors_printResolution(DeviceAddress deviceAddress) // { // Serial.print("Resolution: "); // Serial.print(oneWireSensors.getResolution(deviceAddress)); // Serial.println(); // } // main function to print information about a device // void oneWireSensors_printData(DeviceAddress deviceAddress) // { // Serial.print("Device Address: "); // oneWireSensors_printAddress(deviceAddress); // Serial.print(" "); // oneWireSensors_printTemperature(deviceAddress); // Serial.println(); // } //float owTemp_lastValue_feed, owTemp_lastValue_return, owTemp_lastValue_out; void oneWireSensors_getData() { snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: reading temperatures"); sendLog(logBuf, LOGLEVEL_DEBUG); oneWireSensors.requestTemperatures(); // print the device information //oneWireSensors_printData(oneWireSensors_IndexToAddress[oneWireSensor_index[ONEWIRE_SENSOR_INDEX_FEED]]); //oneWireSensors_printData(oneWireSensors_IndexToAddress[oneWireSensor_index[ONEWIRE_SENSOR_INDEX_RETURN]]); //oneWireSensors_printData(oneWireSensors_IndexToAddress[oneWireSensor_index[ONEWIRE_SENSOR_INDEX_OUTSIDE]]); float tempC; // sensor feed if (oneWireSensor_assignedDevToIndex[ONEWIRE_SENSOR_INDEX_FEED] < oneWireSensors.getDeviceCount()) { tempC = oneWireSensors.getTempC(oneWireSensors_IndexToAddress[oneWireSensor_assignedDevToIndex[ONEWIRE_SENSOR_INDEX_FEED]]); if (tempC == DEVICE_DISCONNECTED_C) { snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: error reading sensor 'FEED'"); sendLog(logBuf, LOGLEVEL_ERROR); owTemp_feed = -127; } else { // filter value 85 as it is used as an error code by the lib // if the last measured value was >=80 and <=90 assume the value is OK bool _valueOK = false; if ((int)tempC == 85) { if (owTemp_feed >= 80 && owTemp_feed <= 90) _valueOK = true; } else _valueOK = true; if (_valueOK) { owTemp_feed = tempC; snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: sensor 'FEED' = %1.1f", owTemp_feed); sendLog(logBuf, LOGLEVEL_INFO); } } } else { snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: WARNING - sensor 'FEED' not properly assigned"); sendLog(logBuf, LOGLEVEL_WARN); } // sensor return if (oneWireSensor_assignedDevToIndex[ONEWIRE_SENSOR_INDEX_RETURN] < oneWireSensors.getDeviceCount()) { tempC = oneWireSensors.getTempC(oneWireSensors_IndexToAddress[oneWireSensor_assignedDevToIndex[ONEWIRE_SENSOR_INDEX_RETURN]]); if (tempC == DEVICE_DISCONNECTED_C) { snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: error reading sensor 'RETURN'"); sendLog(logBuf, LOGLEVEL_ERROR); owTemp_return = -127; } else { // filter value 85 as it is used as an error code by the lib // if the last measured value was >=80 and <=90 assume the value is OK bool _valueOK = false; if ((int)tempC == 85) { if (owTemp_feed >= 80 && owTemp_feed <= 90) _valueOK = true; } else _valueOK = true; if (_valueOK) { owTemp_return = tempC; snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: sensor 'RETURN' = %1.1f", owTemp_return); sendLog(logBuf, LOGLEVEL_INFO); } } } else { snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: WARNING - sensor 'RETURN' not properly assigned"); sendLog(logBuf, LOGLEVEL_WARN); } // sensor out if (oneWireSensor_assignedDevToIndex[ONEWIRE_SENSOR_INDEX_OUT] < oneWireSensors.getDeviceCount()) { tempC = oneWireSensors.getTempC(oneWireSensors_IndexToAddress[oneWireSensor_assignedDevToIndex[ONEWIRE_SENSOR_INDEX_OUT]]); if (tempC == DEVICE_DISCONNECTED_C) { snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: error reading sensor 'OUT'"); sendLog(logBuf, LOGLEVEL_ERROR); owTemp_out = -127; } else { // filter value 85 as it is used as an error code by the lib // if the last measured value was >=80 and <=90 assume the value is OK bool _valueOK = false; if ((int)tempC == 85) { if (owTemp_feed >= 80 && owTemp_feed <= 90) _valueOK = true; } else _valueOK = true; if (_valueOK) { owTemp_out = tempC; snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: sensor 'OUT' = %1.1f", owTemp_out); sendLog(logBuf, LOGLEVEL_INFO); } } } else { snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: WARNING - sensor 'OUT' not properly assigned"); sendLog(logBuf, LOGLEVEL_WARN); } } void oneWireSensors_loadAssignments() { oneWireSensors_loadAssignments(false); } void oneWireSensors_loadAssignments(bool force) { snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: load sensor assignments..."); sendLog(logBuf, LOGLEVEL_INFO); if(force) { snprintf(logBuf, LOG_BUFFER_SIZE, " FORCED"); sendLog(logBuf, LOGLEVEL_INFO); for (uint8_t i = 0; i < ONEWIRE_SENSORS_COUNT; i++) { oneWireSensor_assignedDevToIndex[i] = 255; } } for (uint8_t i = 0; i < ONEWIRE_SENSORS_COUNT; i++) { if(i < oneWireSensors.getDeviceCount()) { bool addrMatch = true; // check if it is Sensor "FEED" if(oneWireSensor_assignedDevToIndex[ONEWIRE_SENSOR_INDEX_FEED] == 255) { for (uint8_t i2 = 0; i2 < 8; i2++) { if(oneWireSensors_IndexToAddress[i][i2] != confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_FEED][i2]) addrMatch = false; } if(addrMatch) { //Serial.print("OneWire Sensor "); oneWireSensor_assignedDevToIndex[ONEWIRE_SENSOR_INDEX_FEED] = i; //oneWireSensors_printAddress(oneWireSensors_IndexToAddress[i]); //Serial.println(" is sensor 'FEED'"); snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: sensor 'FEED': index=%d, address=%02x%02x%02x%02x%02x%02x%02x%02x", i, confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_FEED][0], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_FEED][1], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_FEED][2], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_FEED][3], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_FEED][4], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_FEED][5], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_FEED][6], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_FEED][7]); sendLog(logBuf, LOGLEVEL_INFO); } } // check if it is Sensor "RETURN" if(oneWireSensor_assignedDevToIndex[ONEWIRE_SENSOR_INDEX_RETURN] == 255) { addrMatch = true; for (uint8_t i2 = 0; i2 < 8; i2++) { if(oneWireSensors_IndexToAddress[i][i2] != confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_RETURN][i2]) addrMatch = false; } if(addrMatch) { //Serial.print("OneWire Sensor "); oneWireSensor_assignedDevToIndex[ONEWIRE_SENSOR_INDEX_RETURN] = i; //oneWireSensors_printAddress(oneWireSensors_IndexToAddress[i]); //Serial.println(" is sensor 'RETURN'"); snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: sensor 'RETURN': index=%d, address=%02x%02x%02x%02x%02x%02x%02x%02x", i, confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_RETURN][0], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_RETURN][1], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_RETURN][2], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_RETURN][3], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_RETURN][4], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_RETURN][5], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_RETURN][6], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_RETURN][7]); sendLog(logBuf, LOGLEVEL_INFO); } } // check if it is Sensor "OUT" if(oneWireSensor_assignedDevToIndex[ONEWIRE_SENSOR_INDEX_OUT] == 255) { addrMatch = true; for (uint8_t i2 = 0; i2 < 8; i2++) { if(oneWireSensors_IndexToAddress[i][i2] != confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_OUT][i2]) addrMatch = false; } if(addrMatch) { oneWireSensor_assignedDevToIndex[ONEWIRE_SENSOR_INDEX_OUT] = i; //Serial.print("OneWire Sensor "); //oneWireSensors_printAddress(oneWireSensors_IndexToAddress[i]); //Serial.println(" is sensor 'OUT'"); snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: sensor 'OUT': index=%d, address=%02x%02x%02x%02x%02x%02x%02x%02x", i, confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_OUT][0], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_OUT][1], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_OUT][2], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_OUT][3], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_OUT][4], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_OUT][5], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_OUT][6], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_OUT][7]); sendLog(logBuf, LOGLEVEL_INFO); } } } } // check for still unassigned configured sensors for (uint8_t i=0; i < ONEWIRE_SENSORS_COUNT; i++) { if(oneWireSensor_assignedDevToIndex[i] >= ONEWIRE_SENSORS_COUNT) { char sensName[10]; if(i==0) sprintf(sensName, "FEED"); else if(i==1) sprintf(sensName, "RETURN"); else if(i==2) sprintf(sensName, "OUT"); char sensAddr[25]; sprintf(sensAddr, "%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x", confSens.oneWireDevAddress[i][0], confSens.oneWireDevAddress[i][1], confSens.oneWireDevAddress[i][2], confSens.oneWireDevAddress[i][3], confSens.oneWireDevAddress[i][4], confSens.oneWireDevAddress[i][5], confSens.oneWireDevAddress[i][6], confSens.oneWireDevAddress[i][7]); snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: WARNING - configured sensor '%s', addr='%s' not found", sensName, sensAddr); sendLog(logBuf, LOGLEVEL_WARN); } } } void oneWireSensors_show() { snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20 sensors"); sendLog(logBuf, LOGLEVEL_INFO); snprintf(logBuf, LOG_BUFFER_SIZE, "found:"); sendLog(logBuf, LOGLEVEL_INFO); for (uint8_t i=0; i < oneWireSensors.getDeviceCount(); i++) { snprintf(logBuf, LOG_BUFFER_SIZE, " [%d]: %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x", i, oneWireSensors_IndexToAddress[i][0], oneWireSensors_IndexToAddress[i][1], oneWireSensors_IndexToAddress[i][2], oneWireSensors_IndexToAddress[i][3], oneWireSensors_IndexToAddress[i][4], oneWireSensors_IndexToAddress[i][5], oneWireSensors_IndexToAddress[i][6], oneWireSensors_IndexToAddress[i][7]); sendLog(logBuf, LOGLEVEL_INFO); } snprintf(logBuf, LOG_BUFFER_SIZE, "configured:"); sendLog(logBuf, LOGLEVEL_INFO); snprintf(logBuf, LOG_BUFFER_SIZE, " FEED: %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x", confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_FEED][0], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_FEED][1], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_FEED][2], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_FEED][3], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_FEED][4], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_FEED][5], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_FEED][6], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_FEED][7]); sendLog(logBuf, LOGLEVEL_INFO); if(oneWireSensor_assignedDevToIndex[ONEWIRE_SENSOR_INDEX_FEED] < oneWireSensors.getDeviceCount()) { snprintf(logBuf, LOG_BUFFER_SIZE, " assigned to device [%d]", oneWireSensor_assignedDevToIndex[ONEWIRE_SENSOR_INDEX_FEED]); sendLog(logBuf, LOGLEVEL_INFO); } else { snprintf(logBuf, LOG_BUFFER_SIZE, " not assigned to existing device"); sendLog(logBuf, LOGLEVEL_INFO); } snprintf(logBuf, LOG_BUFFER_SIZE, " RETURN: %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x", confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_RETURN][0], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_RETURN][1], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_RETURN][2], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_RETURN][3], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_RETURN][4], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_RETURN][5], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_RETURN][6], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_RETURN][7]); sendLog(logBuf, LOGLEVEL_INFO); if(oneWireSensor_assignedDevToIndex[ONEWIRE_SENSOR_INDEX_RETURN] < oneWireSensors.getDeviceCount()) { snprintf(logBuf, LOG_BUFFER_SIZE, " assigned to device [%d]", oneWireSensor_assignedDevToIndex[ONEWIRE_SENSOR_INDEX_RETURN]); sendLog(logBuf, LOGLEVEL_INFO); } else { snprintf(logBuf, LOG_BUFFER_SIZE, " not assigned to existing device"); sendLog(logBuf, LOGLEVEL_INFO); } snprintf(logBuf, LOG_BUFFER_SIZE, " OUT: %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x", confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_OUT][0], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_OUT][1], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_OUT][2], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_OUT][3], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_OUT][4], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_OUT][5], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_OUT][6], confSens.oneWireDevAddress[ONEWIRE_SENSOR_INDEX_OUT][7]); sendLog(logBuf, LOGLEVEL_INFO); if(oneWireSensor_assignedDevToIndex[ONEWIRE_SENSOR_INDEX_OUT] < oneWireSensors.getDeviceCount()) { snprintf(logBuf, LOG_BUFFER_SIZE, " assigned to device [%d]", oneWireSensor_assignedDevToIndex[ONEWIRE_SENSOR_INDEX_OUT]); sendLog(logBuf, LOGLEVEL_INFO); } else { snprintf(logBuf, LOG_BUFFER_SIZE, " not assigned to existing device"); sendLog(logBuf, LOGLEVEL_INFO); } } bool oneWireSensor_assign(uint8_t devIndex_found, uint8_t devIndex) { // assign found sensor to saved sensor number by index // stores device address to confSens.oneWireDevAddress[devIndex] // get address of found device char sensName[10]; if(devIndex==0) sprintf(sensName, "FEED"); else if(devIndex==1) sprintf(sensName, "RETURN"); else if(devIndex==2) sprintf(sensName, "OUT"); else { snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: ERROR - sensor assign got invalid target index"); sendLog(logBuf, LOGLEVEL_ERROR); return false; } snprintf(logBuf, LOG_BUFFER_SIZE, "DS18B20: assigning sensor [%d]=%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x --> '%s'", devIndex_found, oneWireSensors_IndexToAddress[devIndex_found][0], oneWireSensors_IndexToAddress[devIndex_found][1], oneWireSensors_IndexToAddress[devIndex_found][2], oneWireSensors_IndexToAddress[devIndex_found][3], oneWireSensors_IndexToAddress[devIndex_found][4], oneWireSensors_IndexToAddress[devIndex_found][5], oneWireSensors_IndexToAddress[devIndex_found][6], oneWireSensors_IndexToAddress[devIndex_found][7], sensName); sendLog(logBuf, LOGLEVEL_INFO); for(uint8_t i=0; i < 8; i++) { confSens.oneWireDevAddress[devIndex][i] = oneWireSensors_IndexToAddress[devIndex_found][i]; } oneWireSensor_assignedDevToIndex[devIndex] = devIndex_found; return true; } #endif