AxisPairs LockSystemController::findAxes()
{
#ifdef LOCK_SYSTEM_CONTROLLER_DEBUG
	debugPrint(F("LSC:findAxes "));
#endif
	int deltaX = calibrationData.maxVals.x - calibrationData.minVals.x;
	int deltaY = calibrationData.maxVals.y - calibrationData.minVals.y;

	if (deltaX < deltaY)
	{
		laObs->setDefaultAxes(yz);
#ifdef LOCK_SYSTEM_CONTROLLER_DEBUG
		debugPrintln(F("yz"));
#endif
		return yz;
	}
	else if (deltaY < deltaX)
	{
		laObs->setDefaultAxes(xz);
#ifdef LOCK_SYSTEM_CONTROLLER_DEBUG
		debugPrintln(F("xz"));
#endif
		return xz;
	}
	else
	{
		//TBD: calibrationFailed();
	}
}
static bool addPanIdCandidate(uint16_t panId)
{
  uint16_t* panIdPointer = emAfPluginNetworkSteeringGetStoredPanIdPointer(0);
  if (panIdPointer == NULL) {
    emberAfCorePrintln("Error: %p could not get memory pointer for stored PAN IDs",
                       PLUGIN_NAME);
    return false;
  }
  uint8_t maxNetworks = emAfPluginNetworkSteeringGetMaxPossiblePanIds();
  uint8_t i;
  for (i = 0; i < maxNetworks; i++) {
    if (panId == *panIdPointer) {
      // We already know about this PAN, no point in recording it twice.
      debugPrintln("Ignoring duplicate PAN ID 0x%2X", panId);
      return true;
    } else if (*panIdPointer == EMBER_AF_INVALID_PAN_ID) {
      *panIdPointer = panId;
      debugPrintln("Stored PAN ID 0x%2X", *panIdPointer);
      return true;
    }
    panIdPointer++;
  }

  if (!printedMaxPanIdsWarning) {
    emberAfCorePrintln("Warning: %p Max PANs reached (%d)",
                       PLUGIN_NAME,
                       maxNetworks);
    printedMaxPanIdsWarning = true;
  }
  return true;
}
void LockSystemController::cmdCalibAtLockedPos()
{
#ifdef LOCK_SYSTEM_CONTROLLER_DEBUG
	debugPrintln(F("LSC:cmdCalibAtLockedPos"));
#endif
	switch (mainState) {
		case Initial:
			// regardlesss of calibration start or end, we are at locked position, record it
			calibrationData.lockedPosition_xz = laObs->getLockAngleDeg(xz);
			calibrationData.lockedPosition_yz = laObs->getLockAngleDeg(yz);
			laObs->getCart(&calibrationData.lockCart);
			switch (initState) {
				case uncalibrated:
				case calibratingStartFromLockedPos:
					// we are just starting the calibration cycle
#ifdef LOCK_SYSTEM_CONTROLLER_DEBUG
					debugPrint(F("LSC:calib start lck xz yz "));
					debugPrint(calibrationData.lockedPosition_xz); debugPrint(SPACE);
					debugPrintln(calibrationData.lockedPosition_yz);
#endif
					calibrationData.lastReading = calibrationData.lockCart;
					newInitState(calibratingStartFromLockedPos);
					break;
				case calibratingStartFromUnlockedPos:
					// we've recorded the other side already, do
					// all the calibration calculations and store
					// the positions
					setLockUnlockPositions();
					// TBD settings.lockedAngle.setData(lockedPosition);
					// TBD settings.unlockedAngle.setData(unlockedPosition);

#ifdef LOCK_SYSTEM_CONTROLLER_DEBUG
					debugPrint(F("LSC:calib lck end xz yz "));
					debugPrint(calibrationData.lockedPosition_xz); debugPrint(SPACE);
					debugPrintln(calibrationData.lockedPosition_yz);
#endif

					// TBD settings.lockedAngle.setData(lockedPosition);
					// TBD settings.unlockedAngle.setData(unlockedPosition);
#ifdef LOCK_SYSTEM_CONTROLLER_DEBUG
					debugPrint(F("LSC:calibration complete lock "));
					debugPrint(lockedPosition);
					debugPrint(F(" unlock "));
					debugPrintln(unlockedPosition);
					debugPrintln(F("LSC:testing orientation"));
#endif
					startRotation(CW);
					newInitState(waitForCW);
					break;
			}
			break;
	}
}
static uint16_t getNextCandidate(void)
{
  debugPrintln("Getting candidate at index %d", emAfPluginNetworkSteeringPanIdIndex);
  uint16_t* pointer =
    emAfPluginNetworkSteeringGetStoredPanIdPointer(emAfPluginNetworkSteeringPanIdIndex);
  if (pointer == NULL) {
    debugPrintln("Error: %p could not get pointer to stored PANs", PLUGIN_NAME);
    return EMBER_AF_INVALID_PAN_ID;
  }
  emAfPluginNetworkSteeringPanIdIndex++;
  return *pointer;
}
Beispiel #5
0
bool Esp8266::connect(String serverIP, String serverPort, bool udp) {
	unsigned long timeout = 5000;
	unsigned long t_start = 0;
	unsigned char buf[10];
	unsigned char index=0;
	String proto = udp ? "UDP" : "TCP";

	clearBuf();
	if (!this->multiFlag) {
		write("AT+CIPSTART=\"" + proto + "\",\"" + serverIP + "\"," + serverPort);	
		t_start = millis();
		while((millis())-t_start < timeout)	{
			while(available()) {
				buf[index] = read();
				if (buf[index]=='T' && buf[(index+9)%10]=='C' && buf[(index+8)%10]=='E' && buf[(index+7)%10]=='N'
									&& buf[(index+6)%10]=='N' && buf[(index+5)%10]=='O' && buf[(index+4)%10]=='C') {
					return true;
				}
				index++;
				if (index==10)
					index = 0;			
			}
		}
		if (this->isDebug) {	
			debugPrintln("connectTCPServer timeout");
		}
		return false;
	} else {
		write("AT+CIPSTART="+ String(this->connectID) + ",\"TCP\",\"" + serverIP + "\"," + serverPort);
		t_start = millis();
		while((millis())-t_start < timeout)	{
			while(available()) {
				buf[index] = read();
				if (buf[index]=='T' && buf[(index+9)%10]=='C' && buf[(index+8)%10]=='E' && buf[(index+7)%10]=='N'
									&& buf[(index+6)%10]=='N' && buf[(index+5)%10]=='O' && buf[(index+4)%10]=='C') {
					this->connectID++;
					return true;
				}
				index++;
				if (index==10)
					index = 0;			
			}
		}
		if (this->isDebug) {
			debugPrintln("connectTCPServer timeout");
		}
		return false;		
	}
}
static EmberStatus stateMachineRun(void)
{
  EmberStatus status = EMBER_SUCCESS;
  emberAfCorePrintln("%p State: %p",
                     PLUGIN_NAME,
                     emAfPluginNetworkSteeringStateNames[emAfPluginNetworkSteeringState]);

  if ((status = setupSecurity()) != EMBER_SUCCESS) {
    emberAfCorePrintln("Error: %p could not setup security: 0x%X",
                       PLUGIN_NAME,
                       status);
    return tryNextMethod();
  }

  switch (emAfPluginNetworkSteeringState) {
  case EMBER_AF_PLUGIN_NETWORK_STEERING_STATE_SCAN_PRIMARY_INSTALL_CODE:
  case EMBER_AF_PLUGIN_NETWORK_STEERING_STATE_SCAN_PRIMARY_CENTRALIZED:
  case EMBER_AF_PLUGIN_NETWORK_STEERING_STATE_SCAN_PRIMARY_DISTRIBUTED:
    currentChannelMask = emAfPluginNetworkSteeringPrimaryChannelMask;
    break;
  default:
    currentChannelMask = emAfPluginNetworkSteeringSecondaryChannelMask;
    break;
  }

  debugPrintln("Channel Mask: 0x%4X", currentChannelMask);
  gotoNextChannel();
  return status;
}
static void networkFoundCallback(EmberZigbeeNetwork *networkFound,
                                 uint8_t lqi,
                                 int8_t rssi)
{
  emAfPluginNetworkSteeringTotalBeacons++;

  if (!(networkFound->allowingJoin
        && networkFound->stackProfile == REQUIRED_STACK_PROFILE)) {
    return;
  }

  debugPrint("%p nwk found ch: %d, panID 0x%2X, xpan: ",
             PLUGIN_NAME,
             networkFound->channel,
             networkFound->panId);
  debugExec(emberAfPrintBigEndianEui64(networkFound->extendedPanId));
  debugPrintln("");

  if (!addPanIdCandidate(networkFound->panId)) {
    emberAfCorePrintln("Error: %p could not add candidate network.",
                       PLUGIN_NAME);
    cleanupAndStop(EMBER_ERR_FATAL);
    return;
  }
}
void tryToJoinNetwork(void)
{
  EmberNetworkParameters networkParams;
  EmberStatus status;
  EmberNodeType nodeType;

  MEMSET(&networkParams, 0, sizeof(EmberNetworkParameters));

  networkParams.panId = getNextCandidate();
  if (networkParams.panId == EMBER_AF_INVALID_PAN_ID) {
    debugPrintln("No networks to join on channel %d", emAfPluginNetworkSteeringCurrentChannel);
    gotoNextChannel();
    return;
  }

  emberAfCorePrintln("%p joining 0x%2x", PLUGIN_NAME, networkParams.panId);
  networkParams.radioChannel = emAfPluginNetworkSteeringCurrentChannel;
  networkParams.radioTxPower = emberAfPluginNetworkSteeringGetPowerForRadioChannelCallback(emAfPluginNetworkSteeringCurrentChannel);
  nodeType = emberAfPluginNetworkSteeringGetNodeTypeCallback(emAfPluginNetworkSteeringState);
  status = emberJoinNetwork(nodeType, &networkParams);
  emAfPluginNetworkSteeringJoinAttempts++;
  if (EMBER_SUCCESS != status) {
    emberAfCorePrintln("Error: %p could not attempt join: 0x%X",
                       PLUGIN_NAME,
                       status);
    cleanupAndStop(status);
    return;
  }
}
void gotoNextChannel(void)
{
  EmberAfPluginScanDispatchScanData scanData;
  EmberStatus status;

  emAfPluginNetworkSteeringCurrentChannel = getNextChannel();
  if (emAfPluginNetworkSteeringCurrentChannel == 0) {
    debugPrintln("No more channels");
    tryNextMethod();
    return;
  }
  clearPanIdCandidates();

  scanData.scanType = EMBER_ACTIVE_SCAN;
  scanData.channelMask = BIT32(emAfPluginNetworkSteeringCurrentChannel);
  scanData.duration = EMBER_AF_PLUGIN_NETWORK_STEERING_SCAN_DURATION;
  scanData.handler = scanResultsHandler;
  status = emberAfPluginScanDispatchScheduleScan(&scanData);
                                      
  if (EMBER_SUCCESS != status) {
    emberAfCorePrintln("Error: %p start scan failed: 0x%X", PLUGIN_NAME, status);
    cleanupAndStop(status);
  } else {
    emberAfCorePrintln("Starting scan on channel %d",
                       emAfPluginNetworkSteeringCurrentChannel);
  }
}
void LockSystemController::motorStuck() {
#ifdef LOCK_SYSTEM_CONTROLLER_DEBUG
	debugPrintln(F("LSC:motorStuck"));
#endif
	switch (mainState) {
		case Automatic:
			{
				switch (autoState) {
					case locking:
						{
							newAutoState(stuck);
							newMainState(Fault);
						}
						break;
					case unlocking:
						{
							newAutoState(stuck);
							newMainState(Fault);
						}
						break;
				}
			}
			break;
	}
}
void LockSystemController::wakeUp()
{
#ifdef LOCK_SYSTEM_CONTROLLER_DEBUG
	debugPrintln(F("LSC:wakeUp"));
#endif
	motorCont->wakeUp();
}
Beispiel #12
0
bool Esp8266::reset() {

	unsigned long timeout = 7000;
	unsigned long t_start = 0;
	int buf[10];
	char index=0;

	clearBuf();
	write("AT+RST");
	t_start = millis();
	while ((millis()-t_start) < timeout) {
		while (available()>0) {
			buf[index] = read();
			if (buf[index]=='y' && buf[(index+9)%10]=='d' && buf[(index+8)%10]=='a' && buf[(index+7)%10]=='e' && buf[(index+6)%10]=='r') {
				return true;
			}
			index++;
			if (index==10)
				index = 0;
		}
	}
   	if (this->isDebug) {
		debugPrintln("rest esp8266 timeout");
	}
	return false;	
}
int LockSystemController::isLocked()
{
#ifdef LOCK_SYSTEM_CONTROLLER_DEBUG
	debugPrint(F("LSC:isLocked locked: "));
	debugPrintln(mainState == Automatic && autoState == locked);
#endif
	return (mainState == Automatic && autoState == locked);
}
Beispiel #14
0
void AsiMS2000::displayCommands()
{
  char buffer [50];
  for(int i = 0; i < _numCommands; i++)
  {
    sprintf(buffer, "%s => %s", _commands[i], _shortcuts[i]);
    debugPrintln(buffer);
  }
}
void LockSystemController::updateCalibData()
{
	if (initState == uncalibrated) {
		return;
	}

	Cartesian curCart;
	laObs->getCart(&curCart);

	if (calibrationData.maxVals.x < curCart.x) { calibrationData.maxVals.x = curCart.x; }
	if (calibrationData.maxVals.y < curCart.y) { calibrationData.maxVals.y = curCart.y; }
	if (calibrationData.maxVals.z < curCart.z) { calibrationData.maxVals.z = curCart.z; }

	if (calibrationData.minVals.x > curCart.x) { calibrationData.minVals.x = curCart.x; }
	if (calibrationData.minVals.y > curCart.y) { calibrationData.minVals.y = curCart.y; }
	if (calibrationData.minVals.z > curCart.z) { calibrationData.minVals.z = curCart.z; }

	calibrationData.absDeltas.x += abs(curCart.x - calibrationData.lastReading.x);
	calibrationData.absDeltas.y += abs(curCart.y - calibrationData.lastReading.y);
	calibrationData.absDeltas.z += abs(curCart.z - calibrationData.lastReading.z);

	calibrationData.lastReading = curCart;
#ifdef LOCK_SYSTEM_CONTROLLER_DEBUG
	static long lastPrint_ms = 0;
	if (millis() - lastPrint_ms > 500) {
		debugPrint(F("LSC:calib minVals "));
		debugPrint(calibrationData.minVals.x); debugPrint(SPACE);
		debugPrint(calibrationData.minVals.y); debugPrint(SPACE);
		debugPrintln(calibrationData.minVals.z);

		debugPrint(F("LSC:calib maxVals "));
		debugPrint(calibrationData.maxVals.x); debugPrint(SPACE);
		debugPrint(calibrationData.maxVals.y); debugPrint(SPACE);
		debugPrintln(calibrationData.maxVals.z);

		debugPrint(F("LSC:calib absDeltas "));
		debugPrint(calibrationData.absDeltas.x); debugPrint(SPACE);
		debugPrint(calibrationData.absDeltas.y); debugPrint(SPACE);
		debugPrintln(calibrationData.absDeltas.z);

		lastPrint_ms = millis();
	}
#endif
}
static void scheduleEvent(bool withDelay)
{
  if (withDelay) {
    debugPrintln("%p scheduled event for %d qs", PLUGIN_NAME, DISCOVERY_DELAY_QS);
    emberEventControlSetDelayQS(emberAfPluginDeviceQueryServiceMyEventControl,
                                DISCOVERY_DELAY_QS);
  } else {
    emberEventControlSetActive(emberAfPluginDeviceQueryServiceMyEventControl);
  }
}
Beispiel #17
0
bool Esp8266::connectAP(String ssid, String password) {

	unsigned long timeout = 20000;
	unsigned long t_start = 0;
	int buf[10];
	char index=0;
 
	if (checkMode()!=WIFI_MODE_AP){
		this->wifiMode = WIFI_MODE_STATION;
	}
	else {
		if (setMode(WIFI_MODE_STATION))
			this->wifiMode = WIFI_MODE_STATION;
		else {
			if (this->isDebug) {
				debugPrintln("set mode to station false!");
			}
			return false;
		}
	}

	clearBuf();
	this->serial->println("AT+CWJAP=\""+ssid+"\",\""+password+"\"");
	t_start = millis();
	while ((millis()-t_start) < timeout) {
		while (available()>0) {
			buf[index] = read();
			if (buf[index]=='K' && buf[(index+9)%10]=='O') {
				return true;
			}
			if (buf[index]=='L' && buf[(index+9)%10]=='I' && buf[(index+8)%10]=='A' && buf[(index+7)%10]=='F') {
				return false;
			}
			index++;
			if (index==10)
				index = 0;
		}
	}
	if (this->isDebug) {
		debugPrintln("connect AP timeout");
	}
	return false;
}
void WaypointStore::storeWaypoint(int waypoint, float lat, float lon)
{
  int latAddress = addressForWaypoint(waypoint);
  if (eepromReadFloat(latAddress) != lat) {
    eepromWriteFloat(latAddress, lat);
  }
  int lonAddress = latAddress + 4;
  if (eepromReadFloat(lonAddress) != lon) {
    eepromWriteFloat(lonAddress, lon);
  }
  debugPrintln(F("Storing"));
}
Beispiel #19
0
void AsiMS2000::settingsSet(AxisSettingsF *settings)
{
    AxisSettingsF units;
    parseXYZArgs(&units);      
    char buffer [50];
    sprintf(buffer, "settings x=%d y=%d z=%d", units.x, units.y, units.z);
    debugPrintln(buffer);
    if(_isAxis.x) {settings->x = units.x;}
    if(_isAxis.y) {settings->y = units.y;}
    if(_isAxis.z) {settings->z = units.z;}
    serialPrintln(":A");
}
void LockSystemController::stateInfo()
{
#ifdef LOCK_SYSTEM_CONTROLLER_DEBUG
	debugPrint(F("LSC:si "));
#endif
	switch (mainState) {
		case Initial: debugPrint(F("Initial/")); break;
		case Automatic: debugPrint(F("Automatic/")); break;
		case Manual: debugPrint(F("Manual/")); break;
		case Fault: debugPrint(F("Fault/")); break;
	}

	switch (initState) {
		case uncalibrated: debugPrint(F("uncalibrated/")); break;
		case calibratingStartFromUnlockedPos: debugPrint(F("calibratingStartFromUnlockedPos/")); break;
		case calibratingStartFromLockedPos: debugPrint(F("calibratingStartFromLockedPos/")); break;
		case waitForCW: debugPrint(F("waitForCW/")); break;
		case waitForCCW: debugPrint(F("waitForCCW/")); break;
		case calibrated: debugPrint(F("calibrated/")); break;
		case failed: debugPrint(F("failed/")); break;
	}

	switch (autoState) {
		case locked: debugPrintln(F("locked")); break;
		case unlocked: debugPrintln(F("unlocked")); break;
		case locking: debugPrintln(F("locking")); break;
		case unlocking: debugPrintln(F("unlocking")); break;
		case stuck: debugPrintln(F("stuck")); break;
		case init: debugPrintln(F("init")); break;
	}
}
static void sendActiveEndpointRequest(const EmberAfDeviceInfo* device)
{
  debugPrintln("%p initiating active endpoint requset for: 0x%2X", PLUGIN_NAME, currentNodeId);
  EmberStatus status = emberAfFindActiveEndpoints(currentNodeId, serviceDiscoveryCallback);
  if (status != EMBER_SUCCESS) {
    emberAfCorePrintln("Error: %p failed to initiate Active EP request (0x%X)", PLUGIN_NAME, status);
    noteFailedDiscovery(device);
    scheduleEvent(WITH_DELAY);
  } else {
    // Don't schedule event, since service discovery returns the results via callback.
    emberAfPluginDeviceDatabaseSetStatus(device->eui64, EMBER_AF_DEVICE_DISCOVERY_STATUS_FIND_ENDPOINTS);
  }
}
void LockSystemController::cmdUnlock() {
	int curAngle = laObs->getLockAngleDeg();
	MotorController::Direction dir;
	if (unlockedPosition > curAngle)
	{
		dir = (angleIncrCW) ? MotorController::CW : MotorController::CCW;
	}
	else
	{
		dir = (angleIncrCW) ? MotorController::CCW : MotorController::CW;
	}
#ifdef LOCK_SYSTEM_CONTROLLER_DEBUG
	debugPrint(F("LSC:cmdUnlock dir pwr pos ")); debugPrint(dir == MotorController::CW ? S_CW : S_CCW); debugPrint(SPACE);
	debugPrint(drivePower); debugPrint(SPACE);
	debugPrintln(unlockedPosition);
#endif
	motorCont->cmdDriveMotorToPosition(dir, drivePower, unlockedPosition);
}
static void sendSimpleDescriptorRequest(const EmberAfDeviceInfo* device)
{
  uint8_t endpoint = emberAfPluginDeviceDatabaseGetDeviceEndpointFromIndex(device->eui64, currentEndpointIndex);
  if (endpoint == 0xFF) {
    emberAfCorePrintln("%p All endpoints discovered for 0x%2X", PLUGIN_NAME, currentNodeId);
    emberAfPluginDeviceDatabaseSetStatus(device->eui64, EMBER_AF_DEVICE_DISCOVERY_STATUS_DONE);
    scheduleEvent(WITH_DELAY);
    clearCurrentDevice();
    return;
  }
  debugPrintln("%p initiating simple descriptor request for: 0x%2X EP %d", PLUGIN_NAME, currentNodeId, endpoint);
  EmberStatus status = emberAfFindClustersByDeviceAndEndpoint(currentNodeId, endpoint, serviceDiscoveryCallback);
  if (status != EMBER_SUCCESS) {
    noteFailedDiscovery(device);
    scheduleEvent(WITH_DELAY);
    return;
  }
  // Don't schedule event, since service discovery returns the results via callback.
}
Beispiel #24
0
int AsiMS2000::getCommandNum(String c)
{
  for(int i = 0; i < _numCommands; i++)
  {
    if( c.equalsIgnoreCase(_commands[i]) || c.equalsIgnoreCase(_shortcuts[i]) )
    {
      if(DEBUG_SERIAL)
      {
        char buffer [100];
        sprintf(buffer, "%d: %s, %s", i, _commands[i], _shortcuts[i]);
        debugPrintln(buffer);
      }
      return i;
    }     
  }
  //TODO: one of the commands has a second alias, check for that special case here.
  
  returnErrorToSerial(-1);//unknown command sent if lookup fails.
  return -1;
}
static uint8_t getNextChannel(void)
{
  if (emAfPluginNetworkSteeringCurrentChannel == 0) {
    emAfPluginNetworkSteeringCurrentChannel = (halCommonGetRandom() & 0x0F)
                                               + EMBER_MIN_802_15_4_CHANNEL_NUMBER;
    debugPrintln("Randomly choosing a starting channel %d.", emAfPluginNetworkSteeringCurrentChannel);
  } else {
    emAfPluginNetworkSteeringCurrentChannel++;
  }
  while (currentChannelMask != 0) {
    if (BIT32(emAfPluginNetworkSteeringCurrentChannel) & currentChannelMask) {
      currentChannelMask &= ~(BIT32(emAfPluginNetworkSteeringCurrentChannel));
      return emAfPluginNetworkSteeringCurrentChannel;
    }
    emAfPluginNetworkSteeringCurrentChannel++;
    if (emAfPluginNetworkSteeringCurrentChannel > EMBER_MAX_802_15_4_CHANNEL_NUMBER) {
      emAfPluginNetworkSteeringCurrentChannel = EMBER_MIN_802_15_4_CHANNEL_NUMBER;
    }
  }
  return 0;
}
Beispiel #26
0
/// Main function for ADC test firmware
int main(void) {
	uint8_t debugAdc, i;
	FunctionalState led = DISABLE;
	defaultInit();
	debugAdc = debugNewSource("ADC");
	debugSourceEnable(debugAdc, ENABLE);
	debugPrintln(debugAdc, "test start");
	timerStartMs(100);
	for (;;) {
		adcLoop();
		if (timerEnd()) {
			timerStartMs(500);
			ledCmd(0, led);
			led = !led;
			debugPrintRaw(debugAdc, "ADC:");
			for (i = 0; i < ADC_NUMBER; i++) {
				debugPrintRaw(debugAdc, " %u", adcRead(i));
			}
			debugPrintRaw(debugAdc, "\r\n");
		}
	}
}
Beispiel #27
0
//call to display detailed position information on the debug port.
void AsiMS2000::displayCurrentToDesired(char message[])
{
    char buffer[20];
    String reply = String(message);    
    AxisSettingsF a = AsiSettings.currentPos;
    AxisSettingsF d = AsiSettings.desiredPos;
    dtostrf(a.x,1,4,buffer);
    reply.concat(" " + String(buffer) + "->");
    dtostrf(d.x,1,4,buffer);
    reply.concat(String(buffer) + " ");
    
    dtostrf(a.y,1,4,buffer);
    reply.concat(String(buffer) + "->");
    dtostrf(d.y,1,4,buffer);
    reply.concat(String(buffer) + " ");

    dtostrf(a.z,1,4,buffer);
    reply.concat(String(buffer) + "->");
    dtostrf(d.z,1,4,buffer);
    reply.concat(String(buffer) + " ");
    
    debugPrintln(reply);
}
void LockSystemController::motorComplete() {
#ifdef LOCK_SYSTEM_CONTROLLER_DEBUG
	debugPrintln(F("LSC:motorComplete"));
#endif
	switch (mainState) {
		case Automatic:
			{
				switch (autoState) {
					case locking:
						{
							newAutoState(locked);
						}
						break;
					case unlocking:
						{
							newAutoState(unlocked);
						}
						break;
				}
			}
			break;
	}
}
void emberAfPluginDeviceQueryServiceInitCallback(void)
{
  debugPrintln("%p init called.", PLUGIN_NAME);
  clearCurrentDevice();
}
void emberAfPluginDeviceQueryServiceMyEventHandler(void)
{
  emberEventControlSetInactive(emberAfPluginDeviceQueryServiceMyEventControl);
  debugPrintln("%p event", PLUGIN_NAME);
  const EmberAfDeviceInfo* device;
  if (emberAfMemoryByteCompare(currentEui64, EUI64_SIZE, 0xFF)) {
    debugPrintln("%p no current device being queried, looking in database for one.", PLUGIN_NAME);
    device = emberAfPluginDeviceDatabaseFindDeviceByStatus(EMBER_AF_DEVICE_DISCOVERY_STATUS_NEW
                                                           | EMBER_AF_DEVICE_DISCOVERY_STATUS_FIND_ENDPOINTS
                                                           | EMBER_AF_DEVICE_DISCOVERY_STATUS_FIND_CLUSTERS);
    if (device != NULL) {
      debugPrintln("%p found device with status (0x%X): %p",
                   PLUGIN_NAME,
                   device->status,
                   emberAfPluginDeviceDatabaseGetStatusString(device->status));
      if ((device->capabilities & RECEIVER_ON_WHEN_IDLE) == 0) {
        emberAfPluginDeviceDatabaseSetStatus(device->eui64, EMBER_AF_DEVICE_DISCOVERY_STATUS_DONE);
        debugPrintln("%p ignoring sleepy device.");
        scheduleEvent(RIGHT_NOW);
        return;

      } else {
        MEMMOVE(currentEui64, device->eui64, EUI64_SIZE);
      }
    }
  } else {
    device = emberAfPluginDeviceDatabaseFindDeviceByEui64(currentEui64);
    if (device == NULL) {
      emberAfCorePrint("Error: %p the current EUI64 does not correspond to any known device: ", PLUGIN_NAME);
      emberAfPrintLittleEndianEui64(currentEui64);
      emberAfCorePrintln("");
      clearCurrentDevice();
      scheduleEvent(WITH_DELAY);
      return;
    }
  }

  if (device == NULL) {
    clearCurrentDevice();

    if (emberAfPluginDeviceDatabaseClearAllFailedDiscoveryStatus(EMBER_AF_PLUGIN_DEVICE_QUERY_SERVICE_MAX_FAILURES)) {
      emberAfCorePrintln("%p Retrying failed discoveries.", PLUGIN_NAME);
      scheduleEvent(WITH_DELAY);
    } else {
      emberAfCorePrintln("%p All known devices discovered.", PLUGIN_NAME);
    }
    return;
  }

  // Although we could consult our local tables for addresses, we perform a broadcast
  // lookup here to insure that we have a current source route back to the destination.
  // The target of the discovery will unicast the result, along with a route record.
  if (currentNodeId == EMBER_NULL_NODE_ID) {
    debugPrint("%p initiating node ID discovery for: ", PLUGIN_NAME);
    debugPrintEui64(currentEui64);
    debugPrintln("");
    EmberStatus status = emberAfFindNodeId(currentEui64, serviceDiscoveryCallback);
    if (status != EMBER_SUCCESS) {
      emberAfCorePrintln("%p failed to initiate node ID discovery.", PLUGIN_NAME);
      noteFailedDiscovery(device);
      scheduleEvent(WITH_DELAY);
    }
    // Else
    //   Don't schedule event, since service discovery callback returns the results.
    return;
  }

  switch (device->status) {
    case EMBER_AF_DEVICE_DISCOVERY_STATUS_NEW:
    case EMBER_AF_DEVICE_DISCOVERY_STATUS_FIND_ENDPOINTS:
      sendActiveEndpointRequest(device);
    break;

    case EMBER_AF_DEVICE_DISCOVERY_STATUS_FIND_CLUSTERS:
      sendSimpleDescriptorRequest(device);
      break;

    default:
      break;
  }
}