diff --git a/owlet/integrationpluginowlet.cpp b/owlet/integrationpluginowlet.cpp index b7f319d9..062fa882 100644 --- a/owlet/integrationpluginowlet.cpp +++ b/owlet/integrationpluginowlet.cpp @@ -54,17 +54,40 @@ void IntegrationPluginOwlet::init() m_owletIdParamTypeMap.insert(digitalInputThingClassId, digitalInputThingOwletIdParamTypeId); m_owletIdParamTypeMap.insert(ws2812ThingClassId, ws2812ThingOwletIdParamTypeId); + m_owletSerialPortParamTypeMap.insert(arduinoUnoThingClassId, arduinoUnoThingSerialPortParamTypeId); m_owletSerialPortParamTypeMap.insert(arduinoMiniProThingClassId, arduinoMiniProThingSerialPortParamTypeId); m_zeroConfBrowser = hardwareManager()->zeroConfController()->createServiceBrowser("_nymea-owlet._tcp"); - // Pin params of thins + // Pin params of serial things m_owletSerialPinParamTypeMap.insert(digitalOutputSerialThingClassId, digitalOutputSerialThingPinParamTypeId); m_owletSerialPinParamTypeMap.insert(digitalInputSerialThingClassId, digitalInputSerialThingPinParamTypeId); m_owletSerialPinParamTypeMap.insert(analogOutputSerialThingClassId, analogOutputSerialThingPinParamTypeId); m_owletSerialPinParamTypeMap.insert(analogInputSerialThingClassId, analogInputSerialThingPinParamTypeId); m_owletSerialPinParamTypeMap.insert(servoSerialThingClassId, servoSerialThingPinParamTypeId); + // Arduino Uno mapping + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPin0ParamTypeId, 0); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPin1ParamTypeId, 1); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPin2ParamTypeId, 2); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPin3ParamTypeId, 3); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPin4ParamTypeId, 4); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPin5ParamTypeId, 5); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPin6ParamTypeId, 6); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPin7ParamTypeId, 7); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPin8ParamTypeId, 8); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPin9ParamTypeId, 9); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPin10ParamTypeId, 10); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPin11ParamTypeId, 11); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPin12ParamTypeId, 12); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPin13ParamTypeId, 13); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPinA0ParamTypeId, 14); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPinA1ParamTypeId, 15); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPinA2ParamTypeId, 16); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPinA3ParamTypeId, 17); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPinA4ParamTypeId, 18); + m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPinA5ParamTypeId, 19); + // Arduino Mini Pro mapping m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin2ParamTypeId, 2); m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin3ParamTypeId, 3); @@ -92,7 +115,7 @@ void IntegrationPluginOwlet::discoverThings(ThingDiscoveryInfo *info) if (info->thingClassId() == arduinoMiniProThingClassId) { // Discover serial ports for arduino bords foreach(const QSerialPortInfo &port, QSerialPortInfo::availablePorts()) { - qCDebug(dcOwlet()) << "Found serial port" << port.systemLocation(); + qCDebug(dcOwlet()) << "Found serial port" << port.systemLocation() << port.description() << port.serialNumber(); QString description = port.systemLocation() + " " + port.manufacturer() + " " + port.description(); ThingDescriptor thingDescriptor(info->thingClassId(), "Arduino Pro Mini Owlet", description); ParamList parameters; @@ -109,6 +132,26 @@ void IntegrationPluginOwlet::discoverThings(ThingDiscoveryInfo *info) info->addThingDescriptor(thingDescriptor); } info->finish(Thing::ThingErrorNoError); + } else if (info->thingClassId() == arduinoUnoThingClassId) { + // Discover serial ports for arduino bords + foreach(const QSerialPortInfo &port, QSerialPortInfo::availablePorts()) { + qCDebug(dcOwlet()) << "Found serial port" << port.systemLocation() << port.description() << port.serialNumber(); + QString description = port.systemLocation() + " " + port.manufacturer() + " " + port.description(); + ThingDescriptor thingDescriptor(info->thingClassId(), "Arduino Uno Owlet", description); + ParamList parameters; + + foreach (Thing *existingThing, myThings()) { + if (existingThing->paramValue(m_owletSerialPortParamTypeMap.value(info->thingClassId())).toString() == port.systemLocation()) { + thingDescriptor.setThingId(existingThing->id()); + break; + } + } + + parameters.append(Param(m_owletSerialPortParamTypeMap.value(info->thingClassId()), port.systemLocation())); + thingDescriptor.setParams(parameters); + info->addThingDescriptor(thingDescriptor); + } + info->finish(Thing::ThingErrorNoError); } else { foreach (const ZeroConfServiceEntry &entry, m_zeroConfBrowser->serviceEntries()) { qCDebug(dcOwlet()) << "Found owlet:" << entry; @@ -204,6 +247,82 @@ void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) return; } + + if (thing->thingClassId() == arduinoUnoThingClassId) { + QString serialPort = thing->paramValue(arduinoUnoThingSerialPortParamTypeId).toString(); + qCDebug(dcOwlet()) << "Setup arduino uno owlet on" << serialPort; + OwletTransport *transport = new OwletSerialTransport(serialPort, 115200, this); + OwletSerialClient *client = new OwletSerialClient(transport, transport); + + // During setup + connect(client, &OwletSerialClient::connected, info, [=](){ + qCDebug(dcOwlet()) << "Connected to serial owlet" << client->firmwareVersion(); + thing->setStateValue("connected", true); + }); + + connect(client, &OwletSerialClient::error, info, [=](){ + //info->finish(Thing::ThingErrorHardwareFailure); + transport->deleteLater(); + }); + + // Runtime + connect(client, &OwletSerialClient::connected, thing, [=](){ + thing->setStateValue("connected", true); + thing->setStateValue(arduinoUnoCurrentVersionStateTypeId, client->firmwareVersion()); + foreach (Thing *childThing, myThings().filterByParentId(thing->id())) { + childThing->setStateValue("connected", true); + } + }); + + connect(client, &OwletSerialClient::disconnected, thing, [=](){ + thing->setStateValue("connected", false); + foreach (Thing *childThing, myThings().filterByParentId(thing->id())) { + childThing->setStateValue("connected", false); + } + }); + + connect(thing, &Thing::settingChanged, thing, [=](const ParamTypeId ¶mTypeId, const QVariant &value){ + qCDebug(dcOwlet()) << "Arduino UNO settings changed" << paramTypeId << value; + quint8 pinId = m_arduinoUnoPinMapping.value(paramTypeId); + OwletSerialClient::PinMode pinMode = getPinModeFromSettingsValue(value.toString()); + + // Check if we have a thing for this pin and if we need to remove it before setting up + Thing *existingThing = nullptr; + foreach (Thing *childThing, myThings().filterByParentId(thing->id())) { + int existingPinId = childThing->paramValue(m_owletSerialPinParamTypeMap.value(childThing->thingClassId())).toUInt(); + if (existingPinId == pinId) { + qCDebug(dcOwlet()) << "Found already configured thing for pin" << pinId; + existingThing = childThing; + break; + } + } + + if (existingThing) { + if ((pinMode == OwletSerialClient::PinModeDigitalOutput && existingThing->thingClassId() == digitalOutputSerialThingClassId) || + (pinMode == OwletSerialClient::PinModeDigitalInput && existingThing->thingClassId() == digitalInputSerialThingClassId) || + (pinMode == OwletSerialClient::PinModeAnalogOutput && existingThing->thingClassId() == analogOutputSerialThingClassId) || + (pinMode == OwletSerialClient::PinModeAnalogInput && existingThing->thingClassId() == analogInputSerialThingClassId) || + (pinMode == OwletSerialClient::PinModeServo && existingThing->thingClassId() == servoSerialThingClassId)) { + + qCDebug(dcOwlet()) << "Thing for pin" << pinId << "is already configured as" << pinMode; + return; + } else { + qCDebug(dcOwlet()) << "Have thing for pin" << pinId << "but should be configured as" << pinMode; + qCDebug(dcOwlet()) << "Remove existing thing before setup a new one"; + emit autoThingDisappeared(existingThing->id()); + } + } + + setupArduinoChildThing(client, pinId, pinMode); + }); + + m_serialClients.insert(thing, client); + info->finish(Thing::ThingErrorNoError); + + client->transport()->connectTransport(); + return; + } + if (thing->thingClassId() == digitalOutputSerialThingClassId) { info->finish(Thing::ThingErrorNoError); @@ -327,7 +446,7 @@ void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) qCWarning(dcOwlet()) << "Configure pin request finished with error" << configurationError; return; } - quint32 value; + quint16 value; stream >> value; qCDebug(dcOwlet()) << "Analog value of" << thing << value; thing->setStateValue(analogInputSerialAnalogValueStateTypeId, value); @@ -608,7 +727,7 @@ void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) return; } - if (!client->ready()) { + if (!client->isReady()) { qCWarning(dcOwlet()) << "Could not execute action. The serial client is not ready or connected."; info->finish(Thing::ThingErrorHardwareNotAvailable); return; @@ -624,6 +743,30 @@ void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) } } + if (info->thing()->thingClassId() == arduinoUnoThingClassId) { + OwletSerialClient *client = m_serialClients.value(info->thing()); + if (!client) { + qCWarning(dcOwlet()) << "Could not execute action. There is no client available for this thing"; + info->finish(Thing::ThingErrorHardwareFailure); + return; + } + + if (!client->isReady()) { + qCWarning(dcOwlet()) << "Could not execute action. The serial client is not ready or connected."; + info->finish(Thing::ThingErrorHardwareNotAvailable); + return; + } + if (info->action().actionTypeId() == arduinoUnoPerformUpdateActionTypeId) { + qCDebug(dcOwlet()) << "Perform firmware update on" << info->thing(); + //if (client->firmwareVersion() != ) + + // TODO: run upgrade process using avrdude + + info->finish(Thing::ThingErrorNoError); + return; + } + } + if (info->thing()->thingClassId() == analogOutputSerialThingClassId) { OwletSerialClient *client = m_serialClients.value(myThings().findById(info->thing()->parentId())); if (!client) { @@ -632,7 +775,7 @@ void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) return; } - if (!client->ready()) { + if (!client->isReady()) { qCWarning(dcOwlet()) << "Could not execute action. The serial client is not ready or connected."; info->finish(Thing::ThingErrorHardwareNotAvailable); return; @@ -683,7 +826,7 @@ void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) return; } - if (!client->ready()) { + if (!client->isReady()) { qCWarning(dcOwlet()) << "Could not execute action. The serial client is not ready or connected."; info->finish(Thing::ThingErrorHardwareNotAvailable); return; @@ -735,7 +878,7 @@ void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) return; } - if (!client->ready()) { + if (!client->isReady()) { qCWarning(dcOwlet()) << "Could not execute action. The serial client is not ready or connected."; info->finish(Thing::ThingErrorHardwareNotAvailable); return; @@ -778,8 +921,6 @@ void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) return; } - - Q_ASSERT_X(false, "IntegrationPluginOwlet", "Not implemented"); info->finish(Thing::ThingErrorUnsupportedFeature); } @@ -841,7 +982,7 @@ void IntegrationPluginOwlet::setupArduinoChildThing(OwletSerialClient *client, q switch (pinMode) { case OwletSerialClient::PinModeDigitalOutput: { qCDebug(dcOwlet()) << "Setting up digital output on serial owlet for pin" << pinId; - ThingDescriptor descriptor(digitalOutputSerialThingClassId, thingClass(digitalOutputSerialThingClassId).displayName() + " (" + QString::number(pinId) + ")", QString(), parentThing->id()); + ThingDescriptor descriptor(digitalOutputSerialThingClassId, thingClass(digitalOutputSerialThingClassId).displayName() + " (" + getPinName(parentThing, pinId) + ")", QString(), parentThing->id()); ParamList params; params.append(Param(digitalOutputSerialThingPinParamTypeId, pinId)); descriptor.setParams(params); @@ -850,7 +991,7 @@ void IntegrationPluginOwlet::setupArduinoChildThing(OwletSerialClient *client, q } case OwletSerialClient::PinModeDigitalInput: { qCDebug(dcOwlet()) << "Setting up digital input on serial owlet for pin" << pinId; - ThingDescriptor descriptor(digitalInputSerialThingClassId, thingClass(digitalInputSerialThingClassId).displayName() + " (" + QString::number(pinId) + ")", QString(), parentThing->id()); + ThingDescriptor descriptor(digitalInputSerialThingClassId, thingClass(digitalInputSerialThingClassId).displayName() + " (" + getPinName(parentThing, pinId) + ")", QString(), parentThing->id()); ParamList params; params.append(Param(digitalInputSerialThingPinParamTypeId, pinId)); descriptor.setParams(params); @@ -859,7 +1000,7 @@ void IntegrationPluginOwlet::setupArduinoChildThing(OwletSerialClient *client, q } case OwletSerialClient::PinModeAnalogOutput: { qCDebug(dcOwlet()) << "Setting up digital output on serial owlet for pin" << pinId; - ThingDescriptor descriptor(analogOutputSerialThingClassId, thingClass(analogOutputSerialThingClassId).displayName() + " (" + QString::number(pinId) + ")", QString(), parentThing->id()); + ThingDescriptor descriptor(analogOutputSerialThingClassId, thingClass(analogOutputSerialThingClassId).displayName() + " (" + getPinName(parentThing, pinId) + ")", QString(), parentThing->id()); ParamList params; params.append(Param(analogOutputSerialThingPinParamTypeId, pinId)); descriptor.setParams(params); @@ -868,7 +1009,7 @@ void IntegrationPluginOwlet::setupArduinoChildThing(OwletSerialClient *client, q } case OwletSerialClient::PinModeAnalogInput: { qCDebug(dcOwlet()) << "Setting up analog input on serial owlet for pin" << pinId; - ThingDescriptor descriptor(analogInputSerialThingClassId, thingClass(analogInputSerialThingClassId).displayName() + " (" + QString::number(pinId) + ")", QString(), parentThing->id()); + ThingDescriptor descriptor(analogInputSerialThingClassId, thingClass(analogInputSerialThingClassId).displayName() + " (" + getPinName(parentThing, pinId) + ")", QString(), parentThing->id()); ParamList params; params.append(Param(analogInputSerialThingPinParamTypeId, pinId)); descriptor.setParams(params); @@ -877,7 +1018,7 @@ void IntegrationPluginOwlet::setupArduinoChildThing(OwletSerialClient *client, q } case OwletSerialClient::PinModeServo: { qCDebug(dcOwlet()) << "Setting up servo on serial owlet for pin" << pinId; - ThingDescriptor descriptor(servoSerialThingClassId, thingClass(servoSerialThingClassId).displayName() + " (" + QString::number(pinId) + ")", QString(), parentThing->id()); + ThingDescriptor descriptor(servoSerialThingClassId, thingClass(servoSerialThingClassId).displayName() + " (" + getPinName(parentThing, pinId) + ")", QString(), parentThing->id()); ParamList params; params.append(Param(servoSerialThingPinParamTypeId, pinId)); descriptor.setParams(params); @@ -915,3 +1056,14 @@ void IntegrationPluginOwlet::configurePin(OwletSerialClient *client, quint8 pinI }); } +QString IntegrationPluginOwlet::getPinName(Thing *parent, quint8 pinId) +{ + if (parent->thingClassId() == arduinoUnoThingClassId) { + return parent->thingClass().settingsTypes().findById(m_arduinoUnoPinMapping.key(pinId)).displayName(); + } else if (parent->thingClassId() == arduinoMiniProThingClassId) { + return parent->thingClass().settingsTypes().findById(m_arduinoMiniProPinMapping.key(pinId)).displayName(); + } + + return QString(); +} + diff --git a/owlet/integrationpluginowlet.h b/owlet/integrationpluginowlet.h index c40c3273..e4e2859c 100644 --- a/owlet/integrationpluginowlet.h +++ b/owlet/integrationpluginowlet.h @@ -67,11 +67,13 @@ private: QHash m_owletSerialPortParamTypeMap; QHash m_owletSerialPinParamTypeMap; + QHash m_arduinoUnoPinMapping; QHash m_arduinoMiniProPinMapping; OwletSerialClient::PinMode getPinModeFromSettingsValue(const QString &settingsValue); void setupArduinoChildThing(OwletSerialClient *client, quint8 pinId, OwletSerialClient::PinMode pinMode); void configurePin(OwletSerialClient *client, quint8 pinId, OwletSerialClient::PinMode pinMode); + QString getPinName(Thing *parent, quint8 pinId); }; #endif // INTEGRATIONPLUGINOWLET_H diff --git a/owlet/integrationpluginowlet.json b/owlet/integrationpluginowlet.json index 4c006ce5..8c412990 100644 --- a/owlet/integrationpluginowlet.json +++ b/owlet/integrationpluginowlet.json @@ -220,6 +220,327 @@ } ] }, + { + "id": "f38fd38f-9f3c-46a6-ba0f-44c256b7217d", + "name": "arduinoUno", + "displayName": "Arduino Uno Owlet", + "createMethods": ["user", "discovery"], + "interfaces": ["gateway", "update", "connectable"], + "paramTypes": [ + { + "id": "96de936e-4625-4c36-83f3-276bd5af38a1", + "name": "serialPort", + "displayName": "Serial port", + "type": "QString", + "inputType": "TextLine", + "defaultValue": "/dev/ttyS0" + } + ], + "settingsTypes": [ + { + "id": "00ddd091-08d8-4b5e-877d-b6456c58f009", + "name": "pin0", + "displayName": "Pin 0", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "22b8e5da-dd43-446d-ba01-bd93f09504c9", + "name": "pin1", + "displayName": "Pin 1", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "479252df-1a83-4910-b51f-551b4badcdc3", + "name": "pin2", + "displayName": "Pin 2", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "f2889d55-31c4-4f28-a679-262efa287f73", + "name": "pin3", + "displayName": "Pin 3", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "7e4ea5e4-4c54-4931-a0ee-05b2b466da78", + "name": "pin4", + "displayName": "Pin 4", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "92c0e77a-12a1-4344-871c-01191be023f6", + "name": "pin5", + "displayName": "Pin 5", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "83cecd4b-c028-4bd5-b522-7fb565aeb1eb", + "name": "pin6", + "displayName": "Pin 6", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "99c728ec-4082-4586-8a29-fb217d6e842c", + "name": "pin7", + "displayName": "Pin 7", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "3f3a7559-90e5-40f4-9cc5-7477cce7e39d", + "name": "pin8", + "displayName": "Pin 8", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "cbdfd303-e226-48e0-a3f3-eaea801b13e3", + "name": "pin9", + "displayName": "Pin 9", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "32cf9abd-7d9d-4b1a-807b-68b2cd70ffb1", + "name": "pin10", + "displayName": "Pin 10", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "ec5ea717-0d78-4cc1-98e9-0b14b46888c3", + "name": "pin11", + "displayName": "Pin 11", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "4ae182bb-1e60-4175-b8aa-3d74172bec37", + "name": "pin12", + "displayName": "Pin 12", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "53e1d640-05a8-4333-bd12-951a99f4ba07", + "name": "pin13", + "displayName": "Pin 13 - LED", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "d09383e2-7719-477e-9986-f5ca3ebca319", + "name": "pinA0", + "displayName": "Pin A0", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "e24e88b4-bdd6-4b01-ad75-d1cda5c6cfdc", + "name": "pinA1", + "displayName": "Pin A1", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "3f65703c-50f2-4df8-b269-be8410624cd2", + "name": "pinA2", + "displayName": "Pin A2", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "0568be9d-6d4d-4807-90cd-24a9ef3fd12f", + "name": "pinA3", + "displayName": "Pin A3", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "95286eda-723b-4a1f-98cd-d43a02b81b0a", + "name": "pinA4", + "displayName": "Pin A4", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "a6d211a7-920d-4fb0-b3b8-0920a360b591", + "name": "pinA5", + "displayName": "Pin A5", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + } + ], + "stateTypes": [ + { + "id": "4a779310-5424-4555-879c-565b1ac04d65", + "name": "connected", + "displayName": "Connected", + "displayNameEvent": "Connected changed", + "type": "bool", + "defaultValue": false, + "cached": false + }, + { + "id": "e142e236-3878-4d04-aac9-e6f0a75b96ed", + "name": "currentVersion", + "displayName": "Firmware version", + "displayNameEvent": "Firmware version changed", + "type": "QString", + "defaultValue": "" + }, + { + "id": "5ea46fc9-e7ba-49c4-aa33-55b4d1f1e7df", + "name": "updateStatus", + "displayName": "Update status", + "displayNameEvent": "Update status changed", + "type": "QString", + "possibleValues": ["idle", "available", "updating"], + "defaultValue": "idle" + } + ], + "actionTypes": [ + { + "id": "d71b7593-584a-4feb-9c8a-77f169d77286", + "name": "performUpdate", + "displayName": "Update firmware" + } + ] + }, { "id": "22f216f4-9715-48f9-ab76-f7d7436d49c9", "name": "arduinoMiniPro", @@ -391,7 +712,7 @@ { "id": "4522ce36-ba6f-46b0-a54b-410a93065b34", "name": "pin13", - "displayName": "Pin 13 (LED)", + "displayName": "Pin 13 - LED", "type": "QString", "allowedValues": [ "None", diff --git a/owlet/owletserialclient.cpp b/owlet/owletserialclient.cpp index c0b6ec3d..105383ae 100644 --- a/owlet/owletserialclient.cpp +++ b/owlet/owletserialclient.cpp @@ -17,16 +17,29 @@ OwletSerialClient::OwletSerialClient(OwletTransport *transport, QObject *parent) // Clean up queue qDeleteAll(m_pendingRequests); m_pendingRequests.clear(); + } else { + // Wait for the ready notification } }); } +OwletSerialClient::~OwletSerialClient() +{ + qCDebug(dcOwlet()) << "Destroy owlet serial client"; + transport()->disconnectTransport(); +} + OwletTransport *OwletSerialClient::transport() const { return m_transport; } -bool OwletSerialClient::ready() const +bool OwletSerialClient::isConnected() const +{ + return m_transport->connected(); +} + +bool OwletSerialClient::isReady() const { return m_ready; } @@ -198,7 +211,7 @@ void OwletSerialClient::dataReceived(const QByteArray &data) m_firmwareVersion = QString("%1.%2.%3").arg(major).arg(minor).arg(patch); qCDebug(dcOwlet()) << "Connected successfully to firmware" << m_firmwareVersion; m_ready = true; - emit connected(); + emit readyChanged(m_ready); }); break; } diff --git a/owlet/owletserialclient.h b/owlet/owletserialclient.h index 2e20188f..15c7bc21 100644 --- a/owlet/owletserialclient.h +++ b/owlet/owletserialclient.h @@ -62,10 +62,14 @@ public: Q_ENUM(PinMode) explicit OwletSerialClient(OwletTransport *transport, QObject *parent = nullptr); + ~OwletSerialClient(); OwletTransport *transport() const; - bool ready() const; + bool isConnected() const; + bool isReady() const; + + QString firmwareVersion() const; OwletSerialClientReply *getFirmwareVersion(); OwletSerialClientReply *configurePin(quint8 pinId, PinMode pinMode); @@ -75,11 +79,11 @@ public: OwletSerialClientReply *readAnalogValue(quint8 pinId); OwletSerialClientReply *writeServoValue(quint8 pinId, quint8 angle); - QString firmwareVersion() const; signals: void connected(); void disconnected(); + void readyChanged(bool ready); void error(); void pinValueChanged(quint8 pinId, bool power);