From 2bb91cf98b23324674e8f9c60916ff5da1c644e7 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Thu, 14 Oct 2021 00:10:11 +0200 Subject: [PATCH 01/18] WIP: New Plugin: nymea owlet --- nymea-plugins.pro | 1 + owlet/owletclient.cpp | 90 +++++++++++++++++++++++++++++++++++++++++++ owlet/owletclient.h | 37 ++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 owlet/owletclient.cpp create mode 100644 owlet/owletclient.h diff --git a/nymea-plugins.pro b/nymea-plugins.pro index d08024766..05ad8ac14 100644 --- a/nymea-plugins.pro +++ b/nymea-plugins.pro @@ -49,6 +49,7 @@ PLUGIN_DIRS = \ openuv \ openweathermap \ osdomotics \ + owlet \ philipshue \ powerfox \ pushbullet \ diff --git a/owlet/owletclient.cpp b/owlet/owletclient.cpp new file mode 100644 index 000000000..cefd94947 --- /dev/null +++ b/owlet/owletclient.cpp @@ -0,0 +1,90 @@ +#include "owletclient.h" + +#include "extern-plugininfo.h" + +#include +#include + +OwletClient::OwletClient(QObject *parent) : QObject(parent) +{ + +} + +void OwletClient::connectToHost(const QHostAddress &address, int port) +{ + if (m_socket) { + m_socket->abort(); + m_socket->deleteLater(); + } + + m_socket = new QTcpSocket(this); + connect(m_socket, &QTcpSocket::connected, this, [this](){ + emit connected(); + }); + connect(m_socket, &QTcpSocket::disconnected, this, [this, address, port](){ + qCDebug(dcOwlet()) << "Disconnected from owleet"; + emit disconnected(); + QTimer::singleShot(1000, this, [=]{ + connectToHost(address, port); + }); + + }); + connect(m_socket, &QTcpSocket::errorOccurred, this, [this](){ + qCDebug(dcOwlet()) << "Error in owlet communication"; + emit error(); + }); + + connect(m_socket, &QTcpSocket::readyRead, this, [this](){ + dataReceived(m_socket->readAll()); + }); + m_socket->connectToHost(address, port); +} + +int OwletClient::sendCommand(const QString &method, const QVariantMap ¶ms) +{ + if (!m_socket) { + qCWarning(dcOwlet()) << "Not connected to owlet. Not sending command."; + return -1; + } + + int id = ++m_commandId; + + QVariantMap packet; + packet.insert("id", id); + packet.insert("method", method); + packet.insert("params", params); + m_socket->write(QJsonDocument::fromVariant(packet).toJson(QJsonDocument::Compact)); + return id; +} + +void OwletClient::dataReceived(const QByteArray &data) +{ + m_receiveBuffer.append(data); + + int splitIndex = m_receiveBuffer.indexOf("}\n{") + 1; + if (splitIndex <= 0) { + splitIndex = m_receiveBuffer.length(); + } + QJsonParseError error; + QJsonDocument jsonDoc = QJsonDocument::fromJson(m_receiveBuffer.left(splitIndex), &error); + if (error.error != QJsonParseError::NoError) { + // qWarning() << "Could not parse json data from nymea" << m_receiveBuffer.left(splitIndex) << error.errorString(); + return; + } + // qDebug() << "received response" << qUtf8Printable(jsonDoc.toJson(QJsonDocument::Indented)); + m_receiveBuffer = m_receiveBuffer.right(m_receiveBuffer.length() - splitIndex - 1); + if (!m_receiveBuffer.isEmpty()) { + staticMetaObject.invokeMethod(this, "dataReceived", Qt::QueuedConnection, Q_ARG(QByteArray, QByteArray())); + } + + QVariantMap packet = jsonDoc.toVariant().toMap(); + + if (packet.contains("notification")) { + qCDebug(dcOwlet()) << "Notification received:" << packet; + emit notificationReceived(packet.value("notification").toString(), packet.value("params").toMap()); + } else if (packet.contains("id")) { + qCDebug(dcOwlet()) << "reply received:" << packet; + int id = packet.value("id").toInt(); + emit replyReceived(id, packet.value("params").toMap()); + } +} diff --git a/owlet/owletclient.h b/owlet/owletclient.h new file mode 100644 index 000000000..289374dea --- /dev/null +++ b/owlet/owletclient.h @@ -0,0 +1,37 @@ +#ifndef OWLETCLIENT_H +#define OWLETCLIENT_H + +#include +#include +#include + +class OwletClient : public QObject +{ + Q_OBJECT +public: + explicit OwletClient(QObject *parent = nullptr); + + void connectToHost(const QHostAddress &address, int port); + + int sendCommand(const QString &method, const QVariantMap ¶ms); + +signals: + void connected(); + void disconnected(); + void error(); + + void replyReceived(int commandId, const QVariantMap ¶ms); + void notificationReceived(const QString &name, const QVariantMap ¶ms); + +private slots: + void dataReceived(const QByteArray &data); + +private: + QTcpSocket *m_socket = nullptr; + int m_commandId = 0; + + QByteArray m_receiveBuffer; + +}; + +#endif // OWLETCLIENT_H From 3985f2ad5a2929aaf07346160577ac61dcb58651 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sat, 16 Oct 2021 10:29:22 +0200 Subject: [PATCH 02/18] WIP: New Plugin: Nymea owlets --- owlet/integrationpluginowlet.cpp | 239 ++++++++++++++++++++++++++++++ owlet/integrationpluginowlet.h | 63 ++++++++ owlet/integrationpluginowlet.json | 216 +++++++++++++++++++++++++++ owlet/owlet.pro | 13 ++ 4 files changed, 531 insertions(+) create mode 100644 owlet/integrationpluginowlet.cpp create mode 100644 owlet/integrationpluginowlet.h create mode 100644 owlet/integrationpluginowlet.json create mode 100644 owlet/owlet.pro diff --git a/owlet/integrationpluginowlet.cpp b/owlet/integrationpluginowlet.cpp new file mode 100644 index 000000000..7fc059fb9 --- /dev/null +++ b/owlet/integrationpluginowlet.cpp @@ -0,0 +1,239 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2021, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea. +* This project including source code and documentation is protected by +* copyright law, and remains the property of nymea GmbH. All rights, including +* reproduction, publication, editing and translation, are reserved. The use of +* this project is subject to the terms of a license agreement to be concluded +* with nymea GmbH in accordance with the terms of use of nymea GmbH, available +* under https://nymea.io/license +* +* GNU Lesser General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU Lesser General Public License as published by the Free +* Software Foundation; version 3. This project is distributed in the hope that +* it will be useful, but WITHOUT ANY WARRANTY; without even the implied +* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this project. If not, see . +* +* For any further details and any questions please contact us under +* contact@nymea.io or see our FAQ/Licensing Information on +* https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "integrationpluginowlet.h" +#include "plugininfo.h" +#include "owletclient.h" + +#include "hardwaremanager.h" +#include "platform/platformzeroconfcontroller.h" +#include "network/zeroconf/zeroconfservicebrowser.h" +#include "network/zeroconf/zeroconfserviceentry.h" + +#include +#include + +static QHash idParamTypeMap = { + { digitalOutputThingClassId, digitalOutputThingOwletIdParamTypeId }, + { digitalInputThingClassId, digitalInputThingOwletIdParamTypeId }, + { ws2812ThingClassId, ws2812ThingOwletIdParamTypeId } +}; + +IntegrationPluginOwlet::IntegrationPluginOwlet() +{ +} + +void IntegrationPluginOwlet::init() +{ + m_zeroConfBrowser = hardwareManager()->zeroConfController()->createServiceBrowser("_nymea-owlet._tcp"); +} + +void IntegrationPluginOwlet::discoverThings(ThingDiscoveryInfo *info) +{ + foreach (const ZeroConfServiceEntry &entry, m_zeroConfBrowser->serviceEntries()) { + qCDebug(dcOwlet()) << "Found owlet:" << entry; + ThingDescriptor descriptor(info->thingClassId(), entry.name(), entry.txt("platform")); + descriptor.setParams(ParamList() << Param(idParamTypeMap.value(info->thingClassId()), entry.txt("id"))); + foreach (Thing *existingThing, myThings().filterByParam(idParamTypeMap.value(info->thingClassId()), entry.txt("id"))) { + descriptor.setThingId(existingThing->id()); + break; + } + info->addThingDescriptor(descriptor); + } + info->finish(Thing::ThingErrorNoError); +} + + +void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) +{ + Thing *thing = info->thing(); + + QHostAddress ip; + int port = 5555; + foreach (const ZeroConfServiceEntry &entry, m_zeroConfBrowser->serviceEntries()) { + if (entry.txt("id") == info->thing()->paramValue(idParamTypeMap.value(info->thing()->thingClassId()))) { + ip = entry.hostAddress(); + port = entry.port(); + break; + } + } + // Try cached ip + if (ip.isNull()) { + pluginStorage()->beginGroup(thing->id().toString()); + ip = QHostAddress(pluginStorage()->value("cachedIP").toString()); + pluginStorage()->endGroup(); + } + + if (ip.isNull()) { + qCWarning(dcOwlet()) << "Can't find owlet in the local network."; + info->finish(Thing::ThingErrorHardwareNotAvailable); + return; + } + + OwletClient *client = new OwletClient(this); + + connect(client, &OwletClient::connected, info, [=](){ + qCDebug(dcOwlet()) << "Connected to owleet"; + m_clients.insert(thing, client); + + if (thing->thingClassId() == digitalOutputThingClassId) { + QVariantMap params; + params.insert("id", thing->paramValue(digitalOutputThingPinParamTypeId).toInt()); + params.insert("mode", "GPIOOutput"); + client->sendCommand("GPIO.ConfigurePin", params); + } + if (thing->thingClassId() == digitalInputThingClassId) { + QVariantMap params; + params.insert("id", thing->paramValue(digitalInputThingPinParamTypeId).toInt()); + params.insert("mode", "GPIOInput"); + client->sendCommand("GPIO.ConfigurePin", params); + } + if (thing->thingClassId() == ws2812ThingClassId) { + QVariantMap params; + params.insert("id", thing->paramValue(ws2812ThingPinParamTypeId).toInt()); + params.insert("mode", "WS2812"); + params.insert("ledCount", thing->paramValue(ws2812ThingLedCountParamTypeId).toUInt()); + params.insert("ledMode", "WS2812Mode" + thing->paramValue(ws2812ThingLedModeParamTypeId).toString()); + params.insert("ledClock", "WS2812Clock" + thing->paramValue(ws2812ThingLedClockParamTypeId).toString()); + client->sendCommand("GPIO.ConfigurePin", params); + } + + info->finish(Thing::ThingErrorNoError); + }); + connect(client, &OwletClient::error, info, [=](){ + info->finish(Thing::ThingErrorHardwareFailure); + }); + connect(client, &OwletClient::connected, thing, [=](){ + thing->setStateValue("connected", true); + pluginStorage()->beginGroup(thing->id().toString()); + pluginStorage()->setValue("cachedIP", ip.toString()); + pluginStorage()->endGroup(); + }); + connect(client, &OwletClient::disconnected, thing, [=](){ + thing->setStateValue("connected", false); + }); + + connect(client, &OwletClient::notificationReceived, this, [=](const QString &name, const QVariantMap ¶ms){ + qCDebug(dcOwlet()) << "***Notif" << name << params; + if (thing->thingClassId() == digitalInputThingClassId) { + if (params.value("id").toInt() == thing->paramValue(digitalInputThingPinParamTypeId)) { + thing->setStateValue(digitalInputPowerStateTypeId, params.value("power").toBool()); + } + } + if (thing->thingClassId() == digitalOutputThingClassId) { + if (params.value("id").toInt() == thing->paramValue(digitalOutputThingPinParamTypeId)) { + thing->setStateValue(digitalOutputPowerStateTypeId, params.value("power").toBool()); + } + } + if (thing->thingClassId() == ws2812ThingClassId) { + if (name == "GPIO.PinChanged") { + if (params.contains("power")) { + thing->setStateValue(ws2812PowerStateTypeId, params.value("power").toBool()); + } + if (params.contains("brightness")) { + thing->setStateValue(ws2812BrightnessStateTypeId, params.value("brightness").toInt()); + } + if (params.contains("color")) { + thing->setStateValue(ws2812ColorStateTypeId, params.value("color").value()); + } + } + } + }); + + client->connectToHost(ip, port); +} + + +void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) +{ + if (info->thing()->thingClassId() == digitalOutputThingClassId) { + OwletClient *client = m_clients.value(info->thing()); + QVariantMap params; + params.insert("id", info->thing()->paramValue(digitalOutputThingPinParamTypeId).toInt()); + params.insert("power", info->action().paramValue(digitalOutputPowerActionPowerParamTypeId).toBool()); + qCDebug(dcOwlet()) << "Sending ControlPin" << params; + int id = client->sendCommand("GPIO.ControlPin", params); + connect(client, &OwletClient::replyReceived, info, [=](int commandId, const QVariantMap ¶ms){ + if (id != commandId) { + return; + } + qCDebug(dcOwlet()) << "reply from owlet:" << params; + QString error = params.value("error").toString(); + if (error == "GPIOErrorNoError") { + info->thing()->setStateValue(digitalOutputPowerStateTypeId, info->action().paramValue(digitalOutputPowerActionPowerParamTypeId).toBool()); + info->finish(Thing::ThingErrorNoError); + } else { + info->finish(Thing::ThingErrorHardwareFailure); + } + }); + + return; + } + + if (info->thing()->thingClassId() == ws2812ThingClassId) { + OwletClient *client = m_clients.value(info->thing()); + QVariantMap params; + params.insert("id", info->thing()->paramValue(ws2812ThingPinParamTypeId).toUInt()); + + if (info->action().actionTypeId() == ws2812PowerActionTypeId) { + params.insert("power", info->action().paramValue(ws2812PowerActionPowerParamTypeId).toBool()); + } + if (info->action().actionTypeId() == ws2812BrightnessActionTypeId) { + params.insert("brightness", info->action().paramValue(ws2812BrightnessActionBrightnessParamTypeId).toInt()); + } + if (info->action().actionTypeId() == ws2812ColorActionTypeId) { + QColor color = info->action().paramValue(ws2812ColorActionColorParamTypeId).value(); + params.insert("color", (color.rgb() & 0xFFFFFF)); + } + + int id = client->sendCommand("GPIO.ControlPin", params); + connect(client, &OwletClient::replyReceived, info, [=](int commandId, const QVariantMap ¶ms){ + if (id != commandId) { + return; + } + qCDebug(dcOwlet()) << "reply from owlet:" << params; + QString error = params.value("error").toString(); + if (error == "GPIOErrorNoError") { + info->finish(Thing::ThingErrorNoError); + } else { + info->finish(Thing::ThingErrorHardwareFailure); + } + }); + return; + } + + Q_ASSERT_X(false, "IntegrationPluginOwlet", "Not implemented"); + info->finish(Thing::ThingErrorUnsupportedFeature); +} + +void IntegrationPluginOwlet::thingRemoved(Thing *thing) +{ + Q_UNUSED(thing) +} diff --git a/owlet/integrationpluginowlet.h b/owlet/integrationpluginowlet.h new file mode 100644 index 000000000..9d6337ab9 --- /dev/null +++ b/owlet/integrationpluginowlet.h @@ -0,0 +1,63 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2021, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea. +* This project including source code and documentation is protected by +* copyright law, and remains the property of nymea GmbH. All rights, including +* reproduction, publication, editing and translation, are reserved. The use of +* this project is subject to the terms of a license agreement to be concluded +* with nymea GmbH in accordance with the terms of use of nymea GmbH, available +* under https://nymea.io/license +* +* GNU Lesser General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU Lesser General Public License as published by the Free +* Software Foundation; version 3. This project is distributed in the hope that +* it will be useful, but WITHOUT ANY WARRANTY; without even the implied +* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this project. If not, see . +* +* For any further details and any questions please contact us under +* contact@nymea.io or see our FAQ/Licensing Information on +* https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef INTEGRATIONPLUGINOWLET_H +#define INTEGRATIONPLUGINOWLET_H + +#include "integrations/integrationplugin.h" +#include "extern-plugininfo.h" + +class ZeroConfServiceBrowser; +class OwletClient; + +class IntegrationPluginOwlet: public IntegrationPlugin +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationpluginowlet.json") + Q_INTERFACES(IntegrationPlugin) + +public: + explicit IntegrationPluginOwlet(); + + void init() override; + void discoverThings(ThingDiscoveryInfo *info) override; + void setupThing(ThingSetupInfo *info) override; + void executeAction(ThingActionInfo *info) override; + void thingRemoved(Thing *thing) override; + +private: + ZeroConfServiceBrowser *m_zeroConfBrowser = nullptr; + + QHash m_clients; + +}; + +#endif // INTEGRATIONPLUGINOWLET_H diff --git a/owlet/integrationpluginowlet.json b/owlet/integrationpluginowlet.json new file mode 100644 index 000000000..71b811aa7 --- /dev/null +++ b/owlet/integrationpluginowlet.json @@ -0,0 +1,216 @@ +{ + "displayName": "nymea owlet", + "name": "owlet", + "id": "699a5b6d-d90f-4554-a8de-9205768a4a98", + "vendors": [ + { + "displayName": "nymea GmbH", + "name": "nymea", + "id": "2062d64d-3232-433c-88bc-0d33c0ba2ba6", + "thingClasses": [ + { + "id": "5a079c4e-9309-4d98-9ff1-9beeda210958", + "displayName": "Digital GPIO output on owlet", + "name": "digitalOutput", + "createMethods": ["discovery"], + "interfaces": ["power"], + "paramTypes": [ + { + "id": "de8cda8f-b8f1-425d-ae16-fd0f5a885ca4", + "name": "owletId", + "displayName": "Owlet ID", + "type": "QString", + "defaultValue": "" + }, + { + "id": "31dbcdea-04f3-4a0c-b131-7eda8a92c602", + "name": "pin", + "displayName": "Pin number", + "type": "uint", + "defaultValue": 1 + } + ], + "stateTypes": [ + { + "id": "dd97a6b1-e98e-4a60-b16a-b27240b91439", + "name": "power", + "displayName": "Power", + "type": "bool", + "defaultValue": false, + "writable": true, + "displayNameEvent": "Power changed", + "displayNameAction": "Set power", + "ioType": "digitalOutput" + } + ] + }, + { + "id": "673512a3-75d8-44a6-9930-198c9f1a1f03", + "displayName": "Digital GPIO Input on owlet", + "name": "digitalInput", + "createMethods": ["discovery"], + "paramTypes": [ + { + "id": "dd7eca3f-13f6-4320-aaaa-b0be8fbfeebf", + "name": "owletId", + "displayName": "Owlet ID", + "type": "QString", + "defaultValue": "" + }, + { + "id": "f6b60a4b-e7a2-4328-884d-818b0e2a361e", + "name": "pin", + "displayName": "Pin number", + "type": "uint", + "defaultValue": 1 + } + ], + "stateTypes": [ + { + "id": "df1fbd9f-10b1-4788-a00e-de3f3f411cc6", + "name": "power", + "displayName": "Powered", + "type": "bool", + "defaultValue": false, + "displayNameEvent": "Powered changed", + "ioType": "digitalInput" + } + ] + }, + { + "id": "76f4ef8e-8e17-4528-a667-3d3f5afdd6a7", + "name": "ws2812", + "displayName": "WS2812 on owlet", + "createMethods": ["discovery"], + "interfaces": ["colorlight", "wirelessconnectable"], + "paramTypes": [ + { + "id": "8c00f42b-5d34-4595-8ae9-6f48056a8be0", + "name": "owletId", + "displayName": "Owlet ID", + "type": "QString", + "defaultValue": "" + }, + { + "id": "d674ee68-7f24-4dec-a75a-647a083d3580", + "name": "pin", + "displayName": "Pin number", + "type": "uint", + "defaultValue": 1 + }, + { + "id": "6c6df8eb-cdf1-424c-b29d-60f7dd19ae41", + "name": "ledCount", + "displayName": "LED count", + "type": "uint", + "defaultValue": 1 + }, + { + "id": "69c7f0e5-fdc4-4f9f-a117-90f165af3178", + "name": "ledMode", + "displayName": "LED color mode", + "type": "QString", + "allowedValues": [ + "RGB", + "RBG", + "GRB", + "GBR", + "BRG", + "BGR", + "WRGB", + "WRBG", + "WGRB", + "WGBR", + "WBRG", + "WBRG", + "RWGB", + "RWBG", + "RGWB", + "RGBW", + "RBWG", + "RBGW", + "GWRB", + "GWBR", + "GRWB", + "GRBW", + "GBWR", + "GBRW", + "BWRG", + "BWGR", + "BRWG", + "BRGW", + "BGWR", + "BGRW" + ], + "defaultValue": "RGB" + }, + { + "id": "c4d99f98-1b46-4b38-bdd4-4bd5559dbb6f", + "name": "ledClock", + "displayName": "LED clock speed", + "type": "QString", + "allowedValues": ["400kHz", "800kHz"], + "defaultValue": "800kHz" + } + ], + "stateTypes": [ + { + "id": "0dbdd49b-578d-4404-87d2-b5a921df6aa6", + "name": "connected", + "displayName": "Connected", + "displayNameEvent": "Connected or disconnected", + "type": "bool", + "defaultValue": false, + "cached": false + }, + { + "id": "58a8b3ca-720c-458e-b045-b99b5aadabd7", + "name": "power", + "displayName": "Power", + "displayNameEvent": "Power changed", + "displayNameAction": "Set power", + "type": "bool", + "defaultValue": false, + "writable": true + }, + { + "id": "b56a9368-db2a-4ee6-99de-9ee8e1ffebd3", + "name": "brightness", + "displayName": "Brightness", + "displayNameEvent": "Brightness changed", + "displayNameAction": "Set brightness", + "type": "int", + "minValue": 0, + "maxValue": 100, + "unit": "Percentage", + "defaultValue": 100, + "writable": true + }, + { + "id": "684c9118-20f3-41a0-928e-b7290d40166d", + "name": "color", + "displayName": "Color", + "displayNameEvent": "Color changed", + "displayNameAction": "Set color", + "type": "QColor", + "defaultValue": "white", + "writable": true + }, + { + "id": "f92ea731-a86e-49b5-955b-9c245c7f874f", + "name": "colorTemperature", + "displayName": "Color temperature", + "displayNameEvent": "Color temperature changed", + "displayNameAction": "Set color temperature", + "type": "int", + "minValue": 0, + "maxValue": 100, + "defaultValue": 50, + "writable": true + } + ] + } + ] + } + ] +} diff --git a/owlet/owlet.pro b/owlet/owlet.pro new file mode 100644 index 000000000..572785b2d --- /dev/null +++ b/owlet/owlet.pro @@ -0,0 +1,13 @@ +include(../plugins.pri) + +QT += network + +SOURCES += \ + integrationpluginowlet.cpp \ + owletclient.cpp + +HEADERS += \ + integrationpluginowlet.h \ + owletclient.h + + From d14e5334e4d1417366360e771ef97dfdb47ed629 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sun, 17 Oct 2021 13:03:29 +0200 Subject: [PATCH 03/18] some more work --- owlet/integrationpluginowlet.cpp | 9 +++++++++ owlet/integrationpluginowlet.json | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/owlet/integrationpluginowlet.cpp b/owlet/integrationpluginowlet.cpp index 7fc059fb9..db30ac4c2 100644 --- a/owlet/integrationpluginowlet.cpp +++ b/owlet/integrationpluginowlet.cpp @@ -163,6 +163,9 @@ void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) if (params.contains("color")) { thing->setStateValue(ws2812ColorStateTypeId, params.value("color").value()); } + if (params.contains("effect")) { + thing->setStateValue(ws2812EffectStateTypeId, params.value("effect").toInt()); + } } } }); @@ -212,6 +215,10 @@ void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) QColor color = info->action().paramValue(ws2812ColorActionColorParamTypeId).value(); params.insert("color", (color.rgb() & 0xFFFFFF)); } + if (info->action().actionTypeId() == ws2812EffectActionTypeId) { + int effect = info->action().paramValue(ws2812EffectActionEffectParamTypeId).toInt(); + params.insert("effect", effect); + } int id = client->sendCommand("GPIO.ControlPin", params); connect(client, &OwletClient::replyReceived, info, [=](int commandId, const QVariantMap ¶ms){ @@ -229,6 +236,8 @@ void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) return; } + + Q_ASSERT_X(false, "IntegrationPluginOwlet", "Not implemented"); info->finish(Thing::ThingErrorUnsupportedFeature); } diff --git a/owlet/integrationpluginowlet.json b/owlet/integrationpluginowlet.json index 71b811aa7..7fef3d74e 100644 --- a/owlet/integrationpluginowlet.json +++ b/owlet/integrationpluginowlet.json @@ -207,6 +207,16 @@ "maxValue": 100, "defaultValue": 50, "writable": true + }, + { + "id": "cb90f7bf-bcb0-42e8-a03b-442d84c5871f", + "name": "effect", + "displayName": "Effect", + "displayNameEvent": "Effect changed", + "displayNameAction": "Set effect", + "type": "int", + "defaultValue": 0, + "writable": true } ] } From affc04d250c3d29ddc5b602ea2d4aa0990cf84cb Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sun, 17 Oct 2021 17:17:29 +0200 Subject: [PATCH 04/18] Add dpkg files --- debian/control | 11 +++++++++++ debian/nymea-plugin-owlet.install.in | 1 + 2 files changed, 12 insertions(+) create mode 100644 debian/nymea-plugin-owlet.install.in diff --git a/debian/control b/debian/control index de77f4b21..4f10c1dc9 100644 --- a/debian/control +++ b/debian/control @@ -464,6 +464,17 @@ Description: nymea integration plugin for osdomotics This package contains the nymea integration plugin for osdomotics. +Package: nymea-plugin-owlet +Architecture: any +Depends: ${shlibs:Depends}, + ${misc:Depends}, + nymea-plugins-translations, +Description: nymea.io plugin for nymea:owlet + nymea:owlet is a firmware for microcontrollers (Arduino/ESP8266/ESP32) which + exposes pins of the microcontroller to nymea and allows using them for + whatever purpose like moodlights, control relays, inputs etc. + + Package: nymea-plugin-philipshue Architecture: any Depends: ${shlibs:Depends}, diff --git a/debian/nymea-plugin-owlet.install.in b/debian/nymea-plugin-owlet.install.in new file mode 100644 index 000000000..2e5fe9706 --- /dev/null +++ b/debian/nymea-plugin-owlet.install.in @@ -0,0 +1 @@ +usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationpluginowlet.so From 1852044ef13ff784eaccd6ec04d433b7f54d6abb Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Thu, 21 Oct 2021 22:25:25 +0200 Subject: [PATCH 05/18] Make it build with older Qt --- owlet/owletclient.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/owlet/owletclient.cpp b/owlet/owletclient.cpp index cefd94947..c9ed5e7c8 100644 --- a/owlet/owletclient.cpp +++ b/owlet/owletclient.cpp @@ -29,7 +29,8 @@ void OwletClient::connectToHost(const QHostAddress &address, int port) }); }); - connect(m_socket, &QTcpSocket::errorOccurred, this, [this](){ + typedef void (QTcpSocket:: *errorSignal)(QAbstractSocket::SocketError); + connect(m_socket, static_cast(&QTcpSocket::error), this, [this](){ qCDebug(dcOwlet()) << "Error in owlet communication"; emit error(); }); From f7872915d0ae18fa5a258e23f7305b20b53fc448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Sun, 14 Nov 2021 13:40:06 +0100 Subject: [PATCH 06/18] Add arduino and abstract transport --- owlet/integrationpluginowlet.cpp | 130 +++++++++----- owlet/integrationpluginowlet.h | 5 +- owlet/integrationpluginowlet.json | 280 ++++++++++++++++++++++++++++++ owlet/owlet.pro | 12 +- owlet/owletclient.cpp | 50 ++---- owlet/owletclient.h | 10 +- owlet/owletserialtransport.cpp | 168 ++++++++++++++++++ owlet/owletserialtransport.h | 45 +++++ owlet/owlettcptransport.cpp | 51 ++++++ owlet/owlettcptransport.h | 30 ++++ owlet/owlettransport.cpp | 11 ++ owlet/owlettransport.h | 29 ++++ 12 files changed, 739 insertions(+), 82 deletions(-) create mode 100644 owlet/owletserialtransport.cpp create mode 100644 owlet/owletserialtransport.h create mode 100644 owlet/owlettcptransport.cpp create mode 100644 owlet/owlettcptransport.h create mode 100644 owlet/owlettransport.cpp create mode 100644 owlet/owlettransport.h diff --git a/owlet/integrationpluginowlet.cpp b/owlet/integrationpluginowlet.cpp index db30ac4c2..a8c546953 100644 --- a/owlet/integrationpluginowlet.cpp +++ b/owlet/integrationpluginowlet.cpp @@ -37,70 +37,104 @@ #include "network/zeroconf/zeroconfservicebrowser.h" #include "network/zeroconf/zeroconfserviceentry.h" +#include "owlettcptransport.h" +#include "owletserialtransport.h" + #include #include -static QHash idParamTypeMap = { - { digitalOutputThingClassId, digitalOutputThingOwletIdParamTypeId }, - { digitalInputThingClassId, digitalInputThingOwletIdParamTypeId }, - { ws2812ThingClassId, ws2812ThingOwletIdParamTypeId } -}; - IntegrationPluginOwlet::IntegrationPluginOwlet() { } void IntegrationPluginOwlet::init() { + m_owletIdParamTypeMap.insert(digitalOutputThingClassId, digitalOutputThingOwletIdParamTypeId); + m_owletIdParamTypeMap.insert(digitalInputThingClassId, digitalInputThingOwletIdParamTypeId); + m_owletIdParamTypeMap.insert(ws2812ThingClassId, ws2812ThingOwletIdParamTypeId); + + m_owletSerialPortParamTypeMap.insert(arduinoMiniProThingClassId, arduinoMiniProThingSerialPortParamTypeId); + m_zeroConfBrowser = hardwareManager()->zeroConfController()->createServiceBrowser("_nymea-owlet._tcp"); } void IntegrationPluginOwlet::discoverThings(ThingDiscoveryInfo *info) { - foreach (const ZeroConfServiceEntry &entry, m_zeroConfBrowser->serviceEntries()) { - qCDebug(dcOwlet()) << "Found owlet:" << entry; - ThingDescriptor descriptor(info->thingClassId(), entry.name(), entry.txt("platform")); - descriptor.setParams(ParamList() << Param(idParamTypeMap.value(info->thingClassId()), entry.txt("id"))); - foreach (Thing *existingThing, myThings().filterByParam(idParamTypeMap.value(info->thingClassId()), entry.txt("id"))) { - descriptor.setThingId(existingThing->id()); - break; - } - info->addThingDescriptor(descriptor); + if (info->thingClassId() == arduinoMiniProThingClassId) { + // Discover serial ports for arduino bords + foreach(QSerialPortInfo port, QSerialPortInfo::availablePorts()) { + qCDebug(dcOwlet()) << "Found serial port" << port.systemLocation(); + QString description = port.systemLocation() + " " + port.manufacturer() + " " + port.description(); + ThingDescriptor thingDescriptor(info->thingClassId(), "Owlet Arduino Pro Mini", 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; + ThingDescriptor descriptor(info->thingClassId(), entry.name(), entry.txt("platform")); + descriptor.setParams(ParamList() << Param(m_owletIdParamTypeMap.value(info->thingClassId()), entry.txt("id"))); + foreach (Thing *existingThing, myThings().filterByParam(m_owletIdParamTypeMap.value(info->thingClassId()), entry.txt("id"))) { + descriptor.setThingId(existingThing->id()); + break; + } + info->addThingDescriptor(descriptor); + } + info->finish(Thing::ThingErrorNoError); } - info->finish(Thing::ThingErrorNoError); } void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) { Thing *thing = info->thing(); - + OwletTransport *transport = nullptr; QHostAddress ip; int port = 5555; - foreach (const ZeroConfServiceEntry &entry, m_zeroConfBrowser->serviceEntries()) { - if (entry.txt("id") == info->thing()->paramValue(idParamTypeMap.value(info->thing()->thingClassId()))) { - ip = entry.hostAddress(); - port = entry.port(); - break; + + if (thing->thingClassId() != arduinoMiniProThingClassId) { + foreach (const ZeroConfServiceEntry &entry, m_zeroConfBrowser->serviceEntries()) { + if (entry.txt("id") == info->thing()->paramValue(m_owletIdParamTypeMap.value(info->thing()->thingClassId()))) { + ip = entry.hostAddress(); + port = entry.port(); + break; + } + } + // Try cached ip + if (ip.isNull()) { + pluginStorage()->beginGroup(thing->id().toString()); + ip = QHostAddress(pluginStorage()->value("cachedIP").toString()); + pluginStorage()->endGroup(); } - } - // Try cached ip - if (ip.isNull()) { - pluginStorage()->beginGroup(thing->id().toString()); - ip = QHostAddress(pluginStorage()->value("cachedIP").toString()); - pluginStorage()->endGroup(); - } - if (ip.isNull()) { - qCWarning(dcOwlet()) << "Can't find owlet in the local network."; - info->finish(Thing::ThingErrorHardwareNotAvailable); - return; - } + if (ip.isNull()) { + qCWarning(dcOwlet()) << "Can't find owlet in the local network."; + info->finish(Thing::ThingErrorHardwareNotAvailable); + return; + } + + transport = new OwletTcpTransport(ip, port, this); - OwletClient *client = new OwletClient(this); + } else if (thing->thingClassId() == arduinoMiniProThingClassId) { + QString serialPort = thing->paramValue(arduinoMiniProThingSerialPortParamTypeId).toString(); + qCDebug(dcOwlet()) << "Setup arduino mini pro owlet on" << serialPort; + transport = new OwletSerialTransport(serialPort, 115200, this); + } + OwletClient *client = new OwletClient(transport, this); connect(client, &OwletClient::connected, info, [=](){ - qCDebug(dcOwlet()) << "Connected to owleet"; + qCDebug(dcOwlet()) << "Connected to owlet"; m_clients.insert(thing, client); if (thing->thingClassId() == digitalOutputThingClassId) { @@ -127,15 +161,31 @@ void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) info->finish(Thing::ThingErrorNoError); }); + connect(client, &OwletClient::error, info, [=](){ info->finish(Thing::ThingErrorHardwareFailure); }); + connect(client, &OwletClient::connected, thing, [=](){ thing->setStateValue("connected", true); - pluginStorage()->beginGroup(thing->id().toString()); - pluginStorage()->setValue("cachedIP", ip.toString()); - pluginStorage()->endGroup(); + + // FIXME: find a better way + if (thing->thingClassId() != arduinoMiniProThingClassId) { + pluginStorage()->beginGroup(thing->id().toString()); + pluginStorage()->setValue("cachedIP", ip.toString()); + pluginStorage()->endGroup(); + } + + qCDebug(dcOwlet()) << "Sending get platform information request..."; + int id = client->sendCommand("Platform.GetInformation"); + connect(client, &OwletClient::replyReceived, thing, [=](int commandId, const QVariantMap ¶ms){ + if (id != commandId) + return; + + qCDebug(dcOwlet()) << "Reply from owlet platform information:" << params; + }); }); + connect(client, &OwletClient::disconnected, thing, [=](){ thing->setStateValue("connected", false); }); @@ -170,7 +220,7 @@ void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) } }); - client->connectToHost(ip, port); + client->transport()->connectTransport(); } diff --git a/owlet/integrationpluginowlet.h b/owlet/integrationpluginowlet.h index 9d6337ab9..902323bda 100644 --- a/owlet/integrationpluginowlet.h +++ b/owlet/integrationpluginowlet.h @@ -56,8 +56,9 @@ class IntegrationPluginOwlet: public IntegrationPlugin private: ZeroConfServiceBrowser *m_zeroConfBrowser = nullptr; - QHash m_clients; - + QHash m_clients; + QHash m_owletIdParamTypeMap; + QHash m_owletSerialPortParamTypeMap; }; #endif // INTEGRATIONPLUGINOWLET_H diff --git a/owlet/integrationpluginowlet.json b/owlet/integrationpluginowlet.json index 7fef3d74e..95b739683 100644 --- a/owlet/integrationpluginowlet.json +++ b/owlet/integrationpluginowlet.json @@ -219,6 +219,286 @@ "writable": true } ] + }, + { + "id": "22f216f4-9715-48f9-ab76-f7d7436d49c9", + "name": "arduinoMiniPro", + "displayName": "Arduino Pro Mini Owlet", + "createMethods": ["user", "discovery"], + "interfaces": ["gateway", "connectable"], + "paramTypes": [ + { + "id": "589715a6-aaf7-4ffb-9c34-015ac22d527e", + "name": "serialPort", + "displayName": "Serial port", + "type": "QString", + "inputType": "TextLine", + "defaultValue": "/dev/ttyS0" + }, + { + "id": "d9643551-883a-4e33-89a8-6e2e1211eb22", + "name": "resetGpio", + "displayName": "Reset GPIO", + "type": "uint", + "defaultValue": 18 + } + ], + "settingsTypes": [ + { + "id": "82a8d0f5-3b42-4138-ae65-8554e19b73e5", + "name": "pin2", + "displayName": "Pin 2", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Interrupt" + ], + "defaultValue": "None" + }, + { + "id": "3953ad67-69a6-4b5f-8a91-f913d75d7d2f", + "name": "pin3", + "displayName": "Pin 3", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Interrupt" + ], + "defaultValue": "None" + }, + { + "id": "cee570df-1669-49df-9eb6-6c28c9cb7aec", + "name": "pin4", + "displayName": "Pin 4", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output" + ], + "defaultValue": "None" + }, + { + "id": "ec366d87-cfdb-4c7e-a23e-20cb8e99b1f5", + "name": "pin5", + "displayName": "Pin 5", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM" + ], + "defaultValue": "None" + }, + { + "id": "40354097-c5e5-4d13-b94c-72cb7a97cf71", + "name": "pin6", + "displayName": "Pin 6", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM" + ], + "defaultValue": "None" + }, + { + "id": "22e5320f-2f34-4fd5-8699-1e4ddf96a8c8", + "name": "pin7", + "displayName": "Pin 7", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output" + ], + "defaultValue": "None" + }, + { + "id": "9b7b159c-9da1-4811-80e1-835d7743bebc", + "name": "pin8", + "displayName": "Pin 8", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output" + ], + "defaultValue": "None" + }, + { + "id": "0d4aa38d-7607-4361-b8c7-cc5c28e17bb8", + "name": "pin9", + "displayName": "Pin 9", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM" + ], + "defaultValue": "None" + }, + { + "id": "d18e6ac5-3bf7-47ac-8b5b-70a9ef8394d5", + "name": "pin10", + "displayName": "Pin 10", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM" + ], + "defaultValue": "None" + }, + { + "id": "f0afb81c-dcd4-4d50-84a7-0ed6739c4011", + "name": "pin11", + "displayName": "Pin 11", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM" + ], + "defaultValue": "None" + }, + { + "id": "c62ab191-40ab-4d20-8130-a6b37801b984", + "name": "pin12", + "displayName": "Pin 12", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output" + ], + "defaultValue": "None" + }, + { + "id": "4522ce36-ba6f-46b0-a54b-410a93065b34", + "name": "pin13", + "displayName": "Pin 13 (LED)", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output" + ], + "defaultValue": "None" + }, + { + "id": "d6cf8433-acef-4312-836b-b34be6592e22", + "name": "pinA1", + "displayName": "Pin A1", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "e22fd058-8eab-4450-a2ef-2f85c347602c", + "name": "pinA2", + "displayName": "Pin A2", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "1702602e-6c05-4dea-b0ff-89af8ec63a88", + "name": "pinA3", + "displayName": "Pin A3", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "02b5022f-8892-4e9d-b11e-6fd8a9d4616f", + "name": "pinA4", + "displayName": "Pin A4", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "704e2a48-b1f4-400e-a378-d7e546f2083d", + "name": "pinA5", + "displayName": "Pin A5", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "69c85170-9447-4a01-acd2-926fbe03489f", + "name": "pinA6", + "displayName": "Pin A6", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "3ad3b667-b51f-4deb-b5d3-8cad1e0fdbba", + "name": "pinA7", + "displayName": "Pin A7", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + } + ], + "stateTypes": [ + { + "id": "9a7d9a6a-f131-4f18-bfc0-956c2dba9329", + "name": "connected", + "displayName": "Connected", + "displayNameEvent": "Connected changed", + "type": "bool", + "defaultValue": false, + "cached": false + } + ] } ] } diff --git a/owlet/owlet.pro b/owlet/owlet.pro index 572785b2d..b940baf5d 100644 --- a/owlet/owlet.pro +++ b/owlet/owlet.pro @@ -1,13 +1,19 @@ include(../plugins.pri) -QT += network +QT += network serialport SOURCES += \ integrationpluginowlet.cpp \ - owletclient.cpp + owletclient.cpp \ + owletserialtransport.cpp \ + owlettcptransport.cpp \ + owlettransport.cpp HEADERS += \ integrationpluginowlet.h \ - owletclient.h + owletclient.h \ + owletserialtransport.h \ + owlettcptransport.h \ + owlettransport.h diff --git a/owlet/owletclient.cpp b/owlet/owletclient.cpp index c9ed5e7c8..cd1c5f038 100644 --- a/owlet/owletclient.cpp +++ b/owlet/owletclient.cpp @@ -1,49 +1,33 @@ #include "owletclient.h" - +#include "owlettransport.h" #include "extern-plugininfo.h" #include #include -OwletClient::OwletClient(QObject *parent) : QObject(parent) +OwletClient::OwletClient(OwletTransport *transport, QObject *parent) : + QObject(parent), + m_transport(transport) { - + connect(m_transport, &OwletTransport::dataReceived, this, &OwletClient::dataReceived); + connect(m_transport, &OwletTransport::error, this, &OwletClient::error); + connect(m_transport, &OwletTransport::connectedChanged, this, [=](bool isConnected){ + if (isConnected) { + emit connected(); + } else { + emit disconnected(); + } + }); } -void OwletClient::connectToHost(const QHostAddress &address, int port) +OwletTransport *OwletClient::transport() const { - if (m_socket) { - m_socket->abort(); - m_socket->deleteLater(); - } - - m_socket = new QTcpSocket(this); - connect(m_socket, &QTcpSocket::connected, this, [this](){ - emit connected(); - }); - connect(m_socket, &QTcpSocket::disconnected, this, [this, address, port](){ - qCDebug(dcOwlet()) << "Disconnected from owleet"; - emit disconnected(); - QTimer::singleShot(1000, this, [=]{ - connectToHost(address, port); - }); - - }); - typedef void (QTcpSocket:: *errorSignal)(QAbstractSocket::SocketError); - connect(m_socket, static_cast(&QTcpSocket::error), this, [this](){ - qCDebug(dcOwlet()) << "Error in owlet communication"; - emit error(); - }); - - connect(m_socket, &QTcpSocket::readyRead, this, [this](){ - dataReceived(m_socket->readAll()); - }); - m_socket->connectToHost(address, port); + return m_transport; } int OwletClient::sendCommand(const QString &method, const QVariantMap ¶ms) { - if (!m_socket) { + if (!m_transport->connected()) { qCWarning(dcOwlet()) << "Not connected to owlet. Not sending command."; return -1; } @@ -54,7 +38,7 @@ int OwletClient::sendCommand(const QString &method, const QVariantMap ¶ms) packet.insert("id", id); packet.insert("method", method); packet.insert("params", params); - m_socket->write(QJsonDocument::fromVariant(packet).toJson(QJsonDocument::Compact)); + m_transport->sendData(QJsonDocument::fromVariant(packet).toJson(QJsonDocument::Compact)); return id; } diff --git a/owlet/owletclient.h b/owlet/owletclient.h index 289374dea..4f9b6e18a 100644 --- a/owlet/owletclient.h +++ b/owlet/owletclient.h @@ -5,15 +5,17 @@ #include #include +class OwletTransport; + class OwletClient : public QObject { Q_OBJECT public: - explicit OwletClient(QObject *parent = nullptr); + explicit OwletClient(OwletTransport *transport, QObject *parent = nullptr); - void connectToHost(const QHostAddress &address, int port); + OwletTransport *transport() const; - int sendCommand(const QString &method, const QVariantMap ¶ms); + int sendCommand(const QString &method, const QVariantMap ¶ms = QVariantMap()); signals: void connected(); @@ -27,7 +29,7 @@ private slots: void dataReceived(const QByteArray &data); private: - QTcpSocket *m_socket = nullptr; + OwletTransport *m_transport = nullptr; int m_commandId = 0; QByteArray m_receiveBuffer; diff --git a/owlet/owletserialtransport.cpp b/owlet/owletserialtransport.cpp new file mode 100644 index 000000000..510211c61 --- /dev/null +++ b/owlet/owletserialtransport.cpp @@ -0,0 +1,168 @@ +#include "owletserialtransport.h" +#include "owlettransport.h" +#include "extern-plugininfo.h" + +#include + +OwletSerialTransport::OwletSerialTransport(const QString &serialPortName, uint baudrate, QObject *parent) : + OwletTransport(parent), + m_serialPortName(serialPortName), + m_baudrate(baudrate) +{ + qRegisterMetaType(); + + m_serialPort = new QSerialPort(this); + m_serialPort->setPortName(serialPortName); + m_serialPort->setBaudRate(115200); + m_serialPort->setDataBits(QSerialPort::DataBits::Data8); + m_serialPort->setParity(QSerialPort::Parity::NoParity); + m_serialPort->setStopBits(QSerialPort::StopBits::OneStop); + m_serialPort->setFlowControl(QSerialPort::FlowControl::NoFlowControl); + + connect(m_serialPort, &QSerialPort::readyRead, this, &OwletSerialTransport::onReadyRead); + connect(m_serialPort, &QSerialPort::errorOccurred, this, [=](QSerialPort::SerialPortError serialPortError){ + if (serialPortError != QSerialPort::NoError) { + qCWarning(dcOwlet()) << "Serial port error occured" << serialPortError << m_serialPort->errorString(); + emit error(); + m_reconnectTimer->start(); + if (m_serialPort->isOpen()) { + m_serialPort->close(); + } + emit connectedChanged(false); + } + }); + + m_reconnectTimer = new QTimer(this); + m_reconnectTimer->setInterval(5000); + m_reconnectTimer->setSingleShot(false); + connect(m_reconnectTimer, &QTimer::timeout, this, [=](){ + if (m_serialPort->isOpen()) { + m_reconnectTimer->stop(); + return; + } else { + connectTransport(); + } + }); +} + +bool OwletSerialTransport::connected() const +{ + return m_serialPort->isOpen(); +} + +void OwletSerialTransport::sendData(const QByteArray &data) +{ + // Stream bytes using SLIP + QByteArray message; + QDataStream stream(&message, QIODevice::WriteOnly); + stream << static_cast(SlipProtocolEnd); + + for (int i = 0; i < data.length(); i++) { + quint8 dataByte = data.at(i); + switch (dataByte) { + case SlipProtocolEnd: + stream << static_cast(SlipProtocolEsc); + stream << static_cast(SlipProtocolTransposedEnd); + break; + case SlipProtocolEsc: + stream << static_cast(SlipProtocolEsc); + stream << static_cast(SlipProtocolTransposedEsc); + break; + default: + stream << dataByte; + break; + } + } + stream << static_cast(SlipProtocolEnd); + + qCDebug(dcOwlet()) << "UART -->" << qUtf8Printable(data) << message.toHex(); + m_serialPort->write(message); + m_serialPort->flush(); +} + +void OwletSerialTransport::connectTransport() +{ + if (m_serialPort->isOpen()) + return; + + qCDebug(dcOwlet()) << "Connecting to" << m_serialPortName; + bool serialPortFound = false; + foreach (const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()) { + if (serialPortInfo.systemLocation() == m_serialPortName) { + serialPortFound = true; + break; + } + } + + // Prevent repeating warnings... + if (!serialPortFound) { + if (!m_reconnectTimer->isActive()) { + m_reconnectTimer->start(); + } + return; + } + + + if (!m_serialPort->open(QIODevice::ReadWrite)) { + qCWarning(dcOwlet()) << "Could not open serial port on" << m_serialPortName << m_serialPort->errorString(); + m_reconnectTimer->start(); + return; + } + + m_reconnectTimer->stop(); + emit connectedChanged(true); +} + +void OwletSerialTransport::disconnectTransport() +{ + if (m_serialPort->isOpen()) { + m_serialPort->close(); + emit connectedChanged(false); + } +} + +void OwletSerialTransport::onReadyRead() +{ + QByteArray data = m_serialPort->readAll(); + qCDebug(dcOwlet()) << "UART <-- raw:" << data.toHex() << qUtf8Printable(data); + + for (int i = 0; i < data.length(); i++) { + quint8 receivedByte = data.at(i); + + if (m_protocolEscaping) { + switch (receivedByte) { + case SlipProtocolTransposedEnd: + m_buffer.append(static_cast(SlipProtocolEnd)); + m_protocolEscaping = false; + break; + case SlipProtocolTransposedEsc: + m_buffer.append(static_cast(SlipProtocolEsc)); + m_protocolEscaping = false; + break; + default: + // SLIP protocol violation...received escape, but it is not an escaped byte + break; + } + } + + switch (receivedByte) { + case SlipProtocolEnd: + // We are done with this package, process it and reset the buffer + if (!m_buffer.isEmpty() && m_buffer.length() >= 3) { + qCDebug(dcOwlet()) << "UART <--" << m_buffer.toHex() << qUtf8Printable(m_buffer); + emit dataReceived(m_buffer); + } + m_buffer.clear(); + m_protocolEscaping = false; + break; + case SlipProtocolEsc: + // The next byte will be escaped, lets wait for it + m_protocolEscaping = true; + break; + default: + // Nothing special, just add to buffer + m_buffer.append(receivedByte); + break; + } + } +} diff --git a/owlet/owletserialtransport.h b/owlet/owletserialtransport.h new file mode 100644 index 000000000..48eed4c5b --- /dev/null +++ b/owlet/owletserialtransport.h @@ -0,0 +1,45 @@ +#ifndef OWLETSERIALTRANSPORT_H +#define OWLETSERIALTRANSPORT_H + +#include +#include +#include +#include + +#include "owlettransport.h" + +class OwletSerialTransport : public OwletTransport +{ + Q_OBJECT +public: + explicit OwletSerialTransport(const QString &serialPortName, uint baudrate, QObject *parent = nullptr); + + bool connected() const override; + void sendData(const QByteArray &data) override; + +public slots: + void connectTransport() override; + void disconnectTransport() override; + +private slots: + void onReadyRead(); + +private: + + enum SlipProtocol { + SlipProtocolEnd = 0xC0, + SlipProtocolEsc = 0xDB, + SlipProtocolTransposedEnd = 0xDC, + SlipProtocolTransposedEsc = 0xDD + }; + + QSerialPort *m_serialPort = nullptr; + QTimer *m_reconnectTimer = nullptr; + QString m_serialPortName; + uint m_baudrate; + + QByteArray m_buffer; + bool m_protocolEscaping = false; +}; + +#endif // OWLETSERIALTRANSPORT_H diff --git a/owlet/owlettcptransport.cpp b/owlet/owlettcptransport.cpp new file mode 100644 index 000000000..a2f0a1bd2 --- /dev/null +++ b/owlet/owlettcptransport.cpp @@ -0,0 +1,51 @@ +#include "owlettcptransport.h" +#include "extern-plugininfo.h" + +#include + +OwletTcpTransport::OwletTcpTransport(const QHostAddress &hostAddress, quint16 port, QObject *parent) : + OwletTransport(parent), + m_socket(new QTcpSocket(this)), + m_hostAddress(hostAddress), + m_port(port) +{ + connect(m_socket, &QTcpSocket::connected, this, [=](){ + emit connectedChanged(true); + }); + connect(m_socket, &QTcpSocket::disconnected, this, [=](){ + qCDebug(dcOwlet()) << "TCP transport: Disconnected from owlet" << QString("%1:%2").arg(m_hostAddress.toString()).arg(m_port); + emit connectedChanged(false); + QTimer::singleShot(1000, this, &OwletTcpTransport::connectTransport); + }); + + typedef void (QTcpSocket:: *errorSignal)(QAbstractSocket::SocketError); + connect(m_socket, static_cast(&QTcpSocket::error), this, [this](){ + qCDebug(dcOwlet()) << "TCP transport: Error in owlet communication" << m_socket->errorString(); + emit error(); + }); + + connect(m_socket, &QTcpSocket::readyRead, this, [this](){ + emit dataReceived(m_socket->readAll()); + }); +} + +bool OwletTcpTransport::connected() const +{ + return m_socket->state() == QAbstractSocket::ConnectedState; +} + +void OwletTcpTransport::sendData(const QByteArray &data) +{ + m_socket->write(data); +} + +void OwletTcpTransport::connectTransport() +{ + qCDebug(dcOwlet()) << "Connecting to" << m_hostAddress << m_port; + m_socket->connectToHost(m_hostAddress, m_port); +} + +void OwletTcpTransport::disconnectTransport() +{ + m_socket->close(); +} diff --git a/owlet/owlettcptransport.h b/owlet/owlettcptransport.h new file mode 100644 index 000000000..15a237904 --- /dev/null +++ b/owlet/owlettcptransport.h @@ -0,0 +1,30 @@ +#ifndef OWLETTCPTRANSPORT_H +#define OWLETTCPTRANSPORT_H + +#include +#include +#include + +#include "owlettransport.h" + +class OwletTcpTransport : public OwletTransport +{ + Q_OBJECT +public: + explicit OwletTcpTransport(const QHostAddress &hostAddress, quint16 port, QObject *parent = nullptr); + + bool connected() const override; + void sendData(const QByteArray &data) override; + +public slots: + void connectTransport() override; + void disconnectTransport() override; + +private: + QTcpSocket *m_socket = nullptr; + QHostAddress m_hostAddress; + quint16 m_port; + +}; + +#endif // OWLETTCPTRANSPORT_H diff --git a/owlet/owlettransport.cpp b/owlet/owlettransport.cpp new file mode 100644 index 000000000..55f481d0d --- /dev/null +++ b/owlet/owlettransport.cpp @@ -0,0 +1,11 @@ +#include "owlettransport.h" + +OwletTransport::OwletTransport(QObject *parent) : QObject(parent) +{ + +} + +bool OwletTransport::connected() const +{ + return m_connected; +} diff --git a/owlet/owlettransport.h b/owlet/owlettransport.h new file mode 100644 index 000000000..48e646a3a --- /dev/null +++ b/owlet/owlettransport.h @@ -0,0 +1,29 @@ +#ifndef OWLETTRANSPORT_H +#define OWLETTRANSPORT_H + +#include + +class OwletTransport : public QObject +{ + Q_OBJECT +public: + explicit OwletTransport(QObject *parent = nullptr); + + virtual bool connected() const; + virtual void sendData(const QByteArray &data) = 0; + +public slots: + virtual void connectTransport() = 0; + virtual void disconnectTransport() = 0; + +signals: + void connectedChanged(bool connected); + void dataReceived(const QByteArray &data); + void error(); + +protected: + bool m_connected; + +}; + +#endif // OWLETTRANSPORT_H From 3c1fd0d7ca3ca7e624b066394892412bdb3c0a78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 15 Nov 2021 12:48:43 +0100 Subject: [PATCH 07/18] Fix serial port error signal for older qt versions --- owlet/owletserialtransport.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/owlet/owletserialtransport.cpp b/owlet/owletserialtransport.cpp index 510211c61..b66a3e330 100644 --- a/owlet/owletserialtransport.cpp +++ b/owlet/owletserialtransport.cpp @@ -20,9 +20,10 @@ OwletSerialTransport::OwletSerialTransport(const QString &serialPortName, uint b m_serialPort->setFlowControl(QSerialPort::FlowControl::NoFlowControl); connect(m_serialPort, &QSerialPort::readyRead, this, &OwletSerialTransport::onReadyRead); - connect(m_serialPort, &QSerialPort::errorOccurred, this, [=](QSerialPort::SerialPortError serialPortError){ - if (serialPortError != QSerialPort::NoError) { - qCWarning(dcOwlet()) << "Serial port error occured" << serialPortError << m_serialPort->errorString(); + typedef void (QSerialPort:: *errorSignal)(QSerialPort::SerialPortError); + connect(m_serialPort, static_cast(&QSerialPort::error), this, [=](){ + if (m_serialPort->error() != QSerialPort::NoError) { + qCWarning(dcOwlet()) << "Serial port error occured" << m_serialPort->error() << m_serialPort->errorString(); emit error(); m_reconnectTimer->start(); if (m_serialPort->isOpen()) { From 9878a0c18cca7ab0565b54f3a48a1e82031986e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 15 Nov 2021 13:55:26 +0100 Subject: [PATCH 08/18] Make error signal depending on the Qt version --- owlet/owletserialtransport.cpp | 32 ++++++++++++++++++++------------ owlet/owletserialtransport.h | 1 + 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/owlet/owletserialtransport.cpp b/owlet/owletserialtransport.cpp index b66a3e330..3fb28a0bf 100644 --- a/owlet/owletserialtransport.cpp +++ b/owlet/owletserialtransport.cpp @@ -20,18 +20,13 @@ OwletSerialTransport::OwletSerialTransport(const QString &serialPortName, uint b m_serialPort->setFlowControl(QSerialPort::FlowControl::NoFlowControl); connect(m_serialPort, &QSerialPort::readyRead, this, &OwletSerialTransport::onReadyRead); - typedef void (QSerialPort:: *errorSignal)(QSerialPort::SerialPortError); - connect(m_serialPort, static_cast(&QSerialPort::error), this, [=](){ - if (m_serialPort->error() != QSerialPort::NoError) { - qCWarning(dcOwlet()) << "Serial port error occured" << m_serialPort->error() << m_serialPort->errorString(); - emit error(); - m_reconnectTimer->start(); - if (m_serialPort->isOpen()) { - m_serialPort->close(); - } - emit connectedChanged(false); - } - }); +#if QT_VERSION < QT_VERSION_CHECK(5, 8, 0) + // NOTE: Using QueuedConnection because in older Qt versions error is emitted before the port says its closed which might end up in a loop... + connect(m_serialPort, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(onError(QSerialPort::SerialPortError)), Qt::QueuedConnection); +#else + connect(m_serialPort, &QSerialPort::errorOccurred, this, &OwletSerialTransport::onError); +#endif + m_reconnectTimer = new QTimer(this); m_reconnectTimer->setInterval(5000); @@ -167,3 +162,16 @@ void OwletSerialTransport::onReadyRead() } } } + +void OwletSerialTransport::onError(QSerialPort::SerialPortError serialPortError) +{ + if (serialPortError != QSerialPort::NoError && serialPortError != QSerialPort::OpenError && m_serialPort->isOpen()) { + qCWarning(dcOwlet()) << "Serial port error occured" << serialPortError << m_serialPort->errorString(); + emit error(); + m_reconnectTimer->start(); + if (m_serialPort->isOpen()) { + m_serialPort->close(); + } + emit connectedChanged(false); + } +} diff --git a/owlet/owletserialtransport.h b/owlet/owletserialtransport.h index 48eed4c5b..032088d0b 100644 --- a/owlet/owletserialtransport.h +++ b/owlet/owletserialtransport.h @@ -23,6 +23,7 @@ public slots: private slots: void onReadyRead(); + void onError(QSerialPort::SerialPortError serialPortError); private: From 42f2e9a3d70ca2ae7f9bb662373f5156f1bc03bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 15 Nov 2021 14:47:09 +0100 Subject: [PATCH 09/18] Add missing meta type declare for serial port errors --- owlet/owletserialtransport.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/owlet/owletserialtransport.h b/owlet/owletserialtransport.h index 032088d0b..e301394c1 100644 --- a/owlet/owletserialtransport.h +++ b/owlet/owletserialtransport.h @@ -43,4 +43,6 @@ private slots: bool m_protocolEscaping = false; }; +Q_DECLARE_METATYPE(QSerialPort::SerialPortError) + #endif // OWLETSERIALTRANSPORT_H From 509b649fbe436179657acc97245675b93772b1b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 5 Jan 2022 10:36:49 +0100 Subject: [PATCH 10/18] Make gpios work with arduino based boards --- owlet/integrationpluginowlet.cpp | 683 ++++++++++++++++++++++++++++-- owlet/integrationpluginowlet.h | 13 + owlet/integrationpluginowlet.json | 244 ++++++++++- owlet/owlet.pro | 2 + owlet/owletserialclient.cpp | 249 +++++++++++ owlet/owletserialclient.h | 150 +++++++ owlet/owletserialtransport.cpp | 16 +- 7 files changed, 1311 insertions(+), 46 deletions(-) create mode 100644 owlet/owletserialclient.cpp create mode 100644 owlet/owletserialclient.h diff --git a/owlet/integrationpluginowlet.cpp b/owlet/integrationpluginowlet.cpp index a8c546953..b7f319d98 100644 --- a/owlet/integrationpluginowlet.cpp +++ b/owlet/integrationpluginowlet.cpp @@ -31,6 +31,7 @@ #include "integrationpluginowlet.h" #include "plugininfo.h" #include "owletclient.h" +#include "owletserialclient.h" #include "hardwaremanager.h" #include "platform/platformzeroconfcontroller.h" @@ -56,16 +57,44 @@ void IntegrationPluginOwlet::init() m_owletSerialPortParamTypeMap.insert(arduinoMiniProThingClassId, arduinoMiniProThingSerialPortParamTypeId); m_zeroConfBrowser = hardwareManager()->zeroConfController()->createServiceBrowser("_nymea-owlet._tcp"); + + // Pin params of thins + 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 Mini Pro mapping + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin2ParamTypeId, 2); + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin3ParamTypeId, 3); + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin4ParamTypeId, 4); + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin5ParamTypeId, 5); + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin6ParamTypeId, 6); + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin7ParamTypeId, 7); + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin8ParamTypeId, 8); + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin9ParamTypeId, 9); + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin10ParamTypeId, 10); + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin11ParamTypeId, 11); + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin12ParamTypeId, 12); + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin13ParamTypeId, 13); + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPinA1ParamTypeId, 15); + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPinA2ParamTypeId, 16); + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPinA3ParamTypeId, 17); + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPinA4ParamTypeId, 18); + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPinA5ParamTypeId, 19); + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPinA6ParamTypeId, 20); + m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPinA7ParamTypeId, 21); } void IntegrationPluginOwlet::discoverThings(ThingDiscoveryInfo *info) { if (info->thingClassId() == arduinoMiniProThingClassId) { // Discover serial ports for arduino bords - foreach(QSerialPortInfo port, QSerialPortInfo::availablePorts()) { + foreach(const QSerialPortInfo &port, QSerialPortInfo::availablePorts()) { qCDebug(dcOwlet()) << "Found serial port" << port.systemLocation(); QString description = port.systemLocation() + " " + port.manufacturer() + " " + port.description(); - ThingDescriptor thingDescriptor(info->thingClassId(), "Owlet Arduino Pro Mini", description); + ThingDescriptor thingDescriptor(info->thingClassId(), "Arduino Pro Mini Owlet", description); ParamList parameters; foreach (Thing *existingThing, myThings()) { @@ -99,39 +128,327 @@ void IntegrationPluginOwlet::discoverThings(ThingDiscoveryInfo *info) void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) { Thing *thing = info->thing(); - OwletTransport *transport = nullptr; - QHostAddress ip; - int port = 5555; - if (thing->thingClassId() != arduinoMiniProThingClassId) { - foreach (const ZeroConfServiceEntry &entry, m_zeroConfBrowser->serviceEntries()) { - if (entry.txt("id") == info->thing()->paramValue(m_owletIdParamTypeMap.value(info->thing()->thingClassId()))) { - ip = entry.hostAddress(); - port = entry.port(); - break; + if (thing->thingClassId() == arduinoMiniProThingClassId) { + QString serialPort = thing->paramValue(arduinoMiniProThingSerialPortParamTypeId).toString(); + qCDebug(dcOwlet()) << "Setup arduino mini pro 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(arduinoMiniProCurrentVersionStateTypeId, 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 Mini Pro settings changed" << paramTypeId << value; + quint8 pinId = m_arduinoMiniProPinMapping.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); + + // Update states + Thing *parent = myThings().findById(thing->parentId()); + bool parentConnected = false; + if (parent) + parentConnected = parent->stateValue("connected").toBool(); + + thing->setStateValue("connected", parentConnected); + + OwletSerialClient *client = m_serialClients.value(parent); + + quint8 pinId = thing->paramValue(digitalOutputSerialThingPinParamTypeId).toUInt(); + OwletSerialClient::PinMode pinMode = OwletSerialClient::PinModeDigitalOutput; + + connect(client, &OwletSerialClient::connected, thing, [=](){ + configurePin(client, pinId, pinMode); + }); + + if (parentConnected) { + configurePin(client, pinId, pinMode); } - // Try cached ip - if (ip.isNull()) { - pluginStorage()->beginGroup(thing->id().toString()); - ip = QHostAddress(pluginStorage()->value("cachedIP").toString()); - pluginStorage()->endGroup(); + } + + if (thing->thingClassId() == digitalInputSerialThingClassId) { + info->finish(Thing::ThingErrorNoError); + + // Update states + Thing *parent = myThings().findById(thing->parentId()); + bool parentConnected = false; + if (parent) + parentConnected = parent->stateValue("connected").toBool(); + + thing->setStateValue("connected", parentConnected); + + quint8 pinId = thing->paramValue(digitalInputSerialThingPinParamTypeId).toUInt(); + OwletSerialClient::PinMode pinMode = OwletSerialClient::PinModeDigitalInput; + + OwletSerialClient *client = m_serialClients.value(parent); + connect(client, &OwletSerialClient::connected, thing, [=](){ + thing->setStateValue("connected", true); + + configurePin(client, pinId, pinMode); + + // Read current value + quint8 pinId = thing->paramValue(digitalInputSerialThingPinParamTypeId).toUInt(); + OwletSerialClientReply *reply = client->readDigitalValue(pinId); + connect(reply, &OwletSerialClientReply::finished, this, [=](){ + if (reply->status() != OwletSerialClient::StatusSuccess) { + qCWarning(dcOwlet()) << "Failed to read digital pin value from" << thing << reply->status(); + return; + } + + if (reply->responsePayload().count() < 2) { + qCWarning(dcOwlet()) << "Invalid response payload size from request" << pinId; + return; + } + + OwletSerialClient::GPIOError configurationError = static_cast(reply->responsePayload().at(0)); + quint8 value = static_cast(reply->responsePayload().at(1)); + if (configurationError != OwletSerialClient::GPIOErrorNoError) { + qCWarning(dcOwlet()) << "Configure pin request finished with error" << configurationError; + return; + } + + thing->setStateValue(digitalInputSerialPowerStateTypeId, value != 0x00); + }); + }); + + connect(client, &OwletSerialClient::pinValueChanged, this, [=](quint8 id, bool power){ + if (id != pinId) + return; + + thing->setStateValue(digitalInputSerialPowerStateTypeId, power); + }); + + if (parentConnected) { + configurePin(client, pinId, pinMode); } - if (ip.isNull()) { - qCWarning(dcOwlet()) << "Can't find owlet in the local network."; - info->finish(Thing::ThingErrorHardwareNotAvailable); - return; + return; + } + + if (thing->thingClassId() == analogInputSerialThingClassId) { + info->finish(Thing::ThingErrorNoError); + + // Update states + Thing *parent = myThings().findById(thing->parentId()); + bool parentConnected = false; + if (parent) + parentConnected = parent->stateValue("connected").toBool(); + + thing->setStateValue("connected", parentConnected); + + OwletSerialClient *client = m_serialClients.value(parent); + + QTimer *refreshTimer = new QTimer(thing); + refreshTimer->setSingleShot(false); + refreshTimer->setInterval(thing->setting(analogInputSerialSettingsRefreshRateParamTypeId).toUInt()); + connect(refreshTimer, &QTimer::timeout, this, [=](){ + // Read current value + quint8 pinId = thing->paramValue(analogInputSerialThingPinParamTypeId).toUInt(); + OwletSerialClientReply *reply = client->readAnalogValue(pinId); + connect(reply, &OwletSerialClientReply::finished, this, [=](){ + if (reply->status() != OwletSerialClient::StatusSuccess) { + qCWarning(dcOwlet()) << "Failed to read analog pin value from" << thing << reply->status(); + return; + } + + if (reply->responsePayload().count() < 3) { + qCWarning(dcOwlet()) << "Invalid response payload size from request" << pinId; + return; + } + + QDataStream stream(reply->responsePayload()); + quint8 errorCode; + stream >> errorCode; + OwletSerialClient::GPIOError configurationError = static_cast(errorCode); + if (configurationError != OwletSerialClient::GPIOErrorNoError) { + qCWarning(dcOwlet()) << "Configure pin request finished with error" << configurationError; + return; + } + quint32 value; + stream >> value; + qCDebug(dcOwlet()) << "Analog value of" << thing << value; + thing->setStateValue(analogInputSerialAnalogValueStateTypeId, value); + }); + }); + + quint8 pinId = thing->paramValue(analogInputSerialThingPinParamTypeId).toUInt(); + OwletSerialClient::PinMode pinMode = OwletSerialClient::PinModeAnalogInput; + + connect(client, &OwletSerialClient::connected, thing, [=](){ + qCDebug(dcOwlet()) << "Starting refresh timer for" << thing; + configurePin(client, pinId, pinMode); + refreshTimer->start(); + }); + + connect(client, &OwletSerialClient::disconnected, thing, [=](){ + qCDebug(dcOwlet()) << "Stopping refresh timer for" << thing; + refreshTimer->stop(); + }); + + // Start reading if already connected + if (parentConnected) { + qCDebug(dcOwlet()) << "Starting refresh timer for" << thing; + configurePin(client, pinId, pinMode); + refreshTimer->start(); } - transport = new OwletTcpTransport(ip, port, this); + connect(thing, &Thing::settingChanged, refreshTimer, [=](const ParamTypeId ¶mTypeId, const QVariant &value){ + if (paramTypeId == analogInputSerialSettingsRefreshRateParamTypeId) { + refreshTimer->setInterval(value.toUInt()); + refreshTimer->start(); + } + }); - } else if (thing->thingClassId() == arduinoMiniProThingClassId) { - QString serialPort = thing->paramValue(arduinoMiniProThingSerialPortParamTypeId).toString(); - qCDebug(dcOwlet()) << "Setup arduino mini pro owlet on" << serialPort; - transport = new OwletSerialTransport(serialPort, 115200, this); + return; + } + + + if (thing->thingClassId() == analogOutputSerialThingClassId) { + info->finish(Thing::ThingErrorNoError); + + // Update states + Thing *parent = myThings().findById(thing->parentId()); + bool parentConnected = false; + if (parent) + parentConnected = parent->stateValue("connected").toBool(); + + thing->setStateValue("connected", parentConnected); + + OwletSerialClient *client = m_serialClients.value(parent); + + quint8 pinId = thing->paramValue(analogInputSerialThingPinParamTypeId).toUInt(); + OwletSerialClient::PinMode pinMode = OwletSerialClient::PinModeAnalogInput; + + connect(client, &OwletSerialClient::connected, thing, [=](){ + configurePin(client, pinId, pinMode); + }); + + // Start reading if already connected + if (parentConnected) { + configurePin(client, pinId, pinMode); + } + + return; + } + + + if (thing->thingClassId() == servoSerialThingClassId) { + info->finish(Thing::ThingErrorNoError); + + // Update states + Thing *parent = myThings().findById(thing->parentId()); + bool parentConnected = false; + if (parent) + parentConnected = parent->stateValue("connected").toBool(); + + thing->setStateValue("connected", parentConnected); + + OwletSerialClient *client = m_serialClients.value(parent); + + quint8 pinId = thing->paramValue(servoSerialThingPinParamTypeId).toUInt(); + OwletSerialClient::PinMode pinMode = OwletSerialClient::PinModeServo; + + connect(client, &OwletSerialClient::connected, thing, [=](){ + configurePin(client, pinId, pinMode); + }); + + // Start reading if already connected + if (parentConnected) { + configurePin(client, pinId, pinMode); + } + + return; + } + + + QHostAddress ip; + int port = 5555; + + foreach (const ZeroConfServiceEntry &entry, m_zeroConfBrowser->serviceEntries()) { + if (entry.txt("id") == info->thing()->paramValue(m_owletIdParamTypeMap.value(info->thing()->thingClassId()))) { + ip = entry.hostAddress(); + port = entry.port(); + break; + } + } + // Try cached ip + if (ip.isNull()) { + pluginStorage()->beginGroup(thing->id().toString()); + ip = QHostAddress(pluginStorage()->value("cachedIP").toString()); + pluginStorage()->endGroup(); + } + + if (ip.isNull()) { + qCWarning(dcOwlet()) << "Can't find owlet in the local network."; + info->finish(Thing::ThingErrorHardwareNotAvailable); + return; } + OwletTransport *transport = new OwletTcpTransport(ip, port, this); + OwletClient *client = new OwletClient(transport, this); connect(client, &OwletClient::connected, info, [=](){ qCDebug(dcOwlet()) << "Connected to owlet"; @@ -169,12 +486,9 @@ void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) connect(client, &OwletClient::connected, thing, [=](){ thing->setStateValue("connected", true); - // FIXME: find a better way - if (thing->thingClassId() != arduinoMiniProThingClassId) { - pluginStorage()->beginGroup(thing->id().toString()); - pluginStorage()->setValue("cachedIP", ip.toString()); - pluginStorage()->endGroup(); - } + pluginStorage()->beginGroup(thing->id().toString()); + pluginStorage()->setValue("cachedIP", ip.toString()); + pluginStorage()->endGroup(); qCDebug(dcOwlet()) << "Sending get platform information request..."; int id = client->sendCommand("Platform.GetInformation"); @@ -286,6 +600,184 @@ void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) return; } + if (info->thing()->thingClassId() == arduinoMiniProThingClassId) { + 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->ready()) { + qCWarning(dcOwlet()) << "Could not execute action. The serial client is not ready or connected."; + info->finish(Thing::ThingErrorHardwareNotAvailable); + return; + } + if (info->action().actionTypeId() == arduinoMiniProPerformUpdateActionTypeId) { + 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) { + qCWarning(dcOwlet()) << "Could not execute action. There is no client available for this thing"; + info->finish(Thing::ThingErrorHardwareFailure); + return; + } + + if (!client->ready()) { + qCWarning(dcOwlet()) << "Could not execute action. The serial client is not ready or connected."; + info->finish(Thing::ThingErrorHardwareNotAvailable); + return; + } + + if (info->action().actionTypeId() == analogOutputSerialDutyCycleActionTypeId) { + quint8 dutyCycle = info->action().paramValue(analogOutputSerialDutyCycleActionDutyCycleParamTypeId).toUInt(); + qCDebug(dcOwlet()) << "Set PWM duty cycle of" << info->thing() << "to" << dutyCycle; + quint8 pinId = info->thing()->paramValue(analogOutputSerialThingPinParamTypeId).toUInt(); + + OwletSerialClientReply *reply = client->writeAnalogValue(pinId, dutyCycle); + connect(reply, &OwletSerialClientReply::finished, this, [=](){ + if (reply->status() != OwletSerialClient::StatusSuccess) { + qCWarning(dcOwlet()) << "Failed to set power on pin" << pinId << dutyCycle << reply->status(); + info->finish(Thing::ThingErrorHardwareFailure); + return; + } + + if (reply->responsePayload().count() < 1) { + qCWarning(dcOwlet()) << "Failed to set power on pin" << pinId << dutyCycle << "Invalid response payload size from request"; + info->finish(Thing::ThingErrorHardwareFailure); + return; + } + + OwletSerialClient::GPIOError gpioError = static_cast(reply->responsePayload().at(0)); + if (gpioError != OwletSerialClient::GPIOErrorNoError) { + qCWarning(dcOwlet()) << "Set power on pin" << pinId << dutyCycle << "request finished with error" << gpioError; + info->finish(Thing::ThingErrorHardwareFailure); + return; + } + + qCDebug(dcOwlet()) << "Set PWM duty cycle finished successfully" << pinId << dutyCycle; + info->thing()->setStateValue(analogOutputSerialDutyCycleStateTypeId, dutyCycle); + info->finish(Thing::ThingErrorNoError); + return; + }); + + return; + } + } + + + if (info->thing()->thingClassId() == digitalOutputSerialThingClassId) { + OwletSerialClient *client = m_serialClients.value(myThings().findById(info->thing()->parentId())); + if (!client) { + qCWarning(dcOwlet()) << "Could not execute action. There is no client available for this thing"; + info->finish(Thing::ThingErrorHardwareFailure); + return; + } + + if (!client->ready()) { + qCWarning(dcOwlet()) << "Could not execute action. The serial client is not ready or connected."; + info->finish(Thing::ThingErrorHardwareNotAvailable); + return; + } + + if (info->action().actionTypeId() == digitalOutputSerialPowerActionTypeId) { + quint8 pinId = info->thing()->paramValue(digitalOutputSerialThingPinParamTypeId).toUInt(); + bool power = info->action().paramValue(digitalOutputSerialPowerActionPowerParamTypeId).toBool(); + OwletSerialClientReply *reply = client->writeDigitalValue(pinId, power); + connect(reply, &OwletSerialClientReply::finished, this, [=](){ + if (reply->status() != OwletSerialClient::StatusSuccess) { + qCWarning(dcOwlet()) << "Failed to set power on pin" << pinId << power << reply->status(); + info->finish(Thing::ThingErrorHardwareFailure); + return; + } + + if (reply->responsePayload().count() < 1) { + qCWarning(dcOwlet()) << "Failed to set power on pin" << pinId << power << "Invalid response payload size from request"; + info->finish(Thing::ThingErrorHardwareFailure); + return; + } + + OwletSerialClient::GPIOError gpioError = static_cast(reply->responsePayload().at(0)); + if (gpioError != OwletSerialClient::GPIOErrorNoError) { + qCWarning(dcOwlet()) << "Set power on pin" << pinId << power << "request finished with error" << gpioError; + info->finish(Thing::ThingErrorHardwareFailure); + return; + } + + qCDebug(dcOwlet()) << "Set power finished successfully" << pinId << power; + info->thing()->setStateValue(digitalOutputSerialPowerStateTypeId, power); + info->finish(Thing::ThingErrorNoError); + return; + }); + + return; + } + + info->finish(Thing::ThingErrorUnsupportedFeature); + return; + } + + + if (info->thing()->thingClassId() == servoSerialThingClassId) { + OwletSerialClient *client = m_serialClients.value(myThings().findById(info->thing()->parentId())); + if (!client) { + qCWarning(dcOwlet()) << "Could not execute action. There is no client available for this thing"; + info->finish(Thing::ThingErrorHardwareFailure); + return; + } + + if (!client->ready()) { + qCWarning(dcOwlet()) << "Could not execute action. The serial client is not ready or connected."; + info->finish(Thing::ThingErrorHardwareNotAvailable); + return; + } + + if (info->action().actionTypeId() == servoSerialAngleActionTypeId) { + quint8 pinId = info->thing()->paramValue(servoSerialThingPinParamTypeId).toUInt(); + quint8 angle = info->action().paramValue(servoSerialAngleActionAngleParamTypeId).toUInt(); + OwletSerialClientReply *reply = client->writeServoValue(pinId, angle); + connect(reply, &OwletSerialClientReply::finished, this, [=](){ + if (reply->status() != OwletSerialClient::StatusSuccess) { + qCWarning(dcOwlet()) << "Failed to set servo angle on pin" << pinId << angle << reply->status(); + info->finish(Thing::ThingErrorHardwareFailure); + return; + } + + if (reply->responsePayload().count() < 1) { + qCWarning(dcOwlet()) << "Failed to set servo angle on pin" << pinId << angle << "Invalid response payload size from request"; + info->finish(Thing::ThingErrorHardwareFailure); + return; + } + + OwletSerialClient::GPIOError gpioError = static_cast(reply->responsePayload().at(0)); + if (gpioError != OwletSerialClient::GPIOErrorNoError) { + qCWarning(dcOwlet()) << "Set angle on servo pin" << pinId << angle << "request finished with error" << gpioError; + info->finish(Thing::ThingErrorHardwareFailure); + return; + } + + qCDebug(dcOwlet()) << "Set servo angle finished successfully" << pinId << angle; + info->thing()->setStateValue(servoSerialAngleStateTypeId, angle); + info->finish(Thing::ThingErrorNoError); + return; + }); + + return; + } + + info->finish(Thing::ThingErrorUnsupportedFeature); + return; + } + Q_ASSERT_X(false, "IntegrationPluginOwlet", "Not implemented"); @@ -294,5 +786,132 @@ void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) void IntegrationPluginOwlet::thingRemoved(Thing *thing) { - Q_UNUSED(thing) + if (thing->thingClassId() == arduinoMiniProThingClassId && m_serialClients.contains(thing)) { + m_serialClients.take(thing)->deleteLater(); + } +} + +OwletSerialClient::PinMode IntegrationPluginOwlet::getPinModeFromSettingsValue(const QString &settingsValue) +{ + if (settingsValue == "Output") { + return OwletSerialClient::PinModeDigitalOutput; + } else if (settingsValue == "Input") { + return OwletSerialClient::PinModeDigitalInput; + } else if (settingsValue == "PWM") { + return OwletSerialClient::PinModeAnalogOutput; + } else if (settingsValue == "Analog Input") { + return OwletSerialClient::PinModeAnalogInput; + } else if (settingsValue == "Servo") { + return OwletSerialClient::PinModeServo; + } else { + return OwletSerialClient::PinModeUnconfigured; + } } + +void IntegrationPluginOwlet::setupArduinoChildThing(OwletSerialClient *client, quint8 pinId, OwletSerialClient::PinMode pinMode) +{ + Thing *parentThing = m_serialClients.key(client); + if (!parentThing) { + qCWarning(dcOwlet()) << "Could not setup child thing because the parent thing seems not to be available"; + return; + } + + // Note: pin has no thing here any more, we can set up a new one if required + OwletSerialClientReply *reply = client->configurePin(pinId, pinMode); + connect(reply, &OwletSerialClientReply::finished, this, [=](){ + if (reply->status() != OwletSerialClient::StatusSuccess) { + qCWarning(dcOwlet()) << "Failed to configure pin" << pinId << pinMode << reply->status(); + return; + } + + if (reply->responsePayload().count() < 1) { + qCWarning(dcOwlet()) << "Invalid configure pin response payload size from request" << pinId << pinMode; + return; + } + + OwletSerialClient::GPIOError configurationError = static_cast(reply->responsePayload().at(0)); + if (configurationError != OwletSerialClient::GPIOErrorNoError) { + qCWarning(dcOwlet()) << "Configure pin request finished with error" << configurationError; + return; + } + + qCDebug(dcOwlet()) << "Configure pin request finished successfully" << pinId << pinMode; + + // Setup child devices + 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()); + ParamList params; + params.append(Param(digitalOutputSerialThingPinParamTypeId, pinId)); + descriptor.setParams(params); + emit autoThingsAppeared(ThingDescriptors() << descriptor); + break; + } + 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()); + ParamList params; + params.append(Param(digitalInputSerialThingPinParamTypeId, pinId)); + descriptor.setParams(params); + emit autoThingsAppeared(ThingDescriptors() << descriptor); + break; + } + 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()); + ParamList params; + params.append(Param(analogOutputSerialThingPinParamTypeId, pinId)); + descriptor.setParams(params); + emit autoThingsAppeared(ThingDescriptors() << descriptor); + break; + } + 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()); + ParamList params; + params.append(Param(analogInputSerialThingPinParamTypeId, pinId)); + descriptor.setParams(params); + emit autoThingsAppeared(ThingDescriptors() << descriptor); + break; + } + 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()); + ParamList params; + params.append(Param(servoSerialThingPinParamTypeId, pinId)); + descriptor.setParams(params); + emit autoThingsAppeared(ThingDescriptors() << descriptor); + break; + } + case OwletSerialClient::PinModeUnconfigured: + + break; + } + }); +} + +void IntegrationPluginOwlet::configurePin(OwletSerialClient *client, quint8 pinId, OwletSerialClient::PinMode pinMode) +{ + OwletSerialClientReply *reply = client->configurePin(pinId, pinMode); + connect(reply, &OwletSerialClientReply::finished, this, [=](){ + if (reply->status() != OwletSerialClient::StatusSuccess) { + qCWarning(dcOwlet()) << "Failed to set pin mode on pin" << pinId << pinMode << reply->status(); + return; + } + + if (reply->responsePayload().count() < 1) { + qCWarning(dcOwlet()) << "Failed to set pin mode on pin" << pinId << pinMode << "Invalid response payload size from request"; + return; + } + + OwletSerialClient::GPIOError gpioError = static_cast(reply->responsePayload().at(0)); + if (gpioError != OwletSerialClient::GPIOErrorNoError) { + qCWarning(dcOwlet()) << "Set pin mode on pin" << pinId << pinMode << "request finished with error" << gpioError; + return; + } + + qCDebug(dcOwlet()) << "Set pin mode finished successfully" << pinId << pinMode; + }); +} + diff --git a/owlet/integrationpluginowlet.h b/owlet/integrationpluginowlet.h index 902323bda..c40c32737 100644 --- a/owlet/integrationpluginowlet.h +++ b/owlet/integrationpluginowlet.h @@ -34,6 +34,8 @@ #include "integrations/integrationplugin.h" #include "extern-plugininfo.h" +#include "owletserialclient.h" + class ZeroConfServiceBrowser; class OwletClient; @@ -57,8 +59,19 @@ class IntegrationPluginOwlet: public IntegrationPlugin ZeroConfServiceBrowser *m_zeroConfBrowser = nullptr; QHash m_clients; + QHash m_serialClients; + QHash m_owletIdParamTypeMap; + + // Serial owlets QHash m_owletSerialPortParamTypeMap; + QHash m_owletSerialPinParamTypeMap; + + 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); }; #endif // INTEGRATIONPLUGINOWLET_H diff --git a/owlet/integrationpluginowlet.json b/owlet/integrationpluginowlet.json index 95b739683..4c006ce54 100644 --- a/owlet/integrationpluginowlet.json +++ b/owlet/integrationpluginowlet.json @@ -225,7 +225,7 @@ "name": "arduinoMiniPro", "displayName": "Arduino Pro Mini Owlet", "createMethods": ["user", "discovery"], - "interfaces": ["gateway", "connectable"], + "interfaces": ["gateway", "update", "connectable"], "paramTypes": [ { "id": "589715a6-aaf7-4ffb-9c34-015ac22d527e", @@ -252,8 +252,7 @@ "allowedValues": [ "None", "Input", - "Output", - "Interrupt" + "Output" ], "defaultValue": "None" }, @@ -267,7 +266,7 @@ "Input", "Output", "PWM", - "Interrupt" + "Servo" ], "defaultValue": "None" }, @@ -292,7 +291,8 @@ "None", "Input", "Output", - "PWM" + "PWM", + "Servo" ], "defaultValue": "None" }, @@ -305,7 +305,8 @@ "None", "Input", "Output", - "PWM" + "PWM", + "Servo" ], "defaultValue": "None" }, @@ -342,7 +343,8 @@ "None", "Input", "Output", - "PWM" + "PWM", + "Servo" ], "defaultValue": "None" }, @@ -355,7 +357,8 @@ "None", "Input", "Output", - "PWM" + "PWM", + "Servo" ], "defaultValue": "None" }, @@ -368,7 +371,8 @@ "None", "Input", "Output", - "PWM" + "PWM", + "Servo" ], "defaultValue": "None" }, @@ -497,6 +501,228 @@ "type": "bool", "defaultValue": false, "cached": false + }, + { + "id": "f7e86ecd-761b-412e-b5de-a2547f883f76", + "name": "currentVersion", + "displayName": "Firmware version", + "displayNameEvent": "Firmware version changed", + "type": "QString", + "defaultValue": "" + }, + { + "id": "43afe87d-3465-4ced-be0f-170f972afea3", + "name": "updateStatus", + "displayName": "Update status", + "displayNameEvent": "Update status changed", + "type": "QString", + "possibleValues": ["idle", "available", "updating"], + "defaultValue": "idle" + } + ], + "actionTypes": [ + { + "id": "8cfbb619-de54-441a-8761-d29c6f0c659a", + "name": "performUpdate", + "displayName": "Update firmware" + } + ] + }, + { + "id": "43aca5c1-3972-49ae-b21f-4d1486942e1f", + "displayName": "Digital GPIO output on owlet", + "name": "digitalOutputSerial", + "createMethods": ["auto"], + "interfaces": [ "power", "connectable" ], + "paramTypes": [ + { + "id": "6e17a423-89c0-430b-ac78-1af60a63ce50", + "name": "pin", + "displayName": "Pin number", + "type": "uint", + "defaultValue": 1 + } + ], + "stateTypes": [ + { + "id": "3da148b9-fe85-4bf1-9005-082b3cf0c014", + "name": "connected", + "displayName": "Connected", + "displayNameEvent": "Connected changed", + "defaultValue": false, + "type": "bool" + }, + { + "id": "2f7dd16b-c1ee-4b2b-859e-e3eacc679400", + "name": "power", + "displayName": "Power", + "type": "bool", + "defaultValue": false, + "writable": true, + "displayNameEvent": "Power changed", + "displayNameAction": "Set power", + "ioType": "digitalOutput" + } + ] + }, + { + "id": "884cb983-3099-4355-a2e6-693f5c1b85e7", + "displayName": "Digital GPIO input on owlet", + "name": "digitalInputSerial", + "createMethods": ["auto"], + "interfaces": [ "connectable" ], + "paramTypes": [ + { + "id": "6e872f08-9110-425c-9e17-e24d83452b7d", + "name": "pin", + "displayName": "Pin number", + "type": "uint", + "defaultValue": 1 + } + ], + "stateTypes": [ + { + "id": "112dad0b-9c94-4310-8962-f81e1050c713", + "name": "connected", + "displayName": "Connected", + "displayNameEvent": "Connected changed", + "defaultValue": false, + "type": "bool" + }, + { + "id": "9fd72a32-a266-4474-b5b1-e6da9835da6d", + "name": "power", + "displayName": "Powered", + "type": "bool", + "defaultValue": false, + "displayNameEvent": "Powered changed", + "ioType": "digitalInput" + } + ] + }, + { + "id": "c6f3cbd9-1863-430a-9fc2-19f7b57b47d7", + "displayName": "Analog input GPIO on owlet", + "name": "analogInputSerial", + "createMethods": ["auto"], + "interfaces": [ "connectable" ], + "paramTypes": [ + { + "id": "55b142ab-ae9a-41cd-a23a-5a78ec141013", + "name": "pin", + "displayName": "Pin number", + "type": "uint", + "defaultValue": 1 + } + ], + "settingsTypes": [ + { + "id": "cfdc6cd0-02ae-403c-aab6-8e86306405af", + "name": "refreshRate", + "displayName": "Refresh rate", + "type": "uint", + "unit": "MilliSeconds", + "minValue": 200, + "defaultValue": 500 + } + ], + "stateTypes": [ + { + "id": "b8fdd65e-dd33-451e-b02f-d7cf73a2e4e2", + "name": "connected", + "displayName": "Connected", + "displayNameEvent": "Connected changed", + "defaultValue": false, + "type": "bool" + }, + { + "id": "5b7b50c8-a3aa-494d-a454-96c38f257836", + "name": "analogValue", + "displayName": "Analog value", + "displayNameEvent": "Analog value changed", + "type": "uint", + "defaultValue": 0, + "minValue": 0, + "maxValue": 1023, + "ioType": "analogInput" + } + ] + }, + { + "id": "ee228a56-9cf2-4401-84c2-8e25f288f136", + "displayName": "PWM on owlet", + "name": "analogOutputSerial", + "createMethods": ["auto"], + "interfaces": [ "connectable" ], + "paramTypes": [ + { + "id": "e2da646f-003f-495b-8250-28067732973a", + "name": "pin", + "displayName": "Pin number", + "type": "uint", + "defaultValue": 1 + } + ], + "stateTypes": [ + { + "id": "d08ed1bd-0ddf-4bad-9689-cc7730a54b05", + "name": "connected", + "displayName": "Connected", + "displayNameEvent": "Connected changed", + "defaultValue": false, + "type": "bool" + }, + { + "id": "8c8065f7-b335-41bf-a015-fd2cd7e68e81", + "name": "dutyCycle", + "displayName": "Duty cycle", + "displayNameEvent": "Duty cycle changed", + "displayNameAction": "Set duty cycle", + "type": "uint", + "minValue": 0, + "maxValue": 255, + "defaultValue": 0, + "writable": true, + "ioType": "analogOutput" + } + ] + }, + { + "id": "66d9725a-b096-4300-b0e1-adc043ee12c3", + "displayName": "Servo on owlet", + "name": "servoSerial", + "createMethods": ["auto"], + "interfaces": [ "connectable" ], + "paramTypes": [ + { + "id": "4596b43d-93e9-46e4-8831-59f96f998606", + "name": "pin", + "displayName": "Pin number", + "type": "uint", + "defaultValue": 1 + } + ], + "stateTypes": [ + { + "id": "0ae0d6a4-8eb1-4d4f-b093-59ce42355ad7", + "name": "connected", + "displayName": "Connected", + "displayNameEvent": "Connected changed", + "defaultValue": false, + "type": "bool" + }, + { + "id": "eee4e07a-1cb1-44d1-98d5-d66d2e63f704", + "name": "angle", + "displayName": "Angle", + "displayNameEvent": "Angle changed", + "displayNameAction": "Set angle", + "type": "uint", + "minValue": 0, + "maxValue": 180, + "defaultValue": 0, + "writable": true, + "ioType": "analogOutput" } ] } diff --git a/owlet/owlet.pro b/owlet/owlet.pro index b940baf5d..f8959c659 100644 --- a/owlet/owlet.pro +++ b/owlet/owlet.pro @@ -5,6 +5,7 @@ QT += network serialport SOURCES += \ integrationpluginowlet.cpp \ owletclient.cpp \ + owletserialclient.cpp \ owletserialtransport.cpp \ owlettcptransport.cpp \ owlettransport.cpp @@ -12,6 +13,7 @@ SOURCES += \ HEADERS += \ integrationpluginowlet.h \ owletclient.h \ + owletserialclient.h \ owletserialtransport.h \ owlettcptransport.h \ owlettransport.h diff --git a/owlet/owletserialclient.cpp b/owlet/owletserialclient.cpp new file mode 100644 index 000000000..c0b6ec3df --- /dev/null +++ b/owlet/owletserialclient.cpp @@ -0,0 +1,249 @@ +#include "owletserialclient.h" +#include "extern-plugininfo.h" + +#include + +OwletSerialClient::OwletSerialClient(OwletTransport *transport, QObject *parent) : + QObject(parent), + m_transport(transport) +{ + connect(m_transport, &OwletTransport::dataReceived, this, &OwletSerialClient::dataReceived); + connect(m_transport, &OwletTransport::error, this, &OwletSerialClient::error); + connect(m_transport, &OwletTransport::connectedChanged, this, [=](bool transportConnected){ + if (!transportConnected) { + m_ready = false; + emit disconnected(); + + // Clean up queue + qDeleteAll(m_pendingRequests); + m_pendingRequests.clear(); + } + }); +} + +OwletTransport *OwletSerialClient::transport() const +{ + return m_transport; +} + +bool OwletSerialClient::ready() const +{ + return m_ready; +} + +OwletSerialClientReply *OwletSerialClient::getFirmwareVersion() +{ + qCDebug(dcOwlet()) << "Request owlet firmware version"; + QByteArray requestData; + QDataStream stream(&requestData, QIODevice::WriteOnly); + stream << static_cast(OwletSerialClient::CommandGetFirmwareVersion); + stream << m_requestId++; + + OwletSerialClientReply *reply = createReply(requestData); + m_pendingRequests.enqueue(reply); + sendNextRequest(); + return reply; +} + +OwletSerialClientReply *OwletSerialClient::configurePin(quint8 pinId, PinMode pinMode) +{ + qCDebug(dcOwlet()) << "Configure pin" << pinId << pinMode; + QByteArray requestData; + QDataStream stream(&requestData, QIODevice::WriteOnly); + stream << static_cast(OwletSerialClient::CommandConfigurePin); + stream << m_requestId++; + stream << pinId << static_cast(pinMode); + + OwletSerialClientReply *reply = createReply(requestData); + m_pendingRequests.enqueue(reply); + sendNextRequest(); + return reply; +} + +OwletSerialClientReply *OwletSerialClient::writeDigitalValue(quint8 pinId, bool power) +{ + qCDebug(dcOwlet()) << "Setting gpio output power of pin" << pinId << power; + QByteArray requestData; + QDataStream stream(&requestData, QIODevice::WriteOnly); + stream << static_cast(OwletSerialClient::CommandWriteDigitalPin); + stream << m_requestId++; + stream << pinId << static_cast(power ? 0x01 : 0x00); + + OwletSerialClientReply *reply = createReply(requestData); + m_pendingRequests.enqueue(reply); + sendNextRequest(); + return reply; +} + +OwletSerialClientReply *OwletSerialClient::readDigitalValue(quint8 pinId) +{ + qCDebug(dcOwlet()) << "Reading digital gpio value of pin" << pinId; + QByteArray requestData; + QDataStream stream(&requestData, QIODevice::WriteOnly); + stream << static_cast(OwletSerialClient::CommandReadDigitalPin); + stream << m_requestId++; + stream << pinId; + + OwletSerialClientReply *reply = createReply(requestData); + m_pendingRequests.enqueue(reply); + sendNextRequest(); + return reply; +} + +OwletSerialClientReply *OwletSerialClient::writeAnalogValue(quint8 pinId, quint8 dutyCycle) +{ + qCDebug(dcOwlet()) << "Write analog gpio value of pin" << pinId << dutyCycle; + QByteArray requestData; + QDataStream stream(&requestData, QIODevice::WriteOnly); + stream << static_cast(OwletSerialClient::CommandWriteAnalogPin); + stream << m_requestId++; + stream << pinId; + stream << dutyCycle; + + OwletSerialClientReply *reply = createReply(requestData); + m_pendingRequests.enqueue(reply); + sendNextRequest(); + return reply; +} + +OwletSerialClientReply *OwletSerialClient::readAnalogValue(quint8 pinId) +{ + qCDebug(dcOwlet()) << "Reading analog gpio value of pin" << pinId; + QByteArray requestData; + QDataStream stream(&requestData, QIODevice::WriteOnly); + stream << static_cast(OwletSerialClient::CommandReadAnalogPin); + stream << m_requestId++; + stream << pinId; + + OwletSerialClientReply *reply = createReply(requestData); + m_pendingRequests.enqueue(reply); + sendNextRequest(); + return reply; +} + +OwletSerialClientReply *OwletSerialClient::writeServoValue(quint8 pinId, quint8 angle) +{ + qCDebug(dcOwlet()) << "Setting servo angle of pin" << pinId << angle; + QByteArray requestData; + QDataStream stream(&requestData, QIODevice::WriteOnly); + stream << static_cast(OwletSerialClient::CommandWriteServoPin); + stream << m_requestId++; + stream << pinId; + stream << angle; + + OwletSerialClientReply *reply = createReply(requestData); + m_pendingRequests.enqueue(reply); + sendNextRequest(); + return reply; +} + +QString OwletSerialClient::firmwareVersion() const +{ + return m_firmwareVersion; +} + +void OwletSerialClient::dataReceived(const QByteArray &data) +{ + QDataStream stream(data); + quint8 commandId; quint8 requestId; + stream >> commandId >> requestId; + + // Check if command or notification + if (commandId < 0xF0) { + quint8 statusId; + stream >> statusId; + OwletSerialClient::Command command = static_cast(commandId); + OwletSerialClient::Status status = static_cast(statusId); + if (m_currentReply) { + if (m_currentReply->command() == command && m_currentReply->requestId() == requestId) { + m_currentReply->m_timer.stop(); + m_currentReply->m_status = status; + m_currentReply->m_responsePayload = data.right(data.length() - 3); + + if (status != OwletSerialClient::StatusSuccess) { + qCWarning(dcOwlet()) << "Request finished with error" << command << "ID:" << m_currentReply->requestId() << status; + } else { + qCDebug(dcOwlet()) << "Request finished" << command << "ID:" << m_currentReply->requestId() << status << "Payload:" << m_currentReply->responsePayload().toHex(); + } + + emit m_currentReply->finished(); + } + } else { + qCWarning(dcOwlet()) << "Received unhandled command response data" << data.toHex(); + } + } else { + OwletSerialClient::Notification notification = static_cast(commandId); + QByteArray notificationPayload = data.right(data.length() - 2); + qCDebug(dcOwlet()) << "Notification received" << notification << "ID:" << requestId << notificationPayload.toHex(); + switch (notification) { + case OwletSerialClient::NotificationReady: { + OwletSerialClientReply *reply = getFirmwareVersion(); + connect(reply, &OwletSerialClientReply::finished, this, [this, reply](){ + if (reply->status() != OwletSerialClient::StatusSuccess) { + qCWarning(dcOwlet()) << "Failed to get firmware version" << reply->status(); + emit error(); + return; + } + + if (reply->responsePayload().count() != 3) { + qCWarning(dcOwlet()) << "Invalid firmware version payload size"; + emit error(); + return; + } + + quint8 major = reply->responsePayload().at(0); + quint8 minor = reply->responsePayload().at(1); + quint8 patch = reply->responsePayload().at(2); + + 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(); + }); + break; + } + case OwletSerialClient::NotificationGpioPinChanged: { + quint8 pinId; quint8 powerValue; + stream >> pinId >> powerValue; + bool power = powerValue != 0x00; + qCDebug(dcOwlet()) << "Pin value changed" << pinId << power; + emit pinValueChanged(pinId, power); + break; + } + case OwletSerialClient::NotificationDebugMessage: + qCDebug(dcOwlet()) << "Firmware debug:" << QString::fromUtf8(data.right(data.length() - 2)); + break; + default: + qCWarning(dcOwlet()) << "Unhandled notification received" << data.toHex(); + break; + } + } +} + +OwletSerialClientReply *OwletSerialClient::createReply(const QByteArray &requestData) +{ + OwletSerialClientReply *reply = new OwletSerialClientReply(requestData, this); + connect(reply, &OwletSerialClientReply::finished, reply, [=](){ + reply->deleteLater(); + if (reply == m_currentReply) { + m_currentReply = nullptr; + } + sendNextRequest(); + }); + + return reply; +} + +void OwletSerialClient::sendNextRequest() +{ + if (m_currentReply) + return; + + if (m_pendingRequests.isEmpty()) + return; + + m_currentReply = m_pendingRequests.dequeue(); + qCDebug(dcOwlet()) << "Sending request" << m_currentReply->command() << "ID:" << m_currentReply->requestId() << "Payload:" << m_currentReply->requestData().right(m_currentReply->requestData().length() - 2).toHex(); + m_transport->sendData(m_currentReply->requestData()); + m_currentReply->m_timer.start(); +} diff --git a/owlet/owletserialclient.h b/owlet/owletserialclient.h new file mode 100644 index 000000000..2e20188f8 --- /dev/null +++ b/owlet/owletserialclient.h @@ -0,0 +1,150 @@ +#ifndef OWLETSERIALCLIENT_H +#define OWLETSERIALCLIENT_H + +#include +#include +#include + +#include "owlettransport.h" + +class OwletSerialClientReply; + +class OwletSerialClient : public QObject +{ + Q_OBJECT +public: + enum Command { + CommandGetFirmwareVersion = 0x00, + CommandConfigurePin = 0x01, + CommandWriteDigitalPin = 0x02, + CommandReadDigitalPin = 0x03, + CommandWriteAnalogPin = 0x04, + CommandReadAnalogPin = 0x05, + CommandWriteServoPin = 0x06 + }; + Q_ENUM(Command) + + enum Notification { + NotificationReady = 0xf0, + NotificationGpioPinChanged = 0xf1, + NotificationDebugMessage = 0xff + }; + Q_ENUM(Notification) + + enum Status { + StatusSuccess = 0x00, + StatusInvalidProtocol = 0x01, + StatusInvalidCommand = 0x02, + StatusInvalidPlayload = 0x03, + StatusTimeout = 0xfe, + StatusUnknownError = 0xff + }; + Q_ENUM(Status) + + enum GPIOError { + GPIOErrorNoError = 0x00, + GPIOErrorUnconfigured = 0x01, + GPIOErrorUnsupported = 0x02, + GPIOErrorConfigurationMismatch = 0x03, + GPIOErrorInvalidParameter = 0x04, + GPIOErrorInvalidPin = 0x05 + }; + Q_ENUM(GPIOError) + + enum PinMode { + PinModeUnconfigured = 0x00, + PinModeDigitalInput = 0x01, + PinModeDigitalOutput = 0x02, + PinModeAnalogInput = 0x03, + PinModeAnalogOutput = 0x04, + PinModeServo = 0x05 + }; + Q_ENUM(PinMode) + + explicit OwletSerialClient(OwletTransport *transport, QObject *parent = nullptr); + + OwletTransport *transport() const; + + bool ready() const; + + OwletSerialClientReply *getFirmwareVersion(); + OwletSerialClientReply *configurePin(quint8 pinId, PinMode pinMode); + OwletSerialClientReply *writeDigitalValue(quint8 pinId, bool power); + OwletSerialClientReply *readDigitalValue(quint8 pinId); + OwletSerialClientReply *writeAnalogValue(quint8 pinId, quint8 dutyCycle); + OwletSerialClientReply *readAnalogValue(quint8 pinId); + OwletSerialClientReply *writeServoValue(quint8 pinId, quint8 angle); + + QString firmwareVersion() const; + +signals: + void connected(); + void disconnected(); + void error(); + + void pinValueChanged(quint8 pinId, bool power); + +private slots: + void dataReceived(const QByteArray &data); + +private: + OwletTransport *m_transport = nullptr; + bool m_ready = false; + + quint8 m_requestId = 0; + + OwletSerialClientReply *m_currentReply = nullptr; + QQueue m_pendingRequests; + + QString m_firmwareVersion; + + OwletSerialClientReply *createReply(const QByteArray &requestData); + void sendNextRequest(); +}; + + +class OwletSerialClientReply : public QObject +{ + Q_OBJECT + + friend class OwletSerialClient; + +public: + QByteArray requestData() const { return m_requestData; }; + OwletSerialClient::Command command() const { return m_command; }; + quint8 requestId() const { return m_requestId; }; + OwletSerialClient::Status status() const { return m_status; }; + QByteArray responsePayload() const { return m_responsePayload; }; + +signals: + void finished(); + +private: + explicit OwletSerialClientReply(const QByteArray &requestData, QObject *parent = nullptr) : + QObject(parent), + m_requestData(requestData) + { + Q_ASSERT(m_requestData.length() >= 2); + m_command = static_cast(m_requestData.at(0)); + m_requestId = static_cast(m_requestData.at(1)); + + m_timer.setInterval(1000); + m_timer.setSingleShot(true); + connect(&m_timer, &QTimer::timeout, this, [=](){ + m_status = OwletSerialClient::StatusTimeout; + emit finished(); + }); + } + + QTimer m_timer; + QByteArray m_requestData; + OwletSerialClient::Command m_command; + quint8 m_requestId = 0; + + // Response + OwletSerialClient::Status m_status = OwletSerialClient::StatusUnknownError; + QByteArray m_responsePayload; +}; + + +#endif // OWLETSERIALCLIENT_H diff --git a/owlet/owletserialtransport.cpp b/owlet/owletserialtransport.cpp index 3fb28a0bf..b49b1de1e 100644 --- a/owlet/owletserialtransport.cpp +++ b/owlet/owletserialtransport.cpp @@ -27,12 +27,13 @@ OwletSerialTransport::OwletSerialTransport(const QString &serialPortName, uint b connect(m_serialPort, &QSerialPort::errorOccurred, this, &OwletSerialTransport::onError); #endif - m_reconnectTimer = new QTimer(this); m_reconnectTimer->setInterval(5000); m_reconnectTimer->setSingleShot(false); connect(m_reconnectTimer, &QTimer::timeout, this, [=](){ if (m_serialPort->isOpen()) { + // Clear any buffer content + m_serialPort->clear(); m_reconnectTimer->stop(); return; } else { @@ -48,6 +49,8 @@ bool OwletSerialTransport::connected() const void OwletSerialTransport::sendData(const QByteArray &data) { + qCDebug(dcOwlet()) << "UART -->" << data.toHex(); + // Stream bytes using SLIP QByteArray message; QDataStream stream(&message, QIODevice::WriteOnly); @@ -71,7 +74,8 @@ void OwletSerialTransport::sendData(const QByteArray &data) } stream << static_cast(SlipProtocolEnd); - qCDebug(dcOwlet()) << "UART -->" << qUtf8Printable(data) << message.toHex(); + //qCDebug(dcOwlet()) << "UART -->" << message.toHex(); + m_serialPort->write(message); m_serialPort->flush(); } @@ -102,6 +106,7 @@ void OwletSerialTransport::connectTransport() if (!m_serialPort->open(QIODevice::ReadWrite)) { qCWarning(dcOwlet()) << "Could not open serial port on" << m_serialPortName << m_serialPort->errorString(); m_reconnectTimer->start(); + emit error(); return; } @@ -120,7 +125,7 @@ void OwletSerialTransport::disconnectTransport() void OwletSerialTransport::onReadyRead() { QByteArray data = m_serialPort->readAll(); - qCDebug(dcOwlet()) << "UART <-- raw:" << data.toHex() << qUtf8Printable(data); + //qCDebug(dcOwlet()) << "UART <--" << data.toHex(); for (int i = 0; i < data.length(); i++) { quint8 receivedByte = data.at(i); @@ -144,8 +149,8 @@ void OwletSerialTransport::onReadyRead() switch (receivedByte) { case SlipProtocolEnd: // We are done with this package, process it and reset the buffer - if (!m_buffer.isEmpty() && m_buffer.length() >= 3) { - qCDebug(dcOwlet()) << "UART <--" << m_buffer.toHex() << qUtf8Printable(m_buffer); + if (!m_buffer.isEmpty() && m_buffer.length() >= 2) { + qCDebug(dcOwlet()) << "UART <--" << m_buffer.toHex(); emit dataReceived(m_buffer); } m_buffer.clear(); @@ -168,6 +173,7 @@ void OwletSerialTransport::onError(QSerialPort::SerialPortError serialPortError) if (serialPortError != QSerialPort::NoError && serialPortError != QSerialPort::OpenError && m_serialPort->isOpen()) { qCWarning(dcOwlet()) << "Serial port error occured" << serialPortError << m_serialPort->errorString(); emit error(); + m_reconnectTimer->start(); if (m_serialPort->isOpen()) { m_serialPort->close(); From 40ba9031e0d87404e8ca1e2f10b9165f98ed5d8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Wed, 5 Jan 2022 15:26:45 +0100 Subject: [PATCH 11/18] Add arduino uno and clean up a bit --- owlet/integrationpluginowlet.cpp | 180 +++++++++++++++-- owlet/integrationpluginowlet.h | 2 + owlet/integrationpluginowlet.json | 323 +++++++++++++++++++++++++++++- owlet/owletserialclient.cpp | 17 +- owlet/owletserialclient.h | 8 +- 5 files changed, 511 insertions(+), 19 deletions(-) diff --git a/owlet/integrationpluginowlet.cpp b/owlet/integrationpluginowlet.cpp index b7f319d98..062fa8825 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 c40c32737..e4e2859cf 100644 --- a/owlet/integrationpluginowlet.h +++ b/owlet/integrationpluginowlet.h @@ -67,11 +67,13 @@ class IntegrationPluginOwlet: public IntegrationPlugin 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 4c006ce54..8c412990c 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 c0b6ec3df..105383ae3 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 2e20188f8..15c7bc21f 100644 --- a/owlet/owletserialclient.h +++ b/owlet/owletserialclient.h @@ -62,10 +62,14 @@ class OwletSerialClient : public QObject 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 @@ class OwletSerialClient : public QObject 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); From 9c87f4c470170ba2f0f3492d5418980e051d1482 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Thu, 6 Jan 2022 17:30:38 +0100 Subject: [PATCH 12/18] Fix memory leak on failed setup, reconfigure --- owlet/integrationpluginowlet.cpp | 36 ++++++++++++++++++++------------ owlet/owletclient.cpp | 2 ++ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/owlet/integrationpluginowlet.cpp b/owlet/integrationpluginowlet.cpp index 062fa8825..78bc2a376 100644 --- a/owlet/integrationpluginowlet.cpp +++ b/owlet/integrationpluginowlet.cpp @@ -43,6 +43,7 @@ #include #include +#include IntegrationPluginOwlet::IntegrationPluginOwlet() { @@ -568,10 +569,32 @@ void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) OwletTransport *transport = new OwletTcpTransport(ip, port, this); + if (m_clients.contains(info->thing())) { + delete m_clients.take(info->thing()); + } OwletClient *client = new OwletClient(transport, this); + + connect(client, &OwletClient::error, info, [=](){ + delete client; + info->finish(Thing::ThingErrorHardwareFailure); + }); + connect(info, &ThingSetupInfo::aborted, client, [=](){ + delete client; + }); + connect(client, &OwletClient::connected, info, [=](){ qCDebug(dcOwlet()) << "Connected to owlet"; m_clients.insert(thing, client); + info->finish(Thing::ThingErrorNoError); + }); + + + connect(client, &OwletClient::connected, thing, [=](){ + thing->setStateValue("connected", true); + + pluginStorage()->beginGroup(thing->id().toString()); + pluginStorage()->setValue("cachedIP", ip.toString()); + pluginStorage()->endGroup(); if (thing->thingClassId() == digitalOutputThingClassId) { QVariantMap params; @@ -595,19 +618,6 @@ void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) client->sendCommand("GPIO.ConfigurePin", params); } - info->finish(Thing::ThingErrorNoError); - }); - - connect(client, &OwletClient::error, info, [=](){ - info->finish(Thing::ThingErrorHardwareFailure); - }); - - connect(client, &OwletClient::connected, thing, [=](){ - thing->setStateValue("connected", true); - - pluginStorage()->beginGroup(thing->id().toString()); - pluginStorage()->setValue("cachedIP", ip.toString()); - pluginStorage()->endGroup(); qCDebug(dcOwlet()) << "Sending get platform information request..."; int id = client->sendCommand("Platform.GetInformation"); diff --git a/owlet/owletclient.cpp b/owlet/owletclient.cpp index cd1c5f038..19e10e542 100644 --- a/owlet/owletclient.cpp +++ b/owlet/owletclient.cpp @@ -9,6 +9,8 @@ OwletClient::OwletClient(OwletTransport *transport, QObject *parent) : QObject(parent), m_transport(transport) { + transport->setParent(this); + connect(m_transport, &OwletTransport::dataReceived, this, &OwletClient::dataReceived); connect(m_transport, &OwletTransport::error, this, &OwletClient::error); connect(m_transport, &OwletTransport::connectedChanged, this, [=](bool isConnected){ From 5954d1b64534d818ee1f918ed240299f04eb7d7c Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Fri, 7 Jan 2022 23:32:08 +0100 Subject: [PATCH 13/18] Some fixes --- owlet/integrationpluginowlet.cpp | 19 ++++++++++++++++++- owlet/owletclient.cpp | 5 +++++ owlet/owletclient.h | 2 ++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/owlet/integrationpluginowlet.cpp b/owlet/integrationpluginowlet.cpp index 78bc2a376..d9639cbcb 100644 --- a/owlet/integrationpluginowlet.cpp +++ b/owlet/integrationpluginowlet.cpp @@ -671,6 +671,10 @@ void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) { if (info->thing()->thingClassId() == digitalOutputThingClassId) { OwletClient *client = m_clients.value(info->thing()); + if (!client->isConnected()) { + info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("Owlet is not connected.")); + return; + } QVariantMap params; params.insert("id", info->thing()->paramValue(digitalOutputThingPinParamTypeId).toInt()); params.insert("power", info->action().paramValue(digitalOutputPowerActionPowerParamTypeId).toBool()); @@ -689,12 +693,19 @@ void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) info->finish(Thing::ThingErrorHardwareFailure); } }); - + connect(client, &OwletClient::disconnected, info, [=](){ + qCDebug(dcOwlet()) << "Owlet disconnected during pending action"; + info->finish(Thing::ThingErrorHardwareFailure); + }); return; } if (info->thing()->thingClassId() == ws2812ThingClassId) { OwletClient *client = m_clients.value(info->thing()); + if (!client->isConnected()) { + info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("Owlet is not connected.")); + return; + } QVariantMap params; params.insert("id", info->thing()->paramValue(ws2812ThingPinParamTypeId).toUInt()); @@ -721,11 +732,17 @@ void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) qCDebug(dcOwlet()) << "reply from owlet:" << params; QString error = params.value("error").toString(); if (error == "GPIOErrorNoError") { + info->thing()->setStateValue(info->action().actionTypeId(), info->action().paramValue(info->action().actionTypeId())); info->finish(Thing::ThingErrorNoError); } else { info->finish(Thing::ThingErrorHardwareFailure); } }); + connect(client, &OwletClient::disconnected, info, [=](){ + qCDebug(dcOwlet()) << "Owlet disconnected during pending action"; + info->finish(Thing::ThingErrorHardwareFailure); + }); + return; } diff --git a/owlet/owletclient.cpp b/owlet/owletclient.cpp index 19e10e542..266571d3a 100644 --- a/owlet/owletclient.cpp +++ b/owlet/owletclient.cpp @@ -22,6 +22,11 @@ OwletClient::OwletClient(OwletTransport *transport, QObject *parent) : }); } +bool OwletClient::isConnected() const +{ + return m_transport->connected(); +} + OwletTransport *OwletClient::transport() const { return m_transport; diff --git a/owlet/owletclient.h b/owlet/owletclient.h index 4f9b6e18a..9e7012a23 100644 --- a/owlet/owletclient.h +++ b/owlet/owletclient.h @@ -13,6 +13,8 @@ class OwletClient : public QObject public: explicit OwletClient(OwletTransport *transport, QObject *parent = nullptr); + bool isConnected() const; + OwletTransport *transport() const; int sendCommand(const QString &method, const QVariantMap ¶ms = QVariantMap()); From 328d282b75f4c99b051cd43a3a61532b8fb5338b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 10 Jan 2022 17:30:14 +0100 Subject: [PATCH 14/18] Add firmware files --- debian/control | 1 + debian/nymea-plugin-owlet.install.in | 1 + owlet/README.md | 84 +++ owlet/arduinoflasher.cpp | 100 +++ owlet/arduinoflasher.h | 49 ++ .../firmware/arduino-mini-pro-3v/firmware.hex | 650 +++++++++++++++++ .../firmware/arduino-mini-pro-3v/release.json | 4 + .../firmware/arduino-mini-pro-5v/firmware.hex | 651 +++++++++++++++++ .../firmware/arduino-mini-pro-5v/release.json | 4 + owlet/firmware/arduino-nano/firmware.hex | 651 +++++++++++++++++ owlet/firmware/arduino-nano/release.json | 4 + owlet/firmware/arduino-uno/firmware.hex | 651 +++++++++++++++++ owlet/firmware/arduino-uno/release.json | 4 + owlet/integrationpluginowlet.cpp | 379 ++++++++-- owlet/integrationpluginowlet.h | 4 +- owlet/integrationpluginowlet.json | 660 +++++++++++++++++- owlet/meta.json | 9 + owlet/owlet.pro | 2 + 18 files changed, 3863 insertions(+), 45 deletions(-) create mode 100644 owlet/README.md create mode 100644 owlet/arduinoflasher.cpp create mode 100644 owlet/arduinoflasher.h create mode 100644 owlet/firmware/arduino-mini-pro-3v/firmware.hex create mode 100644 owlet/firmware/arduino-mini-pro-3v/release.json create mode 100644 owlet/firmware/arduino-mini-pro-5v/firmware.hex create mode 100644 owlet/firmware/arduino-mini-pro-5v/release.json create mode 100644 owlet/firmware/arduino-nano/firmware.hex create mode 100644 owlet/firmware/arduino-nano/release.json create mode 100644 owlet/firmware/arduino-uno/firmware.hex create mode 100644 owlet/firmware/arduino-uno/release.json create mode 100644 owlet/meta.json diff --git a/debian/control b/debian/control index 4f10c1dc9..65daeed77 100644 --- a/debian/control +++ b/debian/control @@ -468,6 +468,7 @@ Package: nymea-plugin-owlet Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, + avrdude, nymea-plugins-translations, Description: nymea.io plugin for nymea:owlet nymea:owlet is a firmware for microcontrollers (Arduino/ESP8266/ESP32) which diff --git a/debian/nymea-plugin-owlet.install.in b/debian/nymea-plugin-owlet.install.in index 2e5fe9706..f5a0b363b 100644 --- a/debian/nymea-plugin-owlet.install.in +++ b/debian/nymea-plugin-owlet.install.in @@ -1 +1,2 @@ usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationpluginowlet.so +owlet/firmware usr/share/nymea/owlet/firmware diff --git a/owlet/README.md b/owlet/README.md new file mode 100644 index 000000000..3fd2cc217 --- /dev/null +++ b/owlet/README.md @@ -0,0 +1,84 @@ +# Owlet + +nymea:owlet is a firmware for different microcontrollers (Arduino/ESP8266/ESP32) which +exposes pins of the microcontroller to nymea and allows using them for +whatever purpose like moodlights, control relays, reading analog values +or controlling servos. + +# ESP8285 + +# ESP32 + +# M5Stick-C + + +# Arduino + +In order to use owlet with an [Arduino](https://docs.arduino.cc/) you need to add the corresponding model into nymea. Once the thing is connected the firmware will be flashed automatically if required. + +Following models are available: + +* [Arduino Uno](https://docs.arduino.cc/hardware/uno-rev3) +* [Arduino Mini Pro (5v, 16MHz)](https://docs.arduino.cc/retired/boards/arduino-pro-mini) +* [Arduino Mini Pro (3.3v, 8MHz)](https://docs.arduino.cc/retired/boards/arduino-pro-mini) +* [Arduino Nano](https://store.arduino.cc/products/arduino-nano) + +Once the Arduino has been added to nymea and the owlet firmware has been flashed successfully, the pins +can be configured as desired within the Arduino thing settings. Depending on the pin capabilities you can select +how the mode for each pin you require for your project. By default all pins are unconfigured. + +When applying the settings, for each pin a new thing will appear in nymea giving you controls and information about +the current states of the pin. If a pin has been configured to a specific type and you want to remove a thing, +just configure it as type `None` and the associated thing will be removed from nymea. + + +## Available configurations + +Not all pins can be configured to any type. Within the settings you can see for each pin +the possible configurations. + +### Digital Output + +If you configure a pin as *Output* you can switch on and off the associated GPIO. + +Usecase examples: + +* Switching relays +* Enable / Disable a LED + +### Digital Input + +If you configure a pin as *Input* you get a thing with a `bool` state indicating if the current state of the pin. + +Usecase examples: + +* Buttons +* Contact sensors + +### Analog output (PWM) + +If you configure a pin as *PWM* you can set the current duty cylcle of the PWM in a range of 0 - 255. The frequency of the duty cycle depends on the hardware you are using and requires some datasheet reading in order to understand hot it works. + +[Arduino analogWrite() refference](https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/ +) + +Usecase examples: + +* LED brightness +* Piezo buzzer +* Control motor speed + +### Analog input (ADC) + +If you configure a pin as *Analog input* you can read periodically the value from the internal ADC (analog digital converter). Most ADCs have a resolution of 10 Bits giving you a value range of 0 - 1023. Once you configured the pin as analog input you can configure in the thing settings how often the value should be fetched. Default is every 500 ms. + +Usecase examples: + +* Reading analog sensor values like humidity, distance... +* Reading a potentiometer value + +### Servo + +If you configure a pin as *Servo* you can control a servo motor in the range of 0° - 180°. A servo normally gets controlled using a PWM signal, but for most DIY servos the internal PWM functionality has a to high frequency. This mode makes use of the [Arduino Servo library](https://www.arduino.cc/reference/en/libraries/servo/) and uses the internal timers to generate a customizable PWM signal. + +> Please note that if you configure a Servo, 2 internal timers will be used and therefore you loose some native PWM functionality. Plase read the documetation of your Hardware. diff --git a/owlet/arduinoflasher.cpp b/owlet/arduinoflasher.cpp new file mode 100644 index 000000000..97b83a585 --- /dev/null +++ b/owlet/arduinoflasher.cpp @@ -0,0 +1,100 @@ +#include "arduinoflasher.h" +#include "extern-plugininfo.h" + +#include +#include + +ArduinoFlasher::ArduinoFlasher(Arduino model, const QString &serialPort, QObject *parent) : + QObject(parent), + m_model(model), + m_serialPort(serialPort) +{ + QString firmwareBasePath = "usr/share/nymea/owlet/firmware"; + + switch (model) { + case ArduinoUno: { + QString firmwarePath = firmwareBasePath + QDir::separator() + "arduino-uno"; + QVariantMap releaseInfo = loadReleaseInfo(firmwarePath); + if (releaseInfo.isEmpty()) + return; + + m_availableVersion = releaseInfo.value("version").toString(); + m_firmwareFileName = firmwarePath + QDir::separator() + releaseInfo.value("firmwareFile").toString(); + + if (!QFileInfo::exists(m_firmwareFileName)) { + qCWarning(dcOwlet()) << "ArduinoFlasher: Could not find the firmware file for flashing" << m_firmwareFileName; + return; + } + + m_flashProcessArguments << "-c" << "avrisp" << "-p" << "m328p" << "-P" << serialPort << "-b" << "19200" << "-U" << QString("flash:w:%1:i").arg(m_firmwareFileName); + m_available = true; + break; + } + case ArduinoNano: { + break; + } + case ArduinoMiniPro3V: { + break; + } + case ArduinoMiniPro5V: { + break; + } + } +} + +QString ArduinoFlasher::availableVersion() const +{ + return m_availableVersion; +} + +bool ArduinoFlasher::flashFirmware() +{ + if (!m_available) + return false; + + if (m_flashProcess) + return false; + + m_flashProcess = new QProcess(this); + m_flashProcess->setProgram("avrdude"); + m_flashProcess->setArguments(m_flashProcessArguments); + connect(m_flashProcess, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(onProcessFinished(int,QProcess::ExitStatus))); + m_flashProcess->start(); + + return true; +} + +QVariantMap ArduinoFlasher::loadReleaseInfo(const QString &firmwareDirectoryPath) +{ + QFileInfo releaseFileInfo(firmwareDirectoryPath + QDir::separator() + "release.json"); + if (!releaseFileInfo.exists()) { + qCWarning(dcOwlet()) << "ArduinoFlasher: Could not load release info. The release file does not exist" << releaseFileInfo.absoluteFilePath(); + return QVariantMap(); + } + + QFile releaseFile; + releaseFile.setFileName(releaseFileInfo.absoluteFilePath()); + if (!releaseFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + qCWarning(dcOwlet()) << "ArduinoFlasher: Could not open release file" << releaseFileInfo.absoluteFilePath(); + return QVariantMap(); + } + + QByteArray releaseJsonData = releaseFile.readAll(); + releaseFile.close(); + + return QJsonDocument::fromJson(releaseJsonData).toVariant().toMap(); +} + +void ArduinoFlasher::onProcessFinished(int returnCode, QProcess::ExitStatus exitStatus) +{ + if (returnCode != EXIT_SUCCESS || exitStatus != QProcess::NormalExit) { + qCWarning(dcOwlet()) << "ArduinoFlasher: Flash process finished with error" << returnCode << exitStatus; + emit flashProcessFinished(false); + } else { + qCDebug(dcOwlet()) << "ArduinoFlasher: Flash process finished successfully"; + emit flashProcessFinished(true); + } + + m_flashProcess->deleteLater(); + m_flashProcess = nullptr; +} diff --git a/owlet/arduinoflasher.h b/owlet/arduinoflasher.h new file mode 100644 index 000000000..05c822be0 --- /dev/null +++ b/owlet/arduinoflasher.h @@ -0,0 +1,49 @@ +#ifndef ARDUINOFLASHER_H +#define ARDUINOFLASHER_H + +#include +#include +#include + +class ArduinoFlasher : public QObject +{ + Q_OBJECT +public: + enum Arduino { + ArduinoUno, + ArduinoMiniPro5V, + ArduinoMiniPro3V, + ArduinoNano + }; + Q_ENUM(Arduino) + + explicit ArduinoFlasher(Arduino model, const QString &serialPort, QObject *parent = nullptr); + + bool available() const; + + QString availableVersion() const; + + bool flashFirmware(); + +signals: + void flashProcessFinished(bool success); + +private: + Arduino m_model = ArduinoUno; + QString m_serialPort; + + QProcess *m_flashProcess = nullptr; + bool m_available = false; + QString m_availableVersion; + QString m_firmwareFileName; + + QStringList m_flashProcessArguments; + + QVariantMap loadReleaseInfo(const QString &firmwareDirectoryPath); + +private slots: + void onProcessFinished(int returnCode, QProcess::ExitStatus exitStatus); + +}; + +#endif // ARDUINOFLASHER_H diff --git a/owlet/firmware/arduino-mini-pro-3v/firmware.hex b/owlet/firmware/arduino-mini-pro-3v/firmware.hex new file mode 100644 index 000000000..062b9aabf --- /dev/null +++ b/owlet/firmware/arduino-mini-pro-3v/firmware.hex @@ -0,0 +1,650 @@ +:100000000C9463000C948B000C948B000C948B006C +:100010000C948B000C948B000C948B000C948B0034 +:100020000C948B000C948B000C948B000C94EB0EB6 +:100030000C948B000C948B000C948B000C948B0014 +:100040000C94490E0C948B000C94B90E0C94930EE6 +:100050000C948B000C948B000C948B000C948B00F4 +:100060000C948B000C948B000000000024002700EF +:100070002A0000000000250028002B0000000000DE +:1000800023002600290004040404040404040202DA +:100090000202020203030303030301020408102007 +:1000A0004080010204081020010204081020000012 +:1000B0000008000201000003040700000000000027 +:1000C0000000A70F601211241FBECFEFD8E0DEBFE3 +:1000D000CDBF11E0A0E0B1E0EEE5F8E202C005908E +:1000E0000D92A832B107D9F722E0A8E2B1E001C031 +:1000F0001D92A13AB207E1F710E0C2E6D0E004C0D9 +:100100002197FE010E94F712C136D107C9F70E945C +:10011000E1100C9422140C940000833081F028F438 +:10012000813099F08230A9F008958730A9F08830A5 +:10013000C9F08430B1F4809180008F7D03C080913C +:1001400080008F7780938000089584B58F7784BD79 +:10015000089584B58F7DFBCF8091B0008F77809319 +:10016000B00008958091B0008F7DF9CFCF93DF93D9 +:10017000282F30E0F901E255FF4F8491F901E6564E +:10018000FF4FD491F901EA57FF4FC491CC23A1F05E +:1001900081110E948D00EC2FF0E0EE0FFF1FE4585C +:1001A000FF4FA591B491EC91ED2381E090E009F42B +:1001B00080E0DF91CF91089580E090E0FACF1F9327 +:1001C000CF93DF93282F30E0F901E255FF4F849160 +:1001D000F901E656FF4FD491F901EA57FF4FC49158 +:1001E000CC23A9F0162F81110E948D00EC2FF0E096 +:1001F000EE0FFF1FEE58FF4FA591B4918FB7F89403 +:10020000EC91111108C0D095DE23DC938FBFDF91F4 +:10021000CF911F910895DE2BF8CFCF93DF9390E01D +:10022000FC01E656FF4F24918A579F4FFC018491B1 +:100230008823D1F090E0880F991FFC01E859FF4F07 +:10024000A591B491FC01EE58FF4FC591D491611175 +:100250000EC09FB7F8948C91E22FE0958E238C937B +:100260002881E223E8839FBFDF91CF9108958FB764 +:10027000F894EC91E22BEC938FBFF6CF8E3008F020 +:100280008E508770806480937C0080917A008064B7 +:1002900080937A0080917A0086FDFCCF809178006F +:1002A0009091790008953FB7F894809163019091FF +:1002B0006401A0916501B091660126B5A89B05C0B7 +:1002C0002F3F19F00196A11DB11D3FBFBA2FA92FD5 +:1002D000982F8827BC01CD01620F711D811D911DD2 +:1002E00043E0660F771F881F991F4A95D1F708953D +:1002F0008F929F92AF92BF92CF92DF92EF92FF9236 +:100300000E9453014B015C0184E6C82ED12CE12CE4 +:10031000F12C0E945301681979098A099B09683EEA +:10032000734081059105A8F321E0C21AD108E108C4 +:10033000F10888EE880E83E0981EA11CB11CC11440 +:10034000D104E104F10429F7FF90EF90DF90CF9002 +:10035000BF90AF909F908F9008950895AF92BF92F5 +:10036000CF92DF92EF92FF920F931F93CF93DF9381 +:100370006C017B018B01040F151FEB015E01AE18B0 +:10038000BF08C017D10759F06991D601ED91FC91D2 +:100390000190F081E02DC6010995892B79F7C501FF +:1003A000DF91CF911F910F91FF90EF90DF90CF9051 +:1003B000BF90AF900895FC01538D448D252F30E000 +:1003C000842F90E0821B930B541710F0CF96089562 +:1003D00001970895FC01918D828D981761F0A28D8F +:1003E000AE0FBF2FB11D5D968C91928D9F5F9F7355 +:1003F000928F90E008958FEF9FEF0895FC01918D0B +:10040000828D981731F0828DE80FF11D858D90E077 +:1004100008958FEF9FEF0895FC01918D228D892F14 +:1004200090E0805C9F4F821B91098F7399270895FC +:1004300087E691E00E940C0221E0892B09F420E07C +:10044000822F089580E090E0892B29F00E94180205 +:1004500081110C9400000895FC01A48DA80FB92F00 +:10046000B11DA35ABF4F2C91848D90E001968F73DC +:100470009927848FA689B7892C93A089B1898C91FB +:10048000837080648C93938D848D981306C002884A +:10049000F389E02D80818F7D80830895EF92FF9214 +:1004A0000F931F93CF93DF93EC0181E0888F9B8D97 +:1004B0008C8D98131AC0E889F989808185FF15C051 +:1004C0009FB7F894EE89FF896083E889F989808174 +:1004D0008370806480839FBF81E090E0DF91CF9143 +:1004E0001F910F91FF90EF900895F62E0B8D10E065 +:1004F0000F5F1F4F0F731127E02E8C8D8E110CC0D4 +:100500000FB607FCFACFE889F989808185FFF5CF1E +:10051000CE010E942C02F1CFEB8DEC0FFD2FF11DCF +:10052000E35AFF4FF0829FB7F8940B8FEA89FB895B +:1005300080818062CFCFCF93DF93EC01888D8823B9 +:10054000B9F0AA89BB89E889F9898C9185FD03C036 +:10055000808186FD0DC00FB607FCF7CF8C9185FF1B +:10056000F2CF808185FFEDCFCE010E942C02E9CF32 +:10057000DF91CF910895CF93DF9300D0CDB7DEB751 +:10058000DA012C91FB01308139832A83DC018D91C2 +:100590009C91DC01ED91FC910284F385E02D22E039 +:1005A00030E0AE014F5F5F4F61EF70E009950F9053 +:1005B0000F90DF91CF9108956115710531F0FC0125 +:1005C00080819181FB01918380830895CF92DF9296 +:1005D000EF92FF920F931F93CF93DF93EC01162FAF +:1005E0006A017901E881F9810280F381E02D41E01F +:1005F00060EC0995E881F9810280F381E02D40E00B +:10060000612FCE010995E881F9810280F381E02D07 +:10061000DE01A95FBE4F6C9181E0860F8C9340E0B4 +:10062000CE0109958601EC0CFD1CE881F981028060 +:10063000F381E02DE016F10639F0D8016D918D01BE +:1006400040E0CE010995F1CF41E060ECCE01099583 +:100650008A819B81DC01ED91FC910680F781E02D80 +:10066000DF91CF911F910F91FF90EF90DF90CF908E +:100670000994BF92CF92DF92EF92FF920F931F9354 +:10068000CF93DF93EC01B62EC42ED22EE881F981F0 +:100690000280F381E02D41E060EC0995E881F98169 +:1006A0000280F381E02D40E06B2DCE010995E881B9 +:1006B000F9810280F381E02D40E06C2DCE01099597 +:1006C000E881F9810280F381E02D40E06D2DCE01BB +:1006D00009956801E00EF11EE881F9810280F3813D +:1006E000E02DEC14FD0439F0D6016D916D0140E070 +:1006F000CE010995F1CF41E060ECCE0109958A81E8 +:100700009B81DC01ED91FC910680F781E02DDF916A +:10071000CF911F910F91FF90EF90DF90CF90BF90FE +:100720000994DC0112968D919C91DC01ED91FC9174 +:100730000190F081E02D0994CF93DF93DC01ED91DE +:10074000FC910480F581E02D442319F0DF91CF91D5 +:100750000994EC01603C21F06B3D59F0CE01F6CFDD +:100760006BED0995E881F9810480F581E02D6CED50 +:10077000F5CF6BED0995E881F9810480F581E02DD5 +:100780006DEDECCF0F931F93CF93DF93EC01CA5F16 +:10079000DE4F2881222321F06C3D49F06D3D09F1A7 +:1007A000603C59F16B3D81F481E088833AC0DC0103 +:1007B000AB5FBE4FEC9121E02E0F2C93E80FF92F89 +:1007C000F11D20EC26831882FC01EB5FFE4F208197 +:1007D00031E0320F3083820F911DDC0116966C934D +:1007E00020C0DC01AB5FBE4FEC9121E02E0F2C93BB +:1007F000E80FF92FF11D2BEDE5CF8C010B5F1E4F9C +:10080000D8014C91442351F0BC016A5F7F4FDC0159 +:10081000ED91FC910680F781E02D0995F801108299 +:100820001882DF91CF911F910F910895DC01ED9116 +:10083000FC91309729F00280F381E02D0296099413 +:100840000895FC01828D938D30E020E02817390750 +:10085000E1F0A785B089A20FB31F4C91641312C0B9 +:1008600080A591A52817390718F082A593A50895AA +:10087000220F331F858D968D280F391FF901808136 +:10088000918108952F5F3F4FE1CF8585968508952B +:10089000CF93DF93EC01CD3C8CE0D807A0F42AE0A5 +:1008A0002C9FC0012D9F900D112402960E94FD12D5 +:1008B000FC01C193D193CF012197D7FD07C01182CD +:1008C00010823A96F9CF8FEF9FEFF0CFDF91CF9163 +:1008D0000895EF92FF920F931F93CF93DF93EC0154 +:1008E0008B0180E190E09F838E8381E088871D8665 +:1008F000FB01E184F284C7010E94FD129983888381 +:10090000892B61F1F801828193819B838A838481A1 +:1009100095819D838C83868197819F838E8380853B +:100920008887FA86E986838594859C878B87858569 +:100930008D8790E080E02B853C858217930770F4CB +:10094000E0913E02F0913F02E80FF91F2081E8811B +:10095000F981E80FF91F20830196EDCFDF91CF9148 +:100960001F910F91FF90EF900895EF92FF920F93D8 +:100970001F93CF93DF930097C1F1EC01FC013297F5 +:10098000808191812AE0289F8001299F100D1124E8 +:100990000C0F1D1F7801CE15DF0539F08AE0E81A2B +:1009A000F108C7010E941604F6CFC8018C1B9D0BED +:1009B000969587954DEC5CE4849F9001859F300D62 +:1009C000949F300D11243F7746EF4203C001439FAF +:1009D000900D11240297800F911FDF91CF911F91ED +:1009E0000F91FF90EF900C949913DF91CF911F918D +:1009F0000F91FF90EF9008952F923F924F925F9248 +:100A00006F927F928F929F92AF92BF92CF92DF921E +:100A1000EF92FF920F931F93CF93DF938C016B01A3 +:100A2000FC01C481D58181859285C617D707B8F4AA +:100A3000C817D907A9F480E0DF91CF911F910F91DA +:100A4000FF90EF90DF90CF90BF90AF909F908F90EE +:100A50007F906F905F904F903F902F900895EB01A3 +:100A6000F8012085211105C08C179D0738F081E021 +:100A7000E3CF6E018C179D0708F46C011E012097CF +:100A800019F480E1282E312CC1010E9448043C0158 +:100A9000009789F27C01512C412CF80180809180D3 +:100AA000C414D504E9F05701A618B708C7010E947D +:100AB0001604E114F10469F0F401EA0DFB1D8191C3 +:100AC0009191D7018D939D9388E001900D928A9525 +:100AD000E1F7FFEF4F1A5F0A8AE0E80EF11CDDCF65 +:100AE000C4010E94B504F8017182608221863286B9 +:100AF00083859485C817D90708F0B9CFD487C387F1 +:100B0000B6CF0F931F93CF93DF938C0160918F0229 +:100B100070919002809191029091920286179707AE +:100B2000F8F420919102309192024AE0429FC00174 +:100B3000439F900D1124C0918602D0918702C80F67 +:100B4000D91FCE010E9416042097E9F480919102EA +:100B500090919202019690939202809391020EC01E +:100B600080918C0290918D02009741F0680F791F5F +:100B700086E892E00E94FC048111D3CFDF91CF91EF +:100B80001F910F910895F80181919191DE018D934C +:100B90009D9388E001900D928A95E1F7D7CF0F934E +:100BA0001F93CF93DF93EC018B0169857A8506173C +:100BB000170738F08E819F81680F791FCE010E9440 +:100BC000FC0489859A852B853C850217130740F024 +:100BD0008017910740F098012F5F3F4F3C872B878C +:100BE0000817190738F0CE010D96DF91CF911F91AC +:100BF0000F9108958AE0809F9001819F300D11240C +:100C000088819981820F931FF0CFAF92BF92CF92CC +:100C1000DF92EF92FF920F931F93CF93DF938C019C +:100C20007B01FC01C481D58181859285C617D707D8 +:100C300078F4C817D90769F480E0DF91CF911F914C +:100C40000F91FF90EF90DF90CF90BF90AF900895FD +:100C5000EB01F8012085211105C08C179D0738F0A4 +:100C600081E0EBCF7E018C179D0708F47C01209773 +:100C700021F16E018FEF9FEFC115F0E4DF0718F44B +:100C8000C601880F991F0E94FD125C010097A1F216 +:100C9000DC01F8018081918130E020E0E216F3066A +:100CA00081F0F901EE0FFF1FE80FF91F408151811C +:100CB0004D935D932F5F3F4FF1CF60E1C62ED12C56 +:100CC000DFCF009711F00E949913F801B182A08242 +:100CD000D286C18683859485C817D90708F6D4873C +:100CE000C387BECF0F931F93CF93DF93EC018B018C +:100CF00069857A850617170738F08E819F81680FFE +:100D0000791FCE010E94050689859A852B853C8531 +:100D10000217130740F08017910740F098012F5FEA +:100D20003F4F3C872B870817190738F0CE010D96E7 +:100D3000DF91CF911F910F910895000F111F8881AE +:100D40009981800F911FF4CF8F929F92AF92BF92A3 +:100D5000CF92DF92EF92FF920F931F93CF93DF9387 +:100D6000EC017B0189859A856817790760F0CE8050 +:100D7000DF80C80ED91E0C811D810C151D0528F5BC +:100D80008017910719F589859A852B853C85E21690 +:100D9000F30640F08E159F0548F097012F5F3F4FF7 +:100DA0003C872B87E816F90608F458C0CE010D964B +:100DB000DF91CF911F910F91FF90EF90DF90CF9037 +:100DC000BF90AF909F908F90089586012885211144 +:100DD00027C080179107B8F60115110539F15801A0 +:100DE000011580E4180730F5C501880F991F0E948E +:100DF000FD124C01009739F2DC018881998130E0C5 +:100E000020E0C216D306C9F0F901EE0FFF1FE80F6C +:100E1000F91F408151814D935D932F5F3F4FF1CF7B +:100E20006C0108171907C0F66801D6CF60E1A62E3D +:100E3000B12CDACF8FEF9FEFDACF009711F00E943D +:100E4000991399828882BA86A9868B859C85081712 +:100E5000190708F098CF1C870B8795CFEE0CFF1C65 +:100E6000888199818E0D9F1DA3CFAF92BF92CF92A3 +:100E7000DF92EF92FF920F931F93CF93DF938C013A +:100E80007B01DC011496CD91DC91159719968D911B +:100E90009C91C617D70778F4C817D90769F480E082 +:100EA000DF91CF911F910F91FF90EF90DF90CF9046 +:100EB000BF90AF900895EB01F8012085211105C086 +:100EC0008C179D0738F081E0EBCF7E018C179D07D2 +:100ED00008F47C016E01209719F480E1C82ED12C12 +:100EE000C6010E94FD125C010097C9F2FC01D80105 +:100EF0008D919C9130E020E0E216F30641F0DC0198 +:100F0000A20FB31F4C9141932F5F3F4FF5CF009736 +:100F100011F00E949913F801B182A082C186D28695 +:100F200083859485C817D90770F6D487C387CBCF3C +:100F3000CF93FC0183859485C0E06817790750F54D +:100F40008385948501976817790778F4808191816A +:100F50009B012F5F3F4FDC01A20FB31F4C91680F25 +:100F6000791FDB014C93B901EBCF94878387C08550 +:100F7000CC2399F04185528526813781BA01621BC5 +:100F8000730B8617970730F42417350718F4CF0131 +:100F90000E9435078C2FCF910895C1E0FBCF0F93AE +:100FA0001F93CF93DF93EC018B0169857A858B8545 +:100FB0009C8586179707A8F4F8018081E881F9815C +:100FC0002B853C85E20FF31F80832B853C85C9016F +:100FD00001969C878B87C901DF91CF911F910F915B +:100FE00008958E819F81009719F48FEF9FEFF4CFC2 +:100FF000680F791FCE010E9435078111DDCFF5CF33 +:101000000F931F93CF93DF93EC018B0169857A8552 +:101010000617170738F08E819F81680F791FCE0160 +:101020000E94350789859A852B853C850217130711 +:1010300040F08017910740F098012F5F3F4F3C87A9 +:101040002B870817190738F0CE010D96DF91CF9145 +:101050001F910F91089588819981800F911FF6CF7C +:10106000CF92DF92FF920F931F93CF93DF938C0168 +:10107000F62ED0E0C0E06C018FE0C80ED11CF80164 +:10108000828D938DC817D90798F4BE01C6010E94BE +:101090000008FC0180818F1109C0CE01DF91CF9142 +:1010A0001F910F91FF90DF90CF9008952196E7CF89 +:1010B0008FEF9FEFF3CFCF92DF92EF92FF920F93DC +:1010C0001F93CF93DF931F92CDB7DEB78C01698357 +:1010D000F12CE12C6C018FE0C80ED11CF801828D3F +:1010E000938DE816F90698F4B701C6010E9400082E +:1010F000FC0190818981981306C0B701C8014D9603 +:101100000E94A4060EC0FFEFEF1AFF0AE7CFBE0150 +:101110006F5F7F4FC6010E94CF0797FF0CC0C801C9 +:101120000D960F90DF91CF911F910F91FF90EF904F +:10113000DF90CF900895F801208131812F5F3F4FDC +:1011400031832083BC01DACFCF92DF92EF92FF92FE +:101150000F931F93CF93DF938C01D62ED0E0C0E086 +:101160007C018FE0E80EF11CD8015A968D919C917C +:10117000C817D90708F052C0BE01C7010E94000875 +:10118000FC0180818D1148C0D80198968D919C9169 +:10119000C817D90798F5AE01440F551FBE01019736 +:1011A000FA0132966817790790F4D8015D962D916F +:1011B0003C916F5F7F4FD901AE0FBF1FCD90DC9088 +:1011C000240F351FD901CD92DC92AF01E9CFF80190 +:1011D00091A780A725A1222389F046A157A123A189 +:1011E00034A1BA01621B730B8617970738F42417D2 +:1011F000350720F4C8014D960E940506BE01C701BF +:101200000E949807CE01DF91CF911F910F91FF901F +:10121000EF90DF90CF9008952196A6CF8FEF9FEFAC +:10122000F2CFCF92DF92EF92FF920F931F93CF9363 +:10123000DF931F92CDB7DEB78C016983F12CE12CCF +:101240006C018FE0C80ED11CF801828D938DE816D9 +:10125000F90698F4B701C6010E940008FC019081CC +:101260008981981306C0B701C8014D960E94720685 +:101270000EC0FFEFEF1AFF0AE7CFBE016F5F7F4F8F +:10128000C6010E94CF0797FF0CC0C8010D960F90B2 +:10129000DF91CF911F910F91FF90EF90DF90CF9052 +:1012A0000895F801208131812F5F3F4F31832083E2 +:1012B000BC01DACFCF92DF92EF92FF920F931F9390 +:1012C000CF93DF931F92CDB7DEB78C016983F12CEA +:1012D000E12C6C018EE0C80ED11CF801818D928D3D +:1012E000E816F90698F4B701C6010E940008FC014F +:1012F00090818981981306C0B701C8014C960E945D +:1013000000080EC0FFEFEF1AFF0AE7CFBE016F5FC4 +:101310007F4FC6010E94CF0797FF0CC0C8010D96F2 +:101320000F90DF91CF911F910F91FF90EF90DF9081 +:10133000CF900895F801208131812F5F3F4F318395 +:101340002083BC01DACFFC0180819181009711F0EC +:101350000C94991308952F923F925F926F927F920F +:101360008F929F92AF92BF92CF92DF92EF92FF92B5 +:101370000F931F93CF93DF93CDB7DEB729970FB6A7 +:10138000F894DEBF0FBECDBF6C017B01DB016C9119 +:1013900011965C90673008F06DC4E62FF0E0ED52D6 +:1013A000F64F0C94F712DA09100AF10B5F0C9E0C41 +:1013B0003D0D790DDC01ED91FC910084F185E02D6E +:1013C000423011F1F12CE12C10E000E023E030E09C +:1013D000452D60E0C601099529960FB6F894DEBF49 +:1013E0000FBECDBFDF91CF911F910F91FF90EF9076 +:1013F000DF90CF90BF90AF909F908F907F906F9035 +:101400005F903F902F90089519821A824B8333E0AA +:10141000E32EF12C8E010F5F1F4F30E020E0D8CF7C +:10142000EDB7FEB7F987E887443079F0DC01ED913C +:10143000FC910084F185E02DF12CE12C10E000E01E +:1014400023E030E0452D61E0C5CFF70112818381B3 +:10145000282E312CD6011496ED90FC90823009F4A0 +:10146000F7C078F4882309F437C1813009F4E0C06B +:10147000612FC7010E945B08DC012D923C9280E045 +:10148000BEC0843009F4F1C008F4E7C0853081F7AC +:101490005701F6E5AF0EB11C712C612C9701205954 +:1014A0003F4F3F832E8345013FE0830E911CAE8169 +:1014B000BF818D919C916816790650F4B301C401E7 +:1014C0000E940008FC0180811813DCC077FEDEC09A +:1014D00083E090E00E94FD124C0180914C018C3021 +:1014E00008F0F6C091E0980F90934C01D4018C93D2 +:1014F00090E0FC01EE0FFF1FE80FF91FE85DFE4FC3 +:101500008CED95E092838183612FC5010E941109C2 +:10151000DC018D929C92612FC5010E941109FC0192 +:1015200080809180D4018C918C3008F055C061E0AE +:10153000812F0E940D01F4018081282F30E0F901F4 +:10154000EE0FFF1FE20FF31FE85DFE4F9081907CCE +:10155000212F2F73922B9083D40111961C921197F7 +:1015600012961C922CE0622F0E94EB12829FB00117 +:10157000112430E020E0AB01420F531FFA01EE0FBF +:10158000FF1FE40FF51FE85DFE4F908196FD16C02A +:101590002F5F3F4F2C30310571F781110FC0109232 +:1015A000800082E080938100109285001092840078 +:1015B000B19A80916F00826080936F00D401EC91AA +:1015C0008E2F90E0FC01EE0FFF1FE80FF91FE85D82 +:1015D000FE4F808180648083F40180818F3F09F019 +:1015E00047CF612FC5010E941109DC018D919C91AB +:1015F0000E949913612FC5010E94A40885E0898388 +:10160000D601ED91FC910084F185E02DEE24E39468 +:10161000F12C8E010F5F1F4F30E020E0452D61E07F +:10162000C60109950FB6F894DEBF0FBECDBFD4CE6C +:1016300060E0812F0E940D01812F0E94B600082FCB +:10164000612FC7018C960E945A09FC01008310CFBC +:1016500061E0812F0E940D010BCF60E0812F0E947D +:101660000D01812F0E943E0103CF61E0812F0E9476 +:101670000D0161E0812F0E940D0160E0812F0E9429 +:10168000DF00F6CEFFEF6F1A7F0A11CF612FC50181 +:101690000E941109DC01ED91FC91E0818E2F90E018 +:1016A000FC01EE0FFF1FE80FF91FE85DFE4F808180 +:1016B0008F7B8083612FC5010E941109FC0180810D +:1016C00091810E949913612FC5010E94A40800CF47 +:1016D0008FEFF401808318CFB12CA12CF701E059D2 +:1016E000FF4FFF83EE834701F6E58F0E911C340117 +:1016F0002FE0620E711CAE81BF818D919C91A81666 +:10170000B90650F4B501C3010E940008FC018081B4 +:1017100018131EC0B7FE20C0B12CA12C3701F5E470 +:101720006F0E711C47012AE3820E911CD3018D912B +:101730009C91A816B90650F4B501C4010E94000896 +:10174000FC01808118132AC0B7FE2CC060E081CF55 +:10175000FFEFAF1ABF0ACFCF612FC4010E9411095A +:10176000DC01ED91FC91E0818E2F90E0FC01EE0F09 +:10177000FF1FE80FF91FE85DFE4F80818F7B80839C +:10178000612FC4010E941109FC01808191810E9496 +:101790009913612FC4010E94A408BECFFFEFAF1AB6 +:1017A000BF0AC4CFB12CA12CD3018D919C91A81656 +:1017B000B90660F6B501C4010E940008FC018081F1 +:1017C00018130BC0B501C701885B9F4F0E94980793 +:1017D000B501C4010E949807B9CFFFEFAF1ABF0A45 +:1017E000E3CF443079F0DC01ED91FC910084F18588 +:1017F000E02DF12CE12C10E000E023E030E0452D5D +:1018000062E0E8CDF70112819380DC011496ED903F +:10181000FC90612FC7010E9430080196C9F1612F29 +:10182000C7010E945B08FC0180819181029709F049 +:1018300042C001E0911001C000E0602F812F0E94A2 +:10184000DF00912C812C3701FDE86F0E711C22E81E +:10185000E20EF11CD3018D919C918816990668F5D2 +:10186000B401C7010E94CF051C830983DC01ED91FF +:10187000FC910480F581E02DAE014F5F5F4FBE010A +:101880006C5F7F4F02960995BFEF8B1A9B0AE2CFE0 +:1018900081E08D83D601ED91FC910084F185E02DEE +:1018A000EE24E394F12C8E010B5F1F4F30E020E01B +:1018B000452D62E0B5CE83E0ECCF80E0EACF433047 +:1018C00079F0DC01ED91FC910084F185E02DF12CA3 +:1018D000E12C10E000E023E030E0452D63E07ACD1C +:1018E000F7011281612FDC0114968D919C910E9469 +:1018F00021040097F1F001970297F0F4812F0E94E4 +:10190000B60021E0892B09F420E080E089832A8356 +:10191000D601ED91FC910084F185E02D02E0E02EEE +:10192000F12C8E010F5F1F4F30E020E0452D63E06A +:1019300077CE81E020E0EACF82E0FCCF443079F03E +:10194000DC01ED91FC910084F185E02DF12CE12C7E +:1019500010E000E023E030E0452D64E03BCDF701EE +:101960001281DC0114968D909C90612FC4010E941D +:101970002104009799F481E08983D601ED91FC91CF +:101980000084F185E02DEE24E394F12C8E010F5FAD +:101990001F4F30E020E0452D64E042CE049711F067 +:1019A00083E0EACFF7010381612FC4010E94300870 +:1019B000019609F3612FC4010E945B08DC018D913F +:1019C0009C91049769F7E02EF12C61E0812F0E9431 +:1019D0000D01E114F10429F460E0812F0E94DF0081 +:1019E0002BC0BFEFEB16F10411F461E0F6CFE12F4D +:1019F000F0E0E255FF4FE491E33029F148F4E130A3 +:101A0000B9F0E230D9F0E0E8EE16F10474F7E4CF73 +:101A1000E73019F1E83049F1E430A9F7809180000E +:101A2000806280938000F0928B00E0928A0004C074 +:101A300084B5806884BD07BD80E09ECF84B5806298 +:101A400084BD08BDF9CF80918000806880938000BC +:101A5000F0928900E0928800EFCF8091B00080681A +:101A60008093B0000093B300E7CF8091B000806214 +:101A70008093B0000093B400DFCF433079F0DC01F5 +:101A8000ED91FC910084F185E02DF12CE12C10E02A +:101A900000E023E030E0452D65E09CCCF7011281A9 +:101AA000612FDC0114968D919C910E942104009776 +:101AB000E1F0039722E00297C8F4812F0E943E01D3 +:101AC00020E029839A838B83D601ED91FC910084D9 +:101AD000F185E02DB3E0EB2EF12C8E010F5F1F4F4F +:101AE00030E020E0452D65E09BCD21E080E090E0F6 +:101AF000E8CF443079F0DC01ED91FC910084F18570 +:101B0000E02DF12CE12C10E000E023E030E0452D49 +:101B100066E060CCF7011281DC0114968D909C90F8 +:101B2000612FC4010E942104009799F481E0898308 +:101B3000D601ED91FC910084F185E02DEE24E39433 +:101B4000F12C8E010F5F1F4F30E020E0452D66E045 +:101B500067CD059709F08AC0F701038184E0053B52 +:101B600030F7612FC4010E94300897FDDFCF612F4D +:101B7000C4010E945B08DC018D919C91059709F0DE +:101B800077C0B6E58B0E911C612FC4010E9411092C +:101B9000DC01ED91FC91E0818E2F90E0FC01EE0FD5 +:101BA000FF1FE80FF91FE85DFE4F808186FFBECF63 +:101BB000612FC4010E941109DC01ED91FC9110819B +:101BC0001C3008F051C0828148E5842E42E0942EFA +:101BD000881A910887FD93941401220C331C220C5F +:101BE000331C818168E8E62EF12CE81AF10887FDA4 +:101BF000F394EE0CFF1CEE0CFF1C37010F2C000CB5 +:101C0000880899089101032C000C440B550B2619E8 +:101C1000370948095909A02FB0E00E94AF1224EB00 +:101C200030E040E050E00E949012BA01A901460D58 +:101C3000571D681D791D4E155F052CF07101421569 +:101C400053050CF47A012FB7F894812F90E0B2E09D +:101C5000EB1AF108FC01EE0FFF1FE80FF91FE85D1A +:101C6000FE4FF282E1822FBF80E061CF82E05FCF42 +:101C700083E05DCFDC01ED91FC910084F185E02DE6 +:101C8000F12CE12C10E000E022E030E0452D099538 +:101C9000A3CB1F920F920FB60F9211242F933F9355 +:101CA0008F939F93AF93BF9380915F019091600159 +:101CB000A0916101B091620130915E0126E0230F95 +:101CC0002D3758F50296A11DB11D20935E0180931A +:101CD0005F0190936001A0936101B09362018091D4 +:101CE000630190916401A0916501B0916601019634 +:101CF000A11DB11D8093630190936401A0936501C0 +:101D0000B0936601BF91AF919F918F913F912F91B9 +:101D10000F900FBE0F901F90189529E8230F039680 +:101D2000A11DB11DD2CF1F920F920FB60F92112499 +:101D30002F933F934F935F936F937F938F939F93D3 +:101D4000AF93BF93EF93FF9387E691E00E942C023D +:101D5000FF91EF91BF91AF919F918F917F916F9183 +:101D60005F914F913F912F910F900FBE0F901F9059 +:101D700018951F920F920FB60F9211242F938F93E5 +:101D80009F93EF93FF93E0917701F0917801808129 +:101D9000E0917D01F0917E0182FD1BC090818091D8 +:101DA00080018F5F8F7320918101821741F0E09154 +:101DB0008001F0E0E959FE4F958F80938001FF91FB +:101DC000EF919F918F912F910F900FBE0F901F90C9 +:101DD00018958081F4CF1F920F920FB60F921124A5 +:101DE0002F933F934F935F936F937F938F939F9323 +:101DF000AF93BF93CF93DF93EF93FF9380914D0108 +:101E0000C0914C01D0E087FF24C010928500109251 +:101E1000840080914D018F5F80934D0180914D0131 +:101E2000082E000C990B8C179D0724F480914D010E +:101E30008C30C4F1809184009091850004968032AA +:101E40009E4408F47AC080918400909185000496A5 +:101E500076C080914D01082E000C990B8C179D07C0 +:101E6000C4F6E0914D018E2FEE0F990BFC01EE0FA1 +:101E7000FF1FE80FF91FE85DFE4F808186FFC9CF85 +:101E8000E0914D018E2FEE0F990BFC01EE0FFF1F1D +:101E9000E80FF91FE85DFE4F808160E08F730E94BC +:101EA000DF00B7CF2091840030918500E0914D0193 +:101EB0008E2FEE0F990BFC01EE0FFF1FE80FF91F9D +:101EC000E85DFE4F81819281820F931F909389007C +:101ED00080938800E0914D018E2FEE0F990BFC014D +:101EE000EE0FFF1FE80FF91FE85DFE4F808186FFB0 +:101EF00011C0E0914D018E2FEE0F990BFC01EE0FFA +:101F0000FF1FE80FF91FE85DFE4F808161E08F73CE +:101F10000E94DF00FF91EF91DF91CF91BF91AF91D0 +:101F20009F918F917F916F915F914F913F912F91F1 +:101F30000F900FBE0F901F90189580E29EE4909333 +:101F40008900809388008FEF80934D01E3CFCF927B +:101F5000DF92FF920F931F93CF93DF93E7E6F1E0B9 +:101F60001382128288EE93E0A0E0B0E08483958330 +:101F7000A683B7838AE191E09183808385EC90E02A +:101F80009587848784EC90E09787868780EC90E043 +:101F9000918B808B81EC90E0938B828B82EC90E034 +:101FA000958B848B86EC90E0978B868B118E128EAE +:101FB000138E148EC4E0D2E000E110E01F830E8384 +:101FC000CC24CA94DC2CD986C8861B870A87FF24B8 +:101FD000F394FC861E861D861A8B098BDC8ACB8ABD +:101FE0001E8B0D8BFF8A1C8E1B8E1A8E198F088FED +:101FF00080E190E00E94FD12988B8F8718A30F8FCD +:10200000DAA2C9A21CA30BA3FDA21BA61AA619A69D +:1020100018A61FA30EA380E290E00E94FD129E8FDF +:102020008D8F198218821D830C831BAB0AABDDAA2E +:10203000CCAA1FAB0EABF8AE19AE1DAF0CAFDFAE26 +:10204000CEAE1093450200934402F09246021092E5 +:102050004B0210924A0210924902109348020093D8 +:10206000470280E190E00E94FD129BAF8AAF10937F +:102070004F0200934E02D0925102C0925002109330 +:10208000530200935202F09254021092590210929D +:10209000580210925702109356020093550280E1A5 +:1020A00090E00E94FD1290934D0280934C021DA679 +:1020B0001CA619AB08AB1093610200936002D0928A +:1020C0006302C09262021093650200936402F09270 +:1020D0006602109268021092670210936C020093DD +:1020E0006B02D0926E02C0926D0210937002009348 +:1020F0006F02F092710210927602109275021092A5 +:102100007402109373020093720280E190E00E94C7 +:10211000FD1290936A028093690210937A020093F1 +:102120007902D0927C02C0927B0210937E020093CF +:102130007D02F0927F02109285021092840210922A +:10214000830210928202109381020093800280E247 +:1021500090E00E94FD129093780280937702109293 +:102160005B0210925A0210935F0200935E0210937A +:10217000890200938802D0928B02C0928A02109347 +:102180008D0200938C02F0928E02109294021092B3 +:102190009302109292021092910210939002009377 +:1021A0008F0280E190E00E94480490938702809320 +:1021B0008602DF91CF911F910F91FF90DF90CF901A +:1021C0000895CF93DF93CDB7DEB760970FB6F8943D +:1021D000DEBF0FBECDBF789484B5826084BD84B568 +:1021E000816084BD85B5826085BD85B5816085BD12 +:1021F00080916E00816080936E00109281008091CA +:102200008100826080938100809181008160809351 +:102210008100809180008160809380008091B10076 +:1022200084608093B1008091B00081608093B000A1 +:1022300080917A00846080937A0080917A00826035 +:1022400080937A0080917A008E7F80937A008091CB +:102250007A00806880937A001092C10088E091E053 +:102260000E94FD128C018AE091E0D80111969C93A6 +:102270008E9387E691E013969C938E93129784E059 +:1022800092E015969C938E931497F801EB5FFE4FA6 +:102290001082319610823196108280915401811102 +:1022A00015C08CED92E090934F0180934E018DEA22 +:1022B00091E090935101809350018BEB92E09093C9 +:1022C00053018093520181E0809354018EE491E0A8 +:1022D0009A8389831C830B83CE0101960E9481051A +:1022E000CE0101960E94160410935D0100935C01DB +:1022F00061E08DE00E940D0161E08DE00E94DF0051 +:102300000E94780160E08DE00E94DF000E94780169 +:1023100061E08DE00E94DF000E94780160E08DE0C6 +:102320000E94DF0060E08DE00E940D01D80112964E +:10233000ED91FC91A089B18982E08C93A485B5854B +:102340001C92A685B78588E08C93108EA489B589E8 +:1023500086E08C93A289B3898C9180618C93A28949 +:10236000B3898C9188608C93A289B3898C918068A1 +:102370008C930288F389E02D80818F7D80830E9479 +:10238000780130E020E050E040E060EF70E0C8010C +:102390000E94E60280E0A82E80E0B82E6EE372E094 +:1023A000CE0101960E946904F12CE12C8C859D855B +:1023B000E816F90608F04FC0B701CE0101960E9459 +:1023C0000008FC011081612F84E092E00E945B080C +:1023D000DC018D919C910197D1F5812F0E94B6006F +:1023E000082F612F80E392E00E945A09FC0180814E +:1023F000081769F1612F80E392E00E945A09DC011D +:102400000C93D12CC12C8091910290919202C8160C +:10241000D906E8F4B60186E892E00E94CF05188B51 +:1024200021E0013009F020E02F87DC01ED91FC91E3 +:102430000480F581E02DAE01415F5F4FBE01605F1A +:102440007F4F02960995BFEFCB1ADB0ADCCFEFEF87 +:10245000EE1AFE0AABCFCE0101960E94A3090091AD +:102460005C0110915D01D80112968D919C91DC0167 +:10247000ED91FC910084F185E02D0995892BA1F067 +:10248000F80182819381DC01ED91FC910284F38556 +:10249000E02D0995D801ED91FC910190F081E02D9E +:1024A000682FC8010995DFCFA114B10409F476CFD4 +:1024B0000E941802882309F471CF0E9400006ECF99 +:1024C0008091860290918702009731F00E94B504B6 +:1024D000109287021092860283E992E00E9416040D +:1024E0008091770290917802009711F00E949913E1 +:1024F00089E692E00E94A3098CE492E00E94A3097D +:102500008EE392E00E94A309809121029091220221 +:10251000009711F00E94991383E192E00C94A309B3 +:10252000052E97FB1EF400940E94A71257FD07D0BA +:102530000E94BA1207FC03D04EF40C94A7125095D7 +:102540004095309521953F4F4F4F5F4F089590959F +:102550008095709561957F4F8F4F9F4F08950E9492 +:10256000DC12A59F900DB49F900DA49F800D911D2E +:1025700011240895A1E21A2EAA1BBB1BFD010DC058 +:10258000AA1FBB1FEE1FFF1FA217B307E407F50723 +:1025900020F0A21BB30BE40BF50B661F771F881FFF +:1025A000991F1A9469F760957095809590959B0195 +:1025B000AC01BD01CF010895A29FB001B39FC0013E +:1025C000A39F700D811D1124911DB29F700D811D5F +:1025D0001124911D0895991B79E004C0991F961745 +:1025E00008F0961B881F7A95C9F780950895EE0F1D +:1025F000FF1F0590F491E02D09940F931F93CF9343 +:10260000DF938230910510F482E090E0E0919F0228 +:10261000F091A00230E020E0B0E0A0E0309799F423 +:102620002115310509F44AC0281B390B2430310526 +:10263000D8F58A819B816115710589F1FB0193832E +:102640008283FE0111C040815181028113814817AC +:102650005907E0F04817590799F4109761F012965E +:102660000C93129713961C933296CF01DF91CF9162 +:102670001F910F91089500939F021093A002F4CF31 +:102680002115310551F04217530738F0A901DB013C +:102690009A01BD01DF01F801C1CFEF01F9CF90939D +:1026A000A00280939F02CDCFFE01E20FF31F819322 +:1026B00091932250310939832883D7CF20919D02ED +:1026C00030919E02232B41F42091020130910301AD +:1026D00030939E0220939D022091000130910101D0 +:1026E0002115310541F42DB73EB7409104015091B9 +:1026F0000501241B350BE0919D02F0919E02E2172B +:10270000F307A0F42E1B3F0B2817390778F0AC0114 +:102710004E5F5F4F2417350748F04E0F5F1F5093F1 +:102720009E0240939D02819391939FCFF0E0E0E061 +:102730009CCFCF93DF930097E9F0FC01329713828F +:102740001282A0919F02B091A002ED0130E020E042 +:102750001097A1F420813181820F931F20919D0257 +:1027600030919E022817390709F061C0F0939E024C +:10277000E0939D02DF91CF910895EA01CE17DF0724 +:10278000E8F54A815B819E0141155105B1F7E901E8 +:10279000FB83EA8349915991C40FD51FEC17FD07BC +:1027A00061F4808191810296840F951FE9019983DC +:1027B0008883828193819B838A83F0E0E0E0129694 +:1027C0008D919C9113970097B9F52D913C9111979C +:1027D000CD010296820F931F20919D0230919E029F +:1027E0002817390739F6309751F51092A002109248 +:1027F0009F02B0939E02A0939D02BCCFD383C2835D +:1028000040815181840F951FC817D90761F44E5F2D +:102810005F4F88819981480F591F518340838A8176 +:102820009B81938382832115310509F0B0CFF0930A +:10283000A002E0939F029ECFFD01DC01C0CF138276 +:102840001282D7CF10E0C2E6D0E004C0FE010E94A1 +:0E285000F7122196C336D107C9F7F894FFCFCF +:10285E000000A102800000000000C2039C0391034F +:10286E00AB093903E602000000004E02AE01DB01A7 +:08287E009B020C02EA01FE01BD +:00000001FF diff --git a/owlet/firmware/arduino-mini-pro-3v/release.json b/owlet/firmware/arduino-mini-pro-3v/release.json new file mode 100644 index 000000000..03bdde17f --- /dev/null +++ b/owlet/firmware/arduino-mini-pro-3v/release.json @@ -0,0 +1,4 @@ +{ + "firmwareFile": "firmware.hex", + "version": "0.0.2" +} diff --git a/owlet/firmware/arduino-mini-pro-5v/firmware.hex b/owlet/firmware/arduino-mini-pro-5v/firmware.hex new file mode 100644 index 000000000..d64a90001 --- /dev/null +++ b/owlet/firmware/arduino-mini-pro-5v/firmware.hex @@ -0,0 +1,651 @@ +:100000000C9463000C948B000C948B000C948B006C +:100010000C948B000C948B000C948B000C948B0034 +:100020000C948B000C948B000C948B000C94ED0EB4 +:100030000C948B000C948B000C948B000C948B0014 +:100040000C944B0E0C948B000C94BB0E0C94950EE0 +:100050000C948B000C948B000C948B000C948B00F4 +:100060000C948B000C948B000000000024002700EF +:100070002A0000000000250028002B0000000000DE +:1000800023002600290004040404040404040202DA +:100090000202020203030303030301020408102007 +:1000A0004080010204081020010204081020000012 +:1000B0000008000201000003040700000000000027 +:1000C0000000A90F621211241FBECFEFD8E0DEBFDF +:1000D000CDBF11E0A0E0B1E0E2E6F8E202C0059099 +:1000E0000D92A832B107D9F722E0A8E2B1E001C031 +:1000F0001D92A13AB207E1F710E0C2E6D0E004C0D9 +:100100002197FE010E94F912C136D107C9F70E945A +:10011000E3100C9424140C940000833081F028F434 +:10012000813099F08230A9F008958730A9F08830A5 +:10013000C9F08430B1F4809180008F7D03C080913C +:1001400080008F7780938000089584B58F7784BD79 +:10015000089584B58F7DFBCF8091B0008F77809319 +:10016000B00008958091B0008F7DF9CFCF93DF93D9 +:10017000282F30E0F901E255FF4F8491F901E6564E +:10018000FF4FD491F901EA57FF4FC491CC23A1F05E +:1001900081110E948D00EC2FF0E0EE0FFF1FE4585C +:1001A000FF4FA591B491EC91ED2381E090E009F42B +:1001B00080E0DF91CF91089580E090E0FACF1F9327 +:1001C000CF93DF93282F30E0F901E255FF4F849160 +:1001D000F901E656FF4FD491F901EA57FF4FC49158 +:1001E000CC23A9F0162F81110E948D00EC2FF0E096 +:1001F000EE0FFF1FEE58FF4FA591B4918FB7F89403 +:10020000EC91111108C0D095DE23DC938FBFDF91F4 +:10021000CF911F910895DE2BF8CFCF93DF9390E01D +:10022000FC01E656FF4F24918A579F4FFC018491B1 +:100230008823D1F090E0880F991FFC01E859FF4F07 +:10024000A591B491FC01EE58FF4FC591D491611175 +:100250000EC09FB7F8948C91E22FE0958E238C937B +:100260002881E223E8839FBFDF91CF9108958FB764 +:10027000F894EC91E22BEC938FBFF6CF8E3008F020 +:100280008E508770806480937C0080917A008064B7 +:1002900080937A0080917A0086FDFCCF809178006F +:1002A0009091790008953FB7F894809163019091FF +:1002B0006401A0916501B091660126B5A89B05C0B7 +:1002C0002F3F19F00196A11DB11D3FBFBA2FA92FD5 +:1002D000982F8827BC01CD01620F711D811D911DD2 +:1002E00042E0660F771F881F991F4A95D1F708953E +:1002F0008F929F92AF92BF92CF92DF92EF92FF9236 +:100300000E9453014B015C0184E6C82ED12CE12CE4 +:10031000F12C0E945301681979098A099B09683EEA +:10032000734081059105A8F321E0C21AD108E108C4 +:10033000F10888EE880E83E0981EA11CB11CC11440 +:10034000D104E104F10429F7FF90EF90DF90CF9002 +:10035000BF90AF909F908F9008950895AF92BF92F5 +:10036000CF92DF92EF92FF920F931F93CF93DF9381 +:100370006C017B018B01040F151FEB015E01AE18B0 +:10038000BF08C017D10759F06991D601ED91FC91D2 +:100390000190F081E02DC6010995892B79F7C501FF +:1003A000DF91CF911F910F91FF90EF90DF90CF9051 +:1003B000BF90AF900895FC01538D448D252F30E000 +:1003C000842F90E0821B930B541710F0CF96089562 +:1003D00001970895FC01918D828D981761F0A28D8F +:1003E000AE0FBF2FB11D5D968C91928D9F5F9F7355 +:1003F000928F90E008958FEF9FEF0895FC01918D0B +:10040000828D981731F0828DE80FF11D858D90E077 +:1004100008958FEF9FEF0895FC01918D228D892F14 +:1004200090E0805C9F4F821B91098F7399270895FC +:1004300087E691E00E940C0221E0892B09F420E07C +:10044000822F089580E090E0892B29F00E94180205 +:1004500081110C9400000895FC01A48DA80FB92F00 +:10046000B11DA35ABF4F2C91848D90E001968F73DC +:100470009927848FA689B7892C93A089B1898C91FB +:10048000837080648C93938D848D981306C002884A +:10049000F389E02D80818F7D80830895EF92FF9214 +:1004A0000F931F93CF93DF93EC0181E0888F9B8D97 +:1004B0008C8D98131AC0E889F989808185FF15C051 +:1004C0009FB7F894EE89FF896083E889F989808174 +:1004D0008370806480839FBF81E090E0DF91CF9143 +:1004E0001F910F91FF90EF900895F62E0B8D10E065 +:1004F0000F5F1F4F0F731127E02E8C8D8E110CC0D4 +:100500000FB607FCFACFE889F989808185FFF5CF1E +:10051000CE010E942C02F1CFEB8DEC0FFD2FF11DCF +:10052000E35AFF4FF0829FB7F8940B8FEA89FB895B +:1005300080818062CFCFCF93DF93EC01888D8823B9 +:10054000B9F0AA89BB89E889F9898C9185FD03C036 +:10055000808186FD0DC00FB607FCF7CF8C9185FF1B +:10056000F2CF808185FFEDCFCE010E942C02E9CF32 +:10057000DF91CF910895CF93DF9300D0CDB7DEB751 +:10058000DA012C91FB01308139832A83DC018D91C2 +:100590009C91DC01ED91FC910284F385E02D22E039 +:1005A00030E0AE014F5F5F4F61EF70E009950F9053 +:1005B0000F90DF91CF9108956115710531F0FC0125 +:1005C00080819181FB01918380830895CF92DF9296 +:1005D000EF92FF920F931F93CF93DF93EC01162FAF +:1005E0006A017901E881F9810280F381E02D41E01F +:1005F00060EC0995E881F9810280F381E02D40E00B +:10060000612FCE010995E881F9810280F381E02D07 +:10061000DE01A95FBE4F6C9181E0860F8C9340E0B4 +:10062000CE0109958601EC0CFD1CE881F981028060 +:10063000F381E02DE016F10639F0D8016D918D01BE +:1006400040E0CE010995F1CF41E060ECCE01099583 +:100650008A819B81DC01ED91FC910680F781E02D80 +:10066000DF91CF911F910F91FF90EF90DF90CF908E +:100670000994BF92CF92DF92EF92FF920F931F9354 +:10068000CF93DF93EC01B62EC42ED22EE881F981F0 +:100690000280F381E02D41E060EC0995E881F98169 +:1006A0000280F381E02D40E06B2DCE010995E881B9 +:1006B000F9810280F381E02D40E06C2DCE01099597 +:1006C000E881F9810280F381E02D40E06D2DCE01BB +:1006D00009956801E00EF11EE881F9810280F3813D +:1006E000E02DEC14FD0439F0D6016D916D0140E070 +:1006F000CE010995F1CF41E060ECCE0109958A81E8 +:100700009B81DC01ED91FC910680F781E02DDF916A +:10071000CF911F910F91FF90EF90DF90CF90BF90FE +:100720000994DC0112968D919C91DC01ED91FC9174 +:100730000190F081E02D0994CF93DF93DC01ED91DE +:10074000FC910480F581E02D442319F0DF91CF91D5 +:100750000994EC01603C21F06B3D59F0CE01F6CFDD +:100760006BED0995E881F9810480F581E02D6CED50 +:10077000F5CF6BED0995E881F9810480F581E02DD5 +:100780006DEDECCF0F931F93CF93DF93EC01CA5F16 +:10079000DE4F2881222321F06C3D49F06D3D09F1A7 +:1007A000603C59F16B3D81F481E088833AC0DC0103 +:1007B000AB5FBE4FEC9121E02E0F2C93E80FF92F89 +:1007C000F11D20EC26831882FC01EB5FFE4F208197 +:1007D00031E0320F3083820F911DDC0116966C934D +:1007E00020C0DC01AB5FBE4FEC9121E02E0F2C93BB +:1007F000E80FF92FF11D2BEDE5CF8C010B5F1E4F9C +:10080000D8014C91442351F0BC016A5F7F4FDC0159 +:10081000ED91FC910680F781E02D0995F801108299 +:100820001882DF91CF911F910F910895DC01ED9116 +:10083000FC91309729F00280F381E02D0296099413 +:100840000895FC01828D938D30E020E02817390750 +:10085000E1F0A785B089A20FB31F4C91641312C0B9 +:1008600080A591A52817390718F082A593A50895AA +:10087000220F331F858D968D280F391FF901808136 +:10088000918108952F5F3F4FE1CF8585968508952B +:10089000CF93DF93EC01CD3C8CE0D807A0F42AE0A5 +:1008A0002C9FC0012D9F900D112402960E94FF12D3 +:1008B000FC01C193D193CF012197D7FD07C01182CD +:1008C00010823A96F9CF8FEF9FEFF0CFDF91CF9163 +:1008D0000895EF92FF920F931F93CF93DF93EC0154 +:1008E0008B0180E190E09F838E8381E088871D8665 +:1008F000FB01E184F284C7010E94FF12998388837F +:10090000892B61F1F801828193819B838A838481A1 +:1009100095819D838C83868197819F838E8380853B +:100920008887FA86E986838594859C878B87858569 +:100930008D8790E080E02B853C858217930770F4CB +:10094000E0913E02F0913F02E80FF91F2081E8811B +:10095000F981E80FF91F20830196EDCFDF91CF9148 +:100960001F910F91FF90EF900895EF92FF920F93D8 +:100970001F93CF93DF930097C1F1EC01FC013297F5 +:10098000808191812AE0289F8001299F100D1124E8 +:100990000C0F1D1F7801CE15DF0539F08AE0E81A2B +:1009A000F108C7010E941604F6CFC8018C1B9D0BED +:1009B000969587954DEC5CE4849F9001859F300D62 +:1009C000949F300D11243F7746EF4203C001439FAF +:1009D000900D11240297800F911FDF91CF911F91ED +:1009E0000F91FF90EF900C949B13DF91CF911F918B +:1009F0000F91FF90EF9008952F923F924F925F9248 +:100A00006F927F928F929F92AF92BF92CF92DF921E +:100A1000EF92FF920F931F93CF93DF938C016B01A3 +:100A2000FC01C481D58181859285C617D707B8F4AA +:100A3000C817D907A9F480E0DF91CF911F910F91DA +:100A4000FF90EF90DF90CF90BF90AF909F908F90EE +:100A50007F906F905F904F903F902F900895EB01A3 +:100A6000F8012085211105C08C179D0738F081E021 +:100A7000E3CF6E018C179D0708F46C011E012097CF +:100A800019F480E1282E312CC1010E9448043C0158 +:100A9000009789F27C01512C412CF80180809180D3 +:100AA000C414D504E9F05701A618B708C7010E947D +:100AB0001604E114F10469F0F401EA0DFB1D8191C3 +:100AC0009191D7018D939D9388E001900D928A9525 +:100AD000E1F7FFEF4F1A5F0A8AE0E80EF11CDDCF65 +:100AE000C4010E94B504F8017182608221863286B9 +:100AF00083859485C817D90708F0B9CFD487C387F1 +:100B0000B6CF0F931F93CF93DF938C0160918F0229 +:100B100070919002809191029091920286179707AE +:100B2000F8F420919102309192024AE0429FC00174 +:100B3000439F900D1124C0918602D0918702C80F67 +:100B4000D91FCE010E9416042097E9F480919102EA +:100B500090919202019690939202809391020EC01E +:100B600080918C0290918D02009741F0680F791F5F +:100B700086E892E00E94FC048111D3CFDF91CF91EF +:100B80001F910F910895F80181919191DE018D934C +:100B90009D9388E001900D928A95E1F7D7CF0F934E +:100BA0001F93CF93DF93EC018B0169857A8506173C +:100BB000170738F08E819F81680F791FCE010E9440 +:100BC000FC0489859A852B853C850217130740F024 +:100BD0008017910740F098012F5F3F4F3C872B878C +:100BE0000817190738F0CE010D96DF91CF911F91AC +:100BF0000F9108958AE0809F9001819F300D11240C +:100C000088819981820F931FF0CFAF92BF92CF92CC +:100C1000DF92EF92FF920F931F93CF93DF938C019C +:100C20007B01FC01C481D58181859285C617D707D8 +:100C300078F4C817D90769F480E0DF91CF911F914C +:100C40000F91FF90EF90DF90CF90BF90AF900895FD +:100C5000EB01F8012085211105C08C179D0738F0A4 +:100C600081E0EBCF7E018C179D0708F47C01209773 +:100C700021F16E018FEF9FEFC115F0E4DF0718F44B +:100C8000C601880F991F0E94FF125C010097A1F214 +:100C9000DC01F8018081918130E020E0E216F3066A +:100CA00081F0F901EE0FFF1FE80FF91F408151811C +:100CB0004D935D932F5F3F4FF1CF60E1C62ED12C56 +:100CC000DFCF009711F00E949B13F801B182A08240 +:100CD000D286C18683859485C817D90708F6D4873C +:100CE000C387BECF0F931F93CF93DF93EC018B018C +:100CF00069857A850617170738F08E819F81680FFE +:100D0000791FCE010E94050689859A852B853C8531 +:100D10000217130740F08017910740F098012F5FEA +:100D20003F4F3C872B870817190738F0CE010D96E7 +:100D3000DF91CF911F910F910895000F111F8881AE +:100D40009981800F911FF4CF8F929F92AF92BF92A3 +:100D5000CF92DF92EF92FF920F931F93CF93DF9387 +:100D6000EC017B0189859A856817790760F0CE8050 +:100D7000DF80C80ED91E0C811D810C151D0528F5BC +:100D80008017910719F589859A852B853C85E21690 +:100D9000F30640F08E159F0548F097012F5F3F4FF7 +:100DA0003C872B87E816F90608F458C0CE010D964B +:100DB000DF91CF911F910F91FF90EF90DF90CF9037 +:100DC000BF90AF909F908F90089586012885211144 +:100DD00027C080179107B8F60115110539F15801A0 +:100DE000011580E4180730F5C501880F991F0E948E +:100DF000FF124C01009739F2DC018881998130E0C3 +:100E000020E0C216D306C9F0F901EE0FFF1FE80F6C +:100E1000F91F408151814D935D932F5F3F4FF1CF7B +:100E20006C0108171907C0F66801D6CF60E1A62E3D +:100E3000B12CDACF8FEF9FEFDACF009711F00E943D +:100E40009B1399828882BA86A9868B859C85081710 +:100E5000190708F098CF1C870B8795CFEE0CFF1C65 +:100E6000888199818E0D9F1DA3CFAF92BF92CF92A3 +:100E7000DF92EF92FF920F931F93CF93DF938C013A +:100E80007B01DC011496CD91DC91159719968D911B +:100E90009C91C617D70778F4C817D90769F480E082 +:100EA000DF91CF911F910F91FF90EF90DF90CF9046 +:100EB000BF90AF900895EB01F8012085211105C086 +:100EC0008C179D0738F081E0EBCF7E018C179D07D2 +:100ED00008F47C016E01209719F480E1C82ED12C12 +:100EE000C6010E94FF125C010097C9F2FC01D80103 +:100EF0008D919C9130E020E0E216F30641F0DC0198 +:100F0000A20FB31F4C9141932F5F3F4FF5CF009736 +:100F100011F00E949B13F801B182A082C186D28693 +:100F200083859485C817D90770F6D487C387CBCF3C +:100F3000CF93FC0183859485C0E06817790750F54D +:100F40008385948501976817790778F4808191816A +:100F50009B012F5F3F4FDC01A20FB31F4C91680F25 +:100F6000791FDB014C93B901EBCF94878387C08550 +:100F7000CC2399F04185528526813781BA01621BC5 +:100F8000730B8617970730F42417350718F4CF0131 +:100F90000E9435078C2FCF910895C1E0FBCF0F93AE +:100FA0001F93CF93DF93EC018B0169857A858B8545 +:100FB0009C8586179707A8F4F8018081E881F9815C +:100FC0002B853C85E20FF31F80832B853C85C9016F +:100FD00001969C878B87C901DF91CF911F910F915B +:100FE00008958E819F81009719F48FEF9FEFF4CFC2 +:100FF000680F791FCE010E9435078111DDCFF5CF33 +:101000000F931F93CF93DF93EC018B0169857A8552 +:101010000617170738F08E819F81680F791FCE0160 +:101020000E94350789859A852B853C850217130711 +:1010300040F08017910740F098012F5F3F4F3C87A9 +:101040002B870817190738F0CE010D96DF91CF9145 +:101050001F910F91089588819981800F911FF6CF7C +:10106000CF92DF92FF920F931F93CF93DF938C0168 +:10107000F62ED0E0C0E06C018FE0C80ED11CF80164 +:10108000828D938DC817D90798F4BE01C6010E94BE +:101090000008FC0180818F1109C0CE01DF91CF9142 +:1010A0001F910F91FF90DF90CF9008952196E7CF89 +:1010B0008FEF9FEFF3CFCF92DF92EF92FF920F93DC +:1010C0001F93CF93DF931F92CDB7DEB78C01698357 +:1010D000F12CE12C6C018FE0C80ED11CF801828D3F +:1010E000938DE816F90698F4B701C6010E9400082E +:1010F000FC0190818981981306C0B701C8014D9603 +:101100000E94A4060EC0FFEFEF1AFF0AE7CFBE0150 +:101110006F5F7F4FC6010E94CF0797FF0CC0C801C9 +:101120000D960F90DF91CF911F910F91FF90EF904F +:10113000DF90CF900895F801208131812F5F3F4FDC +:1011400031832083BC01DACFCF92DF92EF92FF92FE +:101150000F931F93CF93DF938C01D62ED0E0C0E086 +:101160007C018FE0E80EF11CD8015A968D919C917C +:10117000C817D90708F052C0BE01C7010E94000875 +:10118000FC0180818D1148C0D80198968D919C9169 +:10119000C817D90798F5AE01440F551FBE01019736 +:1011A000FA0132966817790790F4D8015D962D916F +:1011B0003C916F5F7F4FD901AE0FBF1FCD90DC9088 +:1011C000240F351FD901CD92DC92AF01E9CFF80190 +:1011D00091A780A725A1222389F046A157A123A189 +:1011E00034A1BA01621B730B8617970738F42417D2 +:1011F000350720F4C8014D960E940506BE01C701BF +:101200000E949807CE01DF91CF911F910F91FF901F +:10121000EF90DF90CF9008952196A6CF8FEF9FEFAC +:10122000F2CFCF92DF92EF92FF920F931F93CF9363 +:10123000DF931F92CDB7DEB78C016983F12CE12CCF +:101240006C018FE0C80ED11CF801828D938DE816D9 +:10125000F90698F4B701C6010E940008FC019081CC +:101260008981981306C0B701C8014D960E94720685 +:101270000EC0FFEFEF1AFF0AE7CFBE016F5F7F4F8F +:10128000C6010E94CF0797FF0CC0C8010D960F90B2 +:10129000DF91CF911F910F91FF90EF90DF90CF9052 +:1012A0000895F801208131812F5F3F4F31832083E2 +:1012B000BC01DACFCF92DF92EF92FF920F931F9390 +:1012C000CF93DF931F92CDB7DEB78C016983F12CEA +:1012D000E12C6C018EE0C80ED11CF801818D928D3D +:1012E000E816F90698F4B701C6010E940008FC014F +:1012F00090818981981306C0B701C8014C960E945D +:1013000000080EC0FFEFEF1AFF0AE7CFBE016F5FC4 +:101310007F4FC6010E94CF0797FF0CC0C8010D96F2 +:101320000F90DF91CF911F910F91FF90EF90DF9081 +:10133000CF900895F801208131812F5F3F4F318395 +:101340002083BC01DACFFC0180819181009711F0EC +:101350000C949B1308952F923F925F926F927F920D +:101360008F929F92AF92BF92CF92DF92EF92FF92B5 +:101370000F931F93CF93DF93CDB7DEB729970FB6A7 +:10138000F894DEBF0FBECDBF6C017B01DB016C9119 +:1013900011965C90673008F06FC4E62FF0E0ED52D4 +:1013A000F64F0C94F912DA09100AF10B5F0C9E0C3F +:1013B0003D0D790DDC01ED91FC910084F185E02D6E +:1013C000423011F1F12CE12C10E000E023E030E09C +:1013D000452D60E0C601099529960FB6F894DEBF49 +:1013E0000FBECDBFDF91CF911F910F91FF90EF9076 +:1013F000DF90CF90BF90AF909F908F907F906F9035 +:101400005F903F902F90089519821A824B8333E0AA +:10141000E32EF12C8E010F5F1F4F30E020E0D8CF7C +:10142000EDB7FEB7F987E887443079F0DC01ED913C +:10143000FC910084F185E02DF12CE12C10E000E01E +:1014400023E030E0452D61E0C5CFF70112818381B3 +:10145000282E312CD6011496ED90FC90823009F4A0 +:10146000F7C078F4882309F437C1813009F4E0C06B +:10147000612FC7010E945B08DC012D923C9280E045 +:10148000BEC0843009F4F1C008F4E7C0853081F7AC +:101490005701F6E5AF0EB11C712C612CC7018059C4 +:1014A0009F4F9F838E8345019FE0890E911CAE81E3 +:1014B000BF818D919C916816790650F4B301C401E7 +:1014C0000E940008FC0180811813DCC077FEDEC09A +:1014D00083E090E00E94FF124C0180914C018C301F +:1014E00008F0F6C091E0980F90934C01D4018C93D2 +:1014F00090E0FC01EE0FFF1FE80FF91FE85DFE4FC3 +:1015000088EB9BE092838183612FC5010E941109C2 +:10151000DC018D929C92612FC5010E941109FC0192 +:1015200080809180D4018C918C3008F055C061E0AE +:10153000812F0E940D01F4018081282F30E0F901F4 +:10154000EE0FFF1FE20FF31FE85DFE4F9081907CCE +:10155000212F2F73922B9083D40111961C921197F7 +:1015600012961C922CE0622F0E94ED12829FB00115 +:10157000112430E020E0AB01420F531FFA01EE0FBF +:10158000FF1FE40FF51FE85DFE4F908196FD16C02A +:101590002F5F3F4F2C30310571F781110FC0109232 +:1015A000800082E080938100109285001092840078 +:1015B000B19A80916F00826080936F00D401EC91AA +:1015C0008E2F90E0FC01EE0FFF1FE80FF91FE85D82 +:1015D000FE4F808180648083F40180818F3F09F019 +:1015E00047CF612FC5010E941109DC018D919C91AB +:1015F0000E949B13612FC5010E94A40885E0898386 +:10160000D601ED91FC910084F185E02DEE24E39468 +:10161000F12C8E010F5F1F4F30E020E0452D61E07F +:10162000C60109950FB6F894DEBF0FBECDBFD4CE6C +:1016300060E0812F0E940D01812F0E94B600082FCB +:10164000612FC7018C960E945A09FC01008310CFBC +:1016500061E0812F0E940D010BCF60E0812F0E947D +:101660000D01812F0E943E0103CF61E0812F0E9476 +:101670000D0161E0812F0E940D0160E0812F0E9429 +:10168000DF00F6CEFFEF6F1A7F0A11CF612FC50181 +:101690000E941109DC01ED91FC91E0818E2F90E018 +:1016A000FC01EE0FFF1FE80FF91FE85DFE4F808180 +:1016B0008F7B8083612FC5010E941109FC0180810D +:1016C00091810E949B13612FC5010E94A40800CF45 +:1016D0008FEFF401808318CFB12CA12CF701E059D2 +:1016E000FF4FFF83EE834701F6E58F0E911C340117 +:1016F0002FE0620E711CAE81BF818D919C91A81666 +:10170000B90650F4B501C3010E940008FC018081B4 +:1017100018131EC0B7FE20C0B12CA12C3701F5E470 +:101720006F0E711C47012AE3820E911CD3018D912B +:101730009C91A816B90650F4B501C4010E94000896 +:10174000FC01808118132AC0B7FE2CC060E081CF55 +:10175000FFEFAF1ABF0ACFCF612FC4010E9411095A +:10176000DC01ED91FC91E0818E2F90E0FC01EE0F09 +:10177000FF1FE80FF91FE85DFE4F80818F7B80839C +:10178000612FC4010E941109FC01808191810E9496 +:101790009B13612FC4010E94A408BECFFFEFAF1AB4 +:1017A000BF0AC4CFB12CA12CD3018D919C91A81656 +:1017B000B90660F6B501C4010E940008FC018081F1 +:1017C00018130BC0B501C701885B9F4F0E94980793 +:1017D000B501C4010E949807B9CFFFEFAF1ABF0A45 +:1017E000E3CF443079F0DC01ED91FC910084F18588 +:1017F000E02DF12CE12C10E000E023E030E0452D5D +:1018000062E0E8CDF70112819380DC011496ED903F +:10181000FC90612FC7010E9430080196C9F1612F29 +:10182000C7010E945B08FC0180819181029709F049 +:1018300042C001E0911001C000E0602F812F0E94A2 +:10184000DF00912C812C3701FDE86F0E711C22E81E +:10185000E20EF11CD3018D919C918816990668F5D2 +:10186000B401C7010E94CF051C830983DC01ED91FF +:10187000FC910480F581E02DAE014F5F5F4FBE010A +:101880006C5F7F4F02960995BFEF8B1A9B0AE2CFE0 +:1018900081E08D83D601ED91FC910084F185E02DEE +:1018A000EE24E394F12C8E010B5F1F4F30E020E01B +:1018B000452D62E0B5CE83E0ECCF80E0EACF433047 +:1018C00079F0DC01ED91FC910084F185E02DF12CA3 +:1018D000E12C10E000E023E030E0452D63E07ACD1C +:1018E000F7011281612FDC0114968D919C910E9469 +:1018F00021040097F1F001970297F0F4812F0E94E4 +:10190000B60021E0892B09F420E080E089832A8356 +:10191000D601ED91FC910084F185E02D02E0E02EEE +:10192000F12C8E010F5F1F4F30E020E0452D63E06A +:1019300077CE81E020E0EACF82E0FCCF443079F03E +:10194000DC01ED91FC910084F185E02DF12CE12C7E +:1019500010E000E023E030E0452D64E03BCDF701EE +:101960001281DC0114968D909C90612FC4010E941D +:101970002104009799F481E08983D601ED91FC91CF +:101980000084F185E02DEE24E394F12C8E010F5FAD +:101990001F4F30E020E0452D64E042CE049711F067 +:1019A00083E0EACFF7010381612FC4010E94300870 +:1019B000019609F3612FC4010E945B08DC018D913F +:1019C0009C91049769F7E02EF12C61E0812F0E9431 +:1019D0000D01E114F10429F460E0812F0E94DF0081 +:1019E0002BC0BFEFEB16F10411F461E0F6CFE12F4D +:1019F000F0E0E255FF4FE491E33029F148F4E130A3 +:101A0000B9F0E230D9F0E0E8EE16F10474F7E4CF73 +:101A1000E73019F1E83049F1E430A9F7809180000E +:101A2000806280938000F0928B00E0928A0004C074 +:101A300084B5806884BD07BD80E09ECF84B5806298 +:101A400084BD08BDF9CF80918000806880938000BC +:101A5000F0928900E0928800EFCF8091B00080681A +:101A60008093B0000093B300E7CF8091B000806214 +:101A70008093B0000093B400DFCF433079F0DC01F5 +:101A8000ED91FC910084F185E02DF12CE12C10E02A +:101A900000E023E030E0452D65E09CCCF7011281A9 +:101AA000612FDC0114968D919C910E942104009776 +:101AB000E1F0039722E00297C8F4812F0E943E01D3 +:101AC00020E029839A838B83D601ED91FC910084D9 +:101AD000F185E02DB3E0EB2EF12C8E010F5F1F4F4F +:101AE00030E020E0452D65E09BCD21E080E090E0F6 +:101AF000E8CF443079F0DC01ED91FC910084F18570 +:101B0000E02DF12CE12C10E000E023E030E0452D49 +:101B100066E060CCF7011281DC0114968D909C90F8 +:101B2000612FC4010E942104009799F481E0898308 +:101B3000D601ED91FC910084F185E02DEE24E39433 +:101B4000F12C8E010F5F1F4F30E020E0452D66E045 +:101B500067CD059709F08CC0F701038184E0053B50 +:101B600030F7612FC4010E94300897FDDFCF612F4D +:101B7000C4010E945B08DC018D919C91059709F0DE +:101B800079C0B6E58B0E911C612FC4010E9411092A +:101B9000DC01ED91FC91E0818E2F90E0FC01EE0FD5 +:101BA000FF1FE80FF91FE85DFE4F808186FFBECF63 +:101BB000612FC4010E941109DC01ED91FC9110819B +:101BC0001C3008F053C0828148E5842E42E0942EF8 +:101BD000881A910887FD93941401220C331C220C5F +:101BE000331C818168E8E62EF12CE81AF10887FDA4 +:101BF000F394EE0CFF1CEE0CFF1C37010F2C000CB5 +:101C0000880899089101032C000C440B550B2619E8 +:101C1000370948095909A02FB0E00E94B11224EBFE +:101C200030E040E050E00E949212BA01A901460D56 +:101C3000571D681D791D4E155F052CF07101421569 +:101C400053050CF47A01B2E0EB1AF108EE0CFF1C1C +:101C50002FB7F894812F90E0FC01EE0FFF1FE80FE3 +:101C6000F91FE85DFE4FF282E1822FBF80E05FCF77 +:101C700082E05DCF83E05BCFDC01ED91FC910084DD +:101C8000F185E02DF12CE12C10E000E022E030E0C5 +:101C9000452D0995A1CB1F920F920FB60F921124DB +:101CA0002F933F938F939F93AF93BF9380915F0147 +:101CB00090916001A0916101B091620130915E014B +:101CC00023E0230F2D3758F50196A11DB11D209358 +:101CD0005E0180935F0190936001A0936101B093D6 +:101CE00062018091630190916401A0916501B091BE +:101CF00066010196A11DB11D80936301909364015B +:101D0000A0936501B0936601BF91AF919F918F91B0 +:101D10003F912F910F900FBE0F901F90189526E8BE +:101D2000230F0296A11DB11DD2CF1F920F920FB6A5 +:101D30000F9211242F933F934F935F936F937F9351 +:101D40008F939F93AF93BF93EF93FF9387E691E0B9 +:101D50000E942C02FF91EF91BF91AF919F918F91C3 +:101D60007F916F915F914F913F912F910F900FBE97 +:101D70000F901F9018951F920F920FB60F9211247B +:101D80002F938F939F93EF93FF93E0917701F091BF +:101D900078018081E0917D01F0917E0182FD1BC080 +:101DA0009081809180018F5F8F73209181018217D4 +:101DB00041F0E0918001F0E0E959FE4F958F80936A +:101DC0008001FF91EF919F918F912F910F900FBE06 +:101DD0000F901F9018958081F4CF1F920F920FB62D +:101DE0000F9211242F933F934F935F936F937F93A1 +:101DF0008F939F93AF93BF93CF93DF93EF93FF9313 +:101E000080914D01C0914C01D0E087FF24C0109219 +:101E100085001092840080914D018F5F80934D0169 +:101E200080914D01082E000C990B8C179D0724F40E +:101E300080914D018C30C4F1809184009091850097 +:101E4000049680349C4908F47AC080918400909173 +:101E50008500049676C080914D01082E000C990BE8 +:101E60008C179D07C4F6E0914D018E2FEE0F990B54 +:101E7000FC01EE0FFF1FE80FF91FE85DFE4F8081A8 +:101E800086FFC9CFE0914D018E2FEE0F990BFC011B +:101E9000EE0FFF1FE80FF91FE85DFE4F808160E045 +:101EA0008F730E94DF00B7CF2091840030918500AE +:101EB000E0914D018E2FEE0F990BFC01EE0FFF1FED +:101EC000E80FF91FE85DFE4F81819281820F931F19 +:101ED0009093890080938800E0914D018E2FEE0F42 +:101EE000990BFC01EE0FFF1FE80FF91FE85DFE4F95 +:101EF000808186FF11C0E0914D018E2FEE0F990B6E +:101F0000FC01EE0FFF1FE80FF91FE85DFE4F808117 +:101F100061E08F730E94DF00FF91EF91DF91CF911D +:101F2000BF91AF919F918F917F916F915F914F91F1 +:101F30003F912F910F900FBE0F901F90189580E446 +:101F40009CE990938900809388008FEF80934D01E6 +:101F5000E3CFCF92DF92FF920F931F93CF93DF9344 +:101F6000E7E6F1E01382128288EE93E0A0E0B0E0B1 +:101F700084839583A683B7838AE191E091838083EC +:101F800085EC90E09587848784EC90E0978786873E +:101F900080EC90E0918B808B81EC90E0938B828B36 +:101FA00082EC90E0958B848B86EC90E0978B868B0F +:101FB000118E128E138E148EC4E0D2E000E110E078 +:101FC0001F830E83CC24CA94DC2CD986C8861B8739 +:101FD0000A87FF24F394FC861E861D861A8B098BC4 +:101FE000DC8ACB8A1E8B0D8BFF8A1C8E1B8E1A8E71 +:101FF000198F088F80E190E00E94FF12988B8F87E5 +:1020000018A30F8FDAA2C9A21CA30BA3FDA21BA6C3 +:102010001AA619A618A61FA30EA380E290E00E949C +:10202000FF129E8F8D8F198218821D830C831BAB2C +:102030000AABDDAACCAA1FAB0EABF8AE19AE1DAF32 +:102040000CAFDFAECEAE1093450200934402F09287 +:10205000460210924B0210924A02109249021093CB +:1020600048020093470280E190E00E94FF129BAF7C +:102070008AAF10934F0200934E02D0925102C09249 +:1020800050021093530200935202F09254021092A5 +:102090005902109258021092570210935602009360 +:1020A000550280E190E00E94FF1290934D028093D0 +:1020B0004C021DA61CA619AB08AB1093610200933D +:1020C0006002D0926302C092620210936502009394 +:1020D0006402F092660210926802109267021093F6 +:1020E0006C0200936B02D0926E02C0926D0210934C +:1020F000700200936F02F0927102109276021092B9 +:10210000750210927402109373020093720280E1C0 +:1021100090E00E94FF1290936A02809369021093EC +:102120007A0200937902D0927C02C0927B021093D3 +:102130007E0200937D02F0927F021092850210923F +:102140008402109283021092820210938102009303 +:10215000800280E290E00E94FF12909378028093C8 +:10216000770210925B0210925A0210935F02009362 +:102170005E021093890200938802D0928B02C09273 +:102180008A0210938D0200938C02F0928E021092BC +:102190009402109293021092920210929102109364 +:1021A000900200938F0280E190E00E944804909397 +:1021B000870280938602DF91CF911F910F91FF904C +:1021C000DF90CF900895CF93DF93CDB7DEB76097C0 +:1021D0000FB6F894DEBF0FBECDBF789484B5826091 +:1021E00084BD84B5816084BD85B5826085BD85B5BB +:1021F000816085BD80916E00816080936E00109239 +:1022000081008091810082608093810080918100B3 +:102210008160809381008091800081608093800044 +:102220008091B10084608093B1008091B0008160A2 +:102230008093B00080917A00846080937A008091CE +:102240007A00826080937A0080917A008160809326 +:102250007A0080917A00806880937A001092C100A1 +:1022600088E091E00E94FF128C018AE091E0D801A1 +:1022700011969C938E9387E691E013969C938E9390 +:10228000129784E092E015969C938E931497F80130 +:10229000EB5FFE4F10823196108231961082809152 +:1022A0005401811115C08CED92E090934F01809301 +:1022B0004E018DEA91E090935101809350018BEB98 +:1022C00092E0909353018093520181E080935401F6 +:1022D0008EE491E09A8389831C830B83CE0101965F +:1022E0000E948105CE0101960E94160410935D01A3 +:1022F00000935C0161E08DE00E940D0161E08DE0E2 +:102300000E94DF000E94780160E08DE00E94DF0003 +:102310000E94780161E08DE00E94DF000E94780158 +:1023200060E08DE00E94DF0060E08DE00E940D0122 +:10233000D8011296ED91FC91A089B18982E08C932D +:10234000A485B5851C92A685B78580E18C93108EF7 +:10235000A489B58986E08C93A289B3898C91806128 +:102360008C93A289B3898C9188608C93A289B3895C +:102370008C9180688C930288F389E02D80818F7D19 +:1023800080830E94780130E020E050E040E060EF80 +:1023900070E0C8010E94E60280E0A82E80E0B82E1E +:1023A0006EE372E0CE0101960E946904F12CE12CEB +:1023B0008C859D85E816F90608F04FC0B701CE015F +:1023C00001960E940008FC011081612F84E092E0D8 +:1023D0000E945B08DC018D919C910197D1F5812FC2 +:1023E0000E94B600082F612F80E392E00E945A09F4 +:1023F000FC018081081769F1612F80E392E00E945F +:102400005A09DC010C93D12CC12C8091910290913E +:102410009202C816D906E8F4B60186E892E00E9456 +:10242000CF05188B21E0013009F020E02F87DC0177 +:10243000ED91FC910480F581E02DAE01415F5F4F8D +:10244000BE01605F7F4F02960995BFEFCB1ADB0A92 +:10245000DCCFEFEFEE1AFE0AABCFCE0101960E9461 +:10246000A30900915C0110915D01D80112968D9134 +:102470009C91DC01ED91FC910084F185E02D0995A2 +:10248000892BA1F0F80182819381DC01ED91FC910F +:102490000284F385E02D0995D801ED91FC9101901E +:1024A000F081E02D682FC8010995DFCFA114B10498 +:1024B00009F476CF0E941802882309F471CF0E9494 +:1024C00000006ECF8091860290918702009731F0D4 +:1024D0000E94B504109287021092860283E992E06E +:1024E0000E9416048091770290917802009711F073 +:1024F0000E949B1389E692E00E94A3098CE492E07B +:102500000E94A3098EE392E00E94A3098091210218 +:1025100090912202009711F00E949B1383E192E0B8 +:102520000C94A309052E97FB1EF400940E94A91297 +:1025300057FD07D00E94BC1207FC03D04EF40C9448 +:10254000A91250954095309521953F4F4F4F5F4FC1 +:10255000089590958095709561957F4F8F4F9F4F0F +:1025600008950E94DE12A59F900DB49F900DA49F28 +:10257000800D911D11240895A1E21A2EAA1BBB1BE8 +:10258000FD010DC0AA1FBB1FEE1FFF1FA217B3073F +:10259000E407F50720F0A21BB30BE40BF50B661F55 +:1025A000771F881F991F1A9469F760957095809519 +:1025B00090959B01AC01BD01CF010895A29FB00190 +:1025C000B39FC001A39F700D811D1124911DB29F67 +:1025D000700D811D1124911D0895991B79E004C08F +:1025E000991F961708F0961B881F7A95C9F7809552 +:1025F0000895EE0FFF1F0590F491E02D09940F93BD +:102600001F93CF93DF938230910510F482E090E026 +:10261000E0919F02F091A00230E020E0B0E0A0E065 +:10262000309799F42115310509F44AC0281B390B5C +:1026300024303105D8F58A819B816115710589F1B6 +:10264000FB0193838283FE0111C04081518102818D +:10265000138148175907E0F04817590799F4109764 +:1026600061F012960C93129713961C933296CF0139 +:10267000DF91CF911F910F91089500939F021093C6 +:10268000A002F4CF2115310551F04217530738F05D +:10269000A901DB019A01BD01DF01F801C1CFEF0102 +:1026A000F9CF9093A00280939F02CDCFFE01E20F5D +:1026B000F31F819391932250310939832883D7CF17 +:1026C00020919D0230919E02232B41F42091020122 +:1026D0003091030130939E0220939D0220910001CE +:1026E000309101012115310541F42DB73EB74091DC +:1026F000040150910501241B350BE0919D02F091DE +:102700009E02E217F307A0F42E1B3F0B2817390790 +:1027100078F0AC014E5F5F4F2417350748F04E0F3D +:102720005F1F50939E0240939D02819391939FCF90 +:10273000F0E0E0E09CCFCF93DF930097E9F0FC015D +:10274000329713821282A0919F02B091A002ED01F4 +:1027500030E020E01097A1F420813181820F931F97 +:1027600020919D0230919E022817390709F061C01F +:10277000F0939E02E0939D02DF91CF910895EA01CC +:10278000CE17DF07E8F54A815B819E0141155105AF +:10279000B1F7E901FB83EA8349915991C40FD51F31 +:1027A000EC17FD0761F4808191810296840F951FDB +:1027B000E90199838883828193819B838A83F0E0F6 +:1027C000E0E012968D919C9113970097B9F52D91A9 +:1027D0003C911197CD010296820F931F20919D028B +:1027E00030919E022817390739F6309751F510922B +:1027F000A00210929F02B0939E02A0939D02BCCFB4 +:10280000D383C28340815181840F951FC817D90794 +:1028100061F44E5F5F4F88819981480F591F518342 +:1028200040838A819B81938382832115310509F03E +:10283000B0CFF093A002E0939F029ECFFD01DC0198 +:10284000C0CF13821282D7CF10E0C2E6D0E004C01E +:10285000FE010E94F9122196C336D107C9F7F894F8 +:02286000FFCFA8 +:102862000000A102800000000000C2039C0391034B +:10287200AB093903E602000000004E02AE01DB01A3 +:082882009B020C02EA01FE01B9 +:00000001FF diff --git a/owlet/firmware/arduino-mini-pro-5v/release.json b/owlet/firmware/arduino-mini-pro-5v/release.json new file mode 100644 index 000000000..03bdde17f --- /dev/null +++ b/owlet/firmware/arduino-mini-pro-5v/release.json @@ -0,0 +1,4 @@ +{ + "firmwareFile": "firmware.hex", + "version": "0.0.2" +} diff --git a/owlet/firmware/arduino-nano/firmware.hex b/owlet/firmware/arduino-nano/firmware.hex new file mode 100644 index 000000000..d64a90001 --- /dev/null +++ b/owlet/firmware/arduino-nano/firmware.hex @@ -0,0 +1,651 @@ +:100000000C9463000C948B000C948B000C948B006C +:100010000C948B000C948B000C948B000C948B0034 +:100020000C948B000C948B000C948B000C94ED0EB4 +:100030000C948B000C948B000C948B000C948B0014 +:100040000C944B0E0C948B000C94BB0E0C94950EE0 +:100050000C948B000C948B000C948B000C948B00F4 +:100060000C948B000C948B000000000024002700EF +:100070002A0000000000250028002B0000000000DE +:1000800023002600290004040404040404040202DA +:100090000202020203030303030301020408102007 +:1000A0004080010204081020010204081020000012 +:1000B0000008000201000003040700000000000027 +:1000C0000000A90F621211241FBECFEFD8E0DEBFDF +:1000D000CDBF11E0A0E0B1E0E2E6F8E202C0059099 +:1000E0000D92A832B107D9F722E0A8E2B1E001C031 +:1000F0001D92A13AB207E1F710E0C2E6D0E004C0D9 +:100100002197FE010E94F912C136D107C9F70E945A +:10011000E3100C9424140C940000833081F028F434 +:10012000813099F08230A9F008958730A9F08830A5 +:10013000C9F08430B1F4809180008F7D03C080913C +:1001400080008F7780938000089584B58F7784BD79 +:10015000089584B58F7DFBCF8091B0008F77809319 +:10016000B00008958091B0008F7DF9CFCF93DF93D9 +:10017000282F30E0F901E255FF4F8491F901E6564E +:10018000FF4FD491F901EA57FF4FC491CC23A1F05E +:1001900081110E948D00EC2FF0E0EE0FFF1FE4585C +:1001A000FF4FA591B491EC91ED2381E090E009F42B +:1001B00080E0DF91CF91089580E090E0FACF1F9327 +:1001C000CF93DF93282F30E0F901E255FF4F849160 +:1001D000F901E656FF4FD491F901EA57FF4FC49158 +:1001E000CC23A9F0162F81110E948D00EC2FF0E096 +:1001F000EE0FFF1FEE58FF4FA591B4918FB7F89403 +:10020000EC91111108C0D095DE23DC938FBFDF91F4 +:10021000CF911F910895DE2BF8CFCF93DF9390E01D +:10022000FC01E656FF4F24918A579F4FFC018491B1 +:100230008823D1F090E0880F991FFC01E859FF4F07 +:10024000A591B491FC01EE58FF4FC591D491611175 +:100250000EC09FB7F8948C91E22FE0958E238C937B +:100260002881E223E8839FBFDF91CF9108958FB764 +:10027000F894EC91E22BEC938FBFF6CF8E3008F020 +:100280008E508770806480937C0080917A008064B7 +:1002900080937A0080917A0086FDFCCF809178006F +:1002A0009091790008953FB7F894809163019091FF +:1002B0006401A0916501B091660126B5A89B05C0B7 +:1002C0002F3F19F00196A11DB11D3FBFBA2FA92FD5 +:1002D000982F8827BC01CD01620F711D811D911DD2 +:1002E00042E0660F771F881F991F4A95D1F708953E +:1002F0008F929F92AF92BF92CF92DF92EF92FF9236 +:100300000E9453014B015C0184E6C82ED12CE12CE4 +:10031000F12C0E945301681979098A099B09683EEA +:10032000734081059105A8F321E0C21AD108E108C4 +:10033000F10888EE880E83E0981EA11CB11CC11440 +:10034000D104E104F10429F7FF90EF90DF90CF9002 +:10035000BF90AF909F908F9008950895AF92BF92F5 +:10036000CF92DF92EF92FF920F931F93CF93DF9381 +:100370006C017B018B01040F151FEB015E01AE18B0 +:10038000BF08C017D10759F06991D601ED91FC91D2 +:100390000190F081E02DC6010995892B79F7C501FF +:1003A000DF91CF911F910F91FF90EF90DF90CF9051 +:1003B000BF90AF900895FC01538D448D252F30E000 +:1003C000842F90E0821B930B541710F0CF96089562 +:1003D00001970895FC01918D828D981761F0A28D8F +:1003E000AE0FBF2FB11D5D968C91928D9F5F9F7355 +:1003F000928F90E008958FEF9FEF0895FC01918D0B +:10040000828D981731F0828DE80FF11D858D90E077 +:1004100008958FEF9FEF0895FC01918D228D892F14 +:1004200090E0805C9F4F821B91098F7399270895FC +:1004300087E691E00E940C0221E0892B09F420E07C +:10044000822F089580E090E0892B29F00E94180205 +:1004500081110C9400000895FC01A48DA80FB92F00 +:10046000B11DA35ABF4F2C91848D90E001968F73DC +:100470009927848FA689B7892C93A089B1898C91FB +:10048000837080648C93938D848D981306C002884A +:10049000F389E02D80818F7D80830895EF92FF9214 +:1004A0000F931F93CF93DF93EC0181E0888F9B8D97 +:1004B0008C8D98131AC0E889F989808185FF15C051 +:1004C0009FB7F894EE89FF896083E889F989808174 +:1004D0008370806480839FBF81E090E0DF91CF9143 +:1004E0001F910F91FF90EF900895F62E0B8D10E065 +:1004F0000F5F1F4F0F731127E02E8C8D8E110CC0D4 +:100500000FB607FCFACFE889F989808185FFF5CF1E +:10051000CE010E942C02F1CFEB8DEC0FFD2FF11DCF +:10052000E35AFF4FF0829FB7F8940B8FEA89FB895B +:1005300080818062CFCFCF93DF93EC01888D8823B9 +:10054000B9F0AA89BB89E889F9898C9185FD03C036 +:10055000808186FD0DC00FB607FCF7CF8C9185FF1B +:10056000F2CF808185FFEDCFCE010E942C02E9CF32 +:10057000DF91CF910895CF93DF9300D0CDB7DEB751 +:10058000DA012C91FB01308139832A83DC018D91C2 +:100590009C91DC01ED91FC910284F385E02D22E039 +:1005A00030E0AE014F5F5F4F61EF70E009950F9053 +:1005B0000F90DF91CF9108956115710531F0FC0125 +:1005C00080819181FB01918380830895CF92DF9296 +:1005D000EF92FF920F931F93CF93DF93EC01162FAF +:1005E0006A017901E881F9810280F381E02D41E01F +:1005F00060EC0995E881F9810280F381E02D40E00B +:10060000612FCE010995E881F9810280F381E02D07 +:10061000DE01A95FBE4F6C9181E0860F8C9340E0B4 +:10062000CE0109958601EC0CFD1CE881F981028060 +:10063000F381E02DE016F10639F0D8016D918D01BE +:1006400040E0CE010995F1CF41E060ECCE01099583 +:100650008A819B81DC01ED91FC910680F781E02D80 +:10066000DF91CF911F910F91FF90EF90DF90CF908E +:100670000994BF92CF92DF92EF92FF920F931F9354 +:10068000CF93DF93EC01B62EC42ED22EE881F981F0 +:100690000280F381E02D41E060EC0995E881F98169 +:1006A0000280F381E02D40E06B2DCE010995E881B9 +:1006B000F9810280F381E02D40E06C2DCE01099597 +:1006C000E881F9810280F381E02D40E06D2DCE01BB +:1006D00009956801E00EF11EE881F9810280F3813D +:1006E000E02DEC14FD0439F0D6016D916D0140E070 +:1006F000CE010995F1CF41E060ECCE0109958A81E8 +:100700009B81DC01ED91FC910680F781E02DDF916A +:10071000CF911F910F91FF90EF90DF90CF90BF90FE +:100720000994DC0112968D919C91DC01ED91FC9174 +:100730000190F081E02D0994CF93DF93DC01ED91DE +:10074000FC910480F581E02D442319F0DF91CF91D5 +:100750000994EC01603C21F06B3D59F0CE01F6CFDD +:100760006BED0995E881F9810480F581E02D6CED50 +:10077000F5CF6BED0995E881F9810480F581E02DD5 +:100780006DEDECCF0F931F93CF93DF93EC01CA5F16 +:10079000DE4F2881222321F06C3D49F06D3D09F1A7 +:1007A000603C59F16B3D81F481E088833AC0DC0103 +:1007B000AB5FBE4FEC9121E02E0F2C93E80FF92F89 +:1007C000F11D20EC26831882FC01EB5FFE4F208197 +:1007D00031E0320F3083820F911DDC0116966C934D +:1007E00020C0DC01AB5FBE4FEC9121E02E0F2C93BB +:1007F000E80FF92FF11D2BEDE5CF8C010B5F1E4F9C +:10080000D8014C91442351F0BC016A5F7F4FDC0159 +:10081000ED91FC910680F781E02D0995F801108299 +:100820001882DF91CF911F910F910895DC01ED9116 +:10083000FC91309729F00280F381E02D0296099413 +:100840000895FC01828D938D30E020E02817390750 +:10085000E1F0A785B089A20FB31F4C91641312C0B9 +:1008600080A591A52817390718F082A593A50895AA +:10087000220F331F858D968D280F391FF901808136 +:10088000918108952F5F3F4FE1CF8585968508952B +:10089000CF93DF93EC01CD3C8CE0D807A0F42AE0A5 +:1008A0002C9FC0012D9F900D112402960E94FF12D3 +:1008B000FC01C193D193CF012197D7FD07C01182CD +:1008C00010823A96F9CF8FEF9FEFF0CFDF91CF9163 +:1008D0000895EF92FF920F931F93CF93DF93EC0154 +:1008E0008B0180E190E09F838E8381E088871D8665 +:1008F000FB01E184F284C7010E94FF12998388837F +:10090000892B61F1F801828193819B838A838481A1 +:1009100095819D838C83868197819F838E8380853B +:100920008887FA86E986838594859C878B87858569 +:100930008D8790E080E02B853C858217930770F4CB +:10094000E0913E02F0913F02E80FF91F2081E8811B +:10095000F981E80FF91F20830196EDCFDF91CF9148 +:100960001F910F91FF90EF900895EF92FF920F93D8 +:100970001F93CF93DF930097C1F1EC01FC013297F5 +:10098000808191812AE0289F8001299F100D1124E8 +:100990000C0F1D1F7801CE15DF0539F08AE0E81A2B +:1009A000F108C7010E941604F6CFC8018C1B9D0BED +:1009B000969587954DEC5CE4849F9001859F300D62 +:1009C000949F300D11243F7746EF4203C001439FAF +:1009D000900D11240297800F911FDF91CF911F91ED +:1009E0000F91FF90EF900C949B13DF91CF911F918B +:1009F0000F91FF90EF9008952F923F924F925F9248 +:100A00006F927F928F929F92AF92BF92CF92DF921E +:100A1000EF92FF920F931F93CF93DF938C016B01A3 +:100A2000FC01C481D58181859285C617D707B8F4AA +:100A3000C817D907A9F480E0DF91CF911F910F91DA +:100A4000FF90EF90DF90CF90BF90AF909F908F90EE +:100A50007F906F905F904F903F902F900895EB01A3 +:100A6000F8012085211105C08C179D0738F081E021 +:100A7000E3CF6E018C179D0708F46C011E012097CF +:100A800019F480E1282E312CC1010E9448043C0158 +:100A9000009789F27C01512C412CF80180809180D3 +:100AA000C414D504E9F05701A618B708C7010E947D +:100AB0001604E114F10469F0F401EA0DFB1D8191C3 +:100AC0009191D7018D939D9388E001900D928A9525 +:100AD000E1F7FFEF4F1A5F0A8AE0E80EF11CDDCF65 +:100AE000C4010E94B504F8017182608221863286B9 +:100AF00083859485C817D90708F0B9CFD487C387F1 +:100B0000B6CF0F931F93CF93DF938C0160918F0229 +:100B100070919002809191029091920286179707AE +:100B2000F8F420919102309192024AE0429FC00174 +:100B3000439F900D1124C0918602D0918702C80F67 +:100B4000D91FCE010E9416042097E9F480919102EA +:100B500090919202019690939202809391020EC01E +:100B600080918C0290918D02009741F0680F791F5F +:100B700086E892E00E94FC048111D3CFDF91CF91EF +:100B80001F910F910895F80181919191DE018D934C +:100B90009D9388E001900D928A95E1F7D7CF0F934E +:100BA0001F93CF93DF93EC018B0169857A8506173C +:100BB000170738F08E819F81680F791FCE010E9440 +:100BC000FC0489859A852B853C850217130740F024 +:100BD0008017910740F098012F5F3F4F3C872B878C +:100BE0000817190738F0CE010D96DF91CF911F91AC +:100BF0000F9108958AE0809F9001819F300D11240C +:100C000088819981820F931FF0CFAF92BF92CF92CC +:100C1000DF92EF92FF920F931F93CF93DF938C019C +:100C20007B01FC01C481D58181859285C617D707D8 +:100C300078F4C817D90769F480E0DF91CF911F914C +:100C40000F91FF90EF90DF90CF90BF90AF900895FD +:100C5000EB01F8012085211105C08C179D0738F0A4 +:100C600081E0EBCF7E018C179D0708F47C01209773 +:100C700021F16E018FEF9FEFC115F0E4DF0718F44B +:100C8000C601880F991F0E94FF125C010097A1F214 +:100C9000DC01F8018081918130E020E0E216F3066A +:100CA00081F0F901EE0FFF1FE80FF91F408151811C +:100CB0004D935D932F5F3F4FF1CF60E1C62ED12C56 +:100CC000DFCF009711F00E949B13F801B182A08240 +:100CD000D286C18683859485C817D90708F6D4873C +:100CE000C387BECF0F931F93CF93DF93EC018B018C +:100CF00069857A850617170738F08E819F81680FFE +:100D0000791FCE010E94050689859A852B853C8531 +:100D10000217130740F08017910740F098012F5FEA +:100D20003F4F3C872B870817190738F0CE010D96E7 +:100D3000DF91CF911F910F910895000F111F8881AE +:100D40009981800F911FF4CF8F929F92AF92BF92A3 +:100D5000CF92DF92EF92FF920F931F93CF93DF9387 +:100D6000EC017B0189859A856817790760F0CE8050 +:100D7000DF80C80ED91E0C811D810C151D0528F5BC +:100D80008017910719F589859A852B853C85E21690 +:100D9000F30640F08E159F0548F097012F5F3F4FF7 +:100DA0003C872B87E816F90608F458C0CE010D964B +:100DB000DF91CF911F910F91FF90EF90DF90CF9037 +:100DC000BF90AF909F908F90089586012885211144 +:100DD00027C080179107B8F60115110539F15801A0 +:100DE000011580E4180730F5C501880F991F0E948E +:100DF000FF124C01009739F2DC018881998130E0C3 +:100E000020E0C216D306C9F0F901EE0FFF1FE80F6C +:100E1000F91F408151814D935D932F5F3F4FF1CF7B +:100E20006C0108171907C0F66801D6CF60E1A62E3D +:100E3000B12CDACF8FEF9FEFDACF009711F00E943D +:100E40009B1399828882BA86A9868B859C85081710 +:100E5000190708F098CF1C870B8795CFEE0CFF1C65 +:100E6000888199818E0D9F1DA3CFAF92BF92CF92A3 +:100E7000DF92EF92FF920F931F93CF93DF938C013A +:100E80007B01DC011496CD91DC91159719968D911B +:100E90009C91C617D70778F4C817D90769F480E082 +:100EA000DF91CF911F910F91FF90EF90DF90CF9046 +:100EB000BF90AF900895EB01F8012085211105C086 +:100EC0008C179D0738F081E0EBCF7E018C179D07D2 +:100ED00008F47C016E01209719F480E1C82ED12C12 +:100EE000C6010E94FF125C010097C9F2FC01D80103 +:100EF0008D919C9130E020E0E216F30641F0DC0198 +:100F0000A20FB31F4C9141932F5F3F4FF5CF009736 +:100F100011F00E949B13F801B182A082C186D28693 +:100F200083859485C817D90770F6D487C387CBCF3C +:100F3000CF93FC0183859485C0E06817790750F54D +:100F40008385948501976817790778F4808191816A +:100F50009B012F5F3F4FDC01A20FB31F4C91680F25 +:100F6000791FDB014C93B901EBCF94878387C08550 +:100F7000CC2399F04185528526813781BA01621BC5 +:100F8000730B8617970730F42417350718F4CF0131 +:100F90000E9435078C2FCF910895C1E0FBCF0F93AE +:100FA0001F93CF93DF93EC018B0169857A858B8545 +:100FB0009C8586179707A8F4F8018081E881F9815C +:100FC0002B853C85E20FF31F80832B853C85C9016F +:100FD00001969C878B87C901DF91CF911F910F915B +:100FE00008958E819F81009719F48FEF9FEFF4CFC2 +:100FF000680F791FCE010E9435078111DDCFF5CF33 +:101000000F931F93CF93DF93EC018B0169857A8552 +:101010000617170738F08E819F81680F791FCE0160 +:101020000E94350789859A852B853C850217130711 +:1010300040F08017910740F098012F5F3F4F3C87A9 +:101040002B870817190738F0CE010D96DF91CF9145 +:101050001F910F91089588819981800F911FF6CF7C +:10106000CF92DF92FF920F931F93CF93DF938C0168 +:10107000F62ED0E0C0E06C018FE0C80ED11CF80164 +:10108000828D938DC817D90798F4BE01C6010E94BE +:101090000008FC0180818F1109C0CE01DF91CF9142 +:1010A0001F910F91FF90DF90CF9008952196E7CF89 +:1010B0008FEF9FEFF3CFCF92DF92EF92FF920F93DC +:1010C0001F93CF93DF931F92CDB7DEB78C01698357 +:1010D000F12CE12C6C018FE0C80ED11CF801828D3F +:1010E000938DE816F90698F4B701C6010E9400082E +:1010F000FC0190818981981306C0B701C8014D9603 +:101100000E94A4060EC0FFEFEF1AFF0AE7CFBE0150 +:101110006F5F7F4FC6010E94CF0797FF0CC0C801C9 +:101120000D960F90DF91CF911F910F91FF90EF904F +:10113000DF90CF900895F801208131812F5F3F4FDC +:1011400031832083BC01DACFCF92DF92EF92FF92FE +:101150000F931F93CF93DF938C01D62ED0E0C0E086 +:101160007C018FE0E80EF11CD8015A968D919C917C +:10117000C817D90708F052C0BE01C7010E94000875 +:10118000FC0180818D1148C0D80198968D919C9169 +:10119000C817D90798F5AE01440F551FBE01019736 +:1011A000FA0132966817790790F4D8015D962D916F +:1011B0003C916F5F7F4FD901AE0FBF1FCD90DC9088 +:1011C000240F351FD901CD92DC92AF01E9CFF80190 +:1011D00091A780A725A1222389F046A157A123A189 +:1011E00034A1BA01621B730B8617970738F42417D2 +:1011F000350720F4C8014D960E940506BE01C701BF +:101200000E949807CE01DF91CF911F910F91FF901F +:10121000EF90DF90CF9008952196A6CF8FEF9FEFAC +:10122000F2CFCF92DF92EF92FF920F931F93CF9363 +:10123000DF931F92CDB7DEB78C016983F12CE12CCF +:101240006C018FE0C80ED11CF801828D938DE816D9 +:10125000F90698F4B701C6010E940008FC019081CC +:101260008981981306C0B701C8014D960E94720685 +:101270000EC0FFEFEF1AFF0AE7CFBE016F5F7F4F8F +:10128000C6010E94CF0797FF0CC0C8010D960F90B2 +:10129000DF91CF911F910F91FF90EF90DF90CF9052 +:1012A0000895F801208131812F5F3F4F31832083E2 +:1012B000BC01DACFCF92DF92EF92FF920F931F9390 +:1012C000CF93DF931F92CDB7DEB78C016983F12CEA +:1012D000E12C6C018EE0C80ED11CF801818D928D3D +:1012E000E816F90698F4B701C6010E940008FC014F +:1012F00090818981981306C0B701C8014C960E945D +:1013000000080EC0FFEFEF1AFF0AE7CFBE016F5FC4 +:101310007F4FC6010E94CF0797FF0CC0C8010D96F2 +:101320000F90DF91CF911F910F91FF90EF90DF9081 +:10133000CF900895F801208131812F5F3F4F318395 +:101340002083BC01DACFFC0180819181009711F0EC +:101350000C949B1308952F923F925F926F927F920D +:101360008F929F92AF92BF92CF92DF92EF92FF92B5 +:101370000F931F93CF93DF93CDB7DEB729970FB6A7 +:10138000F894DEBF0FBECDBF6C017B01DB016C9119 +:1013900011965C90673008F06FC4E62FF0E0ED52D4 +:1013A000F64F0C94F912DA09100AF10B5F0C9E0C3F +:1013B0003D0D790DDC01ED91FC910084F185E02D6E +:1013C000423011F1F12CE12C10E000E023E030E09C +:1013D000452D60E0C601099529960FB6F894DEBF49 +:1013E0000FBECDBFDF91CF911F910F91FF90EF9076 +:1013F000DF90CF90BF90AF909F908F907F906F9035 +:101400005F903F902F90089519821A824B8333E0AA +:10141000E32EF12C8E010F5F1F4F30E020E0D8CF7C +:10142000EDB7FEB7F987E887443079F0DC01ED913C +:10143000FC910084F185E02DF12CE12C10E000E01E +:1014400023E030E0452D61E0C5CFF70112818381B3 +:10145000282E312CD6011496ED90FC90823009F4A0 +:10146000F7C078F4882309F437C1813009F4E0C06B +:10147000612FC7010E945B08DC012D923C9280E045 +:10148000BEC0843009F4F1C008F4E7C0853081F7AC +:101490005701F6E5AF0EB11C712C612CC7018059C4 +:1014A0009F4F9F838E8345019FE0890E911CAE81E3 +:1014B000BF818D919C916816790650F4B301C401E7 +:1014C0000E940008FC0180811813DCC077FEDEC09A +:1014D00083E090E00E94FF124C0180914C018C301F +:1014E00008F0F6C091E0980F90934C01D4018C93D2 +:1014F00090E0FC01EE0FFF1FE80FF91FE85DFE4FC3 +:1015000088EB9BE092838183612FC5010E941109C2 +:10151000DC018D929C92612FC5010E941109FC0192 +:1015200080809180D4018C918C3008F055C061E0AE +:10153000812F0E940D01F4018081282F30E0F901F4 +:10154000EE0FFF1FE20FF31FE85DFE4F9081907CCE +:10155000212F2F73922B9083D40111961C921197F7 +:1015600012961C922CE0622F0E94ED12829FB00115 +:10157000112430E020E0AB01420F531FFA01EE0FBF +:10158000FF1FE40FF51FE85DFE4F908196FD16C02A +:101590002F5F3F4F2C30310571F781110FC0109232 +:1015A000800082E080938100109285001092840078 +:1015B000B19A80916F00826080936F00D401EC91AA +:1015C0008E2F90E0FC01EE0FFF1FE80FF91FE85D82 +:1015D000FE4F808180648083F40180818F3F09F019 +:1015E00047CF612FC5010E941109DC018D919C91AB +:1015F0000E949B13612FC5010E94A40885E0898386 +:10160000D601ED91FC910084F185E02DEE24E39468 +:10161000F12C8E010F5F1F4F30E020E0452D61E07F +:10162000C60109950FB6F894DEBF0FBECDBFD4CE6C +:1016300060E0812F0E940D01812F0E94B600082FCB +:10164000612FC7018C960E945A09FC01008310CFBC +:1016500061E0812F0E940D010BCF60E0812F0E947D +:101660000D01812F0E943E0103CF61E0812F0E9476 +:101670000D0161E0812F0E940D0160E0812F0E9429 +:10168000DF00F6CEFFEF6F1A7F0A11CF612FC50181 +:101690000E941109DC01ED91FC91E0818E2F90E018 +:1016A000FC01EE0FFF1FE80FF91FE85DFE4F808180 +:1016B0008F7B8083612FC5010E941109FC0180810D +:1016C00091810E949B13612FC5010E94A40800CF45 +:1016D0008FEFF401808318CFB12CA12CF701E059D2 +:1016E000FF4FFF83EE834701F6E58F0E911C340117 +:1016F0002FE0620E711CAE81BF818D919C91A81666 +:10170000B90650F4B501C3010E940008FC018081B4 +:1017100018131EC0B7FE20C0B12CA12C3701F5E470 +:101720006F0E711C47012AE3820E911CD3018D912B +:101730009C91A816B90650F4B501C4010E94000896 +:10174000FC01808118132AC0B7FE2CC060E081CF55 +:10175000FFEFAF1ABF0ACFCF612FC4010E9411095A +:10176000DC01ED91FC91E0818E2F90E0FC01EE0F09 +:10177000FF1FE80FF91FE85DFE4F80818F7B80839C +:10178000612FC4010E941109FC01808191810E9496 +:101790009B13612FC4010E94A408BECFFFEFAF1AB4 +:1017A000BF0AC4CFB12CA12CD3018D919C91A81656 +:1017B000B90660F6B501C4010E940008FC018081F1 +:1017C00018130BC0B501C701885B9F4F0E94980793 +:1017D000B501C4010E949807B9CFFFEFAF1ABF0A45 +:1017E000E3CF443079F0DC01ED91FC910084F18588 +:1017F000E02DF12CE12C10E000E023E030E0452D5D +:1018000062E0E8CDF70112819380DC011496ED903F +:10181000FC90612FC7010E9430080196C9F1612F29 +:10182000C7010E945B08FC0180819181029709F049 +:1018300042C001E0911001C000E0602F812F0E94A2 +:10184000DF00912C812C3701FDE86F0E711C22E81E +:10185000E20EF11CD3018D919C918816990668F5D2 +:10186000B401C7010E94CF051C830983DC01ED91FF +:10187000FC910480F581E02DAE014F5F5F4FBE010A +:101880006C5F7F4F02960995BFEF8B1A9B0AE2CFE0 +:1018900081E08D83D601ED91FC910084F185E02DEE +:1018A000EE24E394F12C8E010B5F1F4F30E020E01B +:1018B000452D62E0B5CE83E0ECCF80E0EACF433047 +:1018C00079F0DC01ED91FC910084F185E02DF12CA3 +:1018D000E12C10E000E023E030E0452D63E07ACD1C +:1018E000F7011281612FDC0114968D919C910E9469 +:1018F00021040097F1F001970297F0F4812F0E94E4 +:10190000B60021E0892B09F420E080E089832A8356 +:10191000D601ED91FC910084F185E02D02E0E02EEE +:10192000F12C8E010F5F1F4F30E020E0452D63E06A +:1019300077CE81E020E0EACF82E0FCCF443079F03E +:10194000DC01ED91FC910084F185E02DF12CE12C7E +:1019500010E000E023E030E0452D64E03BCDF701EE +:101960001281DC0114968D909C90612FC4010E941D +:101970002104009799F481E08983D601ED91FC91CF +:101980000084F185E02DEE24E394F12C8E010F5FAD +:101990001F4F30E020E0452D64E042CE049711F067 +:1019A00083E0EACFF7010381612FC4010E94300870 +:1019B000019609F3612FC4010E945B08DC018D913F +:1019C0009C91049769F7E02EF12C61E0812F0E9431 +:1019D0000D01E114F10429F460E0812F0E94DF0081 +:1019E0002BC0BFEFEB16F10411F461E0F6CFE12F4D +:1019F000F0E0E255FF4FE491E33029F148F4E130A3 +:101A0000B9F0E230D9F0E0E8EE16F10474F7E4CF73 +:101A1000E73019F1E83049F1E430A9F7809180000E +:101A2000806280938000F0928B00E0928A0004C074 +:101A300084B5806884BD07BD80E09ECF84B5806298 +:101A400084BD08BDF9CF80918000806880938000BC +:101A5000F0928900E0928800EFCF8091B00080681A +:101A60008093B0000093B300E7CF8091B000806214 +:101A70008093B0000093B400DFCF433079F0DC01F5 +:101A8000ED91FC910084F185E02DF12CE12C10E02A +:101A900000E023E030E0452D65E09CCCF7011281A9 +:101AA000612FDC0114968D919C910E942104009776 +:101AB000E1F0039722E00297C8F4812F0E943E01D3 +:101AC00020E029839A838B83D601ED91FC910084D9 +:101AD000F185E02DB3E0EB2EF12C8E010F5F1F4F4F +:101AE00030E020E0452D65E09BCD21E080E090E0F6 +:101AF000E8CF443079F0DC01ED91FC910084F18570 +:101B0000E02DF12CE12C10E000E023E030E0452D49 +:101B100066E060CCF7011281DC0114968D909C90F8 +:101B2000612FC4010E942104009799F481E0898308 +:101B3000D601ED91FC910084F185E02DEE24E39433 +:101B4000F12C8E010F5F1F4F30E020E0452D66E045 +:101B500067CD059709F08CC0F701038184E0053B50 +:101B600030F7612FC4010E94300897FDDFCF612F4D +:101B7000C4010E945B08DC018D919C91059709F0DE +:101B800079C0B6E58B0E911C612FC4010E9411092A +:101B9000DC01ED91FC91E0818E2F90E0FC01EE0FD5 +:101BA000FF1FE80FF91FE85DFE4F808186FFBECF63 +:101BB000612FC4010E941109DC01ED91FC9110819B +:101BC0001C3008F053C0828148E5842E42E0942EF8 +:101BD000881A910887FD93941401220C331C220C5F +:101BE000331C818168E8E62EF12CE81AF10887FDA4 +:101BF000F394EE0CFF1CEE0CFF1C37010F2C000CB5 +:101C0000880899089101032C000C440B550B2619E8 +:101C1000370948095909A02FB0E00E94B11224EBFE +:101C200030E040E050E00E949212BA01A901460D56 +:101C3000571D681D791D4E155F052CF07101421569 +:101C400053050CF47A01B2E0EB1AF108EE0CFF1C1C +:101C50002FB7F894812F90E0FC01EE0FFF1FE80FE3 +:101C6000F91FE85DFE4FF282E1822FBF80E05FCF77 +:101C700082E05DCF83E05BCFDC01ED91FC910084DD +:101C8000F185E02DF12CE12C10E000E022E030E0C5 +:101C9000452D0995A1CB1F920F920FB60F921124DB +:101CA0002F933F938F939F93AF93BF9380915F0147 +:101CB00090916001A0916101B091620130915E014B +:101CC00023E0230F2D3758F50196A11DB11D209358 +:101CD0005E0180935F0190936001A0936101B093D6 +:101CE00062018091630190916401A0916501B091BE +:101CF00066010196A11DB11D80936301909364015B +:101D0000A0936501B0936601BF91AF919F918F91B0 +:101D10003F912F910F900FBE0F901F90189526E8BE +:101D2000230F0296A11DB11DD2CF1F920F920FB6A5 +:101D30000F9211242F933F934F935F936F937F9351 +:101D40008F939F93AF93BF93EF93FF9387E691E0B9 +:101D50000E942C02FF91EF91BF91AF919F918F91C3 +:101D60007F916F915F914F913F912F910F900FBE97 +:101D70000F901F9018951F920F920FB60F9211247B +:101D80002F938F939F93EF93FF93E0917701F091BF +:101D900078018081E0917D01F0917E0182FD1BC080 +:101DA0009081809180018F5F8F73209181018217D4 +:101DB00041F0E0918001F0E0E959FE4F958F80936A +:101DC0008001FF91EF919F918F912F910F900FBE06 +:101DD0000F901F9018958081F4CF1F920F920FB62D +:101DE0000F9211242F933F934F935F936F937F93A1 +:101DF0008F939F93AF93BF93CF93DF93EF93FF9313 +:101E000080914D01C0914C01D0E087FF24C0109219 +:101E100085001092840080914D018F5F80934D0169 +:101E200080914D01082E000C990B8C179D0724F40E +:101E300080914D018C30C4F1809184009091850097 +:101E4000049680349C4908F47AC080918400909173 +:101E50008500049676C080914D01082E000C990BE8 +:101E60008C179D07C4F6E0914D018E2FEE0F990B54 +:101E7000FC01EE0FFF1FE80FF91FE85DFE4F8081A8 +:101E800086FFC9CFE0914D018E2FEE0F990BFC011B +:101E9000EE0FFF1FE80FF91FE85DFE4F808160E045 +:101EA0008F730E94DF00B7CF2091840030918500AE +:101EB000E0914D018E2FEE0F990BFC01EE0FFF1FED +:101EC000E80FF91FE85DFE4F81819281820F931F19 +:101ED0009093890080938800E0914D018E2FEE0F42 +:101EE000990BFC01EE0FFF1FE80FF91FE85DFE4F95 +:101EF000808186FF11C0E0914D018E2FEE0F990B6E +:101F0000FC01EE0FFF1FE80FF91FE85DFE4F808117 +:101F100061E08F730E94DF00FF91EF91DF91CF911D +:101F2000BF91AF919F918F917F916F915F914F91F1 +:101F30003F912F910F900FBE0F901F90189580E446 +:101F40009CE990938900809388008FEF80934D01E6 +:101F5000E3CFCF92DF92FF920F931F93CF93DF9344 +:101F6000E7E6F1E01382128288EE93E0A0E0B0E0B1 +:101F700084839583A683B7838AE191E091838083EC +:101F800085EC90E09587848784EC90E0978786873E +:101F900080EC90E0918B808B81EC90E0938B828B36 +:101FA00082EC90E0958B848B86EC90E0978B868B0F +:101FB000118E128E138E148EC4E0D2E000E110E078 +:101FC0001F830E83CC24CA94DC2CD986C8861B8739 +:101FD0000A87FF24F394FC861E861D861A8B098BC4 +:101FE000DC8ACB8A1E8B0D8BFF8A1C8E1B8E1A8E71 +:101FF000198F088F80E190E00E94FF12988B8F87E5 +:1020000018A30F8FDAA2C9A21CA30BA3FDA21BA6C3 +:102010001AA619A618A61FA30EA380E290E00E949C +:10202000FF129E8F8D8F198218821D830C831BAB2C +:102030000AABDDAACCAA1FAB0EABF8AE19AE1DAF32 +:102040000CAFDFAECEAE1093450200934402F09287 +:10205000460210924B0210924A02109249021093CB +:1020600048020093470280E190E00E94FF129BAF7C +:102070008AAF10934F0200934E02D0925102C09249 +:1020800050021093530200935202F09254021092A5 +:102090005902109258021092570210935602009360 +:1020A000550280E190E00E94FF1290934D028093D0 +:1020B0004C021DA61CA619AB08AB1093610200933D +:1020C0006002D0926302C092620210936502009394 +:1020D0006402F092660210926802109267021093F6 +:1020E0006C0200936B02D0926E02C0926D0210934C +:1020F000700200936F02F0927102109276021092B9 +:10210000750210927402109373020093720280E1C0 +:1021100090E00E94FF1290936A02809369021093EC +:102120007A0200937902D0927C02C0927B021093D3 +:102130007E0200937D02F0927F021092850210923F +:102140008402109283021092820210938102009303 +:10215000800280E290E00E94FF12909378028093C8 +:10216000770210925B0210925A0210935F02009362 +:102170005E021093890200938802D0928B02C09273 +:102180008A0210938D0200938C02F0928E021092BC +:102190009402109293021092920210929102109364 +:1021A000900200938F0280E190E00E944804909397 +:1021B000870280938602DF91CF911F910F91FF904C +:1021C000DF90CF900895CF93DF93CDB7DEB76097C0 +:1021D0000FB6F894DEBF0FBECDBF789484B5826091 +:1021E00084BD84B5816084BD85B5826085BD85B5BB +:1021F000816085BD80916E00816080936E00109239 +:1022000081008091810082608093810080918100B3 +:102210008160809381008091800081608093800044 +:102220008091B10084608093B1008091B0008160A2 +:102230008093B00080917A00846080937A008091CE +:102240007A00826080937A0080917A008160809326 +:102250007A0080917A00806880937A001092C100A1 +:1022600088E091E00E94FF128C018AE091E0D801A1 +:1022700011969C938E9387E691E013969C938E9390 +:10228000129784E092E015969C938E931497F80130 +:10229000EB5FFE4F10823196108231961082809152 +:1022A0005401811115C08CED92E090934F01809301 +:1022B0004E018DEA91E090935101809350018BEB98 +:1022C00092E0909353018093520181E080935401F6 +:1022D0008EE491E09A8389831C830B83CE0101965F +:1022E0000E948105CE0101960E94160410935D01A3 +:1022F00000935C0161E08DE00E940D0161E08DE0E2 +:102300000E94DF000E94780160E08DE00E94DF0003 +:102310000E94780161E08DE00E94DF000E94780158 +:1023200060E08DE00E94DF0060E08DE00E940D0122 +:10233000D8011296ED91FC91A089B18982E08C932D +:10234000A485B5851C92A685B78580E18C93108EF7 +:10235000A489B58986E08C93A289B3898C91806128 +:102360008C93A289B3898C9188608C93A289B3895C +:102370008C9180688C930288F389E02D80818F7D19 +:1023800080830E94780130E020E050E040E060EF80 +:1023900070E0C8010E94E60280E0A82E80E0B82E1E +:1023A0006EE372E0CE0101960E946904F12CE12CEB +:1023B0008C859D85E816F90608F04FC0B701CE015F +:1023C00001960E940008FC011081612F84E092E0D8 +:1023D0000E945B08DC018D919C910197D1F5812FC2 +:1023E0000E94B600082F612F80E392E00E945A09F4 +:1023F000FC018081081769F1612F80E392E00E945F +:102400005A09DC010C93D12CC12C8091910290913E +:102410009202C816D906E8F4B60186E892E00E9456 +:10242000CF05188B21E0013009F020E02F87DC0177 +:10243000ED91FC910480F581E02DAE01415F5F4F8D +:10244000BE01605F7F4F02960995BFEFCB1ADB0A92 +:10245000DCCFEFEFEE1AFE0AABCFCE0101960E9461 +:10246000A30900915C0110915D01D80112968D9134 +:102470009C91DC01ED91FC910084F185E02D0995A2 +:10248000892BA1F0F80182819381DC01ED91FC910F +:102490000284F385E02D0995D801ED91FC9101901E +:1024A000F081E02D682FC8010995DFCFA114B10498 +:1024B00009F476CF0E941802882309F471CF0E9494 +:1024C00000006ECF8091860290918702009731F0D4 +:1024D0000E94B504109287021092860283E992E06E +:1024E0000E9416048091770290917802009711F073 +:1024F0000E949B1389E692E00E94A3098CE492E07B +:102500000E94A3098EE392E00E94A3098091210218 +:1025100090912202009711F00E949B1383E192E0B8 +:102520000C94A309052E97FB1EF400940E94A91297 +:1025300057FD07D00E94BC1207FC03D04EF40C9448 +:10254000A91250954095309521953F4F4F4F5F4FC1 +:10255000089590958095709561957F4F8F4F9F4F0F +:1025600008950E94DE12A59F900DB49F900DA49F28 +:10257000800D911D11240895A1E21A2EAA1BBB1BE8 +:10258000FD010DC0AA1FBB1FEE1FFF1FA217B3073F +:10259000E407F50720F0A21BB30BE40BF50B661F55 +:1025A000771F881F991F1A9469F760957095809519 +:1025B00090959B01AC01BD01CF010895A29FB00190 +:1025C000B39FC001A39F700D811D1124911DB29F67 +:1025D000700D811D1124911D0895991B79E004C08F +:1025E000991F961708F0961B881F7A95C9F7809552 +:1025F0000895EE0FFF1F0590F491E02D09940F93BD +:102600001F93CF93DF938230910510F482E090E026 +:10261000E0919F02F091A00230E020E0B0E0A0E065 +:10262000309799F42115310509F44AC0281B390B5C +:1026300024303105D8F58A819B816115710589F1B6 +:10264000FB0193838283FE0111C04081518102818D +:10265000138148175907E0F04817590799F4109764 +:1026600061F012960C93129713961C933296CF0139 +:10267000DF91CF911F910F91089500939F021093C6 +:10268000A002F4CF2115310551F04217530738F05D +:10269000A901DB019A01BD01DF01F801C1CFEF0102 +:1026A000F9CF9093A00280939F02CDCFFE01E20F5D +:1026B000F31F819391932250310939832883D7CF17 +:1026C00020919D0230919E02232B41F42091020122 +:1026D0003091030130939E0220939D0220910001CE +:1026E000309101012115310541F42DB73EB74091DC +:1026F000040150910501241B350BE0919D02F091DE +:102700009E02E217F307A0F42E1B3F0B2817390790 +:1027100078F0AC014E5F5F4F2417350748F04E0F3D +:102720005F1F50939E0240939D02819391939FCF90 +:10273000F0E0E0E09CCFCF93DF930097E9F0FC015D +:10274000329713821282A0919F02B091A002ED01F4 +:1027500030E020E01097A1F420813181820F931F97 +:1027600020919D0230919E022817390709F061C01F +:10277000F0939E02E0939D02DF91CF910895EA01CC +:10278000CE17DF07E8F54A815B819E0141155105AF +:10279000B1F7E901FB83EA8349915991C40FD51F31 +:1027A000EC17FD0761F4808191810296840F951FDB +:1027B000E90199838883828193819B838A83F0E0F6 +:1027C000E0E012968D919C9113970097B9F52D91A9 +:1027D0003C911197CD010296820F931F20919D028B +:1027E00030919E022817390739F6309751F510922B +:1027F000A00210929F02B0939E02A0939D02BCCFB4 +:10280000D383C28340815181840F951FC817D90794 +:1028100061F44E5F5F4F88819981480F591F518342 +:1028200040838A819B81938382832115310509F03E +:10283000B0CFF093A002E0939F029ECFFD01DC0198 +:10284000C0CF13821282D7CF10E0C2E6D0E004C01E +:10285000FE010E94F9122196C336D107C9F7F894F8 +:02286000FFCFA8 +:102862000000A102800000000000C2039C0391034B +:10287200AB093903E602000000004E02AE01DB01A3 +:082882009B020C02EA01FE01B9 +:00000001FF diff --git a/owlet/firmware/arduino-nano/release.json b/owlet/firmware/arduino-nano/release.json new file mode 100644 index 000000000..03bdde17f --- /dev/null +++ b/owlet/firmware/arduino-nano/release.json @@ -0,0 +1,4 @@ +{ + "firmwareFile": "firmware.hex", + "version": "0.0.2" +} diff --git a/owlet/firmware/arduino-uno/firmware.hex b/owlet/firmware/arduino-uno/firmware.hex new file mode 100644 index 000000000..d64a90001 --- /dev/null +++ b/owlet/firmware/arduino-uno/firmware.hex @@ -0,0 +1,651 @@ +:100000000C9463000C948B000C948B000C948B006C +:100010000C948B000C948B000C948B000C948B0034 +:100020000C948B000C948B000C948B000C94ED0EB4 +:100030000C948B000C948B000C948B000C948B0014 +:100040000C944B0E0C948B000C94BB0E0C94950EE0 +:100050000C948B000C948B000C948B000C948B00F4 +:100060000C948B000C948B000000000024002700EF +:100070002A0000000000250028002B0000000000DE +:1000800023002600290004040404040404040202DA +:100090000202020203030303030301020408102007 +:1000A0004080010204081020010204081020000012 +:1000B0000008000201000003040700000000000027 +:1000C0000000A90F621211241FBECFEFD8E0DEBFDF +:1000D000CDBF11E0A0E0B1E0E2E6F8E202C0059099 +:1000E0000D92A832B107D9F722E0A8E2B1E001C031 +:1000F0001D92A13AB207E1F710E0C2E6D0E004C0D9 +:100100002197FE010E94F912C136D107C9F70E945A +:10011000E3100C9424140C940000833081F028F434 +:10012000813099F08230A9F008958730A9F08830A5 +:10013000C9F08430B1F4809180008F7D03C080913C +:1001400080008F7780938000089584B58F7784BD79 +:10015000089584B58F7DFBCF8091B0008F77809319 +:10016000B00008958091B0008F7DF9CFCF93DF93D9 +:10017000282F30E0F901E255FF4F8491F901E6564E +:10018000FF4FD491F901EA57FF4FC491CC23A1F05E +:1001900081110E948D00EC2FF0E0EE0FFF1FE4585C +:1001A000FF4FA591B491EC91ED2381E090E009F42B +:1001B00080E0DF91CF91089580E090E0FACF1F9327 +:1001C000CF93DF93282F30E0F901E255FF4F849160 +:1001D000F901E656FF4FD491F901EA57FF4FC49158 +:1001E000CC23A9F0162F81110E948D00EC2FF0E096 +:1001F000EE0FFF1FEE58FF4FA591B4918FB7F89403 +:10020000EC91111108C0D095DE23DC938FBFDF91F4 +:10021000CF911F910895DE2BF8CFCF93DF9390E01D +:10022000FC01E656FF4F24918A579F4FFC018491B1 +:100230008823D1F090E0880F991FFC01E859FF4F07 +:10024000A591B491FC01EE58FF4FC591D491611175 +:100250000EC09FB7F8948C91E22FE0958E238C937B +:100260002881E223E8839FBFDF91CF9108958FB764 +:10027000F894EC91E22BEC938FBFF6CF8E3008F020 +:100280008E508770806480937C0080917A008064B7 +:1002900080937A0080917A0086FDFCCF809178006F +:1002A0009091790008953FB7F894809163019091FF +:1002B0006401A0916501B091660126B5A89B05C0B7 +:1002C0002F3F19F00196A11DB11D3FBFBA2FA92FD5 +:1002D000982F8827BC01CD01620F711D811D911DD2 +:1002E00042E0660F771F881F991F4A95D1F708953E +:1002F0008F929F92AF92BF92CF92DF92EF92FF9236 +:100300000E9453014B015C0184E6C82ED12CE12CE4 +:10031000F12C0E945301681979098A099B09683EEA +:10032000734081059105A8F321E0C21AD108E108C4 +:10033000F10888EE880E83E0981EA11CB11CC11440 +:10034000D104E104F10429F7FF90EF90DF90CF9002 +:10035000BF90AF909F908F9008950895AF92BF92F5 +:10036000CF92DF92EF92FF920F931F93CF93DF9381 +:100370006C017B018B01040F151FEB015E01AE18B0 +:10038000BF08C017D10759F06991D601ED91FC91D2 +:100390000190F081E02DC6010995892B79F7C501FF +:1003A000DF91CF911F910F91FF90EF90DF90CF9051 +:1003B000BF90AF900895FC01538D448D252F30E000 +:1003C000842F90E0821B930B541710F0CF96089562 +:1003D00001970895FC01918D828D981761F0A28D8F +:1003E000AE0FBF2FB11D5D968C91928D9F5F9F7355 +:1003F000928F90E008958FEF9FEF0895FC01918D0B +:10040000828D981731F0828DE80FF11D858D90E077 +:1004100008958FEF9FEF0895FC01918D228D892F14 +:1004200090E0805C9F4F821B91098F7399270895FC +:1004300087E691E00E940C0221E0892B09F420E07C +:10044000822F089580E090E0892B29F00E94180205 +:1004500081110C9400000895FC01A48DA80FB92F00 +:10046000B11DA35ABF4F2C91848D90E001968F73DC +:100470009927848FA689B7892C93A089B1898C91FB +:10048000837080648C93938D848D981306C002884A +:10049000F389E02D80818F7D80830895EF92FF9214 +:1004A0000F931F93CF93DF93EC0181E0888F9B8D97 +:1004B0008C8D98131AC0E889F989808185FF15C051 +:1004C0009FB7F894EE89FF896083E889F989808174 +:1004D0008370806480839FBF81E090E0DF91CF9143 +:1004E0001F910F91FF90EF900895F62E0B8D10E065 +:1004F0000F5F1F4F0F731127E02E8C8D8E110CC0D4 +:100500000FB607FCFACFE889F989808185FFF5CF1E +:10051000CE010E942C02F1CFEB8DEC0FFD2FF11DCF +:10052000E35AFF4FF0829FB7F8940B8FEA89FB895B +:1005300080818062CFCFCF93DF93EC01888D8823B9 +:10054000B9F0AA89BB89E889F9898C9185FD03C036 +:10055000808186FD0DC00FB607FCF7CF8C9185FF1B +:10056000F2CF808185FFEDCFCE010E942C02E9CF32 +:10057000DF91CF910895CF93DF9300D0CDB7DEB751 +:10058000DA012C91FB01308139832A83DC018D91C2 +:100590009C91DC01ED91FC910284F385E02D22E039 +:1005A00030E0AE014F5F5F4F61EF70E009950F9053 +:1005B0000F90DF91CF9108956115710531F0FC0125 +:1005C00080819181FB01918380830895CF92DF9296 +:1005D000EF92FF920F931F93CF93DF93EC01162FAF +:1005E0006A017901E881F9810280F381E02D41E01F +:1005F00060EC0995E881F9810280F381E02D40E00B +:10060000612FCE010995E881F9810280F381E02D07 +:10061000DE01A95FBE4F6C9181E0860F8C9340E0B4 +:10062000CE0109958601EC0CFD1CE881F981028060 +:10063000F381E02DE016F10639F0D8016D918D01BE +:1006400040E0CE010995F1CF41E060ECCE01099583 +:100650008A819B81DC01ED91FC910680F781E02D80 +:10066000DF91CF911F910F91FF90EF90DF90CF908E +:100670000994BF92CF92DF92EF92FF920F931F9354 +:10068000CF93DF93EC01B62EC42ED22EE881F981F0 +:100690000280F381E02D41E060EC0995E881F98169 +:1006A0000280F381E02D40E06B2DCE010995E881B9 +:1006B000F9810280F381E02D40E06C2DCE01099597 +:1006C000E881F9810280F381E02D40E06D2DCE01BB +:1006D00009956801E00EF11EE881F9810280F3813D +:1006E000E02DEC14FD0439F0D6016D916D0140E070 +:1006F000CE010995F1CF41E060ECCE0109958A81E8 +:100700009B81DC01ED91FC910680F781E02DDF916A +:10071000CF911F910F91FF90EF90DF90CF90BF90FE +:100720000994DC0112968D919C91DC01ED91FC9174 +:100730000190F081E02D0994CF93DF93DC01ED91DE +:10074000FC910480F581E02D442319F0DF91CF91D5 +:100750000994EC01603C21F06B3D59F0CE01F6CFDD +:100760006BED0995E881F9810480F581E02D6CED50 +:10077000F5CF6BED0995E881F9810480F581E02DD5 +:100780006DEDECCF0F931F93CF93DF93EC01CA5F16 +:10079000DE4F2881222321F06C3D49F06D3D09F1A7 +:1007A000603C59F16B3D81F481E088833AC0DC0103 +:1007B000AB5FBE4FEC9121E02E0F2C93E80FF92F89 +:1007C000F11D20EC26831882FC01EB5FFE4F208197 +:1007D00031E0320F3083820F911DDC0116966C934D +:1007E00020C0DC01AB5FBE4FEC9121E02E0F2C93BB +:1007F000E80FF92FF11D2BEDE5CF8C010B5F1E4F9C +:10080000D8014C91442351F0BC016A5F7F4FDC0159 +:10081000ED91FC910680F781E02D0995F801108299 +:100820001882DF91CF911F910F910895DC01ED9116 +:10083000FC91309729F00280F381E02D0296099413 +:100840000895FC01828D938D30E020E02817390750 +:10085000E1F0A785B089A20FB31F4C91641312C0B9 +:1008600080A591A52817390718F082A593A50895AA +:10087000220F331F858D968D280F391FF901808136 +:10088000918108952F5F3F4FE1CF8585968508952B +:10089000CF93DF93EC01CD3C8CE0D807A0F42AE0A5 +:1008A0002C9FC0012D9F900D112402960E94FF12D3 +:1008B000FC01C193D193CF012197D7FD07C01182CD +:1008C00010823A96F9CF8FEF9FEFF0CFDF91CF9163 +:1008D0000895EF92FF920F931F93CF93DF93EC0154 +:1008E0008B0180E190E09F838E8381E088871D8665 +:1008F000FB01E184F284C7010E94FF12998388837F +:10090000892B61F1F801828193819B838A838481A1 +:1009100095819D838C83868197819F838E8380853B +:100920008887FA86E986838594859C878B87858569 +:100930008D8790E080E02B853C858217930770F4CB +:10094000E0913E02F0913F02E80FF91F2081E8811B +:10095000F981E80FF91F20830196EDCFDF91CF9148 +:100960001F910F91FF90EF900895EF92FF920F93D8 +:100970001F93CF93DF930097C1F1EC01FC013297F5 +:10098000808191812AE0289F8001299F100D1124E8 +:100990000C0F1D1F7801CE15DF0539F08AE0E81A2B +:1009A000F108C7010E941604F6CFC8018C1B9D0BED +:1009B000969587954DEC5CE4849F9001859F300D62 +:1009C000949F300D11243F7746EF4203C001439FAF +:1009D000900D11240297800F911FDF91CF911F91ED +:1009E0000F91FF90EF900C949B13DF91CF911F918B +:1009F0000F91FF90EF9008952F923F924F925F9248 +:100A00006F927F928F929F92AF92BF92CF92DF921E +:100A1000EF92FF920F931F93CF93DF938C016B01A3 +:100A2000FC01C481D58181859285C617D707B8F4AA +:100A3000C817D907A9F480E0DF91CF911F910F91DA +:100A4000FF90EF90DF90CF90BF90AF909F908F90EE +:100A50007F906F905F904F903F902F900895EB01A3 +:100A6000F8012085211105C08C179D0738F081E021 +:100A7000E3CF6E018C179D0708F46C011E012097CF +:100A800019F480E1282E312CC1010E9448043C0158 +:100A9000009789F27C01512C412CF80180809180D3 +:100AA000C414D504E9F05701A618B708C7010E947D +:100AB0001604E114F10469F0F401EA0DFB1D8191C3 +:100AC0009191D7018D939D9388E001900D928A9525 +:100AD000E1F7FFEF4F1A5F0A8AE0E80EF11CDDCF65 +:100AE000C4010E94B504F8017182608221863286B9 +:100AF00083859485C817D90708F0B9CFD487C387F1 +:100B0000B6CF0F931F93CF93DF938C0160918F0229 +:100B100070919002809191029091920286179707AE +:100B2000F8F420919102309192024AE0429FC00174 +:100B3000439F900D1124C0918602D0918702C80F67 +:100B4000D91FCE010E9416042097E9F480919102EA +:100B500090919202019690939202809391020EC01E +:100B600080918C0290918D02009741F0680F791F5F +:100B700086E892E00E94FC048111D3CFDF91CF91EF +:100B80001F910F910895F80181919191DE018D934C +:100B90009D9388E001900D928A95E1F7D7CF0F934E +:100BA0001F93CF93DF93EC018B0169857A8506173C +:100BB000170738F08E819F81680F791FCE010E9440 +:100BC000FC0489859A852B853C850217130740F024 +:100BD0008017910740F098012F5F3F4F3C872B878C +:100BE0000817190738F0CE010D96DF91CF911F91AC +:100BF0000F9108958AE0809F9001819F300D11240C +:100C000088819981820F931FF0CFAF92BF92CF92CC +:100C1000DF92EF92FF920F931F93CF93DF938C019C +:100C20007B01FC01C481D58181859285C617D707D8 +:100C300078F4C817D90769F480E0DF91CF911F914C +:100C40000F91FF90EF90DF90CF90BF90AF900895FD +:100C5000EB01F8012085211105C08C179D0738F0A4 +:100C600081E0EBCF7E018C179D0708F47C01209773 +:100C700021F16E018FEF9FEFC115F0E4DF0718F44B +:100C8000C601880F991F0E94FF125C010097A1F214 +:100C9000DC01F8018081918130E020E0E216F3066A +:100CA00081F0F901EE0FFF1FE80FF91F408151811C +:100CB0004D935D932F5F3F4FF1CF60E1C62ED12C56 +:100CC000DFCF009711F00E949B13F801B182A08240 +:100CD000D286C18683859485C817D90708F6D4873C +:100CE000C387BECF0F931F93CF93DF93EC018B018C +:100CF00069857A850617170738F08E819F81680FFE +:100D0000791FCE010E94050689859A852B853C8531 +:100D10000217130740F08017910740F098012F5FEA +:100D20003F4F3C872B870817190738F0CE010D96E7 +:100D3000DF91CF911F910F910895000F111F8881AE +:100D40009981800F911FF4CF8F929F92AF92BF92A3 +:100D5000CF92DF92EF92FF920F931F93CF93DF9387 +:100D6000EC017B0189859A856817790760F0CE8050 +:100D7000DF80C80ED91E0C811D810C151D0528F5BC +:100D80008017910719F589859A852B853C85E21690 +:100D9000F30640F08E159F0548F097012F5F3F4FF7 +:100DA0003C872B87E816F90608F458C0CE010D964B +:100DB000DF91CF911F910F91FF90EF90DF90CF9037 +:100DC000BF90AF909F908F90089586012885211144 +:100DD00027C080179107B8F60115110539F15801A0 +:100DE000011580E4180730F5C501880F991F0E948E +:100DF000FF124C01009739F2DC018881998130E0C3 +:100E000020E0C216D306C9F0F901EE0FFF1FE80F6C +:100E1000F91F408151814D935D932F5F3F4FF1CF7B +:100E20006C0108171907C0F66801D6CF60E1A62E3D +:100E3000B12CDACF8FEF9FEFDACF009711F00E943D +:100E40009B1399828882BA86A9868B859C85081710 +:100E5000190708F098CF1C870B8795CFEE0CFF1C65 +:100E6000888199818E0D9F1DA3CFAF92BF92CF92A3 +:100E7000DF92EF92FF920F931F93CF93DF938C013A +:100E80007B01DC011496CD91DC91159719968D911B +:100E90009C91C617D70778F4C817D90769F480E082 +:100EA000DF91CF911F910F91FF90EF90DF90CF9046 +:100EB000BF90AF900895EB01F8012085211105C086 +:100EC0008C179D0738F081E0EBCF7E018C179D07D2 +:100ED00008F47C016E01209719F480E1C82ED12C12 +:100EE000C6010E94FF125C010097C9F2FC01D80103 +:100EF0008D919C9130E020E0E216F30641F0DC0198 +:100F0000A20FB31F4C9141932F5F3F4FF5CF009736 +:100F100011F00E949B13F801B182A082C186D28693 +:100F200083859485C817D90770F6D487C387CBCF3C +:100F3000CF93FC0183859485C0E06817790750F54D +:100F40008385948501976817790778F4808191816A +:100F50009B012F5F3F4FDC01A20FB31F4C91680F25 +:100F6000791FDB014C93B901EBCF94878387C08550 +:100F7000CC2399F04185528526813781BA01621BC5 +:100F8000730B8617970730F42417350718F4CF0131 +:100F90000E9435078C2FCF910895C1E0FBCF0F93AE +:100FA0001F93CF93DF93EC018B0169857A858B8545 +:100FB0009C8586179707A8F4F8018081E881F9815C +:100FC0002B853C85E20FF31F80832B853C85C9016F +:100FD00001969C878B87C901DF91CF911F910F915B +:100FE00008958E819F81009719F48FEF9FEFF4CFC2 +:100FF000680F791FCE010E9435078111DDCFF5CF33 +:101000000F931F93CF93DF93EC018B0169857A8552 +:101010000617170738F08E819F81680F791FCE0160 +:101020000E94350789859A852B853C850217130711 +:1010300040F08017910740F098012F5F3F4F3C87A9 +:101040002B870817190738F0CE010D96DF91CF9145 +:101050001F910F91089588819981800F911FF6CF7C +:10106000CF92DF92FF920F931F93CF93DF938C0168 +:10107000F62ED0E0C0E06C018FE0C80ED11CF80164 +:10108000828D938DC817D90798F4BE01C6010E94BE +:101090000008FC0180818F1109C0CE01DF91CF9142 +:1010A0001F910F91FF90DF90CF9008952196E7CF89 +:1010B0008FEF9FEFF3CFCF92DF92EF92FF920F93DC +:1010C0001F93CF93DF931F92CDB7DEB78C01698357 +:1010D000F12CE12C6C018FE0C80ED11CF801828D3F +:1010E000938DE816F90698F4B701C6010E9400082E +:1010F000FC0190818981981306C0B701C8014D9603 +:101100000E94A4060EC0FFEFEF1AFF0AE7CFBE0150 +:101110006F5F7F4FC6010E94CF0797FF0CC0C801C9 +:101120000D960F90DF91CF911F910F91FF90EF904F +:10113000DF90CF900895F801208131812F5F3F4FDC +:1011400031832083BC01DACFCF92DF92EF92FF92FE +:101150000F931F93CF93DF938C01D62ED0E0C0E086 +:101160007C018FE0E80EF11CD8015A968D919C917C +:10117000C817D90708F052C0BE01C7010E94000875 +:10118000FC0180818D1148C0D80198968D919C9169 +:10119000C817D90798F5AE01440F551FBE01019736 +:1011A000FA0132966817790790F4D8015D962D916F +:1011B0003C916F5F7F4FD901AE0FBF1FCD90DC9088 +:1011C000240F351FD901CD92DC92AF01E9CFF80190 +:1011D00091A780A725A1222389F046A157A123A189 +:1011E00034A1BA01621B730B8617970738F42417D2 +:1011F000350720F4C8014D960E940506BE01C701BF +:101200000E949807CE01DF91CF911F910F91FF901F +:10121000EF90DF90CF9008952196A6CF8FEF9FEFAC +:10122000F2CFCF92DF92EF92FF920F931F93CF9363 +:10123000DF931F92CDB7DEB78C016983F12CE12CCF +:101240006C018FE0C80ED11CF801828D938DE816D9 +:10125000F90698F4B701C6010E940008FC019081CC +:101260008981981306C0B701C8014D960E94720685 +:101270000EC0FFEFEF1AFF0AE7CFBE016F5F7F4F8F +:10128000C6010E94CF0797FF0CC0C8010D960F90B2 +:10129000DF91CF911F910F91FF90EF90DF90CF9052 +:1012A0000895F801208131812F5F3F4F31832083E2 +:1012B000BC01DACFCF92DF92EF92FF920F931F9390 +:1012C000CF93DF931F92CDB7DEB78C016983F12CEA +:1012D000E12C6C018EE0C80ED11CF801818D928D3D +:1012E000E816F90698F4B701C6010E940008FC014F +:1012F00090818981981306C0B701C8014C960E945D +:1013000000080EC0FFEFEF1AFF0AE7CFBE016F5FC4 +:101310007F4FC6010E94CF0797FF0CC0C8010D96F2 +:101320000F90DF91CF911F910F91FF90EF90DF9081 +:10133000CF900895F801208131812F5F3F4F318395 +:101340002083BC01DACFFC0180819181009711F0EC +:101350000C949B1308952F923F925F926F927F920D +:101360008F929F92AF92BF92CF92DF92EF92FF92B5 +:101370000F931F93CF93DF93CDB7DEB729970FB6A7 +:10138000F894DEBF0FBECDBF6C017B01DB016C9119 +:1013900011965C90673008F06FC4E62FF0E0ED52D4 +:1013A000F64F0C94F912DA09100AF10B5F0C9E0C3F +:1013B0003D0D790DDC01ED91FC910084F185E02D6E +:1013C000423011F1F12CE12C10E000E023E030E09C +:1013D000452D60E0C601099529960FB6F894DEBF49 +:1013E0000FBECDBFDF91CF911F910F91FF90EF9076 +:1013F000DF90CF90BF90AF909F908F907F906F9035 +:101400005F903F902F90089519821A824B8333E0AA +:10141000E32EF12C8E010F5F1F4F30E020E0D8CF7C +:10142000EDB7FEB7F987E887443079F0DC01ED913C +:10143000FC910084F185E02DF12CE12C10E000E01E +:1014400023E030E0452D61E0C5CFF70112818381B3 +:10145000282E312CD6011496ED90FC90823009F4A0 +:10146000F7C078F4882309F437C1813009F4E0C06B +:10147000612FC7010E945B08DC012D923C9280E045 +:10148000BEC0843009F4F1C008F4E7C0853081F7AC +:101490005701F6E5AF0EB11C712C612CC7018059C4 +:1014A0009F4F9F838E8345019FE0890E911CAE81E3 +:1014B000BF818D919C916816790650F4B301C401E7 +:1014C0000E940008FC0180811813DCC077FEDEC09A +:1014D00083E090E00E94FF124C0180914C018C301F +:1014E00008F0F6C091E0980F90934C01D4018C93D2 +:1014F00090E0FC01EE0FFF1FE80FF91FE85DFE4FC3 +:1015000088EB9BE092838183612FC5010E941109C2 +:10151000DC018D929C92612FC5010E941109FC0192 +:1015200080809180D4018C918C3008F055C061E0AE +:10153000812F0E940D01F4018081282F30E0F901F4 +:10154000EE0FFF1FE20FF31FE85DFE4F9081907CCE +:10155000212F2F73922B9083D40111961C921197F7 +:1015600012961C922CE0622F0E94ED12829FB00115 +:10157000112430E020E0AB01420F531FFA01EE0FBF +:10158000FF1FE40FF51FE85DFE4F908196FD16C02A +:101590002F5F3F4F2C30310571F781110FC0109232 +:1015A000800082E080938100109285001092840078 +:1015B000B19A80916F00826080936F00D401EC91AA +:1015C0008E2F90E0FC01EE0FFF1FE80FF91FE85D82 +:1015D000FE4F808180648083F40180818F3F09F019 +:1015E00047CF612FC5010E941109DC018D919C91AB +:1015F0000E949B13612FC5010E94A40885E0898386 +:10160000D601ED91FC910084F185E02DEE24E39468 +:10161000F12C8E010F5F1F4F30E020E0452D61E07F +:10162000C60109950FB6F894DEBF0FBECDBFD4CE6C +:1016300060E0812F0E940D01812F0E94B600082FCB +:10164000612FC7018C960E945A09FC01008310CFBC +:1016500061E0812F0E940D010BCF60E0812F0E947D +:101660000D01812F0E943E0103CF61E0812F0E9476 +:101670000D0161E0812F0E940D0160E0812F0E9429 +:10168000DF00F6CEFFEF6F1A7F0A11CF612FC50181 +:101690000E941109DC01ED91FC91E0818E2F90E018 +:1016A000FC01EE0FFF1FE80FF91FE85DFE4F808180 +:1016B0008F7B8083612FC5010E941109FC0180810D +:1016C00091810E949B13612FC5010E94A40800CF45 +:1016D0008FEFF401808318CFB12CA12CF701E059D2 +:1016E000FF4FFF83EE834701F6E58F0E911C340117 +:1016F0002FE0620E711CAE81BF818D919C91A81666 +:10170000B90650F4B501C3010E940008FC018081B4 +:1017100018131EC0B7FE20C0B12CA12C3701F5E470 +:101720006F0E711C47012AE3820E911CD3018D912B +:101730009C91A816B90650F4B501C4010E94000896 +:10174000FC01808118132AC0B7FE2CC060E081CF55 +:10175000FFEFAF1ABF0ACFCF612FC4010E9411095A +:10176000DC01ED91FC91E0818E2F90E0FC01EE0F09 +:10177000FF1FE80FF91FE85DFE4F80818F7B80839C +:10178000612FC4010E941109FC01808191810E9496 +:101790009B13612FC4010E94A408BECFFFEFAF1AB4 +:1017A000BF0AC4CFB12CA12CD3018D919C91A81656 +:1017B000B90660F6B501C4010E940008FC018081F1 +:1017C00018130BC0B501C701885B9F4F0E94980793 +:1017D000B501C4010E949807B9CFFFEFAF1ABF0A45 +:1017E000E3CF443079F0DC01ED91FC910084F18588 +:1017F000E02DF12CE12C10E000E023E030E0452D5D +:1018000062E0E8CDF70112819380DC011496ED903F +:10181000FC90612FC7010E9430080196C9F1612F29 +:10182000C7010E945B08FC0180819181029709F049 +:1018300042C001E0911001C000E0602F812F0E94A2 +:10184000DF00912C812C3701FDE86F0E711C22E81E +:10185000E20EF11CD3018D919C918816990668F5D2 +:10186000B401C7010E94CF051C830983DC01ED91FF +:10187000FC910480F581E02DAE014F5F5F4FBE010A +:101880006C5F7F4F02960995BFEF8B1A9B0AE2CFE0 +:1018900081E08D83D601ED91FC910084F185E02DEE +:1018A000EE24E394F12C8E010B5F1F4F30E020E01B +:1018B000452D62E0B5CE83E0ECCF80E0EACF433047 +:1018C00079F0DC01ED91FC910084F185E02DF12CA3 +:1018D000E12C10E000E023E030E0452D63E07ACD1C +:1018E000F7011281612FDC0114968D919C910E9469 +:1018F00021040097F1F001970297F0F4812F0E94E4 +:10190000B60021E0892B09F420E080E089832A8356 +:10191000D601ED91FC910084F185E02D02E0E02EEE +:10192000F12C8E010F5F1F4F30E020E0452D63E06A +:1019300077CE81E020E0EACF82E0FCCF443079F03E +:10194000DC01ED91FC910084F185E02DF12CE12C7E +:1019500010E000E023E030E0452D64E03BCDF701EE +:101960001281DC0114968D909C90612FC4010E941D +:101970002104009799F481E08983D601ED91FC91CF +:101980000084F185E02DEE24E394F12C8E010F5FAD +:101990001F4F30E020E0452D64E042CE049711F067 +:1019A00083E0EACFF7010381612FC4010E94300870 +:1019B000019609F3612FC4010E945B08DC018D913F +:1019C0009C91049769F7E02EF12C61E0812F0E9431 +:1019D0000D01E114F10429F460E0812F0E94DF0081 +:1019E0002BC0BFEFEB16F10411F461E0F6CFE12F4D +:1019F000F0E0E255FF4FE491E33029F148F4E130A3 +:101A0000B9F0E230D9F0E0E8EE16F10474F7E4CF73 +:101A1000E73019F1E83049F1E430A9F7809180000E +:101A2000806280938000F0928B00E0928A0004C074 +:101A300084B5806884BD07BD80E09ECF84B5806298 +:101A400084BD08BDF9CF80918000806880938000BC +:101A5000F0928900E0928800EFCF8091B00080681A +:101A60008093B0000093B300E7CF8091B000806214 +:101A70008093B0000093B400DFCF433079F0DC01F5 +:101A8000ED91FC910084F185E02DF12CE12C10E02A +:101A900000E023E030E0452D65E09CCCF7011281A9 +:101AA000612FDC0114968D919C910E942104009776 +:101AB000E1F0039722E00297C8F4812F0E943E01D3 +:101AC00020E029839A838B83D601ED91FC910084D9 +:101AD000F185E02DB3E0EB2EF12C8E010F5F1F4F4F +:101AE00030E020E0452D65E09BCD21E080E090E0F6 +:101AF000E8CF443079F0DC01ED91FC910084F18570 +:101B0000E02DF12CE12C10E000E023E030E0452D49 +:101B100066E060CCF7011281DC0114968D909C90F8 +:101B2000612FC4010E942104009799F481E0898308 +:101B3000D601ED91FC910084F185E02DEE24E39433 +:101B4000F12C8E010F5F1F4F30E020E0452D66E045 +:101B500067CD059709F08CC0F701038184E0053B50 +:101B600030F7612FC4010E94300897FDDFCF612F4D +:101B7000C4010E945B08DC018D919C91059709F0DE +:101B800079C0B6E58B0E911C612FC4010E9411092A +:101B9000DC01ED91FC91E0818E2F90E0FC01EE0FD5 +:101BA000FF1FE80FF91FE85DFE4F808186FFBECF63 +:101BB000612FC4010E941109DC01ED91FC9110819B +:101BC0001C3008F053C0828148E5842E42E0942EF8 +:101BD000881A910887FD93941401220C331C220C5F +:101BE000331C818168E8E62EF12CE81AF10887FDA4 +:101BF000F394EE0CFF1CEE0CFF1C37010F2C000CB5 +:101C0000880899089101032C000C440B550B2619E8 +:101C1000370948095909A02FB0E00E94B11224EBFE +:101C200030E040E050E00E949212BA01A901460D56 +:101C3000571D681D791D4E155F052CF07101421569 +:101C400053050CF47A01B2E0EB1AF108EE0CFF1C1C +:101C50002FB7F894812F90E0FC01EE0FFF1FE80FE3 +:101C6000F91FE85DFE4FF282E1822FBF80E05FCF77 +:101C700082E05DCF83E05BCFDC01ED91FC910084DD +:101C8000F185E02DF12CE12C10E000E022E030E0C5 +:101C9000452D0995A1CB1F920F920FB60F921124DB +:101CA0002F933F938F939F93AF93BF9380915F0147 +:101CB00090916001A0916101B091620130915E014B +:101CC00023E0230F2D3758F50196A11DB11D209358 +:101CD0005E0180935F0190936001A0936101B093D6 +:101CE00062018091630190916401A0916501B091BE +:101CF00066010196A11DB11D80936301909364015B +:101D0000A0936501B0936601BF91AF919F918F91B0 +:101D10003F912F910F900FBE0F901F90189526E8BE +:101D2000230F0296A11DB11DD2CF1F920F920FB6A5 +:101D30000F9211242F933F934F935F936F937F9351 +:101D40008F939F93AF93BF93EF93FF9387E691E0B9 +:101D50000E942C02FF91EF91BF91AF919F918F91C3 +:101D60007F916F915F914F913F912F910F900FBE97 +:101D70000F901F9018951F920F920FB60F9211247B +:101D80002F938F939F93EF93FF93E0917701F091BF +:101D900078018081E0917D01F0917E0182FD1BC080 +:101DA0009081809180018F5F8F73209181018217D4 +:101DB00041F0E0918001F0E0E959FE4F958F80936A +:101DC0008001FF91EF919F918F912F910F900FBE06 +:101DD0000F901F9018958081F4CF1F920F920FB62D +:101DE0000F9211242F933F934F935F936F937F93A1 +:101DF0008F939F93AF93BF93CF93DF93EF93FF9313 +:101E000080914D01C0914C01D0E087FF24C0109219 +:101E100085001092840080914D018F5F80934D0169 +:101E200080914D01082E000C990B8C179D0724F40E +:101E300080914D018C30C4F1809184009091850097 +:101E4000049680349C4908F47AC080918400909173 +:101E50008500049676C080914D01082E000C990BE8 +:101E60008C179D07C4F6E0914D018E2FEE0F990B54 +:101E7000FC01EE0FFF1FE80FF91FE85DFE4F8081A8 +:101E800086FFC9CFE0914D018E2FEE0F990BFC011B +:101E9000EE0FFF1FE80FF91FE85DFE4F808160E045 +:101EA0008F730E94DF00B7CF2091840030918500AE +:101EB000E0914D018E2FEE0F990BFC01EE0FFF1FED +:101EC000E80FF91FE85DFE4F81819281820F931F19 +:101ED0009093890080938800E0914D018E2FEE0F42 +:101EE000990BFC01EE0FFF1FE80FF91FE85DFE4F95 +:101EF000808186FF11C0E0914D018E2FEE0F990B6E +:101F0000FC01EE0FFF1FE80FF91FE85DFE4F808117 +:101F100061E08F730E94DF00FF91EF91DF91CF911D +:101F2000BF91AF919F918F917F916F915F914F91F1 +:101F30003F912F910F900FBE0F901F90189580E446 +:101F40009CE990938900809388008FEF80934D01E6 +:101F5000E3CFCF92DF92FF920F931F93CF93DF9344 +:101F6000E7E6F1E01382128288EE93E0A0E0B0E0B1 +:101F700084839583A683B7838AE191E091838083EC +:101F800085EC90E09587848784EC90E0978786873E +:101F900080EC90E0918B808B81EC90E0938B828B36 +:101FA00082EC90E0958B848B86EC90E0978B868B0F +:101FB000118E128E138E148EC4E0D2E000E110E078 +:101FC0001F830E83CC24CA94DC2CD986C8861B8739 +:101FD0000A87FF24F394FC861E861D861A8B098BC4 +:101FE000DC8ACB8A1E8B0D8BFF8A1C8E1B8E1A8E71 +:101FF000198F088F80E190E00E94FF12988B8F87E5 +:1020000018A30F8FDAA2C9A21CA30BA3FDA21BA6C3 +:102010001AA619A618A61FA30EA380E290E00E949C +:10202000FF129E8F8D8F198218821D830C831BAB2C +:102030000AABDDAACCAA1FAB0EABF8AE19AE1DAF32 +:102040000CAFDFAECEAE1093450200934402F09287 +:10205000460210924B0210924A02109249021093CB +:1020600048020093470280E190E00E94FF129BAF7C +:102070008AAF10934F0200934E02D0925102C09249 +:1020800050021093530200935202F09254021092A5 +:102090005902109258021092570210935602009360 +:1020A000550280E190E00E94FF1290934D028093D0 +:1020B0004C021DA61CA619AB08AB1093610200933D +:1020C0006002D0926302C092620210936502009394 +:1020D0006402F092660210926802109267021093F6 +:1020E0006C0200936B02D0926E02C0926D0210934C +:1020F000700200936F02F0927102109276021092B9 +:10210000750210927402109373020093720280E1C0 +:1021100090E00E94FF1290936A02809369021093EC +:102120007A0200937902D0927C02C0927B021093D3 +:102130007E0200937D02F0927F021092850210923F +:102140008402109283021092820210938102009303 +:10215000800280E290E00E94FF12909378028093C8 +:10216000770210925B0210925A0210935F02009362 +:102170005E021093890200938802D0928B02C09273 +:102180008A0210938D0200938C02F0928E021092BC +:102190009402109293021092920210929102109364 +:1021A000900200938F0280E190E00E944804909397 +:1021B000870280938602DF91CF911F910F91FF904C +:1021C000DF90CF900895CF93DF93CDB7DEB76097C0 +:1021D0000FB6F894DEBF0FBECDBF789484B5826091 +:1021E00084BD84B5816084BD85B5826085BD85B5BB +:1021F000816085BD80916E00816080936E00109239 +:1022000081008091810082608093810080918100B3 +:102210008160809381008091800081608093800044 +:102220008091B10084608093B1008091B0008160A2 +:102230008093B00080917A00846080937A008091CE +:102240007A00826080937A0080917A008160809326 +:102250007A0080917A00806880937A001092C100A1 +:1022600088E091E00E94FF128C018AE091E0D801A1 +:1022700011969C938E9387E691E013969C938E9390 +:10228000129784E092E015969C938E931497F80130 +:10229000EB5FFE4F10823196108231961082809152 +:1022A0005401811115C08CED92E090934F01809301 +:1022B0004E018DEA91E090935101809350018BEB98 +:1022C00092E0909353018093520181E080935401F6 +:1022D0008EE491E09A8389831C830B83CE0101965F +:1022E0000E948105CE0101960E94160410935D01A3 +:1022F00000935C0161E08DE00E940D0161E08DE0E2 +:102300000E94DF000E94780160E08DE00E94DF0003 +:102310000E94780161E08DE00E94DF000E94780158 +:1023200060E08DE00E94DF0060E08DE00E940D0122 +:10233000D8011296ED91FC91A089B18982E08C932D +:10234000A485B5851C92A685B78580E18C93108EF7 +:10235000A489B58986E08C93A289B3898C91806128 +:102360008C93A289B3898C9188608C93A289B3895C +:102370008C9180688C930288F389E02D80818F7D19 +:1023800080830E94780130E020E050E040E060EF80 +:1023900070E0C8010E94E60280E0A82E80E0B82E1E +:1023A0006EE372E0CE0101960E946904F12CE12CEB +:1023B0008C859D85E816F90608F04FC0B701CE015F +:1023C00001960E940008FC011081612F84E092E0D8 +:1023D0000E945B08DC018D919C910197D1F5812FC2 +:1023E0000E94B600082F612F80E392E00E945A09F4 +:1023F000FC018081081769F1612F80E392E00E945F +:102400005A09DC010C93D12CC12C8091910290913E +:102410009202C816D906E8F4B60186E892E00E9456 +:10242000CF05188B21E0013009F020E02F87DC0177 +:10243000ED91FC910480F581E02DAE01415F5F4F8D +:10244000BE01605F7F4F02960995BFEFCB1ADB0A92 +:10245000DCCFEFEFEE1AFE0AABCFCE0101960E9461 +:10246000A30900915C0110915D01D80112968D9134 +:102470009C91DC01ED91FC910084F185E02D0995A2 +:10248000892BA1F0F80182819381DC01ED91FC910F +:102490000284F385E02D0995D801ED91FC9101901E +:1024A000F081E02D682FC8010995DFCFA114B10498 +:1024B00009F476CF0E941802882309F471CF0E9494 +:1024C00000006ECF8091860290918702009731F0D4 +:1024D0000E94B504109287021092860283E992E06E +:1024E0000E9416048091770290917802009711F073 +:1024F0000E949B1389E692E00E94A3098CE492E07B +:102500000E94A3098EE392E00E94A3098091210218 +:1025100090912202009711F00E949B1383E192E0B8 +:102520000C94A309052E97FB1EF400940E94A91297 +:1025300057FD07D00E94BC1207FC03D04EF40C9448 +:10254000A91250954095309521953F4F4F4F5F4FC1 +:10255000089590958095709561957F4F8F4F9F4F0F +:1025600008950E94DE12A59F900DB49F900DA49F28 +:10257000800D911D11240895A1E21A2EAA1BBB1BE8 +:10258000FD010DC0AA1FBB1FEE1FFF1FA217B3073F +:10259000E407F50720F0A21BB30BE40BF50B661F55 +:1025A000771F881F991F1A9469F760957095809519 +:1025B00090959B01AC01BD01CF010895A29FB00190 +:1025C000B39FC001A39F700D811D1124911DB29F67 +:1025D000700D811D1124911D0895991B79E004C08F +:1025E000991F961708F0961B881F7A95C9F7809552 +:1025F0000895EE0FFF1F0590F491E02D09940F93BD +:102600001F93CF93DF938230910510F482E090E026 +:10261000E0919F02F091A00230E020E0B0E0A0E065 +:10262000309799F42115310509F44AC0281B390B5C +:1026300024303105D8F58A819B816115710589F1B6 +:10264000FB0193838283FE0111C04081518102818D +:10265000138148175907E0F04817590799F4109764 +:1026600061F012960C93129713961C933296CF0139 +:10267000DF91CF911F910F91089500939F021093C6 +:10268000A002F4CF2115310551F04217530738F05D +:10269000A901DB019A01BD01DF01F801C1CFEF0102 +:1026A000F9CF9093A00280939F02CDCFFE01E20F5D +:1026B000F31F819391932250310939832883D7CF17 +:1026C00020919D0230919E02232B41F42091020122 +:1026D0003091030130939E0220939D0220910001CE +:1026E000309101012115310541F42DB73EB74091DC +:1026F000040150910501241B350BE0919D02F091DE +:102700009E02E217F307A0F42E1B3F0B2817390790 +:1027100078F0AC014E5F5F4F2417350748F04E0F3D +:102720005F1F50939E0240939D02819391939FCF90 +:10273000F0E0E0E09CCFCF93DF930097E9F0FC015D +:10274000329713821282A0919F02B091A002ED01F4 +:1027500030E020E01097A1F420813181820F931F97 +:1027600020919D0230919E022817390709F061C01F +:10277000F0939E02E0939D02DF91CF910895EA01CC +:10278000CE17DF07E8F54A815B819E0141155105AF +:10279000B1F7E901FB83EA8349915991C40FD51F31 +:1027A000EC17FD0761F4808191810296840F951FDB +:1027B000E90199838883828193819B838A83F0E0F6 +:1027C000E0E012968D919C9113970097B9F52D91A9 +:1027D0003C911197CD010296820F931F20919D028B +:1027E00030919E022817390739F6309751F510922B +:1027F000A00210929F02B0939E02A0939D02BCCFB4 +:10280000D383C28340815181840F951FC817D90794 +:1028100061F44E5F5F4F88819981480F591F518342 +:1028200040838A819B81938382832115310509F03E +:10283000B0CFF093A002E0939F029ECFFD01DC0198 +:10284000C0CF13821282D7CF10E0C2E6D0E004C01E +:10285000FE010E94F9122196C336D107C9F7F894F8 +:02286000FFCFA8 +:102862000000A102800000000000C2039C0391034B +:10287200AB093903E602000000004E02AE01DB01A3 +:082882009B020C02EA01FE01B9 +:00000001FF diff --git a/owlet/firmware/arduino-uno/release.json b/owlet/firmware/arduino-uno/release.json new file mode 100644 index 000000000..03bdde17f --- /dev/null +++ b/owlet/firmware/arduino-uno/release.json @@ -0,0 +1,4 @@ +{ + "firmwareFile": "firmware.hex", + "version": "0.0.2" +} diff --git a/owlet/integrationpluginowlet.cpp b/owlet/integrationpluginowlet.cpp index d9639cbcb..62374b007 100644 --- a/owlet/integrationpluginowlet.cpp +++ b/owlet/integrationpluginowlet.cpp @@ -47,6 +47,7 @@ IntegrationPluginOwlet::IntegrationPluginOwlet() { + } void IntegrationPluginOwlet::init() @@ -56,7 +57,9 @@ void IntegrationPluginOwlet::init() m_owletIdParamTypeMap.insert(ws2812ThingClassId, ws2812ThingOwletIdParamTypeId); m_owletSerialPortParamTypeMap.insert(arduinoUnoThingClassId, arduinoUnoThingSerialPortParamTypeId); - m_owletSerialPortParamTypeMap.insert(arduinoMiniProThingClassId, arduinoMiniProThingSerialPortParamTypeId); + m_owletSerialPortParamTypeMap.insert(arduinoNanoThingClassId, arduinoNanoThingSerialPortParamTypeId); + m_owletSerialPortParamTypeMap.insert(arduinoMiniPro5VThingClassId, arduinoMiniPro5VThingSerialPortParamTypeId); + m_owletSerialPortParamTypeMap.insert(arduinoMiniPro3VThingClassId, arduinoMiniPro3VThingSerialPortParamTypeId); m_zeroConfBrowser = hardwareManager()->zeroConfController()->createServiceBrowser("_nymea-owlet._tcp"); @@ -89,36 +92,121 @@ void IntegrationPluginOwlet::init() m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPinA4ParamTypeId, 18); m_arduinoUnoPinMapping.insert(arduinoUnoSettingsPinA5ParamTypeId, 19); - // Arduino Mini Pro mapping - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin2ParamTypeId, 2); - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin3ParamTypeId, 3); - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin4ParamTypeId, 4); - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin5ParamTypeId, 5); - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin6ParamTypeId, 6); - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin7ParamTypeId, 7); - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin8ParamTypeId, 8); - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin9ParamTypeId, 9); - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin10ParamTypeId, 10); - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin11ParamTypeId, 11); - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin12ParamTypeId, 12); - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPin13ParamTypeId, 13); - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPinA1ParamTypeId, 15); - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPinA2ParamTypeId, 16); - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPinA3ParamTypeId, 17); - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPinA4ParamTypeId, 18); - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPinA5ParamTypeId, 19); - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPinA6ParamTypeId, 20); - m_arduinoMiniProPinMapping.insert(arduinoMiniProSettingsPinA7ParamTypeId, 21); + // Arduino Mini Pro 5V mapping + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPin2ParamTypeId, 2); + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPin3ParamTypeId, 3); + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPin4ParamTypeId, 4); + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPin5ParamTypeId, 5); + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPin6ParamTypeId, 6); + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPin7ParamTypeId, 7); + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPin8ParamTypeId, 8); + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPin9ParamTypeId, 9); + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPin10ParamTypeId, 10); + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPin11ParamTypeId, 11); + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPin12ParamTypeId, 12); + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPin13ParamTypeId, 13); + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPinA1ParamTypeId, 15); + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPinA2ParamTypeId, 16); + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPinA3ParamTypeId, 17); + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPinA4ParamTypeId, 18); + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPinA5ParamTypeId, 19); + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPinA6ParamTypeId, 20); + m_arduinoMiniPro5VPinMapping.insert(arduinoMiniPro5VSettingsPinA7ParamTypeId, 21); + + // Arduino Mini Pro 3.3V mapping + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPin2ParamTypeId, 2); + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPin3ParamTypeId, 3); + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPin4ParamTypeId, 4); + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPin5ParamTypeId, 5); + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPin6ParamTypeId, 6); + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPin7ParamTypeId, 7); + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPin8ParamTypeId, 8); + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPin9ParamTypeId, 9); + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPin10ParamTypeId, 10); + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPin11ParamTypeId, 11); + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPin12ParamTypeId, 12); + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPin13ParamTypeId, 13); + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPinA1ParamTypeId, 15); + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPinA2ParamTypeId, 16); + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPinA3ParamTypeId, 17); + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPinA4ParamTypeId, 18); + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPinA5ParamTypeId, 19); + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPinA6ParamTypeId, 20); + m_arduinoMiniPro3VPinMapping.insert(arduinoMiniPro3VSettingsPinA7ParamTypeId, 21); + + // Arduino Nano + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPin0ParamTypeId, 0); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPin1ParamTypeId, 1); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPin2ParamTypeId, 2); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPin3ParamTypeId, 3); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPin4ParamTypeId, 4); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPin5ParamTypeId, 5); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPin6ParamTypeId, 6); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPin7ParamTypeId, 7); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPin8ParamTypeId, 8); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPin9ParamTypeId, 9); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPin10ParamTypeId, 10); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPin11ParamTypeId, 11); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPin12ParamTypeId, 12); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPin13ParamTypeId, 13); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPinA0ParamTypeId, 14); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPinA1ParamTypeId, 15); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPinA2ParamTypeId, 16); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPinA3ParamTypeId, 17); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPinA4ParamTypeId, 18); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPinA5ParamTypeId, 19); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPinA6ParamTypeId, 20); + m_arduinoNanoPinMapping.insert(arduinoNanoSettingsPinA7ParamTypeId, 21); } void IntegrationPluginOwlet::discoverThings(ThingDiscoveryInfo *info) { - if (info->thingClassId() == arduinoMiniProThingClassId) { + if (info->thingClassId() == arduinoMiniPro5VThingClassId) { + // 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 Pro Mini 5V 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 if (info->thingClassId() == arduinoMiniPro3VThingClassId) { // 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 Pro Mini Owlet", description); + ThingDescriptor thingDescriptor(info->thingClassId(), "Arduino Pro Mini 3.3V 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 if (info->thingClassId() == arduinoNanoThingClassId) { + // 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 Nano Owlet", description); ParamList parameters; foreach (Thing *existingThing, myThings()) { @@ -173,9 +261,9 @@ void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) { Thing *thing = info->thing(); - if (thing->thingClassId() == arduinoMiniProThingClassId) { - QString serialPort = thing->paramValue(arduinoMiniProThingSerialPortParamTypeId).toString(); - qCDebug(dcOwlet()) << "Setup arduino mini pro owlet on" << serialPort; + 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); @@ -193,7 +281,7 @@ void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) // Runtime connect(client, &OwletSerialClient::connected, thing, [=](){ thing->setStateValue("connected", true); - thing->setStateValue(arduinoMiniProCurrentVersionStateTypeId, client->firmwareVersion()); + thing->setStateValue(arduinoUnoCurrentVersionStateTypeId, client->firmwareVersion()); foreach (Thing *childThing, myThings().filterByParentId(thing->id())) { childThing->setStateValue("connected", true); } @@ -207,8 +295,8 @@ void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) }); connect(thing, &Thing::settingChanged, thing, [=](const ParamTypeId ¶mTypeId, const QVariant &value){ - qCDebug(dcOwlet()) << "Arduino Mini Pro settings changed" << paramTypeId << value; - quint8 pinId = m_arduinoMiniProPinMapping.value(paramTypeId); + 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 @@ -248,10 +336,84 @@ void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) return; } + if (thing->thingClassId() == arduinoNanoThingClassId) { + QString serialPort = thing->paramValue(arduinoNanoThingSerialPortParamTypeId).toString(); + qCDebug(dcOwlet()) << "Setup Arduino Nano owlet on" << serialPort; + OwletTransport *transport = new OwletSerialTransport(serialPort, 115200, this); + OwletSerialClient *client = new OwletSerialClient(transport, transport); - if (thing->thingClassId() == arduinoUnoThingClassId) { - QString serialPort = thing->paramValue(arduinoUnoThingSerialPortParamTypeId).toString(); - qCDebug(dcOwlet()) << "Setup arduino uno owlet on" << serialPort; + // 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(arduinoNanoCurrentVersionStateTypeId, 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 Nano settings changed" << paramTypeId << value; + quint8 pinId = m_arduinoNanoPinMapping.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() == arduinoMiniPro5VThingClassId) { + QString serialPort = thing->paramValue(arduinoMiniPro5VThingSerialPortParamTypeId).toString(); + qCDebug(dcOwlet()) << "Setup Arduino Mini Pro 5V owlet on" << serialPort; OwletTransport *transport = new OwletSerialTransport(serialPort, 115200, this); OwletSerialClient *client = new OwletSerialClient(transport, transport); @@ -269,7 +431,7 @@ void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) // Runtime connect(client, &OwletSerialClient::connected, thing, [=](){ thing->setStateValue("connected", true); - thing->setStateValue(arduinoUnoCurrentVersionStateTypeId, client->firmwareVersion()); + thing->setStateValue(arduinoMiniPro5VCurrentVersionStateTypeId, client->firmwareVersion()); foreach (Thing *childThing, myThings().filterByParentId(thing->id())) { childThing->setStateValue("connected", true); } @@ -283,8 +445,83 @@ void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) }); 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); + qCDebug(dcOwlet()) << "Arduino Mini Pro 5V settings changed" << paramTypeId << value; + quint8 pinId = m_arduinoMiniPro5VPinMapping.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() == arduinoMiniPro3VThingClassId) { + QString serialPort = thing->paramValue(arduinoMiniPro3VThingSerialPortParamTypeId).toString(); + qCDebug(dcOwlet()) << "Setup Arduino Mini Pro 3.3V 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(arduinoMiniPro3VCurrentVersionStateTypeId, 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 Mini Pro 3.3V settings changed" << paramTypeId << value; + quint8 pinId = m_arduinoMiniPro3VPinMapping.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 @@ -746,7 +983,7 @@ void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) return; } - if (info->thing()->thingClassId() == arduinoMiniProThingClassId) { + 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"; @@ -759,7 +996,7 @@ void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) info->finish(Thing::ThingErrorHardwareNotAvailable); return; } - if (info->action().actionTypeId() == arduinoMiniProPerformUpdateActionTypeId) { + if (info->action().actionTypeId() == arduinoUnoPerformUpdateActionTypeId) { qCDebug(dcOwlet()) << "Perform firmware update on" << info->thing(); //if (client->firmwareVersion() != ) @@ -770,7 +1007,7 @@ void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) } } - if (info->thing()->thingClassId() == arduinoUnoThingClassId) { + if (info->thing()->thingClassId() == arduinoNanoThingClassId) { OwletSerialClient *client = m_serialClients.value(info->thing()); if (!client) { qCWarning(dcOwlet()) << "Could not execute action. There is no client available for this thing"; @@ -783,7 +1020,55 @@ void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) info->finish(Thing::ThingErrorHardwareNotAvailable); return; } - if (info->action().actionTypeId() == arduinoUnoPerformUpdateActionTypeId) { + if (info->action().actionTypeId() == arduinoNanoPerformUpdateActionTypeId) { + 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() == arduinoMiniPro5VThingClassId) { + 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() == arduinoMiniPro5VPerformUpdateActionTypeId) { + 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() == arduinoMiniPro3VThingClassId) { + 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() == arduinoMiniPro3VPerformUpdateActionTypeId) { qCDebug(dcOwlet()) << "Perform firmware update on" << info->thing(); //if (client->firmwareVersion() != ) @@ -954,7 +1239,13 @@ void IntegrationPluginOwlet::executeAction(ThingActionInfo *info) void IntegrationPluginOwlet::thingRemoved(Thing *thing) { - if (thing->thingClassId() == arduinoMiniProThingClassId && m_serialClients.contains(thing)) { + if (thing->thingClassId() == arduinoMiniPro5VThingClassId && m_serialClients.contains(thing)) { + m_serialClients.take(thing)->deleteLater(); + } else if (thing->thingClassId() == arduinoMiniPro3VThingClassId && m_serialClients.contains(thing)) { + m_serialClients.take(thing)->deleteLater(); + } else if (thing->thingClassId() == arduinoUnoThingClassId && m_serialClients.contains(thing)) { + m_serialClients.take(thing)->deleteLater(); + } else if (thing->thingClassId() == arduinoNanoThingClassId && m_serialClients.contains(thing)) { m_serialClients.take(thing)->deleteLater(); } } @@ -1087,8 +1378,12 @@ 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(); + } else if (parent->thingClassId() == arduinoMiniPro5VThingClassId) { + return parent->thingClass().settingsTypes().findById(m_arduinoMiniPro5VPinMapping.key(pinId)).displayName(); + } else if (parent->thingClassId() == arduinoMiniPro3VThingClassId) { + return parent->thingClass().settingsTypes().findById(m_arduinoMiniPro3VPinMapping.key(pinId)).displayName(); + } else if (parent->thingClassId() == arduinoNanoThingClassId) { + return parent->thingClass().settingsTypes().findById(m_arduinoNanoPinMapping.key(pinId)).displayName(); } return QString(); diff --git a/owlet/integrationpluginowlet.h b/owlet/integrationpluginowlet.h index e4e2859cf..5d4a34367 100644 --- a/owlet/integrationpluginowlet.h +++ b/owlet/integrationpluginowlet.h @@ -68,7 +68,9 @@ class IntegrationPluginOwlet: public IntegrationPlugin QHash m_owletSerialPinParamTypeMap; QHash m_arduinoUnoPinMapping; - QHash m_arduinoMiniProPinMapping; + QHash m_arduinoMiniPro5VPinMapping; + QHash m_arduinoMiniPro3VPinMapping; + QHash m_arduinoNanoPinMapping; OwletSerialClient::PinMode getPinModeFromSettingsValue(const QString &settingsValue); void setupArduinoChildThing(OwletSerialClient *client, quint8 pinId, OwletSerialClient::PinMode pinMode); diff --git a/owlet/integrationpluginowlet.json b/owlet/integrationpluginowlet.json index 8c412990c..9974a3a8a 100644 --- a/owlet/integrationpluginowlet.json +++ b/owlet/integrationpluginowlet.json @@ -543,8 +543,8 @@ }, { "id": "22f216f4-9715-48f9-ab76-f7d7436d49c9", - "name": "arduinoMiniPro", - "displayName": "Arduino Pro Mini Owlet", + "name": "arduinoMiniPro5V", + "displayName": "Arduino Pro Mini 5V Owlet", "createMethods": ["user", "discovery"], "interfaces": ["gateway", "update", "connectable"], "paramTypes": [ @@ -849,6 +849,661 @@ } ] }, + { + "id": "851e3edb-91f5-4a9b-82ee-ce8b0c140f63", + "name": "arduinoMiniPro3V", + "displayName": "Arduino Pro Mini 3.3V Owlet", + "createMethods": ["user", "discovery"], + "interfaces": ["gateway", "update", "connectable"], + "paramTypes": [ + { + "id": "bb177b49-f601-4afe-9107-3273622efaf3", + "name": "serialPort", + "displayName": "Serial port", + "type": "QString", + "inputType": "TextLine", + "defaultValue": "/dev/ttyS0" + }, + { + "id": "f953d32a-72d6-4e69-b784-00aaa590307f", + "name": "resetGpio", + "displayName": "Reset GPIO", + "type": "uint", + "defaultValue": 18 + } + ], + "settingsTypes": [ + { + "id": "52ec2ef1-2eb8-4249-a968-31851fc1ffb0", + "name": "pin2", + "displayName": "Pin 2", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output" + ], + "defaultValue": "None" + }, + { + "id": "e810eeeb-46db-453e-9526-b66632183184", + "name": "pin3", + "displayName": "Pin 3", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "4d8df173-bcc5-4965-8163-b3b178d7ecc3", + "name": "pin4", + "displayName": "Pin 4", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output" + ], + "defaultValue": "None" + }, + { + "id": "c59494c0-b5b3-4fdc-9efa-3c7d8981bc69", + "name": "pin5", + "displayName": "Pin 5", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "cb908496-e638-4280-999a-517723855078", + "name": "pin6", + "displayName": "Pin 6", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "3ea774fd-1548-4b49-96c8-57b7d444319c", + "name": "pin7", + "displayName": "Pin 7", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output" + ], + "defaultValue": "None" + }, + { + "id": "68af1181-482c-4c6c-abe0-29f3665dada3", + "name": "pin8", + "displayName": "Pin 8", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output" + ], + "defaultValue": "None" + }, + { + "id": "0b1d1fd6-d4fc-47d2-8023-a7dfbff69684", + "name": "pin9", + "displayName": "Pin 9", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "96501a1a-360f-4704-bcd5-97219fcc24c5", + "name": "pin10", + "displayName": "Pin 10", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "8a57d186-d55d-405d-a2ad-58b9a7113250", + "name": "pin11", + "displayName": "Pin 11", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "2c2cf54c-7463-4b10-b360-65aa6d74dc5d", + "name": "pin12", + "displayName": "Pin 12", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output" + ], + "defaultValue": "None" + }, + { + "id": "a99af2d8-4195-48f1-a85d-59de7f8575ca", + "name": "pin13", + "displayName": "Pin 13 - LED", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output" + ], + "defaultValue": "None" + }, + { + "id": "3211da31-2765-41ce-ad57-09db29e67d92", + "name": "pinA1", + "displayName": "Pin A1", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "69022223-6e8e-4900-8cb3-2027c1dff0e4", + "name": "pinA2", + "displayName": "Pin A2", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "91a121c5-4bae-490f-be3d-45aca3a08153", + "name": "pinA3", + "displayName": "Pin A3", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "19e712be-8da8-4bd9-ad47-aa7ebe8a2750", + "name": "pinA4", + "displayName": "Pin A4", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "82d02472-ec98-4824-a2b4-eb61acb08bc6", + "name": "pinA5", + "displayName": "Pin A5", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "e57824d7-5718-4718-bbf0-daf364eb0881", + "name": "pinA6", + "displayName": "Pin A6", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "836f26f1-3b5a-444e-8ebd-30e05aa08293", + "name": "pinA7", + "displayName": "Pin A7", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + } + ], + "stateTypes": [ + { + "id": "5092d770-b1f1-491b-ab4d-261f7e9d28f6", + "name": "connected", + "displayName": "Connected", + "displayNameEvent": "Connected changed", + "type": "bool", + "defaultValue": false, + "cached": false + }, + { + "id": "97e4757f-f12b-411c-9d12-4385c624da41", + "name": "currentVersion", + "displayName": "Firmware version", + "displayNameEvent": "Firmware version changed", + "type": "QString", + "defaultValue": "" + }, + { + "id": "877a41fa-28f9-4e55-aef1-1578d8144f11", + "name": "updateStatus", + "displayName": "Update status", + "displayNameEvent": "Update status changed", + "type": "QString", + "possibleValues": ["idle", "available", "updating"], + "defaultValue": "idle" + } + ], + "actionTypes": [ + { + "id": "c4725773-b51f-48c1-9b83-65c64d44c8d8", + "name": "performUpdate", + "displayName": "Update firmware" + } + ] + }, + { + "id": "08320505-4247-4afb-90f8-ec7cba4988dc", + "name": "arduinoNano", + "displayName": "Arduino Nano Owlet", + "createMethods": ["user", "discovery"], + "interfaces": ["gateway", "update", "connectable"], + "paramTypes": [ + { + "id": "59659d72-ed74-4a0e-8bcd-0d383da0c66e", + "name": "serialPort", + "displayName": "Serial port", + "type": "QString", + "inputType": "TextLine", + "defaultValue": "/dev/ttyS0" + } + ], + "settingsTypes": [ + { + "id": "5bea8e92-4549-4fab-8094-b385233e1674", + "name": "pin0", + "displayName": "D0 - RX", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "9989f40b-f74c-4af9-bf3c-e06aadf61f33", + "name": "pin1", + "displayName": "D1 - TX", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "92fb8412-fd61-4217-8e9b-29129c99e28f", + "name": "pin2", + "displayName": "D2", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "d535b1be-91ac-4f39-a4b8-e68cb2913e19", + "name": "pin3", + "displayName": "D3", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "5a3cbfda-5f49-4165-b9a8-cb7c63700396", + "name": "pin4", + "displayName": "D4", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "3aae34ae-4603-42dc-a37d-a2bfaff50a9d", + "name": "pin5", + "displayName": "D5", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "0d41ebd4-9968-48d4-847d-838c4516cb5b", + "name": "pin6", + "displayName": "D6", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "6126783c-fcd7-4a47-833b-ae7b1a0d38d7", + "name": "pin7", + "displayName": "D7", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "c0110e6d-0447-4c1e-ba47-1076d368f910", + "name": "pin8", + "displayName": "D8", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "ccb92f37-85aa-49ba-b23a-841a3e62f6f9", + "name": "pin9", + "displayName": "D9", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "eafd8726-b379-44a7-8045-b92b1277223e", + "name": "pin10", + "displayName": "D10", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "12c5a481-6358-485a-9f2e-bf15c73b92a6", + "name": "pin11", + "displayName": "D11", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "PWM", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "f662e8ee-1e3e-4549-bbe1-853b096687e4", + "name": "pin12", + "displayName": "D12", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "6169b8db-0041-4404-a569-62fe65dad7a7", + "name": "pin13", + "displayName": "D13 - LED", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "d6792750-e6b2-4114-a920-fdd58af26add", + "name": "pinA0", + "displayName": "A0", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input", + "Servo" + ], + "defaultValue": "None" + }, + { + "id": "20ca17fd-8717-40f8-8d01-89f78d275919", + "name": "pinA1", + "displayName": "A1", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "16571039-7c64-41e6-baaa-65670170341d", + "name": "pinA2", + "displayName": "A2", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "eb3f6de3-c953-4881-a86f-68725d481246", + "name": "pinA3", + "displayName": "A3", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "1d89e5f1-089e-4d17-aa6b-7dba1f12c622", + "name": "pinA4", + "displayName": "A4", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "34745f25-551e-49c0-8af4-c4724884a220", + "name": "pinA5", + "displayName": "A5", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "37b6d1ff-5bbc-4f77-9f40-6d4e237d7fcd", + "name": "pinA6", + "displayName": "A6", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + }, + { + "id": "dc4ce0d4-9544-4aaf-8834-d936a3336449", + "name": "pinA7", + "displayName": "A7", + "type": "QString", + "allowedValues": [ + "None", + "Input", + "Output", + "Analog Input" + ], + "defaultValue": "None" + } + ], + "stateTypes": [ + { + "id": "e3821856-b4db-4306-b6ca-8d72ca38803f", + "name": "connected", + "displayName": "Connected", + "displayNameEvent": "Connected changed", + "type": "bool", + "defaultValue": false, + "cached": false + }, + { + "id": "55f54f1c-7545-4138-b20a-d07fd706ff9e", + "name": "currentVersion", + "displayName": "Firmware version", + "displayNameEvent": "Firmware version changed", + "type": "QString", + "defaultValue": "" + }, + { + "id": "bbf9cae1-6272-488e-8664-a1b08bd402eb", + "name": "updateStatus", + "displayName": "Update status", + "displayNameEvent": "Update status changed", + "type": "QString", + "possibleValues": ["idle", "available", "updating"], + "defaultValue": "idle" + } + ], + "actionTypes": [ + { + "id": "a9f3a645-8ece-4692-928f-093fd51c53e2", + "name": "performUpdate", + "displayName": "Update firmware" + } + ] + }, { "id": "43aca5c1-3972-49ae-b21f-4d1486942e1f", "displayName": "Digital GPIO output on owlet", @@ -1039,6 +1694,7 @@ "displayNameEvent": "Angle changed", "displayNameAction": "Set angle", "type": "uint", + "unit": "Degree", "minValue": 0, "maxValue": 180, "defaultValue": 0, diff --git a/owlet/meta.json b/owlet/meta.json new file mode 100644 index 000000000..04ecac227 --- /dev/null +++ b/owlet/meta.json @@ -0,0 +1,9 @@ +{ + "title": "Owlet", + "tagline": "Allows using microcontroller pins of various microcontrollers with nymea", + "icon": "", + "stability": "community", + "offline": true, + "technologies": ["Serial Port", "Network"], + "categories": ["Sensor", "Relay", "Switch", "Gateway"] +} diff --git a/owlet/owlet.pro b/owlet/owlet.pro index f8959c659..6614c46f7 100644 --- a/owlet/owlet.pro +++ b/owlet/owlet.pro @@ -3,6 +3,7 @@ include(../plugins.pri) QT += network serialport SOURCES += \ + arduinoflasher.cpp \ integrationpluginowlet.cpp \ owletclient.cpp \ owletserialclient.cpp \ @@ -11,6 +12,7 @@ SOURCES += \ owlettransport.cpp HEADERS += \ + arduinoflasher.h \ integrationpluginowlet.h \ owletclient.h \ owletserialclient.h \ From e112dfc0dc59c4be3813e753868a9f3fd3395fd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 21 Feb 2022 14:33:51 +0100 Subject: [PATCH 15/18] Fix connected signal when the controller is ready --- owlet/owletserialclient.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/owlet/owletserialclient.cpp b/owlet/owletserialclient.cpp index 105383ae3..172ba8f12 100644 --- a/owlet/owletserialclient.cpp +++ b/owlet/owletserialclient.cpp @@ -212,6 +212,7 @@ void OwletSerialClient::dataReceived(const QByteArray &data) qCDebug(dcOwlet()) << "Connected successfully to firmware" << m_firmwareVersion; m_ready = true; emit readyChanged(m_ready); + emit connected(); }); break; } From ec46526917f7085ac1850e1d87dedd36bcf62cfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 21 Feb 2022 14:39:08 +0100 Subject: [PATCH 16/18] Update firmware to 0.0.3 --- .../firmware/arduino-mini-pro-3v/firmware.hex | 694 +++++++++-------- .../firmware/arduino-mini-pro-5v/firmware.hex | 695 +++++++++--------- owlet/firmware/arduino-nano/firmware.hex | 695 +++++++++--------- owlet/firmware/arduino-uno/firmware.hex | 695 +++++++++--------- 4 files changed, 1384 insertions(+), 1395 deletions(-) diff --git a/owlet/firmware/arduino-mini-pro-3v/firmware.hex b/owlet/firmware/arduino-mini-pro-3v/firmware.hex index 062b9aabf..8d6ec1818 100644 --- a/owlet/firmware/arduino-mini-pro-3v/firmware.hex +++ b/owlet/firmware/arduino-mini-pro-3v/firmware.hex @@ -1,8 +1,8 @@ :100000000C9463000C948B000C948B000C948B006C :100010000C948B000C948B000C948B000C948B0034 -:100020000C948B000C948B000C948B000C94EB0EB6 +:100020000C948B000C948B000C948B000C94D80EC9 :100030000C948B000C948B000C948B000C948B0014 -:100040000C94490E0C948B000C94B90E0C94930EE6 +:100040000C94360E0C948B000C94A60E0C94800E1F :100050000C948B000C948B000C948B000C948B00F4 :100060000C948B000C948B000000000024002700EF :100070002A0000000000250028002B0000000000DE @@ -10,12 +10,12 @@ :100090000202020203030303030301020408102007 :1000A0004080010204081020010204081020000012 :1000B0000008000201000003040700000000000027 -:1000C0000000A70F601211241FBECFEFD8E0DEBFE3 -:1000D000CDBF11E0A0E0B1E0EEE5F8E202C005908E +:1000C0000000940F4D1211241FBECFEFD8E0DEBF09 +:1000D000CDBF11E0A0E0B1E0E8E3F8E202C0059096 :1000E0000D92A832B107D9F722E0A8E2B1E001C031 :1000F0001D92A13AB207E1F710E0C2E6D0E004C0D9 -:100100002197FE010E94F712C136D107C9F70E945C -:10011000E1100C9422140C940000833081F028F438 +:100100002197FE010E94E412C136D107C9F70E946F +:10011000CE100C940F140C940000833081F028F45E :10012000813099F08230A9F008958730A9F08830A5 :10013000C9F08430B1F4809180008F7D03C080913C :1001400080008F7780938000089584B58F7784BD79 @@ -136,12 +136,12 @@ :10087000220F331F858D968D280F391FF901808136 :10088000918108952F5F3F4FE1CF8585968508952B :10089000CF93DF93EC01CD3C8CE0D807A0F42AE0A5 -:1008A0002C9FC0012D9F900D112402960E94FD12D5 +:1008A0002C9FC0012D9F900D112402960E94EA12E8 :1008B000FC01C193D193CF012197D7FD07C01182CD :1008C00010823A96F9CF8FEF9FEFF0CFDF91CF9163 :1008D0000895EF92FF920F931F93CF93DF93EC0154 :1008E0008B0180E190E09F838E8381E088871D8665 -:1008F000FB01E184F284C7010E94FD129983888381 +:1008F000FB01E184F284C7010E94EA129983888394 :10090000892B61F1F801828193819B838A838481A1 :1009100095819D838C83868197819F838E8380853B :100920008887FA86E986838594859C878B87858569 @@ -156,7 +156,7 @@ :1009B000969587954DEC5CE4849F9001859F300D62 :1009C000949F300D11243F7746EF4203C001439FAF :1009D000900D11240297800F911FDF91CF911F91ED -:1009E0000F91FF90EF900C949913DF91CF911F918D +:1009E0000F91FF90EF900C948613DF91CF911F91A0 :1009F0000F91FF90EF9008952F923F924F925F9248 :100A00006F927F928F929F92AF92BF92CF92DF921E :100A1000EF92FF920F931F93CF93DF938C016B01A3 @@ -198,11 +198,11 @@ :100C5000EB01F8012085211105C08C179D0738F0A4 :100C600081E0EBCF7E018C179D0708F47C01209773 :100C700021F16E018FEF9FEFC115F0E4DF0718F44B -:100C8000C601880F991F0E94FD125C010097A1F216 +:100C8000C601880F991F0E94EA125C010097A1F229 :100C9000DC01F8018081918130E020E0E216F3066A :100CA00081F0F901EE0FFF1FE80FF91F408151811C :100CB0004D935D932F5F3F4FF1CF60E1C62ED12C56 -:100CC000DFCF009711F00E949913F801B182A08242 +:100CC000DFCF009711F00E948613F801B182A08255 :100CD000D286C18683859485C817D90708F6D4873C :100CE000C387BECF0F931F93CF93DF93EC018B018C :100CF00069857A850617170738F08E819F81680FFE @@ -221,12 +221,12 @@ :100DC000BF90AF909F908F90089586012885211144 :100DD00027C080179107B8F60115110539F15801A0 :100DE000011580E4180730F5C501880F991F0E948E -:100DF000FD124C01009739F2DC018881998130E0C5 +:100DF000EA124C01009739F2DC018881998130E0D8 :100E000020E0C216D306C9F0F901EE0FFF1FE80F6C :100E1000F91F408151814D935D932F5F3F4FF1CF7B :100E20006C0108171907C0F66801D6CF60E1A62E3D :100E3000B12CDACF8FEF9FEFDACF009711F00E943D -:100E4000991399828882BA86A9868B859C85081712 +:100E4000861399828882BA86A9868B859C85081725 :100E5000190708F098CF1C870B8795CFEE0CFF1C65 :100E6000888199818E0D9F1DA3CFAF92BF92CF92A3 :100E7000DF92EF92FF920F931F93CF93DF938C013A @@ -236,10 +236,10 @@ :100EB000BF90AF900895EB01F8012085211105C086 :100EC0008C179D0738F081E0EBCF7E018C179D07D2 :100ED00008F47C016E01209719F480E1C82ED12C12 -:100EE000C6010E94FD125C010097C9F2FC01D80105 +:100EE000C6010E94EA125C010097C9F2FC01D80118 :100EF0008D919C9130E020E0E216F30641F0DC0198 :100F0000A20FB31F4C9141932F5F3F4FF5CF009736 -:100F100011F00E949913F801B182A082C186D28695 +:100F100011F00E948613F801B182A082C186D286A8 :100F200083859485C817D90770F6D487C387CBCF3C :100F3000CF93FC0183859485C0E06817790750F54D :100F40008385948501976817790778F4808191816A @@ -307,344 +307,342 @@ :101320000F90DF91CF911F910F91FF90EF90DF9081 :10133000CF900895F801208131812F5F3F4F318395 :101340002083BC01DACFFC0180819181009711F0EC -:101350000C94991308952F923F925F926F927F920F +:101350000C94861308952F923F925F926F927F9222 :101360008F929F92AF92BF92CF92DF92EF92FF92B5 :101370000F931F93CF93DF93CDB7DEB729970FB6A7 :10138000F894DEBF0FBECDBF6C017B01DB016C9119 -:1013900011965C90673008F06DC4E62FF0E0ED52D6 -:1013A000F64F0C94F712DA09100AF10B5F0C9E0C41 -:1013B0003D0D790DDC01ED91FC910084F185E02D6E +:1013900011965C90673008F05AC4E62FF0E0ED52E9 +:1013A000F64F0C94E412DA09110ADE0B4C0C8B0C8C +:1013B0002A0D660DDC01ED91FC910084F185E02D94 :1013C000423011F1F12CE12C10E000E023E030E09C :1013D000452D60E0C601099529960FB6F894DEBF49 :1013E0000FBECDBFDF91CF911F910F91FF90EF9076 :1013F000DF90CF90BF90AF909F908F907F906F9035 -:101400005F903F902F90089519821A824B8333E0AA -:10141000E32EF12C8E010F5F1F4F30E020E0D8CF7C -:10142000EDB7FEB7F987E887443079F0DC01ED913C -:10143000FC910084F185E02DF12CE12C10E000E01E -:1014400023E030E0452D61E0C5CFF70112818381B3 -:10145000282E312CD6011496ED90FC90823009F4A0 -:10146000F7C078F4882309F437C1813009F4E0C06B -:10147000612FC7010E945B08DC012D923C9280E045 -:10148000BEC0843009F4F1C008F4E7C0853081F7AC -:101490005701F6E5AF0EB11C712C612C9701205954 -:1014A0003F4F3F832E8345013FE0830E911CAE8169 -:1014B000BF818D919C916816790650F4B301C401E7 -:1014C0000E940008FC0180811813DCC077FEDEC09A -:1014D00083E090E00E94FD124C0180914C018C3021 -:1014E00008F0F6C091E0980F90934C01D4018C93D2 -:1014F00090E0FC01EE0FFF1FE80FF91FE85DFE4FC3 -:101500008CED95E092838183612FC5010E941109C2 -:10151000DC018D929C92612FC5010E941109FC0192 -:1015200080809180D4018C918C3008F055C061E0AE -:10153000812F0E940D01F4018081282F30E0F901F4 -:10154000EE0FFF1FE20FF31FE85DFE4F9081907CCE -:10155000212F2F73922B9083D40111961C921197F7 -:1015600012961C922CE0622F0E94EB12829FB00117 -:10157000112430E020E0AB01420F531FFA01EE0FBF -:10158000FF1FE40FF51FE85DFE4F908196FD16C02A -:101590002F5F3F4F2C30310571F781110FC0109232 -:1015A000800082E080938100109285001092840078 -:1015B000B19A80916F00826080936F00D401EC91AA -:1015C0008E2F90E0FC01EE0FFF1FE80FF91FE85D82 -:1015D000FE4F808180648083F40180818F3F09F019 -:1015E00047CF612FC5010E941109DC018D919C91AB -:1015F0000E949913612FC5010E94A40885E0898388 -:10160000D601ED91FC910084F185E02DEE24E39468 -:10161000F12C8E010F5F1F4F30E020E0452D61E07F -:10162000C60109950FB6F894DEBF0FBECDBFD4CE6C -:1016300060E0812F0E940D01812F0E94B600082FCB -:10164000612FC7018C960E945A09FC01008310CFBC -:1016500061E0812F0E940D010BCF60E0812F0E947D -:101660000D01812F0E943E0103CF61E0812F0E9476 -:101670000D0161E0812F0E940D0160E0812F0E9429 -:10168000DF00F6CEFFEF6F1A7F0A11CF612FC50181 -:101690000E941109DC01ED91FC91E0818E2F90E018 -:1016A000FC01EE0FFF1FE80FF91FE85DFE4F808180 -:1016B0008F7B8083612FC5010E941109FC0180810D -:1016C00091810E949913612FC5010E94A40800CF47 -:1016D0008FEFF401808318CFB12CA12CF701E059D2 -:1016E000FF4FFF83EE834701F6E58F0E911C340117 -:1016F0002FE0620E711CAE81BF818D919C91A81666 -:10170000B90650F4B501C3010E940008FC018081B4 -:1017100018131EC0B7FE20C0B12CA12C3701F5E470 -:101720006F0E711C47012AE3820E911CD3018D912B -:101730009C91A816B90650F4B501C4010E94000896 -:10174000FC01808118132AC0B7FE2CC060E081CF55 -:10175000FFEFAF1ABF0ACFCF612FC4010E9411095A -:10176000DC01ED91FC91E0818E2F90E0FC01EE0F09 -:10177000FF1FE80FF91FE85DFE4F80818F7B80839C -:10178000612FC4010E941109FC01808191810E9496 -:101790009913612FC4010E94A408BECFFFEFAF1AB6 -:1017A000BF0AC4CFB12CA12CD3018D919C91A81656 -:1017B000B90660F6B501C4010E940008FC018081F1 -:1017C00018130BC0B501C701885B9F4F0E94980793 -:1017D000B501C4010E949807B9CFFFEFAF1ABF0A45 -:1017E000E3CF443079F0DC01ED91FC910084F18588 -:1017F000E02DF12CE12C10E000E023E030E0452D5D -:1018000062E0E8CDF70112819380DC011496ED903F -:10181000FC90612FC7010E9430080196C9F1612F29 -:10182000C7010E945B08FC0180819181029709F049 -:1018300042C001E0911001C000E0602F812F0E94A2 -:10184000DF00912C812C3701FDE86F0E711C22E81E -:10185000E20EF11CD3018D919C918816990668F5D2 -:10186000B401C7010E94CF051C830983DC01ED91FF -:10187000FC910480F581E02DAE014F5F5F4FBE010A -:101880006C5F7F4F02960995BFEF8B1A9B0AE2CFE0 -:1018900081E08D83D601ED91FC910084F185E02DEE -:1018A000EE24E394F12C8E010B5F1F4F30E020E01B -:1018B000452D62E0B5CE83E0ECCF80E0EACF433047 -:1018C00079F0DC01ED91FC910084F185E02DF12CA3 -:1018D000E12C10E000E023E030E0452D63E07ACD1C -:1018E000F7011281612FDC0114968D919C910E9469 -:1018F00021040097F1F001970297F0F4812F0E94E4 -:10190000B60021E0892B09F420E080E089832A8356 -:10191000D601ED91FC910084F185E02D02E0E02EEE -:10192000F12C8E010F5F1F4F30E020E0452D63E06A -:1019300077CE81E020E0EACF82E0FCCF443079F03E -:10194000DC01ED91FC910084F185E02DF12CE12C7E -:1019500010E000E023E030E0452D64E03BCDF701EE -:101960001281DC0114968D909C90612FC4010E941D -:101970002104009799F481E08983D601ED91FC91CF -:101980000084F185E02DEE24E394F12C8E010F5FAD -:101990001F4F30E020E0452D64E042CE049711F067 -:1019A00083E0EACFF7010381612FC4010E94300870 -:1019B000019609F3612FC4010E945B08DC018D913F -:1019C0009C91049769F7E02EF12C61E0812F0E9431 -:1019D0000D01E114F10429F460E0812F0E94DF0081 -:1019E0002BC0BFEFEB16F10411F461E0F6CFE12F4D -:1019F000F0E0E255FF4FE491E33029F148F4E130A3 -:101A0000B9F0E230D9F0E0E8EE16F10474F7E4CF73 -:101A1000E73019F1E83049F1E430A9F7809180000E -:101A2000806280938000F0928B00E0928A0004C074 -:101A300084B5806884BD07BD80E09ECF84B5806298 -:101A400084BD08BDF9CF80918000806880938000BC -:101A5000F0928900E0928800EFCF8091B00080681A -:101A60008093B0000093B300E7CF8091B000806214 -:101A70008093B0000093B400DFCF433079F0DC01F5 -:101A8000ED91FC910084F185E02DF12CE12C10E02A -:101A900000E023E030E0452D65E09CCCF7011281A9 -:101AA000612FDC0114968D919C910E942104009776 -:101AB000E1F0039722E00297C8F4812F0E943E01D3 -:101AC00020E029839A838B83D601ED91FC910084D9 -:101AD000F185E02DB3E0EB2EF12C8E010F5F1F4F4F -:101AE00030E020E0452D65E09BCD21E080E090E0F6 -:101AF000E8CF443079F0DC01ED91FC910084F18570 -:101B0000E02DF12CE12C10E000E023E030E0452D49 -:101B100066E060CCF7011281DC0114968D909C90F8 -:101B2000612FC4010E942104009799F481E0898308 -:101B3000D601ED91FC910084F185E02DEE24E39433 -:101B4000F12C8E010F5F1F4F30E020E0452D66E045 -:101B500067CD059709F08AC0F701038184E0053B52 -:101B600030F7612FC4010E94300897FDDFCF612F4D -:101B7000C4010E945B08DC018D919C91059709F0DE -:101B800077C0B6E58B0E911C612FC4010E9411092C -:101B9000DC01ED91FC91E0818E2F90E0FC01EE0FD5 -:101BA000FF1FE80FF91FE85DFE4F808186FFBECF63 -:101BB000612FC4010E941109DC01ED91FC9110819B -:101BC0001C3008F051C0828148E5842E42E0942EFA -:101BD000881A910887FD93941401220C331C220C5F -:101BE000331C818168E8E62EF12CE81AF10887FDA4 -:101BF000F394EE0CFF1CEE0CFF1C37010F2C000CB5 -:101C0000880899089101032C000C440B550B2619E8 -:101C1000370948095909A02FB0E00E94AF1224EB00 -:101C200030E040E050E00E949012BA01A901460D58 -:101C3000571D681D791D4E155F052CF07101421569 -:101C400053050CF47A012FB7F894812F90E0B2E09D -:101C5000EB1AF108FC01EE0FFF1FE80FF91FE85D1A -:101C6000FE4FF282E1822FBF80E061CF82E05FCF42 -:101C700083E05DCFDC01ED91FC910084F185E02DE6 -:101C8000F12CE12C10E000E022E030E0452D099538 -:101C9000A3CB1F920F920FB60F9211242F933F9355 -:101CA0008F939F93AF93BF9380915F019091600159 -:101CB000A0916101B091620130915E0126E0230F95 -:101CC0002D3758F50296A11DB11D20935E0180931A -:101CD0005F0190936001A0936101B09362018091D4 -:101CE000630190916401A0916501B0916601019634 -:101CF000A11DB11D8093630190936401A0936501C0 -:101D0000B0936601BF91AF919F918F913F912F91B9 -:101D10000F900FBE0F901F90189529E8230F039680 -:101D2000A11DB11DD2CF1F920F920FB60F92112499 -:101D30002F933F934F935F936F937F938F939F93D3 -:101D4000AF93BF93EF93FF9387E691E00E942C023D -:101D5000FF91EF91BF91AF919F918F917F916F9183 -:101D60005F914F913F912F910F900FBE0F901F9059 -:101D700018951F920F920FB60F9211242F938F93E5 -:101D80009F93EF93FF93E0917701F0917801808129 -:101D9000E0917D01F0917E0182FD1BC090818091D8 -:101DA00080018F5F8F7320918101821741F0E09154 -:101DB0008001F0E0E959FE4F958F80938001FF91FB -:101DC000EF919F918F912F910F900FBE0F901F90C9 -:101DD00018958081F4CF1F920F920FB60F921124A5 -:101DE0002F933F934F935F936F937F938F939F9323 -:101DF000AF93BF93CF93DF93EF93FF9380914D0108 -:101E0000C0914C01D0E087FF24C010928500109251 -:101E1000840080914D018F5F80934D0180914D0131 -:101E2000082E000C990B8C179D0724F480914D010E -:101E30008C30C4F1809184009091850004968032AA -:101E40009E4408F47AC080918400909185000496A5 -:101E500076C080914D01082E000C990B8C179D07C0 -:101E6000C4F6E0914D018E2FEE0F990BFC01EE0FA1 -:101E7000FF1FE80FF91FE85DFE4F808186FFC9CF85 -:101E8000E0914D018E2FEE0F990BFC01EE0FFF1F1D -:101E9000E80FF91FE85DFE4F808160E08F730E94BC -:101EA000DF00B7CF2091840030918500E0914D0193 -:101EB0008E2FEE0F990BFC01EE0FFF1FE80FF91F9D -:101EC000E85DFE4F81819281820F931F909389007C -:101ED00080938800E0914D018E2FEE0F990BFC014D -:101EE000EE0FFF1FE80FF91FE85DFE4F808186FFB0 -:101EF00011C0E0914D018E2FEE0F990BFC01EE0FFA -:101F0000FF1FE80FF91FE85DFE4F808161E08F73CE -:101F10000E94DF00FF91EF91DF91CF91BF91AF91D0 -:101F20009F918F917F916F915F914F913F912F91F1 -:101F30000F900FBE0F901F90189580E29EE4909333 -:101F40008900809388008FEF80934D01E3CFCF927B -:101F5000DF92FF920F931F93CF93DF93E7E6F1E0B9 -:101F60001382128288EE93E0A0E0B0E08483958330 -:101F7000A683B7838AE191E09183808385EC90E02A -:101F80009587848784EC90E09787868780EC90E043 -:101F9000918B808B81EC90E0938B828B82EC90E034 -:101FA000958B848B86EC90E0978B868B118E128EAE -:101FB000138E148EC4E0D2E000E110E01F830E8384 -:101FC000CC24CA94DC2CD986C8861B870A87FF24B8 -:101FD000F394FC861E861D861A8B098BDC8ACB8ABD -:101FE0001E8B0D8BFF8A1C8E1B8E1A8E198F088FED -:101FF00080E190E00E94FD12988B8F8718A30F8FCD -:10200000DAA2C9A21CA30BA3FDA21BA61AA619A69D -:1020100018A61FA30EA380E290E00E94FD129E8FDF -:102020008D8F198218821D830C831BAB0AABDDAA2E -:10203000CCAA1FAB0EABF8AE19AE1DAF0CAFDFAE26 -:10204000CEAE1093450200934402F09246021092E5 -:102050004B0210924A0210924902109348020093D8 -:10206000470280E190E00E94FD129BAF8AAF10937F -:102070004F0200934E02D0925102C0925002109330 -:10208000530200935202F09254021092590210929D -:10209000580210925702109356020093550280E1A5 -:1020A00090E00E94FD1290934D0280934C021DA679 -:1020B0001CA619AB08AB1093610200936002D0928A -:1020C0006302C09262021093650200936402F09270 -:1020D0006602109268021092670210936C020093DD -:1020E0006B02D0926E02C0926D0210937002009348 -:1020F0006F02F092710210927602109275021092A5 -:102100007402109373020093720280E190E00E94C7 -:10211000FD1290936A028093690210937A020093F1 -:102120007902D0927C02C0927B0210937E020093CF -:102130007D02F0927F02109285021092840210922A -:10214000830210928202109381020093800280E247 -:1021500090E00E94FD129093780280937702109293 -:102160005B0210925A0210935F0200935E0210937A -:10217000890200938802D0928B02C0928A02109347 -:102180008D0200938C02F0928E02109294021092B3 -:102190009302109292021092910210939002009377 -:1021A0008F0280E190E00E94480490938702809320 -:1021B0008602DF91CF911F910F91FF90DF90CF901A -:1021C0000895CF93DF93CDB7DEB760970FB6F8943D -:1021D000DEBF0FBECDBF789484B5826084BD84B568 -:1021E000816084BD85B5826085BD85B5816085BD12 -:1021F00080916E00816080936E00109281008091CA -:102200008100826080938100809181008160809351 -:102210008100809180008160809380008091B10076 -:1022200084608093B1008091B00081608093B000A1 -:1022300080917A00846080937A0080917A00826035 -:1022400080937A0080917A008E7F80937A008091CB -:102250007A00806880937A001092C10088E091E053 -:102260000E94FD128C018AE091E0D80111969C93A6 -:102270008E9387E691E013969C938E93129784E059 -:1022800092E015969C938E931497F801EB5FFE4FA6 -:102290001082319610823196108280915401811102 -:1022A00015C08CED92E090934F0180934E018DEA22 -:1022B00091E090935101809350018BEB92E09093C9 -:1022C00053018093520181E0809354018EE491E0A8 -:1022D0009A8389831C830B83CE0101960E9481051A -:1022E000CE0101960E94160410935D0100935C01DB -:1022F00061E08DE00E940D0161E08DE00E94DF0051 -:102300000E94780160E08DE00E94DF000E94780169 -:1023100061E08DE00E94DF000E94780160E08DE0C6 -:102320000E94DF0060E08DE00E940D01D80112964E -:10233000ED91FC91A089B18982E08C93A485B5854B -:102340001C92A685B78588E08C93108EA489B589E8 -:1023500086E08C93A289B3898C9180618C93A28949 -:10236000B3898C9188608C93A289B3898C918068A1 -:102370008C930288F389E02D80818F7D80830E9479 -:10238000780130E020E050E040E060EF70E0C8010C -:102390000E94E60280E0A82E80E0B82E6EE372E094 -:1023A000CE0101960E946904F12CE12C8C859D855B -:1023B000E816F90608F04FC0B701CE0101960E9459 -:1023C0000008FC011081612F84E092E00E945B080C -:1023D000DC018D919C910197D1F5812F0E94B6006F -:1023E000082F612F80E392E00E945A09FC0180814E -:1023F000081769F1612F80E392E00E945A09DC011D -:102400000C93D12CC12C8091910290919202C8160C -:10241000D906E8F4B60186E892E00E94CF05188B51 -:1024200021E0013009F020E02F87DC01ED91FC91E3 -:102430000480F581E02DAE01415F5F4FBE01605F1A -:102440007F4F02960995BFEFCB1ADB0ADCCFEFEF87 -:10245000EE1AFE0AABCFCE0101960E94A3090091AD -:102460005C0110915D01D80112968D919C91DC0167 -:10247000ED91FC910084F185E02D0995892BA1F067 -:10248000F80182819381DC01ED91FC910284F38556 -:10249000E02D0995D801ED91FC910190F081E02D9E -:1024A000682FC8010995DFCFA114B10409F476CFD4 -:1024B0000E941802882309F471CF0E9400006ECF99 -:1024C0008091860290918702009731F00E94B504B6 -:1024D000109287021092860283E992E00E9416040D -:1024E0008091770290917802009711F00E949913E1 -:1024F00089E692E00E94A3098CE492E00E94A3097D -:102500008EE392E00E94A309809121029091220221 -:10251000009711F00E94991383E192E00C94A309B3 -:10252000052E97FB1EF400940E94A71257FD07D0BA -:102530000E94BA1207FC03D04EF40C94A7125095D7 -:102540004095309521953F4F4F4F5F4F089590959F -:102550008095709561957F4F8F4F9F4F08950E9492 -:10256000DC12A59F900DB49F900DA49F800D911D2E -:1025700011240895A1E21A2EAA1BBB1BFD010DC058 -:10258000AA1FBB1FEE1FFF1FA217B307E407F50723 -:1025900020F0A21BB30BE40BF50B661F771F881FFF -:1025A000991F1A9469F760957095809590959B0195 -:1025B000AC01BD01CF010895A29FB001B39FC0013E -:1025C000A39F700D811D1124911DB29F700D811D5F -:1025D0001124911D0895991B79E004C0991F961745 -:1025E00008F0961B881F7A95C9F780950895EE0F1D -:1025F000FF1F0590F491E02D09940F931F93CF9343 -:10260000DF938230910510F482E090E0E0919F0228 -:10261000F091A00230E020E0B0E0A0E0309799F423 -:102620002115310509F44AC0281B390B2430310526 -:10263000D8F58A819B816115710589F1FB0193832E -:102640008283FE0111C040815181028113814817AC -:102650005907E0F04817590799F4109761F012965E -:102660000C93129713961C933296CF01DF91CF9162 -:102670001F910F91089500939F021093A002F4CF31 -:102680002115310551F04217530738F0A901DB013C -:102690009A01BD01DF01F801C1CFEF01F9CF90939D -:1026A000A00280939F02CDCFFE01E20FF31F819322 -:1026B00091932250310939832883D7CF20919D02ED -:1026C00030919E02232B41F42091020130910301AD -:1026D00030939E0220939D022091000130910101D0 -:1026E0002115310541F42DB73EB7409104015091B9 -:1026F0000501241B350BE0919D02F0919E02E2172B -:10270000F307A0F42E1B3F0B2817390778F0AC0114 -:102710004E5F5F4F2417350748F04E0F5F1F5093F1 -:102720009E0240939D02819391939FCFF0E0E0E061 -:102730009CCFCF93DF930097E9F0FC01329713828F -:102740001282A0919F02B091A002ED0130E020E042 -:102750001097A1F420813181820F931F20919D0257 -:1027600030919E022817390709F061C0F0939E024C -:10277000E0939D02DF91CF910895EA01CE17DF0724 -:10278000E8F54A815B819E0141155105B1F7E901E8 -:10279000FB83EA8349915991C40FD51FEC17FD07BC -:1027A00061F4808191810296840F951FE9019983DC -:1027B0008883828193819B838A83F0E0E0E0129694 -:1027C0008D919C9113970097B9F52D913C9111979C -:1027D000CD010296820F931F20919D0230919E029F -:1027E0002817390739F6309751F51092A002109248 -:1027F0009F02B0939E02A0939D02BCCFD383C2835D -:1028000040815181840F951FC817D90761F44E5F2D -:102810005F4F88819981480F591F518340838A8176 -:102820009B81938382832115310509F0B0CFF0930A -:10283000A002E0939F029ECFFD01DC01C0CF138276 -:102840001282D7CF10E0C2E6D0E004C0FE010E94A1 -:0E285000F7122196C336D107C9F7F894FFCFCF -:10285E000000A102800000000000C2039C0391034F -:10286E00AB093903E602000000004E02AE01DB01A7 -:08287E009B020C02EA01FE01BD +:101400005F903F902F90089519821A8283E08B831A +:1014100033E0E32EF12C8E010F5F1F4F30E020E010 +:10142000D7CFEDB7FEB7F987E887443079F0DC0114 +:10143000ED91FC910084F185E02DF12CE12C10E080 +:1014400000E023E030E0452D61E0C4CFF7011281D8 +:101450008381282E312CD6011496ED90FC90823099 +:1014600009F4E3C030F5882309F423C1813009F47D +:10147000CCC0612FC7010E945B08DC012D923C9219 +:101480001982D601ED91FC910084F185E02DEE24C6 +:10149000E394F12C8E010F5F1F4F30E020E0452DCB +:1014A00061E0C60109950FB6F894DEBF0FBECDBF4F +:1014B00093CF843009F4C6C008F4BCC08530C9F6A7 +:1014C0005701F6E5AF0EB11C712C612C9701205924 +:1014D0003F4F3F832E8345013FE0830E911CAE8139 +:1014E000BF818D919C916816790650F4B301C401B7 +:1014F0000E940008FC0180811813B1C077FEB3C0C0 +:1015000083E090E00E94EA124C0180914C018C3003 +:1015100008F0CBC091E0980F90934C01D4018C93CC +:1015200090E0FC01EE0FFF1FE80FF91FE85DFE4F92 +:101530008CED95E092838183612FC5010E94110992 +:10154000DC018D929C92612FC5010E941109FC0162 +:10155000A080B180D5018C918C3008F08ACF61E0F9 +:10156000812F0E940D01F5018081282F30E0F901C3 +:10157000EE0FFF1FE20FF31FE85DFE4F9081907C9E +:10158000212F2F73922B9083D50111961C921197C6 +:1015900012961C922CE0622F0E94D812829FB001FA +:1015A000112430E020E0AB01420F531FFA01EE0F8F +:1015B000FF1FE40FF51FE85DFE4F908196FD16C0FA +:1015C0002F5F3F4F2C30310571F781110FC0109202 +:1015D000800082E080938100109285001092840048 +:1015E000B19A80916F00826080936F00D501EC9179 +:1015F0008E2F90E0FC01EE0FFF1FE80FF91FE85D52 +:10160000FE4F80818064808334CF60E0812F0E9410 +:101610000D01812F0E94B600082F612FC7018C9603 +:101620000E945A09FC01008324CF61E0812F0E94AF +:101630000D011FCF60E0812F0E940D01812F0E94BC +:101640003E0117CF61E0812F0E940D0161E0812FE3 +:101650000E940D0160E0812F0E94DF000ACFFFEFA2 +:101660006F1A7F0A3CCF612FC5010E941109DC016E +:10167000ED91FC91E0818E2F90E0FC01EE0FFF1FB9 +:10168000E80FF91FE85DFE4F80818F7B8083612F1B +:10169000C5010E941109FC01808191810E9486137D +:1016A000612FC5010E94A4082BCF8FEFF401808326 +:1016B00043CFB12CA12CF701E059FF4FFF83EE83FC +:1016C0004701F6E58F0E911C34012FE0620E711C6C +:1016D000AE81BF818D919C91A816B90650F4B501D9 +:1016E000C3010E940008FC01808118131EC0B7FED0 +:1016F00020C0B12CA12C3701F5E46F0E711C4701FD +:101700002AE3820E911CD3018D919C91A816B906F3 +:1017100050F4B501C4010E940008FC018081181337 +:101720002AC0B7FE2CC060E081CFFFEFAF1ABF0A1E +:10173000CFCF612FC4010E941109DC01ED91FC9112 +:10174000E0818E2F90E0FC01EE0FFF1FE80FF91FE4 +:10175000E85DFE4F80818F7B8083612FC4010E94F2 +:101760001109FC01808191810E948613612FC401BF +:101770000E94A408BECFFFEFAF1ABF0AC4CFB12C9E +:10178000A12CD3018D919C91A816B90660F6B501E4 +:10179000C4010E940008FC01808118130BC0B50130 +:1017A000C701885B9F4F0E949807B501C4010E9442 +:1017B0009807B9CFFFEFAF1ABF0AE3CF443079F0F3 +:1017C000DC01ED91FC910084F185E02DF12CE12C00 +:1017D00010E000E023E030E0452D62E0FBCDF701B2 +:1017E00012819380DC011496ED90FC90612FC7016B +:1017F0000E9430080196C9F1612FC7010E945B0861 +:10180000FC0180819181029709F042C001E09110B2 +:1018100001C000E0602F812F0E94DF00912C812CFD +:101820003701FDE86F0E711C22E8E20EF11CD301B6 +:101830008D919C918816990668F5B401C7010E94A4 +:10184000CF051C830983DC01ED91FC910480F581B7 +:10185000E02DAE014F5F5F4FBE016C5F7F4F029680 +:101860000995BFEF8B1A9B0AE2CF81E08D83D601E9 +:10187000ED91FC910084F185E02DEE24E394F12CB0 +:101880008E010B5F1F4F30E020E0452D62E009CE56 +:1018900083E0ECCF80E0EACF433079F0DC01ED91DA +:1018A000FC910084F185E02DF12CE12C10E000E0AA +:1018B00023E030E0452D63E08DCDF7011281612FEB +:1018C000DC0114968D919C910E9421040097F1F007 +:1018D00001970297F0F4812F0E94B60021E0892B36 +:1018E00009F420E080E089832A83D601ED91FC9100 +:1018F0000084F185E02D02E0E02EF12C8E010F5FD7 +:101900001F4F30E020E0452D63E0CBCD81E020E0AB +:10191000EACF82E0FCCF443079F0DC01ED91FC911C +:101920000084F185E02DF12CE12C10E000E023E0B3 +:1019300030E0452D64E04ECDF7011281DC011496B4 +:101940008D909C90612FC4010E942104009799F40E +:1019500081E08983D601ED91FC910084F185E02D31 +:10196000EE24E394F12C8E010F5F1F4F30E020E056 +:10197000452D64E096CD049711F083E0EACFF7019E +:101980000381612FC4010E943008019609F3612F81 +:10199000C4010E945B08DC018D919C91049769F75A +:1019A000E02EF12C61E0812F0E940D01E114F10481 +:1019B00029F460E0812F0E94DF002BC0BFEFEB16FF +:1019C000F10411F461E0F6CFE12FF0E0E255FF4FB2 +:1019D000E491E33029F148F4E130B9F0E230D9F094 +:1019E000E0E8EE16F10474F7E4CFE73019F1E830DF +:1019F00049F1E430A9F780918000806280938000F3 +:101A0000F0928B00E0928A0004C084B5806884BDA7 +:101A100007BD80E09ECF84B5806284BD08BDF9CF4C +:101A200080918000806880938000F0928900E0922D +:101A30008800EFCF8091B00080688093B000009361 +:101A4000B300E7CF8091B00080628093B000009334 +:101A5000B400DFCF433079F0DC01ED91FC910084DC +:101A6000F185E02DF12CE12C10E000E023E030E0E6 +:101A7000452D65E0AFCCF7011281612FDC01149692 +:101A80008D919C910E9421040097E1F0039722E040 +:101A90000297C8F4812F0E943E0120E029839A8397 +:101AA0008B83D601ED91FC910084F185E02DB3E0AC +:101AB000EB2EF12C8E010F5F1F4F30E020E0452D03 +:101AC00065E0EFCC21E080E090E0E8CF443079F0B1 +:101AD000DC01ED91FC910084F185E02DF12CE12CED +:101AE00010E000E023E030E0452D66E073CCF70124 +:101AF0001281DC0114968D909C90612FC4010E948C +:101B00002104009799F481E08983D601ED91FC913D +:101B10000084F185E02DEE24E394F12C8E010F5F1B +:101B20001F4F30E020E0452D66E0BBCC059709F063 +:101B30008AC0F701038184E0053B30F7612FC401BF +:101B40000E94300897FDDFCF612FC4010E945B081F +:101B5000DC018D919C91059709F077C0B6E58B0E5D +:101B6000911C612FC4010E941109DC01ED91FC91CF +:101B7000E0818E2F90E0FC01EE0FFF1FE80FF91FB0 +:101B8000E85DFE4F808186FFBECF612FC4010E94B9 +:101B90001109DC01ED91FC9110811C3008F051C05D +:101BA000828148E5842E42E0942E881A910887FDB0 +:101BB00093941401220C331C220C331C818168E89D +:101BC000E62EF12CE81AF10887FDF394EE0CFF1CC9 +:101BD000EE0CFF1C37010F2C000C880899089101AE +:101BE000032C000C440B550B2619370948095909D9 +:101BF000A02FB0E00E949C1224EB30E040E050E0C7 +:101C00000E947D12BA01A901460D571D681D791D5C +:101C10004E155F052CF07101421553050CF47A0145 +:101C20002FB7F894812F90E0B2E0EB1AF108FC0195 +:101C3000EE0FFF1FE80FF91FE85DFE4FF282E18211 +:101C40002FBF80E061CF82E05FCF83E05DCFDC011A +:101C5000ED91FC910084F185E02DF12CE12C10E058 +:101C600000E022E030E0452D0995B6CB1F920F929F +:101C70000FB60F9211242F933F938F939F93AF939F +:101C8000BF9380915F0190916001A0916101B0913B +:101C9000620130915E0126E0230F2D3758F5029640 +:101CA000A11DB11D20935E0180935F01909360019F +:101CB000A0936101B09362018091630190916401EE +:101CC000A0916501B09166010196A11DB11D80939F +:101CD000630190936401A0936501B0936601BF9185 +:101CE000AF919F918F913F912F910F900FBE0F90C9 +:101CF0001F90189529E8230F0396A11DB11DD2CF7F +:101D00001F920F920FB60F9211242F933F934F9370 +:101D10005F936F937F938F939F93AF93BF93EF9353 +:101D2000FF9387E691E00E942C02FF91EF91BF9113 +:101D3000AF919F918F917F916F915F914F913F9163 +:101D40002F910F900FBE0F901F9018951F920F921A +:101D50000FB60F9211242F938F939F93EF93FF93BE +:101D6000E0917701F09178018081E0917D01F0911F +:101D70007E0182FD1BC09081809180018F5F8F73F7 +:101D800020918101821741F0E0918001F0E0E95952 +:101D9000FE4F958F80938001FF91EF919F918F91DE +:101DA0002F910F900FBE0F901F9018958081F4CF48 +:101DB0001F920F920FB60F9211242F933F934F93C0 +:101DC0005F936F937F938F939F93AF93BF93CF93C3 +:101DD000DF93EF93FF9380914D01C0914C01D0E0D0 +:101DE00087FF24C0109285001092840080914D01DD +:101DF0008F5F80934D0180914D01082E000C990B4F +:101E00008C179D0724F480914D018C30C4F1809192 +:101E1000840090918500049680329E4408F47AC034 +:101E20008091840090918500049676C080914D0148 +:101E3000082E000C990B8C179D07C4F6E0914D01FC +:101E40008E2FEE0F990BFC01EE0FFF1FE80FF91F0D +:101E5000E85DFE4F808186FFC9CFE0914D018E2F56 +:101E6000EE0F990BFC01EE0FFF1FE80FF91FE85D65 +:101E7000FE4F808160E08F730E94DF00B7CF20911A +:101E8000840030918500E0914D018E2FEE0F990B6B +:101E9000FC01EE0FFF1FE80FF91FE85DFE4F818187 +:101EA0009281820F931F9093890080938800E09124 +:101EB0004D018E2FEE0F990BFC01EE0FFF1FE80F67 +:101EC000F91FE85DFE4F808186FF11C0E0914D0152 +:101ED0008E2FEE0F990BFC01EE0FFF1FE80FF91F7D +:101EE000E85DFE4F808161E08F730E94DF00FF910B +:101EF000EF91DF91CF91BF91AF919F918F917F91A2 +:101F00006F915F914F913F912F910F900FBE0F9066 +:101F10001F90189580E29EE490938900809388003A +:101F20008FEF80934D01E3CFCF92DF92FF920F931B +:101F30001F93CF93DF93E7E6F1E01382128288EEDE +:101F400093E0A0E0B0E084839583A683B7838AE121 +:101F500091E09183808385EC90E09587848784EC81 +:101F600090E09787868780EC90E0918B808B81EC66 +:101F700090E0938B828B82EC90E0958B848B86EC47 +:101F800090E0978B868B118E128E138E148EC4E088 +:101F9000D2E000E110E01F830E83CC24CA94DC2C35 +:101FA000D986C8861B870A87FF24F394FC861E8681 +:101FB0001D861A8B098BDC8ACB8A1E8B0D8BFF8AC0 +:101FC0001C8E1B8E1A8E198F088F80E190E00E9464 +:101FD000EA12988B8F8718A30F8FDAA2C9A21CA3CD +:101FE0000BA3FDA21BA61AA619A618A61FA30EA333 +:101FF00080E290E00E94EA129E8F8D8F19821882F3 +:102000001D830C831BAB0AABDDAACCAA1FAB0EABA6 +:10201000F8AE19AE1DAF0CAFDFAECEAE10934502D9 +:1020200000934402F092460210924B0210924A0230 +:1020300010924902109348020093470280E190E019 +:102040000E94EA129BAF8AAF10934F0200934E0298 +:10205000D0925102C0925002109353020093520248 +:10206000F0925402109259021092580210925702A4 +:10207000109356020093550280E190E00E94EA120C +:1020800090934D0280934C021DA61CA619AB08AB81 +:102090001093610200936002D0926302C0926202C8 +:1020A0001093650200936402F09266021092680237 +:1020B0001092670210936C0200936B02D0926E0232 +:1020C000C0926D021093700200936F02F092710241 +:1020D000109276021092750210927402109373029D +:1020E0000093720280E190E00E94EA1290936A02EB +:1020F0008093690210937A0200937902D0927C0255 +:10210000C0927B0210937E0200937D02F0927F02C8 +:102110001092850210928402109283021092820221 +:10212000109381020093800280E290E00E94EA1204 +:10213000909378028093770210925B0210925A0279 +:1021400010935F0200935E0210938902009388024D +:10215000D0928B02C0928A0210938D0200938C025F +:10216000F0928E02109294021092930210929202B8 +:10217000109291021093900200938F0280E190E000 +:102180000E9448049093870280938602DF91CF914A +:102190001F910F91FF90DF90CF900895CF93DF9321 +:1021A000CDB7DEB760970FB6F894DEBF0FBECDBFD8 +:1021B000789484B5826084BD84B5816084BD85B522 +:1021C000826085BD85B5816085BD80916E0081602E +:1021D00080936E00109281008091810082608093D4 +:1021E00081008091810081608093810080918000D6 +:1021F0008160809380008091B10084608093B10001 +:102200008091B00081608093B00080917A008460FA +:1022100080937A0080917A00826080937A00809126 +:102220007A008E7F80937A0080917A008068809314 +:102230007A001092C10088E091E00E94EA128C01BD +:102240008AE091E0D80111969C938E9387E691E005 +:1022500013969C938E93129784E092E015969C932C +:102260008E931497F801EB5FFE4F10823196108227 +:102270003196108280915401811115C08CED92E04D +:1022800090934F0180934E018DEA91E0909351011C +:10229000809350018BEB92E0909353018093520115 +:1022A00081E0809354018EE491E09A8389831C83BA +:1022B0000B83CE0101960E948105CE0101960E94FA +:1022C000160410935D0100935C0161E08DE00E94B3 +:1022D0000D0161E08DE00E94DF000E94780160E066 +:1022E0008DE00E94DF000E94780161E08DE00E9495 +:1022F000DF000E94780160E08DE00E94DF0060E076 +:102300008DE00E940D01D8011296ED91FC91A089FB +:10231000B18982E08C93A485B5851C92A685B7858A +:1023200088E08C93108EA489B58986E08C93A2896D +:10233000B3898C9180618C93A289B3898C918860D8 +:102340008C93A289B3898C9180688C930288F389DD +:10235000E02D80818F7D80830E94780130E020E035 +:1023600050E040E060EF70E0C8010E94E60280E0CB +:10237000A82E80E0B82E6EE372E0CE0101960E9496 +:102380006904F12CE12C8C859D85E816F90608F08E +:102390004FC0B701CE0101960E940008FC011081D8 +:1023A000612F84E092E00E945B08DC018D919C919A +:1023B0000197D1F5812F0E94B600082F612F80E38D +:1023C00092E00E945A09FC018081081769F1612F8F +:1023D00080E392E00E945A09DC010C93D12CC12CBD +:1023E0008091910290919202C816D906E8F4B60144 +:1023F00086E892E00E94CF05188B21E0013009F0B9 +:1024000020E02F87DC01ED91FC910480F581E02D27 +:10241000AE01415F5F4FBE01605F7F4F029609953D +:10242000BFEFCB1ADB0ADCCFEFEFEE1AFE0AABCF21 +:10243000CE0101960E94A30900915C0110915D01FB +:10244000D80112968D919C91DC01ED91FC91008454 +:10245000F185E02D0995892BA1F0F8018281938106 +:10246000DC01ED91FC910284F385E02D0995D80102 +:10247000ED91FC910190F081E02D682FC801099544 +:10248000DFCFA114B10409F476CF0E94180288238B +:1024900009F471CF0E9400006ECF80918602909166 +:1024A0008702009731F00E94B504109287021092C3 +:1024B000860283E992E00E9416048091770290914F +:1024C0007802009711F00E94861389E692E00E943C +:1024D000A3098CE492E00E94A3098EE392E00E949B +:1024E000A3098091210290912202009711F00E948D +:1024F000861383E192E00C94A309052E97FB1EF44A +:1025000000940E94941257FD07D00E94A71207FC66 +:1025100003D04EF40C94941250954095309521952B +:102520003F4F4F4F5F4F08959095809570956195FF +:102530007F4F8F4F9F4F08950E94C912A59F900D06 +:10254000B49F900DA49F800D911D11240895A1E2C8 +:102550001A2EAA1BBB1BFD010DC0AA1FBB1FEE1F1D +:10256000FF1FA217B307E407F50720F0A21BB30B68 +:10257000E40BF50B661F771F881F991F1A9469F7E4 +:1025800060957095809590959B01AC01BD01CF0140 +:102590000895A29FB001B39FC001A39F700D811D3C +:1025A0001124911DB29F700D811D1124911D08955C +:1025B000991B79E004C0991F961708F0961B881F95 +:1025C0007A95C9F780950895EE0FFF1F0590F49155 +:1025D000E02D09940F931F93CF93DF9382309105E1 +:1025E00010F482E090E0E0919F02F091A00230E0D0 +:1025F00020E0B0E0A0E0309799F42115310509F40E +:102600004AC0281B390B24303105D8F58A819B81BB +:102610006115710589F1FB0193838283FE0111C06D +:10262000408151810281138148175907E0F0481712 +:10263000590799F4109761F012960C93129713961C +:102640001C933296CF01DF91CF911F910F91089586 +:1026500000939F021093A002F4CF2115310551F091 +:102660004217530738F0A901DB019A01BD01DF01D0 +:10267000F801C1CFEF01F9CF9093A00280939F02A0 +:10268000CDCFFE01E20FF31F8193919322503109C8 +:1026900039832883D7CF20919D0230919E02232B2E +:1026A00041F4209102013091030130939E02209366 +:1026B0009D0220910001309101012115310541F465 +:1026C0002DB73EB74091040150910501241B350BF5 +:1026D000E0919D02F0919E02E217F307A0F42E1BF9 +:1026E0003F0B2817390778F0AC014E5F5F4F241776 +:1026F000350748F04E0F5F1F50939E0240939D0296 +:10270000819391939FCFF0E0E0E09CCFCF93DF9354 +:102710000097E9F0FC01329713821282A0919F0288 +:10272000B091A002ED0130E020E01097A1F42081EB +:102730003181820F931F20919D0230919E022817B4 +:10274000390709F061C0F0939E02E0939D02DF918A +:10275000CF910895EA01CE17DF07E8F54A815B8142 +:102760009E0141155105B1F7E901FB83EA834991C7 +:102770005991C40FD51FEC17FD0761F48081918139 +:102780000296840F951FE901998388838281938142 +:102790009B838A83F0E0E0E012968D919C911397E1 +:1027A0000097B9F52D913C911197CD010296820FBA +:1027B000931F20919D0230919E022817390739F608 +:1027C000309751F51092A00210929F02B0939E0292 +:1027D000A0939D02BCCFD383C28340815181840FDB +:1027E000951FC817D90761F44E5F5F4F88819981A3 +:1027F000480F591F518340838A819B819383828331 +:102800002115310509F0B0CFF093A002E0939F02AB +:102810009ECFFD01DC01C0CF13821282D7CF10E022 +:10282000C2E6D0E004C0FE010E94E4122196C33645 +:08283000D107C9F7F894FFCFAE +:102838000000A102800000000000C2039C03910375 +:10284800AB093903E602000000004E02AE01DB01CD +:082858009B020C02EA01FE01E3 :00000001FF diff --git a/owlet/firmware/arduino-mini-pro-5v/firmware.hex b/owlet/firmware/arduino-mini-pro-5v/firmware.hex index d64a90001..5c856436f 100644 --- a/owlet/firmware/arduino-mini-pro-5v/firmware.hex +++ b/owlet/firmware/arduino-mini-pro-5v/firmware.hex @@ -1,8 +1,8 @@ :100000000C9463000C948B000C948B000C948B006C :100010000C948B000C948B000C948B000C948B0034 -:100020000C948B000C948B000C948B000C94ED0EB4 +:100020000C948B000C948B000C948B000C94DA0EC7 :100030000C948B000C948B000C948B000C948B0014 -:100040000C944B0E0C948B000C94BB0E0C94950EE0 +:100040000C94380E0C948B000C94A80E0C94820E19 :100050000C948B000C948B000C948B000C948B00F4 :100060000C948B000C948B000000000024002700EF :100070002A0000000000250028002B0000000000DE @@ -10,12 +10,12 @@ :100090000202020203030303030301020408102007 :1000A0004080010204081020010204081020000012 :1000B0000008000201000003040700000000000027 -:1000C0000000A90F621211241FBECFEFD8E0DEBFDF -:1000D000CDBF11E0A0E0B1E0E2E6F8E202C0059099 +:1000C0000000960F4F1211241FBECFEFD8E0DEBF05 +:1000D000CDBF11E0A0E0B1E0ECE3F8E202C0059092 :1000E0000D92A832B107D9F722E0A8E2B1E001C031 :1000F0001D92A13AB207E1F710E0C2E6D0E004C0D9 -:100100002197FE010E94F912C136D107C9F70E945A -:10011000E3100C9424140C940000833081F028F434 +:100100002197FE010E94E612C136D107C9F70E946D +:10011000D0100C9411140C940000833081F028F45A :10012000813099F08230A9F008958730A9F08830A5 :10013000C9F08430B1F4809180008F7D03C080913C :1001400080008F7780938000089584B58F7784BD79 @@ -136,12 +136,12 @@ :10087000220F331F858D968D280F391FF901808136 :10088000918108952F5F3F4FE1CF8585968508952B :10089000CF93DF93EC01CD3C8CE0D807A0F42AE0A5 -:1008A0002C9FC0012D9F900D112402960E94FF12D3 +:1008A0002C9FC0012D9F900D112402960E94EC12E6 :1008B000FC01C193D193CF012197D7FD07C01182CD :1008C00010823A96F9CF8FEF9FEFF0CFDF91CF9163 :1008D0000895EF92FF920F931F93CF93DF93EC0154 :1008E0008B0180E190E09F838E8381E088871D8665 -:1008F000FB01E184F284C7010E94FF12998388837F +:1008F000FB01E184F284C7010E94EC129983888392 :10090000892B61F1F801828193819B838A838481A1 :1009100095819D838C83868197819F838E8380853B :100920008887FA86E986838594859C878B87858569 @@ -156,7 +156,7 @@ :1009B000969587954DEC5CE4849F9001859F300D62 :1009C000949F300D11243F7746EF4203C001439FAF :1009D000900D11240297800F911FDF91CF911F91ED -:1009E0000F91FF90EF900C949B13DF91CF911F918B +:1009E0000F91FF90EF900C948813DF91CF911F919E :1009F0000F91FF90EF9008952F923F924F925F9248 :100A00006F927F928F929F92AF92BF92CF92DF921E :100A1000EF92FF920F931F93CF93DF938C016B01A3 @@ -198,11 +198,11 @@ :100C5000EB01F8012085211105C08C179D0738F0A4 :100C600081E0EBCF7E018C179D0708F47C01209773 :100C700021F16E018FEF9FEFC115F0E4DF0718F44B -:100C8000C601880F991F0E94FF125C010097A1F214 +:100C8000C601880F991F0E94EC125C010097A1F227 :100C9000DC01F8018081918130E020E0E216F3066A :100CA00081F0F901EE0FFF1FE80FF91F408151811C :100CB0004D935D932F5F3F4FF1CF60E1C62ED12C56 -:100CC000DFCF009711F00E949B13F801B182A08240 +:100CC000DFCF009711F00E948813F801B182A08253 :100CD000D286C18683859485C817D90708F6D4873C :100CE000C387BECF0F931F93CF93DF93EC018B018C :100CF00069857A850617170738F08E819F81680FFE @@ -221,12 +221,12 @@ :100DC000BF90AF909F908F90089586012885211144 :100DD00027C080179107B8F60115110539F15801A0 :100DE000011580E4180730F5C501880F991F0E948E -:100DF000FF124C01009739F2DC018881998130E0C3 +:100DF000EC124C01009739F2DC018881998130E0D6 :100E000020E0C216D306C9F0F901EE0FFF1FE80F6C :100E1000F91F408151814D935D932F5F3F4FF1CF7B :100E20006C0108171907C0F66801D6CF60E1A62E3D :100E3000B12CDACF8FEF9FEFDACF009711F00E943D -:100E40009B1399828882BA86A9868B859C85081710 +:100E4000881399828882BA86A9868B859C85081723 :100E5000190708F098CF1C870B8795CFEE0CFF1C65 :100E6000888199818E0D9F1DA3CFAF92BF92CF92A3 :100E7000DF92EF92FF920F931F93CF93DF938C013A @@ -236,10 +236,10 @@ :100EB000BF90AF900895EB01F8012085211105C086 :100EC0008C179D0738F081E0EBCF7E018C179D07D2 :100ED00008F47C016E01209719F480E1C82ED12C12 -:100EE000C6010E94FF125C010097C9F2FC01D80103 +:100EE000C6010E94EC125C010097C9F2FC01D80116 :100EF0008D919C9130E020E0E216F30641F0DC0198 :100F0000A20FB31F4C9141932F5F3F4FF5CF009736 -:100F100011F00E949B13F801B182A082C186D28693 +:100F100011F00E948813F801B182A082C186D286A6 :100F200083859485C817D90770F6D487C387CBCF3C :100F3000CF93FC0183859485C0E06817790750F54D :100F40008385948501976817790778F4808191816A @@ -307,345 +307,342 @@ :101320000F90DF91CF911F910F91FF90EF90DF9081 :10133000CF900895F801208131812F5F3F4F318395 :101340002083BC01DACFFC0180819181009711F0EC -:101350000C949B1308952F923F925F926F927F920D +:101350000C94881308952F923F925F926F927F9220 :101360008F929F92AF92BF92CF92DF92EF92FF92B5 :101370000F931F93CF93DF93CDB7DEB729970FB6A7 :10138000F894DEBF0FBECDBF6C017B01DB016C9119 -:1013900011965C90673008F06FC4E62FF0E0ED52D4 -:1013A000F64F0C94F912DA09100AF10B5F0C9E0C3F -:1013B0003D0D790DDC01ED91FC910084F185E02D6E +:1013900011965C90673008F05CC4E62FF0E0ED52E7 +:1013A000F64F0C94E612DA09110ADE0B4C0C8B0C8A +:1013B0002A0D660DDC01ED91FC910084F185E02D94 :1013C000423011F1F12CE12C10E000E023E030E09C :1013D000452D60E0C601099529960FB6F894DEBF49 :1013E0000FBECDBFDF91CF911F910F91FF90EF9076 :1013F000DF90CF90BF90AF909F908F907F906F9035 -:101400005F903F902F90089519821A824B8333E0AA -:10141000E32EF12C8E010F5F1F4F30E020E0D8CF7C -:10142000EDB7FEB7F987E887443079F0DC01ED913C -:10143000FC910084F185E02DF12CE12C10E000E01E -:1014400023E030E0452D61E0C5CFF70112818381B3 -:10145000282E312CD6011496ED90FC90823009F4A0 -:10146000F7C078F4882309F437C1813009F4E0C06B -:10147000612FC7010E945B08DC012D923C9280E045 -:10148000BEC0843009F4F1C008F4E7C0853081F7AC -:101490005701F6E5AF0EB11C712C612CC7018059C4 -:1014A0009F4F9F838E8345019FE0890E911CAE81E3 -:1014B000BF818D919C916816790650F4B301C401E7 -:1014C0000E940008FC0180811813DCC077FEDEC09A -:1014D00083E090E00E94FF124C0180914C018C301F -:1014E00008F0F6C091E0980F90934C01D4018C93D2 -:1014F00090E0FC01EE0FFF1FE80FF91FE85DFE4FC3 -:1015000088EB9BE092838183612FC5010E941109C2 -:10151000DC018D929C92612FC5010E941109FC0192 -:1015200080809180D4018C918C3008F055C061E0AE -:10153000812F0E940D01F4018081282F30E0F901F4 -:10154000EE0FFF1FE20FF31FE85DFE4F9081907CCE -:10155000212F2F73922B9083D40111961C921197F7 -:1015600012961C922CE0622F0E94ED12829FB00115 -:10157000112430E020E0AB01420F531FFA01EE0FBF -:10158000FF1FE40FF51FE85DFE4F908196FD16C02A -:101590002F5F3F4F2C30310571F781110FC0109232 -:1015A000800082E080938100109285001092840078 -:1015B000B19A80916F00826080936F00D401EC91AA -:1015C0008E2F90E0FC01EE0FFF1FE80FF91FE85D82 -:1015D000FE4F808180648083F40180818F3F09F019 -:1015E00047CF612FC5010E941109DC018D919C91AB -:1015F0000E949B13612FC5010E94A40885E0898386 -:10160000D601ED91FC910084F185E02DEE24E39468 -:10161000F12C8E010F5F1F4F30E020E0452D61E07F -:10162000C60109950FB6F894DEBF0FBECDBFD4CE6C -:1016300060E0812F0E940D01812F0E94B600082FCB -:10164000612FC7018C960E945A09FC01008310CFBC -:1016500061E0812F0E940D010BCF60E0812F0E947D -:101660000D01812F0E943E0103CF61E0812F0E9476 -:101670000D0161E0812F0E940D0160E0812F0E9429 -:10168000DF00F6CEFFEF6F1A7F0A11CF612FC50181 -:101690000E941109DC01ED91FC91E0818E2F90E018 -:1016A000FC01EE0FFF1FE80FF91FE85DFE4F808180 -:1016B0008F7B8083612FC5010E941109FC0180810D -:1016C00091810E949B13612FC5010E94A40800CF45 -:1016D0008FEFF401808318CFB12CA12CF701E059D2 -:1016E000FF4FFF83EE834701F6E58F0E911C340117 -:1016F0002FE0620E711CAE81BF818D919C91A81666 -:10170000B90650F4B501C3010E940008FC018081B4 -:1017100018131EC0B7FE20C0B12CA12C3701F5E470 -:101720006F0E711C47012AE3820E911CD3018D912B -:101730009C91A816B90650F4B501C4010E94000896 -:10174000FC01808118132AC0B7FE2CC060E081CF55 -:10175000FFEFAF1ABF0ACFCF612FC4010E9411095A -:10176000DC01ED91FC91E0818E2F90E0FC01EE0F09 -:10177000FF1FE80FF91FE85DFE4F80818F7B80839C -:10178000612FC4010E941109FC01808191810E9496 -:101790009B13612FC4010E94A408BECFFFEFAF1AB4 -:1017A000BF0AC4CFB12CA12CD3018D919C91A81656 -:1017B000B90660F6B501C4010E940008FC018081F1 -:1017C00018130BC0B501C701885B9F4F0E94980793 -:1017D000B501C4010E949807B9CFFFEFAF1ABF0A45 -:1017E000E3CF443079F0DC01ED91FC910084F18588 -:1017F000E02DF12CE12C10E000E023E030E0452D5D -:1018000062E0E8CDF70112819380DC011496ED903F -:10181000FC90612FC7010E9430080196C9F1612F29 -:10182000C7010E945B08FC0180819181029709F049 -:1018300042C001E0911001C000E0602F812F0E94A2 -:10184000DF00912C812C3701FDE86F0E711C22E81E -:10185000E20EF11CD3018D919C918816990668F5D2 -:10186000B401C7010E94CF051C830983DC01ED91FF -:10187000FC910480F581E02DAE014F5F5F4FBE010A -:101880006C5F7F4F02960995BFEF8B1A9B0AE2CFE0 -:1018900081E08D83D601ED91FC910084F185E02DEE -:1018A000EE24E394F12C8E010B5F1F4F30E020E01B -:1018B000452D62E0B5CE83E0ECCF80E0EACF433047 -:1018C00079F0DC01ED91FC910084F185E02DF12CA3 -:1018D000E12C10E000E023E030E0452D63E07ACD1C -:1018E000F7011281612FDC0114968D919C910E9469 -:1018F00021040097F1F001970297F0F4812F0E94E4 -:10190000B60021E0892B09F420E080E089832A8356 -:10191000D601ED91FC910084F185E02D02E0E02EEE -:10192000F12C8E010F5F1F4F30E020E0452D63E06A -:1019300077CE81E020E0EACF82E0FCCF443079F03E -:10194000DC01ED91FC910084F185E02DF12CE12C7E -:1019500010E000E023E030E0452D64E03BCDF701EE -:101960001281DC0114968D909C90612FC4010E941D -:101970002104009799F481E08983D601ED91FC91CF -:101980000084F185E02DEE24E394F12C8E010F5FAD -:101990001F4F30E020E0452D64E042CE049711F067 -:1019A00083E0EACFF7010381612FC4010E94300870 -:1019B000019609F3612FC4010E945B08DC018D913F -:1019C0009C91049769F7E02EF12C61E0812F0E9431 -:1019D0000D01E114F10429F460E0812F0E94DF0081 -:1019E0002BC0BFEFEB16F10411F461E0F6CFE12F4D -:1019F000F0E0E255FF4FE491E33029F148F4E130A3 -:101A0000B9F0E230D9F0E0E8EE16F10474F7E4CF73 -:101A1000E73019F1E83049F1E430A9F7809180000E -:101A2000806280938000F0928B00E0928A0004C074 -:101A300084B5806884BD07BD80E09ECF84B5806298 -:101A400084BD08BDF9CF80918000806880938000BC -:101A5000F0928900E0928800EFCF8091B00080681A -:101A60008093B0000093B300E7CF8091B000806214 -:101A70008093B0000093B400DFCF433079F0DC01F5 -:101A8000ED91FC910084F185E02DF12CE12C10E02A -:101A900000E023E030E0452D65E09CCCF7011281A9 -:101AA000612FDC0114968D919C910E942104009776 -:101AB000E1F0039722E00297C8F4812F0E943E01D3 -:101AC00020E029839A838B83D601ED91FC910084D9 -:101AD000F185E02DB3E0EB2EF12C8E010F5F1F4F4F -:101AE00030E020E0452D65E09BCD21E080E090E0F6 -:101AF000E8CF443079F0DC01ED91FC910084F18570 -:101B0000E02DF12CE12C10E000E023E030E0452D49 -:101B100066E060CCF7011281DC0114968D909C90F8 -:101B2000612FC4010E942104009799F481E0898308 -:101B3000D601ED91FC910084F185E02DEE24E39433 -:101B4000F12C8E010F5F1F4F30E020E0452D66E045 -:101B500067CD059709F08CC0F701038184E0053B50 -:101B600030F7612FC4010E94300897FDDFCF612F4D -:101B7000C4010E945B08DC018D919C91059709F0DE -:101B800079C0B6E58B0E911C612FC4010E9411092A -:101B9000DC01ED91FC91E0818E2F90E0FC01EE0FD5 -:101BA000FF1FE80FF91FE85DFE4F808186FFBECF63 -:101BB000612FC4010E941109DC01ED91FC9110819B -:101BC0001C3008F053C0828148E5842E42E0942EF8 -:101BD000881A910887FD93941401220C331C220C5F -:101BE000331C818168E8E62EF12CE81AF10887FDA4 -:101BF000F394EE0CFF1CEE0CFF1C37010F2C000CB5 -:101C0000880899089101032C000C440B550B2619E8 -:101C1000370948095909A02FB0E00E94B11224EBFE -:101C200030E040E050E00E949212BA01A901460D56 -:101C3000571D681D791D4E155F052CF07101421569 -:101C400053050CF47A01B2E0EB1AF108EE0CFF1C1C -:101C50002FB7F894812F90E0FC01EE0FFF1FE80FE3 -:101C6000F91FE85DFE4FF282E1822FBF80E05FCF77 -:101C700082E05DCF83E05BCFDC01ED91FC910084DD -:101C8000F185E02DF12CE12C10E000E022E030E0C5 -:101C9000452D0995A1CB1F920F920FB60F921124DB -:101CA0002F933F938F939F93AF93BF9380915F0147 -:101CB00090916001A0916101B091620130915E014B -:101CC00023E0230F2D3758F50196A11DB11D209358 -:101CD0005E0180935F0190936001A0936101B093D6 -:101CE00062018091630190916401A0916501B091BE -:101CF00066010196A11DB11D80936301909364015B -:101D0000A0936501B0936601BF91AF919F918F91B0 -:101D10003F912F910F900FBE0F901F90189526E8BE -:101D2000230F0296A11DB11DD2CF1F920F920FB6A5 -:101D30000F9211242F933F934F935F936F937F9351 -:101D40008F939F93AF93BF93EF93FF9387E691E0B9 -:101D50000E942C02FF91EF91BF91AF919F918F91C3 -:101D60007F916F915F914F913F912F910F900FBE97 -:101D70000F901F9018951F920F920FB60F9211247B -:101D80002F938F939F93EF93FF93E0917701F091BF -:101D900078018081E0917D01F0917E0182FD1BC080 -:101DA0009081809180018F5F8F73209181018217D4 -:101DB00041F0E0918001F0E0E959FE4F958F80936A -:101DC0008001FF91EF919F918F912F910F900FBE06 -:101DD0000F901F9018958081F4CF1F920F920FB62D -:101DE0000F9211242F933F934F935F936F937F93A1 -:101DF0008F939F93AF93BF93CF93DF93EF93FF9313 -:101E000080914D01C0914C01D0E087FF24C0109219 -:101E100085001092840080914D018F5F80934D0169 -:101E200080914D01082E000C990B8C179D0724F40E -:101E300080914D018C30C4F1809184009091850097 -:101E4000049680349C4908F47AC080918400909173 -:101E50008500049676C080914D01082E000C990BE8 -:101E60008C179D07C4F6E0914D018E2FEE0F990B54 -:101E7000FC01EE0FFF1FE80FF91FE85DFE4F8081A8 -:101E800086FFC9CFE0914D018E2FEE0F990BFC011B -:101E9000EE0FFF1FE80FF91FE85DFE4F808160E045 -:101EA0008F730E94DF00B7CF2091840030918500AE -:101EB000E0914D018E2FEE0F990BFC01EE0FFF1FED -:101EC000E80FF91FE85DFE4F81819281820F931F19 -:101ED0009093890080938800E0914D018E2FEE0F42 -:101EE000990BFC01EE0FFF1FE80FF91FE85DFE4F95 -:101EF000808186FF11C0E0914D018E2FEE0F990B6E -:101F0000FC01EE0FFF1FE80FF91FE85DFE4F808117 -:101F100061E08F730E94DF00FF91EF91DF91CF911D -:101F2000BF91AF919F918F917F916F915F914F91F1 -:101F30003F912F910F900FBE0F901F90189580E446 -:101F40009CE990938900809388008FEF80934D01E6 -:101F5000E3CFCF92DF92FF920F931F93CF93DF9344 -:101F6000E7E6F1E01382128288EE93E0A0E0B0E0B1 -:101F700084839583A683B7838AE191E091838083EC -:101F800085EC90E09587848784EC90E0978786873E -:101F900080EC90E0918B808B81EC90E0938B828B36 -:101FA00082EC90E0958B848B86EC90E0978B868B0F -:101FB000118E128E138E148EC4E0D2E000E110E078 -:101FC0001F830E83CC24CA94DC2CD986C8861B8739 -:101FD0000A87FF24F394FC861E861D861A8B098BC4 -:101FE000DC8ACB8A1E8B0D8BFF8A1C8E1B8E1A8E71 -:101FF000198F088F80E190E00E94FF12988B8F87E5 -:1020000018A30F8FDAA2C9A21CA30BA3FDA21BA6C3 -:102010001AA619A618A61FA30EA380E290E00E949C -:10202000FF129E8F8D8F198218821D830C831BAB2C -:102030000AABDDAACCAA1FAB0EABF8AE19AE1DAF32 -:102040000CAFDFAECEAE1093450200934402F09287 -:10205000460210924B0210924A02109249021093CB -:1020600048020093470280E190E00E94FF129BAF7C -:102070008AAF10934F0200934E02D0925102C09249 -:1020800050021093530200935202F09254021092A5 -:102090005902109258021092570210935602009360 -:1020A000550280E190E00E94FF1290934D028093D0 -:1020B0004C021DA61CA619AB08AB1093610200933D -:1020C0006002D0926302C092620210936502009394 -:1020D0006402F092660210926802109267021093F6 -:1020E0006C0200936B02D0926E02C0926D0210934C -:1020F000700200936F02F0927102109276021092B9 -:10210000750210927402109373020093720280E1C0 -:1021100090E00E94FF1290936A02809369021093EC -:102120007A0200937902D0927C02C0927B021093D3 -:102130007E0200937D02F0927F021092850210923F -:102140008402109283021092820210938102009303 -:10215000800280E290E00E94FF12909378028093C8 -:10216000770210925B0210925A0210935F02009362 -:102170005E021093890200938802D0928B02C09273 -:102180008A0210938D0200938C02F0928E021092BC -:102190009402109293021092920210929102109364 -:1021A000900200938F0280E190E00E944804909397 -:1021B000870280938602DF91CF911F910F91FF904C -:1021C000DF90CF900895CF93DF93CDB7DEB76097C0 -:1021D0000FB6F894DEBF0FBECDBF789484B5826091 -:1021E00084BD84B5816084BD85B5826085BD85B5BB -:1021F000816085BD80916E00816080936E00109239 -:1022000081008091810082608093810080918100B3 -:102210008160809381008091800081608093800044 -:102220008091B10084608093B1008091B0008160A2 -:102230008093B00080917A00846080937A008091CE -:102240007A00826080937A0080917A008160809326 -:102250007A0080917A00806880937A001092C100A1 -:1022600088E091E00E94FF128C018AE091E0D801A1 -:1022700011969C938E9387E691E013969C938E9390 -:10228000129784E092E015969C938E931497F80130 -:10229000EB5FFE4F10823196108231961082809152 -:1022A0005401811115C08CED92E090934F01809301 -:1022B0004E018DEA91E090935101809350018BEB98 -:1022C00092E0909353018093520181E080935401F6 -:1022D0008EE491E09A8389831C830B83CE0101965F -:1022E0000E948105CE0101960E94160410935D01A3 -:1022F00000935C0161E08DE00E940D0161E08DE0E2 -:102300000E94DF000E94780160E08DE00E94DF0003 -:102310000E94780161E08DE00E94DF000E94780158 -:1023200060E08DE00E94DF0060E08DE00E940D0122 -:10233000D8011296ED91FC91A089B18982E08C932D -:10234000A485B5851C92A685B78580E18C93108EF7 -:10235000A489B58986E08C93A289B3898C91806128 -:102360008C93A289B3898C9188608C93A289B3895C -:102370008C9180688C930288F389E02D80818F7D19 -:1023800080830E94780130E020E050E040E060EF80 -:1023900070E0C8010E94E60280E0A82E80E0B82E1E -:1023A0006EE372E0CE0101960E946904F12CE12CEB -:1023B0008C859D85E816F90608F04FC0B701CE015F -:1023C00001960E940008FC011081612F84E092E0D8 -:1023D0000E945B08DC018D919C910197D1F5812FC2 -:1023E0000E94B600082F612F80E392E00E945A09F4 -:1023F000FC018081081769F1612F80E392E00E945F -:102400005A09DC010C93D12CC12C8091910290913E -:102410009202C816D906E8F4B60186E892E00E9456 -:10242000CF05188B21E0013009F020E02F87DC0177 -:10243000ED91FC910480F581E02DAE01415F5F4F8D -:10244000BE01605F7F4F02960995BFEFCB1ADB0A92 -:10245000DCCFEFEFEE1AFE0AABCFCE0101960E9461 -:10246000A30900915C0110915D01D80112968D9134 -:102470009C91DC01ED91FC910084F185E02D0995A2 -:10248000892BA1F0F80182819381DC01ED91FC910F -:102490000284F385E02D0995D801ED91FC9101901E -:1024A000F081E02D682FC8010995DFCFA114B10498 -:1024B00009F476CF0E941802882309F471CF0E9494 -:1024C00000006ECF8091860290918702009731F0D4 -:1024D0000E94B504109287021092860283E992E06E -:1024E0000E9416048091770290917802009711F073 -:1024F0000E949B1389E692E00E94A3098CE492E07B -:102500000E94A3098EE392E00E94A3098091210218 -:1025100090912202009711F00E949B1383E192E0B8 -:102520000C94A309052E97FB1EF400940E94A91297 -:1025300057FD07D00E94BC1207FC03D04EF40C9448 -:10254000A91250954095309521953F4F4F4F5F4FC1 -:10255000089590958095709561957F4F8F4F9F4F0F -:1025600008950E94DE12A59F900DB49F900DA49F28 -:10257000800D911D11240895A1E21A2EAA1BBB1BE8 -:10258000FD010DC0AA1FBB1FEE1FFF1FA217B3073F -:10259000E407F50720F0A21BB30BE40BF50B661F55 -:1025A000771F881F991F1A9469F760957095809519 -:1025B00090959B01AC01BD01CF010895A29FB00190 -:1025C000B39FC001A39F700D811D1124911DB29F67 -:1025D000700D811D1124911D0895991B79E004C08F -:1025E000991F961708F0961B881F7A95C9F7809552 -:1025F0000895EE0FFF1F0590F491E02D09940F93BD -:102600001F93CF93DF938230910510F482E090E026 -:10261000E0919F02F091A00230E020E0B0E0A0E065 -:10262000309799F42115310509F44AC0281B390B5C -:1026300024303105D8F58A819B816115710589F1B6 -:10264000FB0193838283FE0111C04081518102818D -:10265000138148175907E0F04817590799F4109764 -:1026600061F012960C93129713961C933296CF0139 -:10267000DF91CF911F910F91089500939F021093C6 -:10268000A002F4CF2115310551F04217530738F05D -:10269000A901DB019A01BD01DF01F801C1CFEF0102 -:1026A000F9CF9093A00280939F02CDCFFE01E20F5D -:1026B000F31F819391932250310939832883D7CF17 -:1026C00020919D0230919E02232B41F42091020122 -:1026D0003091030130939E0220939D0220910001CE -:1026E000309101012115310541F42DB73EB74091DC -:1026F000040150910501241B350BE0919D02F091DE -:102700009E02E217F307A0F42E1B3F0B2817390790 -:1027100078F0AC014E5F5F4F2417350748F04E0F3D -:102720005F1F50939E0240939D02819391939FCF90 -:10273000F0E0E0E09CCFCF93DF930097E9F0FC015D -:10274000329713821282A0919F02B091A002ED01F4 -:1027500030E020E01097A1F420813181820F931F97 -:1027600020919D0230919E022817390709F061C01F -:10277000F0939E02E0939D02DF91CF910895EA01CC -:10278000CE17DF07E8F54A815B819E0141155105AF -:10279000B1F7E901FB83EA8349915991C40FD51F31 -:1027A000EC17FD0761F4808191810296840F951FDB -:1027B000E90199838883828193819B838A83F0E0F6 -:1027C000E0E012968D919C9113970097B9F52D91A9 -:1027D0003C911197CD010296820F931F20919D028B -:1027E00030919E022817390739F6309751F510922B -:1027F000A00210929F02B0939E02A0939D02BCCFB4 -:10280000D383C28340815181840F951FC817D90794 -:1028100061F44E5F5F4F88819981480F591F518342 -:1028200040838A819B81938382832115310509F03E -:10283000B0CFF093A002E0939F029ECFFD01DC0198 -:10284000C0CF13821282D7CF10E0C2E6D0E004C01E -:10285000FE010E94F9122196C336D107C9F7F894F8 -:02286000FFCFA8 -:102862000000A102800000000000C2039C0391034B -:10287200AB093903E602000000004E02AE01DB01A3 -:082882009B020C02EA01FE01B9 +:101400005F903F902F90089519821A8283E08B831A +:1014100033E0E32EF12C8E010F5F1F4F30E020E010 +:10142000D7CFEDB7FEB7F987E887443079F0DC0114 +:10143000ED91FC910084F185E02DF12CE12C10E080 +:1014400000E023E030E0452D61E0C4CFF7011281D8 +:101450008381282E312CD6011496ED90FC90823099 +:1014600009F4E3C030F5882309F423C1813009F47D +:10147000CCC0612FC7010E945B08DC012D923C9219 +:101480001982D601ED91FC910084F185E02DEE24C6 +:10149000E394F12C8E010F5F1F4F30E020E0452DCB +:1014A00061E0C60109950FB6F894DEBF0FBECDBF4F +:1014B00093CF843009F4C6C008F4BCC08530C9F6A7 +:1014C0005701F6E5AF0EB11C712C612CC701805994 +:1014D0009F4F9F838E8345019FE0890E911CAE81B3 +:1014E000BF818D919C916816790650F4B301C401B7 +:1014F0000E940008FC0180811813B1C077FEB3C0C0 +:1015000083E090E00E94EC124C0180914C018C3001 +:1015100008F0CBC091E0980F90934C01D4018C93CC +:1015200090E0FC01EE0FFF1FE80FF91FE85DFE4F92 +:1015300088EB9BE092838183612FC5010E94110992 +:10154000DC018D929C92612FC5010E941109FC0162 +:10155000A080B180D5018C918C3008F08ACF61E0F9 +:10156000812F0E940D01F5018081282F30E0F901C3 +:10157000EE0FFF1FE20FF31FE85DFE4F9081907C9E +:10158000212F2F73922B9083D50111961C921197C6 +:1015900012961C922CE0622F0E94DA12829FB001F8 +:1015A000112430E020E0AB01420F531FFA01EE0F8F +:1015B000FF1FE40FF51FE85DFE4F908196FD16C0FA +:1015C0002F5F3F4F2C30310571F781110FC0109202 +:1015D000800082E080938100109285001092840048 +:1015E000B19A80916F00826080936F00D501EC9179 +:1015F0008E2F90E0FC01EE0FFF1FE80FF91FE85D52 +:10160000FE4F80818064808334CF60E0812F0E9410 +:101610000D01812F0E94B600082F612FC7018C9603 +:101620000E945A09FC01008324CF61E0812F0E94AF +:101630000D011FCF60E0812F0E940D01812F0E94BC +:101640003E0117CF61E0812F0E940D0161E0812FE3 +:101650000E940D0160E0812F0E94DF000ACFFFEFA2 +:101660006F1A7F0A3CCF612FC5010E941109DC016E +:10167000ED91FC91E0818E2F90E0FC01EE0FFF1FB9 +:10168000E80FF91FE85DFE4F80818F7B8083612F1B +:10169000C5010E941109FC01808191810E9488137B +:1016A000612FC5010E94A4082BCF8FEFF401808326 +:1016B00043CFB12CA12CF701E059FF4FFF83EE83FC +:1016C0004701F6E58F0E911C34012FE0620E711C6C +:1016D000AE81BF818D919C91A816B90650F4B501D9 +:1016E000C3010E940008FC01808118131EC0B7FED0 +:1016F00020C0B12CA12C3701F5E46F0E711C4701FD +:101700002AE3820E911CD3018D919C91A816B906F3 +:1017100050F4B501C4010E940008FC018081181337 +:101720002AC0B7FE2CC060E081CFFFEFAF1ABF0A1E +:10173000CFCF612FC4010E941109DC01ED91FC9112 +:10174000E0818E2F90E0FC01EE0FFF1FE80FF91FE4 +:10175000E85DFE4F80818F7B8083612FC4010E94F2 +:101760001109FC01808191810E948813612FC401BD +:101770000E94A408BECFFFEFAF1ABF0AC4CFB12C9E +:10178000A12CD3018D919C91A816B90660F6B501E4 +:10179000C4010E940008FC01808118130BC0B50130 +:1017A000C701885B9F4F0E949807B501C4010E9442 +:1017B0009807B9CFFFEFAF1ABF0AE3CF443079F0F3 +:1017C000DC01ED91FC910084F185E02DF12CE12C00 +:1017D00010E000E023E030E0452D62E0FBCDF701B2 +:1017E00012819380DC011496ED90FC90612FC7016B +:1017F0000E9430080196C9F1612FC7010E945B0861 +:10180000FC0180819181029709F042C001E09110B2 +:1018100001C000E0602F812F0E94DF00912C812CFD +:101820003701FDE86F0E711C22E8E20EF11CD301B6 +:101830008D919C918816990668F5B401C7010E94A4 +:10184000CF051C830983DC01ED91FC910480F581B7 +:10185000E02DAE014F5F5F4FBE016C5F7F4F029680 +:101860000995BFEF8B1A9B0AE2CF81E08D83D601E9 +:10187000ED91FC910084F185E02DEE24E394F12CB0 +:101880008E010B5F1F4F30E020E0452D62E009CE56 +:1018900083E0ECCF80E0EACF433079F0DC01ED91DA +:1018A000FC910084F185E02DF12CE12C10E000E0AA +:1018B00023E030E0452D63E08DCDF7011281612FEB +:1018C000DC0114968D919C910E9421040097F1F007 +:1018D00001970297F0F4812F0E94B60021E0892B36 +:1018E00009F420E080E089832A83D601ED91FC9100 +:1018F0000084F185E02D02E0E02EF12C8E010F5FD7 +:101900001F4F30E020E0452D63E0CBCD81E020E0AB +:10191000EACF82E0FCCF443079F0DC01ED91FC911C +:101920000084F185E02DF12CE12C10E000E023E0B3 +:1019300030E0452D64E04ECDF7011281DC011496B4 +:101940008D909C90612FC4010E942104009799F40E +:1019500081E08983D601ED91FC910084F185E02D31 +:10196000EE24E394F12C8E010F5F1F4F30E020E056 +:10197000452D64E096CD049711F083E0EACFF7019E +:101980000381612FC4010E943008019609F3612F81 +:10199000C4010E945B08DC018D919C91049769F75A +:1019A000E02EF12C61E0812F0E940D01E114F10481 +:1019B00029F460E0812F0E94DF002BC0BFEFEB16FF +:1019C000F10411F461E0F6CFE12FF0E0E255FF4FB2 +:1019D000E491E33029F148F4E130B9F0E230D9F094 +:1019E000E0E8EE16F10474F7E4CFE73019F1E830DF +:1019F00049F1E430A9F780918000806280938000F3 +:101A0000F0928B00E0928A0004C084B5806884BDA7 +:101A100007BD80E09ECF84B5806284BD08BDF9CF4C +:101A200080918000806880938000F0928900E0922D +:101A30008800EFCF8091B00080688093B000009361 +:101A4000B300E7CF8091B00080628093B000009334 +:101A5000B400DFCF433079F0DC01ED91FC910084DC +:101A6000F185E02DF12CE12C10E000E023E030E0E6 +:101A7000452D65E0AFCCF7011281612FDC01149692 +:101A80008D919C910E9421040097E1F0039722E040 +:101A90000297C8F4812F0E943E0120E029839A8397 +:101AA0008B83D601ED91FC910084F185E02DB3E0AC +:101AB000EB2EF12C8E010F5F1F4F30E020E0452D03 +:101AC00065E0EFCC21E080E090E0E8CF443079F0B1 +:101AD000DC01ED91FC910084F185E02DF12CE12CED +:101AE00010E000E023E030E0452D66E073CCF70124 +:101AF0001281DC0114968D909C90612FC4010E948C +:101B00002104009799F481E08983D601ED91FC913D +:101B10000084F185E02DEE24E394F12C8E010F5F1B +:101B20001F4F30E020E0452D66E0BBCC059709F063 +:101B30008CC0F701038184E0053B30F7612FC401BD +:101B40000E94300897FDDFCF612FC4010E945B081F +:101B5000DC018D919C91059709F079C0B6E58B0E5B +:101B6000911C612FC4010E941109DC01ED91FC91CF +:101B7000E0818E2F90E0FC01EE0FFF1FE80FF91FB0 +:101B8000E85DFE4F808186FFBECF612FC4010E94B9 +:101B90001109DC01ED91FC9110811C3008F053C05B +:101BA000828148E5842E42E0942E881A910887FDB0 +:101BB00093941401220C331C220C331C818168E89D +:101BC000E62EF12CE81AF10887FDF394EE0CFF1CC9 +:101BD000EE0CFF1C37010F2C000C880899089101AE +:101BE000032C000C440B550B2619370948095909D9 +:101BF000A02FB0E00E949E1224EB30E040E050E0C5 +:101C00000E947F12BA01A901460D571D681D791D5A +:101C10004E155F052CF07101421553050CF47A0145 +:101C2000B2E0EB1AF108EE0CFF1C2FB7F894812FED +:101C300090E0FC01EE0FFF1FE80FF91FE85DFE4F7B +:101C4000F282E1822FBF80E05FCF82E05DCF83E050 +:101C50005BCFDC01ED91FC910084F185E02DF12C4E +:101C6000E12C10E000E022E030E0452D0995B4CBF6 +:101C70001F920F920FB60F9211242F933F938F93C1 +:101C80009F93AF93BF9380915F0190916001A0916A +:101C90006101B091620130915E0123E0230F2D3785 +:101CA00058F50196A11DB11D20935E0180935F013F +:101CB00090936001A0936101B093620180916301F0 +:101CC00090916401A0916501B09166010196A11DFA +:101CD000B11D8093630190936401A0936501B0935B +:101CE0006601BF91AF919F918F913F912F910F907E +:101CF0000FBE0F901F90189526E8230F0296A11D86 +:101D0000B11DD2CF1F920F920FB60F9211242F93B5 +:101D10003F934F935F936F937F938F939F93AF9373 +:101D2000BF93EF93FF9387E691E00E942C02FF910F +:101D3000EF91BF91AF919F918F917F916F915F9143 +:101D40004F913F912F910F900FBE0F901F901895BC +:101D50001F920F920FB60F9211242F938F939F9380 +:101D6000EF93FF93E0917701F09178018081E0910A +:101D70007D01F0917E0182FD1BC0908180918001E8 +:101D80008F5F8F7320918101821741F0E091800174 +:101D9000F0E0E959FE4F958F80938001FF91EF911C +:101DA0009F918F912F910F900FBE0F901F901895BC +:101DB0008081F4CF1F920F920FB60F9211242F93B0 +:101DC0003F934F935F936F937F938F939F93AF93C3 +:101DD000BF93CF93DF93EF93FF9380914D01C09119 +:101DE0004C01D0E087FF24C010928500109284003F +:101DF00080914D018F5F80934D0180914D01082EA0 +:101E0000000C990B8C179D0724F480914D018C30A8 +:101E1000C4F18091840090918500049680349C499F +:101E200008F47AC08091840090918500049676C071 +:101E300080914D01082E000C990B8C179D07C4F65C +:101E4000E0914D018E2FEE0F990BFC01EE0FFF1F5D +:101E5000E80FF91FE85DFE4F808186FFC9CFE09152 +:101E60004D018E2FEE0F990BFC01EE0FFF1FE80FB7 +:101E7000F91FE85DFE4F808160E08F730E94DF00F4 +:101E8000B7CF2091840030918500E0914D018E2FD5 +:101E9000EE0F990BFC01EE0FFF1FE80FF91FE85D35 +:101EA000FE4F81819281820F931F909389008093CE +:101EB0008800E0914D018E2FEE0F990BFC01EE0F83 +:101EC000FF1FE80FF91FE85DFE4F808186FF11C0FC +:101ED000E0914D018E2FEE0F990BFC01EE0FFF1FCD +:101EE000E80FF91FE85DFE4F808161E08F730E946B +:101EF000DF00FF91EF91DF91CF91BF91AF919F9163 +:101F00008F917F916F915F914F913F912F910F90A2 +:101F10000FBE0F901F90189580E49CE99093890064 +:101F2000809388008FEF80934D01E3CFCF92DF92B3 +:101F3000FF920F931F93CF93DF93E7E6F1E01382B5 +:101F4000128288EE93E0A0E0B0E084839583A683BC +:101F5000B7838AE191E09183808385EC90E0958757 +:101F6000848784EC90E09787868780EC90E0918B63 +:101F7000808B81EC90E0938B828B82EC90E0958B50 +:101F8000848B86EC90E0978B868B118E128E138E4D +:101F9000148EC4E0D2E000E110E01F830E83CC2455 +:101FA000CA94DC2CD986C8861B870A87FF24F39441 +:101FB000FC861E861D861A8B098BDC8ACB8A1E8BBB +:101FC0000D8BFF8A1C8E1B8E1A8E198F088F80E155 +:101FD00090E00E94EC12988B8F8718A30F8FDAA2E3 +:101FE000C9A21CA30BA3FDA21BA61AA619A618A67C +:101FF0001FA30EA380E290E00E94EC129E8F8D8FB3 +:10200000198218821D830C831BAB0AABDDAACCAAF4 +:102010001FAB0EABF8AE19AE1DAF0CAFDFAECEAE40 +:102020001093450200934402F092460210924B0234 +:1020300010924A02109249021093480200934702FC +:1020400080E190E00E94EC129BAF8AAF10934F02A8 +:1020500000934E02D0925102C0925002109353024C +:1020600000935202F09254021092590210925802B8 +:1020700010925702109356020093550280E190E0AF +:102080000E94EC1290934D0280934C021DA61CA658 +:1020900019AB08AB1093610200936002D092630207 +:1020A000C09262021093650200936402F09266028D +:1020B000109268021092670210936C0200936B02F8 +:1020C000D0926E02C0926D021093700200936F0264 +:1020D000F0927102109276021092750210927402C0 +:1020E000109373020093720280E190E00E94EC1260 +:1020F00090936A028093690210937A0200937902A6 +:10210000D0927C02C0927B0210937E0200937D02EB +:10211000F0927F0210928502109284021092830244 +:1021200010928202109381020093800280E290E07C +:102130000E94EC12909378028093770210925B02D7 +:1021400010925A0210935F0200935E02109389026C +:1021500000938802D0928B02C0928A0210938D0263 +:1021600000938C02F0928E021092940210929302CD +:1021700010929202109291021093900200938F029B +:1021800080E190E00E944804909387028093860249 +:10219000DF91CF911F910F91FF90DF90CF90089525 +:1021A000CF93DF93CDB7DEB760970FB6F894DEBF5D +:1021B0000FBECDBF789484B5826084BD84B5816044 +:1021C00084BD85B5826085BD85B5816085BD809102 +:1021D0006E00816080936E0010928100809181007A +:1021E0008260809381008091810081608093810072 +:1021F000809180008160809380008091B100846034 +:102200008093B1008091B00081608093B000809194 +:102210007A00846080937A0080917A008260809353 +:102220007A0080917A00816080937A0080917A00B0 +:10223000806880937A001092C10088E091E00E944B +:10224000EC128C018AE091E0D80111969C938E9358 +:1022500087E691E013969C938E93129784E092E028 +:1022600015969C938E931497F801EB5FFE4F1082A6 +:10227000319610823196108280915401811115C0DF +:102280008CED92E090934F0180934E018DEA91E0A6 +:1022900090935101809350018BEB92E09093530106 +:1022A0008093520181E0809354018EE491E09A83FF +:1022B00089831C830B83CE0101960E948105CE0188 +:1022C00001960E94160410935D0100935C0161E089 +:1022D0008DE00E940D0161E08DE00E94DF000E9410 +:1022E000780160E08DE00E94DF000E94780161E0EB +:1022F0008DE00E94DF000E94780160E08DE00E9486 +:10230000DF0060E08DE00E940D01D8011296ED9192 +:10231000FC91A089B18982E08C93A485B5851C923B +:10232000A685B78580E18C93108EA489B58986E057 +:102330008C93A289B3898C9180618C93A289B38993 +:102340008C9188608C93A289B3898C9180688C93DE +:102350000288F389E02D80818F7D80830E9478013F +:1023600030E020E050E040E060EF70E0C8010E9403 +:10237000E60280E0A82E80E0B82E6EE372E0CE0187 +:1023800001960E946904F12CE12C8C859D85E8164C +:10239000F90608F04FC0B701CE0101960E9400086F +:1023A000FC011081612F84E092E00E945B08DC0157 +:1023B0008D919C910197D1F5812F0E94B600082F35 +:1023C000612F80E392E00E945A09FC018081081786 +:1023D00069F1612F80E392E00E945A09DC010C93BD +:1023E000D12CC12C8091910290919202C816D906ED +:1023F000E8F4B60186E892E00E94CF05188B21E050 +:10240000013009F020E02F87DC01ED91FC91048080 +:10241000F581E02DAE01415F5F4FBE01605F7F4FF0 +:1024200002960995BFEFCB1ADB0ADCCFEFEFEE1A6D +:10243000FE0AABCFCE0101960E94A30900915C0178 +:1024400010915D01D80112968D919C91DC01ED9166 +:10245000FC910084F185E02D0995892BA1F0F8010C +:1024600082819381DC01ED91FC910284F385E02D62 +:102470000995D801ED91FC910190F081E02D682F34 +:10248000C8010995DFCFA114B10409F476CF0E94E9 +:102490001802882309F471CF0E9400006ECF80914A +:1024A000860290918702009731F00E94B504109245 +:1024B00087021092860283E992E00E9416048091BE +:1024C000770290917802009711F00E94881389E6B4 +:1024D00092E00E94A3098CE492E00E94A3098EE39B +:1024E00092E00E94A309809121029091220200971C +:1024F00011F00E94881383E192E00C94A309052E49 +:1025000097FB1EF400940E94961257FD07D00E947C +:10251000A91207FC03D04EF40C94961250954095E6 +:10252000309521953F4F4F4F5F4F0895909580957F +:10253000709561957F4F8F4F9F4F08950E94CB12EA +:10254000A59F900DB49F900DA49F800D911D112407 +:102550000895A1E21A2EAA1BBB1BFD010DC0AA1FE4 +:10256000BB1FEE1FFF1FA217B307E407F50720F0FC +:10257000A21BB30BE40BF50B661F771F881F991F77 +:102580001A9469F760957095809590959B01AC01C0 +:10259000BD01CF010895A29FB001B39FC001A39FC9 +:1025A000700D811D1124911DB29F700D811D11248C +:1025B000911D0895991B79E004C0991F961708F0A2 +:1025C000961B881F7A95C9F780950895EE0FFF1F17 +:1025D0000590F491E02D09940F931F93CF93DF930F +:1025E0008230910510F482E090E0E0919F02F0913A +:1025F000A00230E020E0B0E0A0E0309799F421158F +:10260000310509F44AC0281B390B24303105D8F5AF +:102610008A819B816115710589F1FB019383828316 +:10262000FE0111C040815181028113814817590771 +:10263000E0F04817590799F4109761F012960C933F +:10264000129713961C933296CF01DF91CF911F9171 +:102650000F91089500939F021093A002F4CF2115CB +:10266000310551F04217530738F0A901DB019A01F7 +:10267000BD01DF01F801C1CFEF01F9CF9093A002B6 +:1026800080939F02CDCFFE01E20FF31F81939193C0 +:102690002250310939832883D7CF20919D02309170 +:1026A0009E02232B41F420910201309103013093CB +:1026B0009E0220939D02209100013091010121157D +:1026C000310541F42DB73EB7409104015091050109 +:1026D000241B350BE0919D02F0919E02E217F30757 +:1026E000A0F42E1B3F0B2817390778F0AC014E5F82 +:1026F0005F4F2417350748F04E0F5F1F50939E021F +:1027000040939D02819391939FCFF0E0E0E09CCFB6 +:10271000CF93DF930097E9F0FC0132971382128286 +:10272000A0919F02B091A002ED0130E020E010974F +:10273000A1F420813181820F931F20919D0230915D +:102740009E022817390709F061C0F0939E02E093BA +:102750009D02DF91CF910895EA01CE17DF07E8F5DA +:102760004A815B819E0141155105B1F7E901FB8367 +:10277000EA8349915991C40FD51FEC17FD0761F405 +:10278000808191810296840F951FE9019983888346 +:10279000828193819B838A83F0E0E0E012968D91A1 +:1027A0009C9113970097B9F52D913C911197CD010C +:1027B0000296820F931F20919D0230919E0228174E +:1027C000390739F6309751F51092A00210929F0206 +:1027D000B0939E02A0939D02BCCFD383C28340815D +:1027E0005181840F951FC817D90761F44E5F5F4F61 +:1027F00088819981480F591F518340838A819B8129 +:10280000938382832115310509F0B0CFF093A002A4 +:10281000E0939F029ECFFD01DC01C0CF13821282A4 +:10282000D7CF10E0C2E6D0E004C0FE010E94E6125D +:0C2830002196C336D107C9F7F894FFCFFA +:10283C000000A102800000000000C2039C03910371 +:10284C00AB093903E602000000004E02AE01DB01C9 +:08285C009B020C02EA01FE01DF :00000001FF diff --git a/owlet/firmware/arduino-nano/firmware.hex b/owlet/firmware/arduino-nano/firmware.hex index d64a90001..5c856436f 100644 --- a/owlet/firmware/arduino-nano/firmware.hex +++ b/owlet/firmware/arduino-nano/firmware.hex @@ -1,8 +1,8 @@ :100000000C9463000C948B000C948B000C948B006C :100010000C948B000C948B000C948B000C948B0034 -:100020000C948B000C948B000C948B000C94ED0EB4 +:100020000C948B000C948B000C948B000C94DA0EC7 :100030000C948B000C948B000C948B000C948B0014 -:100040000C944B0E0C948B000C94BB0E0C94950EE0 +:100040000C94380E0C948B000C94A80E0C94820E19 :100050000C948B000C948B000C948B000C948B00F4 :100060000C948B000C948B000000000024002700EF :100070002A0000000000250028002B0000000000DE @@ -10,12 +10,12 @@ :100090000202020203030303030301020408102007 :1000A0004080010204081020010204081020000012 :1000B0000008000201000003040700000000000027 -:1000C0000000A90F621211241FBECFEFD8E0DEBFDF -:1000D000CDBF11E0A0E0B1E0E2E6F8E202C0059099 +:1000C0000000960F4F1211241FBECFEFD8E0DEBF05 +:1000D000CDBF11E0A0E0B1E0ECE3F8E202C0059092 :1000E0000D92A832B107D9F722E0A8E2B1E001C031 :1000F0001D92A13AB207E1F710E0C2E6D0E004C0D9 -:100100002197FE010E94F912C136D107C9F70E945A -:10011000E3100C9424140C940000833081F028F434 +:100100002197FE010E94E612C136D107C9F70E946D +:10011000D0100C9411140C940000833081F028F45A :10012000813099F08230A9F008958730A9F08830A5 :10013000C9F08430B1F4809180008F7D03C080913C :1001400080008F7780938000089584B58F7784BD79 @@ -136,12 +136,12 @@ :10087000220F331F858D968D280F391FF901808136 :10088000918108952F5F3F4FE1CF8585968508952B :10089000CF93DF93EC01CD3C8CE0D807A0F42AE0A5 -:1008A0002C9FC0012D9F900D112402960E94FF12D3 +:1008A0002C9FC0012D9F900D112402960E94EC12E6 :1008B000FC01C193D193CF012197D7FD07C01182CD :1008C00010823A96F9CF8FEF9FEFF0CFDF91CF9163 :1008D0000895EF92FF920F931F93CF93DF93EC0154 :1008E0008B0180E190E09F838E8381E088871D8665 -:1008F000FB01E184F284C7010E94FF12998388837F +:1008F000FB01E184F284C7010E94EC129983888392 :10090000892B61F1F801828193819B838A838481A1 :1009100095819D838C83868197819F838E8380853B :100920008887FA86E986838594859C878B87858569 @@ -156,7 +156,7 @@ :1009B000969587954DEC5CE4849F9001859F300D62 :1009C000949F300D11243F7746EF4203C001439FAF :1009D000900D11240297800F911FDF91CF911F91ED -:1009E0000F91FF90EF900C949B13DF91CF911F918B +:1009E0000F91FF90EF900C948813DF91CF911F919E :1009F0000F91FF90EF9008952F923F924F925F9248 :100A00006F927F928F929F92AF92BF92CF92DF921E :100A1000EF92FF920F931F93CF93DF938C016B01A3 @@ -198,11 +198,11 @@ :100C5000EB01F8012085211105C08C179D0738F0A4 :100C600081E0EBCF7E018C179D0708F47C01209773 :100C700021F16E018FEF9FEFC115F0E4DF0718F44B -:100C8000C601880F991F0E94FF125C010097A1F214 +:100C8000C601880F991F0E94EC125C010097A1F227 :100C9000DC01F8018081918130E020E0E216F3066A :100CA00081F0F901EE0FFF1FE80FF91F408151811C :100CB0004D935D932F5F3F4FF1CF60E1C62ED12C56 -:100CC000DFCF009711F00E949B13F801B182A08240 +:100CC000DFCF009711F00E948813F801B182A08253 :100CD000D286C18683859485C817D90708F6D4873C :100CE000C387BECF0F931F93CF93DF93EC018B018C :100CF00069857A850617170738F08E819F81680FFE @@ -221,12 +221,12 @@ :100DC000BF90AF909F908F90089586012885211144 :100DD00027C080179107B8F60115110539F15801A0 :100DE000011580E4180730F5C501880F991F0E948E -:100DF000FF124C01009739F2DC018881998130E0C3 +:100DF000EC124C01009739F2DC018881998130E0D6 :100E000020E0C216D306C9F0F901EE0FFF1FE80F6C :100E1000F91F408151814D935D932F5F3F4FF1CF7B :100E20006C0108171907C0F66801D6CF60E1A62E3D :100E3000B12CDACF8FEF9FEFDACF009711F00E943D -:100E40009B1399828882BA86A9868B859C85081710 +:100E4000881399828882BA86A9868B859C85081723 :100E5000190708F098CF1C870B8795CFEE0CFF1C65 :100E6000888199818E0D9F1DA3CFAF92BF92CF92A3 :100E7000DF92EF92FF920F931F93CF93DF938C013A @@ -236,10 +236,10 @@ :100EB000BF90AF900895EB01F8012085211105C086 :100EC0008C179D0738F081E0EBCF7E018C179D07D2 :100ED00008F47C016E01209719F480E1C82ED12C12 -:100EE000C6010E94FF125C010097C9F2FC01D80103 +:100EE000C6010E94EC125C010097C9F2FC01D80116 :100EF0008D919C9130E020E0E216F30641F0DC0198 :100F0000A20FB31F4C9141932F5F3F4FF5CF009736 -:100F100011F00E949B13F801B182A082C186D28693 +:100F100011F00E948813F801B182A082C186D286A6 :100F200083859485C817D90770F6D487C387CBCF3C :100F3000CF93FC0183859485C0E06817790750F54D :100F40008385948501976817790778F4808191816A @@ -307,345 +307,342 @@ :101320000F90DF91CF911F910F91FF90EF90DF9081 :10133000CF900895F801208131812F5F3F4F318395 :101340002083BC01DACFFC0180819181009711F0EC -:101350000C949B1308952F923F925F926F927F920D +:101350000C94881308952F923F925F926F927F9220 :101360008F929F92AF92BF92CF92DF92EF92FF92B5 :101370000F931F93CF93DF93CDB7DEB729970FB6A7 :10138000F894DEBF0FBECDBF6C017B01DB016C9119 -:1013900011965C90673008F06FC4E62FF0E0ED52D4 -:1013A000F64F0C94F912DA09100AF10B5F0C9E0C3F -:1013B0003D0D790DDC01ED91FC910084F185E02D6E +:1013900011965C90673008F05CC4E62FF0E0ED52E7 +:1013A000F64F0C94E612DA09110ADE0B4C0C8B0C8A +:1013B0002A0D660DDC01ED91FC910084F185E02D94 :1013C000423011F1F12CE12C10E000E023E030E09C :1013D000452D60E0C601099529960FB6F894DEBF49 :1013E0000FBECDBFDF91CF911F910F91FF90EF9076 :1013F000DF90CF90BF90AF909F908F907F906F9035 -:101400005F903F902F90089519821A824B8333E0AA -:10141000E32EF12C8E010F5F1F4F30E020E0D8CF7C -:10142000EDB7FEB7F987E887443079F0DC01ED913C -:10143000FC910084F185E02DF12CE12C10E000E01E -:1014400023E030E0452D61E0C5CFF70112818381B3 -:10145000282E312CD6011496ED90FC90823009F4A0 -:10146000F7C078F4882309F437C1813009F4E0C06B -:10147000612FC7010E945B08DC012D923C9280E045 -:10148000BEC0843009F4F1C008F4E7C0853081F7AC -:101490005701F6E5AF0EB11C712C612CC7018059C4 -:1014A0009F4F9F838E8345019FE0890E911CAE81E3 -:1014B000BF818D919C916816790650F4B301C401E7 -:1014C0000E940008FC0180811813DCC077FEDEC09A -:1014D00083E090E00E94FF124C0180914C018C301F -:1014E00008F0F6C091E0980F90934C01D4018C93D2 -:1014F00090E0FC01EE0FFF1FE80FF91FE85DFE4FC3 -:1015000088EB9BE092838183612FC5010E941109C2 -:10151000DC018D929C92612FC5010E941109FC0192 -:1015200080809180D4018C918C3008F055C061E0AE -:10153000812F0E940D01F4018081282F30E0F901F4 -:10154000EE0FFF1FE20FF31FE85DFE4F9081907CCE -:10155000212F2F73922B9083D40111961C921197F7 -:1015600012961C922CE0622F0E94ED12829FB00115 -:10157000112430E020E0AB01420F531FFA01EE0FBF -:10158000FF1FE40FF51FE85DFE4F908196FD16C02A -:101590002F5F3F4F2C30310571F781110FC0109232 -:1015A000800082E080938100109285001092840078 -:1015B000B19A80916F00826080936F00D401EC91AA -:1015C0008E2F90E0FC01EE0FFF1FE80FF91FE85D82 -:1015D000FE4F808180648083F40180818F3F09F019 -:1015E00047CF612FC5010E941109DC018D919C91AB -:1015F0000E949B13612FC5010E94A40885E0898386 -:10160000D601ED91FC910084F185E02DEE24E39468 -:10161000F12C8E010F5F1F4F30E020E0452D61E07F -:10162000C60109950FB6F894DEBF0FBECDBFD4CE6C -:1016300060E0812F0E940D01812F0E94B600082FCB -:10164000612FC7018C960E945A09FC01008310CFBC -:1016500061E0812F0E940D010BCF60E0812F0E947D -:101660000D01812F0E943E0103CF61E0812F0E9476 -:101670000D0161E0812F0E940D0160E0812F0E9429 -:10168000DF00F6CEFFEF6F1A7F0A11CF612FC50181 -:101690000E941109DC01ED91FC91E0818E2F90E018 -:1016A000FC01EE0FFF1FE80FF91FE85DFE4F808180 -:1016B0008F7B8083612FC5010E941109FC0180810D -:1016C00091810E949B13612FC5010E94A40800CF45 -:1016D0008FEFF401808318CFB12CA12CF701E059D2 -:1016E000FF4FFF83EE834701F6E58F0E911C340117 -:1016F0002FE0620E711CAE81BF818D919C91A81666 -:10170000B90650F4B501C3010E940008FC018081B4 -:1017100018131EC0B7FE20C0B12CA12C3701F5E470 -:101720006F0E711C47012AE3820E911CD3018D912B -:101730009C91A816B90650F4B501C4010E94000896 -:10174000FC01808118132AC0B7FE2CC060E081CF55 -:10175000FFEFAF1ABF0ACFCF612FC4010E9411095A -:10176000DC01ED91FC91E0818E2F90E0FC01EE0F09 -:10177000FF1FE80FF91FE85DFE4F80818F7B80839C -:10178000612FC4010E941109FC01808191810E9496 -:101790009B13612FC4010E94A408BECFFFEFAF1AB4 -:1017A000BF0AC4CFB12CA12CD3018D919C91A81656 -:1017B000B90660F6B501C4010E940008FC018081F1 -:1017C00018130BC0B501C701885B9F4F0E94980793 -:1017D000B501C4010E949807B9CFFFEFAF1ABF0A45 -:1017E000E3CF443079F0DC01ED91FC910084F18588 -:1017F000E02DF12CE12C10E000E023E030E0452D5D -:1018000062E0E8CDF70112819380DC011496ED903F -:10181000FC90612FC7010E9430080196C9F1612F29 -:10182000C7010E945B08FC0180819181029709F049 -:1018300042C001E0911001C000E0602F812F0E94A2 -:10184000DF00912C812C3701FDE86F0E711C22E81E -:10185000E20EF11CD3018D919C918816990668F5D2 -:10186000B401C7010E94CF051C830983DC01ED91FF -:10187000FC910480F581E02DAE014F5F5F4FBE010A -:101880006C5F7F4F02960995BFEF8B1A9B0AE2CFE0 -:1018900081E08D83D601ED91FC910084F185E02DEE -:1018A000EE24E394F12C8E010B5F1F4F30E020E01B -:1018B000452D62E0B5CE83E0ECCF80E0EACF433047 -:1018C00079F0DC01ED91FC910084F185E02DF12CA3 -:1018D000E12C10E000E023E030E0452D63E07ACD1C -:1018E000F7011281612FDC0114968D919C910E9469 -:1018F00021040097F1F001970297F0F4812F0E94E4 -:10190000B60021E0892B09F420E080E089832A8356 -:10191000D601ED91FC910084F185E02D02E0E02EEE -:10192000F12C8E010F5F1F4F30E020E0452D63E06A -:1019300077CE81E020E0EACF82E0FCCF443079F03E -:10194000DC01ED91FC910084F185E02DF12CE12C7E -:1019500010E000E023E030E0452D64E03BCDF701EE -:101960001281DC0114968D909C90612FC4010E941D -:101970002104009799F481E08983D601ED91FC91CF -:101980000084F185E02DEE24E394F12C8E010F5FAD -:101990001F4F30E020E0452D64E042CE049711F067 -:1019A00083E0EACFF7010381612FC4010E94300870 -:1019B000019609F3612FC4010E945B08DC018D913F -:1019C0009C91049769F7E02EF12C61E0812F0E9431 -:1019D0000D01E114F10429F460E0812F0E94DF0081 -:1019E0002BC0BFEFEB16F10411F461E0F6CFE12F4D -:1019F000F0E0E255FF4FE491E33029F148F4E130A3 -:101A0000B9F0E230D9F0E0E8EE16F10474F7E4CF73 -:101A1000E73019F1E83049F1E430A9F7809180000E -:101A2000806280938000F0928B00E0928A0004C074 -:101A300084B5806884BD07BD80E09ECF84B5806298 -:101A400084BD08BDF9CF80918000806880938000BC -:101A5000F0928900E0928800EFCF8091B00080681A -:101A60008093B0000093B300E7CF8091B000806214 -:101A70008093B0000093B400DFCF433079F0DC01F5 -:101A8000ED91FC910084F185E02DF12CE12C10E02A -:101A900000E023E030E0452D65E09CCCF7011281A9 -:101AA000612FDC0114968D919C910E942104009776 -:101AB000E1F0039722E00297C8F4812F0E943E01D3 -:101AC00020E029839A838B83D601ED91FC910084D9 -:101AD000F185E02DB3E0EB2EF12C8E010F5F1F4F4F -:101AE00030E020E0452D65E09BCD21E080E090E0F6 -:101AF000E8CF443079F0DC01ED91FC910084F18570 -:101B0000E02DF12CE12C10E000E023E030E0452D49 -:101B100066E060CCF7011281DC0114968D909C90F8 -:101B2000612FC4010E942104009799F481E0898308 -:101B3000D601ED91FC910084F185E02DEE24E39433 -:101B4000F12C8E010F5F1F4F30E020E0452D66E045 -:101B500067CD059709F08CC0F701038184E0053B50 -:101B600030F7612FC4010E94300897FDDFCF612F4D -:101B7000C4010E945B08DC018D919C91059709F0DE -:101B800079C0B6E58B0E911C612FC4010E9411092A -:101B9000DC01ED91FC91E0818E2F90E0FC01EE0FD5 -:101BA000FF1FE80FF91FE85DFE4F808186FFBECF63 -:101BB000612FC4010E941109DC01ED91FC9110819B -:101BC0001C3008F053C0828148E5842E42E0942EF8 -:101BD000881A910887FD93941401220C331C220C5F -:101BE000331C818168E8E62EF12CE81AF10887FDA4 -:101BF000F394EE0CFF1CEE0CFF1C37010F2C000CB5 -:101C0000880899089101032C000C440B550B2619E8 -:101C1000370948095909A02FB0E00E94B11224EBFE -:101C200030E040E050E00E949212BA01A901460D56 -:101C3000571D681D791D4E155F052CF07101421569 -:101C400053050CF47A01B2E0EB1AF108EE0CFF1C1C -:101C50002FB7F894812F90E0FC01EE0FFF1FE80FE3 -:101C6000F91FE85DFE4FF282E1822FBF80E05FCF77 -:101C700082E05DCF83E05BCFDC01ED91FC910084DD -:101C8000F185E02DF12CE12C10E000E022E030E0C5 -:101C9000452D0995A1CB1F920F920FB60F921124DB -:101CA0002F933F938F939F93AF93BF9380915F0147 -:101CB00090916001A0916101B091620130915E014B -:101CC00023E0230F2D3758F50196A11DB11D209358 -:101CD0005E0180935F0190936001A0936101B093D6 -:101CE00062018091630190916401A0916501B091BE -:101CF00066010196A11DB11D80936301909364015B -:101D0000A0936501B0936601BF91AF919F918F91B0 -:101D10003F912F910F900FBE0F901F90189526E8BE -:101D2000230F0296A11DB11DD2CF1F920F920FB6A5 -:101D30000F9211242F933F934F935F936F937F9351 -:101D40008F939F93AF93BF93EF93FF9387E691E0B9 -:101D50000E942C02FF91EF91BF91AF919F918F91C3 -:101D60007F916F915F914F913F912F910F900FBE97 -:101D70000F901F9018951F920F920FB60F9211247B -:101D80002F938F939F93EF93FF93E0917701F091BF -:101D900078018081E0917D01F0917E0182FD1BC080 -:101DA0009081809180018F5F8F73209181018217D4 -:101DB00041F0E0918001F0E0E959FE4F958F80936A -:101DC0008001FF91EF919F918F912F910F900FBE06 -:101DD0000F901F9018958081F4CF1F920F920FB62D -:101DE0000F9211242F933F934F935F936F937F93A1 -:101DF0008F939F93AF93BF93CF93DF93EF93FF9313 -:101E000080914D01C0914C01D0E087FF24C0109219 -:101E100085001092840080914D018F5F80934D0169 -:101E200080914D01082E000C990B8C179D0724F40E -:101E300080914D018C30C4F1809184009091850097 -:101E4000049680349C4908F47AC080918400909173 -:101E50008500049676C080914D01082E000C990BE8 -:101E60008C179D07C4F6E0914D018E2FEE0F990B54 -:101E7000FC01EE0FFF1FE80FF91FE85DFE4F8081A8 -:101E800086FFC9CFE0914D018E2FEE0F990BFC011B -:101E9000EE0FFF1FE80FF91FE85DFE4F808160E045 -:101EA0008F730E94DF00B7CF2091840030918500AE -:101EB000E0914D018E2FEE0F990BFC01EE0FFF1FED -:101EC000E80FF91FE85DFE4F81819281820F931F19 -:101ED0009093890080938800E0914D018E2FEE0F42 -:101EE000990BFC01EE0FFF1FE80FF91FE85DFE4F95 -:101EF000808186FF11C0E0914D018E2FEE0F990B6E -:101F0000FC01EE0FFF1FE80FF91FE85DFE4F808117 -:101F100061E08F730E94DF00FF91EF91DF91CF911D -:101F2000BF91AF919F918F917F916F915F914F91F1 -:101F30003F912F910F900FBE0F901F90189580E446 -:101F40009CE990938900809388008FEF80934D01E6 -:101F5000E3CFCF92DF92FF920F931F93CF93DF9344 -:101F6000E7E6F1E01382128288EE93E0A0E0B0E0B1 -:101F700084839583A683B7838AE191E091838083EC -:101F800085EC90E09587848784EC90E0978786873E -:101F900080EC90E0918B808B81EC90E0938B828B36 -:101FA00082EC90E0958B848B86EC90E0978B868B0F -:101FB000118E128E138E148EC4E0D2E000E110E078 -:101FC0001F830E83CC24CA94DC2CD986C8861B8739 -:101FD0000A87FF24F394FC861E861D861A8B098BC4 -:101FE000DC8ACB8A1E8B0D8BFF8A1C8E1B8E1A8E71 -:101FF000198F088F80E190E00E94FF12988B8F87E5 -:1020000018A30F8FDAA2C9A21CA30BA3FDA21BA6C3 -:102010001AA619A618A61FA30EA380E290E00E949C -:10202000FF129E8F8D8F198218821D830C831BAB2C -:102030000AABDDAACCAA1FAB0EABF8AE19AE1DAF32 -:102040000CAFDFAECEAE1093450200934402F09287 -:10205000460210924B0210924A02109249021093CB -:1020600048020093470280E190E00E94FF129BAF7C -:102070008AAF10934F0200934E02D0925102C09249 -:1020800050021093530200935202F09254021092A5 -:102090005902109258021092570210935602009360 -:1020A000550280E190E00E94FF1290934D028093D0 -:1020B0004C021DA61CA619AB08AB1093610200933D -:1020C0006002D0926302C092620210936502009394 -:1020D0006402F092660210926802109267021093F6 -:1020E0006C0200936B02D0926E02C0926D0210934C -:1020F000700200936F02F0927102109276021092B9 -:10210000750210927402109373020093720280E1C0 -:1021100090E00E94FF1290936A02809369021093EC -:102120007A0200937902D0927C02C0927B021093D3 -:102130007E0200937D02F0927F021092850210923F -:102140008402109283021092820210938102009303 -:10215000800280E290E00E94FF12909378028093C8 -:10216000770210925B0210925A0210935F02009362 -:102170005E021093890200938802D0928B02C09273 -:102180008A0210938D0200938C02F0928E021092BC -:102190009402109293021092920210929102109364 -:1021A000900200938F0280E190E00E944804909397 -:1021B000870280938602DF91CF911F910F91FF904C -:1021C000DF90CF900895CF93DF93CDB7DEB76097C0 -:1021D0000FB6F894DEBF0FBECDBF789484B5826091 -:1021E00084BD84B5816084BD85B5826085BD85B5BB -:1021F000816085BD80916E00816080936E00109239 -:1022000081008091810082608093810080918100B3 -:102210008160809381008091800081608093800044 -:102220008091B10084608093B1008091B0008160A2 -:102230008093B00080917A00846080937A008091CE -:102240007A00826080937A0080917A008160809326 -:102250007A0080917A00806880937A001092C100A1 -:1022600088E091E00E94FF128C018AE091E0D801A1 -:1022700011969C938E9387E691E013969C938E9390 -:10228000129784E092E015969C938E931497F80130 -:10229000EB5FFE4F10823196108231961082809152 -:1022A0005401811115C08CED92E090934F01809301 -:1022B0004E018DEA91E090935101809350018BEB98 -:1022C00092E0909353018093520181E080935401F6 -:1022D0008EE491E09A8389831C830B83CE0101965F -:1022E0000E948105CE0101960E94160410935D01A3 -:1022F00000935C0161E08DE00E940D0161E08DE0E2 -:102300000E94DF000E94780160E08DE00E94DF0003 -:102310000E94780161E08DE00E94DF000E94780158 -:1023200060E08DE00E94DF0060E08DE00E940D0122 -:10233000D8011296ED91FC91A089B18982E08C932D -:10234000A485B5851C92A685B78580E18C93108EF7 -:10235000A489B58986E08C93A289B3898C91806128 -:102360008C93A289B3898C9188608C93A289B3895C -:102370008C9180688C930288F389E02D80818F7D19 -:1023800080830E94780130E020E050E040E060EF80 -:1023900070E0C8010E94E60280E0A82E80E0B82E1E -:1023A0006EE372E0CE0101960E946904F12CE12CEB -:1023B0008C859D85E816F90608F04FC0B701CE015F -:1023C00001960E940008FC011081612F84E092E0D8 -:1023D0000E945B08DC018D919C910197D1F5812FC2 -:1023E0000E94B600082F612F80E392E00E945A09F4 -:1023F000FC018081081769F1612F80E392E00E945F -:102400005A09DC010C93D12CC12C8091910290913E -:102410009202C816D906E8F4B60186E892E00E9456 -:10242000CF05188B21E0013009F020E02F87DC0177 -:10243000ED91FC910480F581E02DAE01415F5F4F8D -:10244000BE01605F7F4F02960995BFEFCB1ADB0A92 -:10245000DCCFEFEFEE1AFE0AABCFCE0101960E9461 -:10246000A30900915C0110915D01D80112968D9134 -:102470009C91DC01ED91FC910084F185E02D0995A2 -:10248000892BA1F0F80182819381DC01ED91FC910F -:102490000284F385E02D0995D801ED91FC9101901E -:1024A000F081E02D682FC8010995DFCFA114B10498 -:1024B00009F476CF0E941802882309F471CF0E9494 -:1024C00000006ECF8091860290918702009731F0D4 -:1024D0000E94B504109287021092860283E992E06E -:1024E0000E9416048091770290917802009711F073 -:1024F0000E949B1389E692E00E94A3098CE492E07B -:102500000E94A3098EE392E00E94A3098091210218 -:1025100090912202009711F00E949B1383E192E0B8 -:102520000C94A309052E97FB1EF400940E94A91297 -:1025300057FD07D00E94BC1207FC03D04EF40C9448 -:10254000A91250954095309521953F4F4F4F5F4FC1 -:10255000089590958095709561957F4F8F4F9F4F0F -:1025600008950E94DE12A59F900DB49F900DA49F28 -:10257000800D911D11240895A1E21A2EAA1BBB1BE8 -:10258000FD010DC0AA1FBB1FEE1FFF1FA217B3073F -:10259000E407F50720F0A21BB30BE40BF50B661F55 -:1025A000771F881F991F1A9469F760957095809519 -:1025B00090959B01AC01BD01CF010895A29FB00190 -:1025C000B39FC001A39F700D811D1124911DB29F67 -:1025D000700D811D1124911D0895991B79E004C08F -:1025E000991F961708F0961B881F7A95C9F7809552 -:1025F0000895EE0FFF1F0590F491E02D09940F93BD -:102600001F93CF93DF938230910510F482E090E026 -:10261000E0919F02F091A00230E020E0B0E0A0E065 -:10262000309799F42115310509F44AC0281B390B5C -:1026300024303105D8F58A819B816115710589F1B6 -:10264000FB0193838283FE0111C04081518102818D -:10265000138148175907E0F04817590799F4109764 -:1026600061F012960C93129713961C933296CF0139 -:10267000DF91CF911F910F91089500939F021093C6 -:10268000A002F4CF2115310551F04217530738F05D -:10269000A901DB019A01BD01DF01F801C1CFEF0102 -:1026A000F9CF9093A00280939F02CDCFFE01E20F5D -:1026B000F31F819391932250310939832883D7CF17 -:1026C00020919D0230919E02232B41F42091020122 -:1026D0003091030130939E0220939D0220910001CE -:1026E000309101012115310541F42DB73EB74091DC -:1026F000040150910501241B350BE0919D02F091DE -:102700009E02E217F307A0F42E1B3F0B2817390790 -:1027100078F0AC014E5F5F4F2417350748F04E0F3D -:102720005F1F50939E0240939D02819391939FCF90 -:10273000F0E0E0E09CCFCF93DF930097E9F0FC015D -:10274000329713821282A0919F02B091A002ED01F4 -:1027500030E020E01097A1F420813181820F931F97 -:1027600020919D0230919E022817390709F061C01F -:10277000F0939E02E0939D02DF91CF910895EA01CC -:10278000CE17DF07E8F54A815B819E0141155105AF -:10279000B1F7E901FB83EA8349915991C40FD51F31 -:1027A000EC17FD0761F4808191810296840F951FDB -:1027B000E90199838883828193819B838A83F0E0F6 -:1027C000E0E012968D919C9113970097B9F52D91A9 -:1027D0003C911197CD010296820F931F20919D028B -:1027E00030919E022817390739F6309751F510922B -:1027F000A00210929F02B0939E02A0939D02BCCFB4 -:10280000D383C28340815181840F951FC817D90794 -:1028100061F44E5F5F4F88819981480F591F518342 -:1028200040838A819B81938382832115310509F03E -:10283000B0CFF093A002E0939F029ECFFD01DC0198 -:10284000C0CF13821282D7CF10E0C2E6D0E004C01E -:10285000FE010E94F9122196C336D107C9F7F894F8 -:02286000FFCFA8 -:102862000000A102800000000000C2039C0391034B -:10287200AB093903E602000000004E02AE01DB01A3 -:082882009B020C02EA01FE01B9 +:101400005F903F902F90089519821A8283E08B831A +:1014100033E0E32EF12C8E010F5F1F4F30E020E010 +:10142000D7CFEDB7FEB7F987E887443079F0DC0114 +:10143000ED91FC910084F185E02DF12CE12C10E080 +:1014400000E023E030E0452D61E0C4CFF7011281D8 +:101450008381282E312CD6011496ED90FC90823099 +:1014600009F4E3C030F5882309F423C1813009F47D +:10147000CCC0612FC7010E945B08DC012D923C9219 +:101480001982D601ED91FC910084F185E02DEE24C6 +:10149000E394F12C8E010F5F1F4F30E020E0452DCB +:1014A00061E0C60109950FB6F894DEBF0FBECDBF4F +:1014B00093CF843009F4C6C008F4BCC08530C9F6A7 +:1014C0005701F6E5AF0EB11C712C612CC701805994 +:1014D0009F4F9F838E8345019FE0890E911CAE81B3 +:1014E000BF818D919C916816790650F4B301C401B7 +:1014F0000E940008FC0180811813B1C077FEB3C0C0 +:1015000083E090E00E94EC124C0180914C018C3001 +:1015100008F0CBC091E0980F90934C01D4018C93CC +:1015200090E0FC01EE0FFF1FE80FF91FE85DFE4F92 +:1015300088EB9BE092838183612FC5010E94110992 +:10154000DC018D929C92612FC5010E941109FC0162 +:10155000A080B180D5018C918C3008F08ACF61E0F9 +:10156000812F0E940D01F5018081282F30E0F901C3 +:10157000EE0FFF1FE20FF31FE85DFE4F9081907C9E +:10158000212F2F73922B9083D50111961C921197C6 +:1015900012961C922CE0622F0E94DA12829FB001F8 +:1015A000112430E020E0AB01420F531FFA01EE0F8F +:1015B000FF1FE40FF51FE85DFE4F908196FD16C0FA +:1015C0002F5F3F4F2C30310571F781110FC0109202 +:1015D000800082E080938100109285001092840048 +:1015E000B19A80916F00826080936F00D501EC9179 +:1015F0008E2F90E0FC01EE0FFF1FE80FF91FE85D52 +:10160000FE4F80818064808334CF60E0812F0E9410 +:101610000D01812F0E94B600082F612FC7018C9603 +:101620000E945A09FC01008324CF61E0812F0E94AF +:101630000D011FCF60E0812F0E940D01812F0E94BC +:101640003E0117CF61E0812F0E940D0161E0812FE3 +:101650000E940D0160E0812F0E94DF000ACFFFEFA2 +:101660006F1A7F0A3CCF612FC5010E941109DC016E +:10167000ED91FC91E0818E2F90E0FC01EE0FFF1FB9 +:10168000E80FF91FE85DFE4F80818F7B8083612F1B +:10169000C5010E941109FC01808191810E9488137B +:1016A000612FC5010E94A4082BCF8FEFF401808326 +:1016B00043CFB12CA12CF701E059FF4FFF83EE83FC +:1016C0004701F6E58F0E911C34012FE0620E711C6C +:1016D000AE81BF818D919C91A816B90650F4B501D9 +:1016E000C3010E940008FC01808118131EC0B7FED0 +:1016F00020C0B12CA12C3701F5E46F0E711C4701FD +:101700002AE3820E911CD3018D919C91A816B906F3 +:1017100050F4B501C4010E940008FC018081181337 +:101720002AC0B7FE2CC060E081CFFFEFAF1ABF0A1E +:10173000CFCF612FC4010E941109DC01ED91FC9112 +:10174000E0818E2F90E0FC01EE0FFF1FE80FF91FE4 +:10175000E85DFE4F80818F7B8083612FC4010E94F2 +:101760001109FC01808191810E948813612FC401BD +:101770000E94A408BECFFFEFAF1ABF0AC4CFB12C9E +:10178000A12CD3018D919C91A816B90660F6B501E4 +:10179000C4010E940008FC01808118130BC0B50130 +:1017A000C701885B9F4F0E949807B501C4010E9442 +:1017B0009807B9CFFFEFAF1ABF0AE3CF443079F0F3 +:1017C000DC01ED91FC910084F185E02DF12CE12C00 +:1017D00010E000E023E030E0452D62E0FBCDF701B2 +:1017E00012819380DC011496ED90FC90612FC7016B +:1017F0000E9430080196C9F1612FC7010E945B0861 +:10180000FC0180819181029709F042C001E09110B2 +:1018100001C000E0602F812F0E94DF00912C812CFD +:101820003701FDE86F0E711C22E8E20EF11CD301B6 +:101830008D919C918816990668F5B401C7010E94A4 +:10184000CF051C830983DC01ED91FC910480F581B7 +:10185000E02DAE014F5F5F4FBE016C5F7F4F029680 +:101860000995BFEF8B1A9B0AE2CF81E08D83D601E9 +:10187000ED91FC910084F185E02DEE24E394F12CB0 +:101880008E010B5F1F4F30E020E0452D62E009CE56 +:1018900083E0ECCF80E0EACF433079F0DC01ED91DA +:1018A000FC910084F185E02DF12CE12C10E000E0AA +:1018B00023E030E0452D63E08DCDF7011281612FEB +:1018C000DC0114968D919C910E9421040097F1F007 +:1018D00001970297F0F4812F0E94B60021E0892B36 +:1018E00009F420E080E089832A83D601ED91FC9100 +:1018F0000084F185E02D02E0E02EF12C8E010F5FD7 +:101900001F4F30E020E0452D63E0CBCD81E020E0AB +:10191000EACF82E0FCCF443079F0DC01ED91FC911C +:101920000084F185E02DF12CE12C10E000E023E0B3 +:1019300030E0452D64E04ECDF7011281DC011496B4 +:101940008D909C90612FC4010E942104009799F40E +:1019500081E08983D601ED91FC910084F185E02D31 +:10196000EE24E394F12C8E010F5F1F4F30E020E056 +:10197000452D64E096CD049711F083E0EACFF7019E +:101980000381612FC4010E943008019609F3612F81 +:10199000C4010E945B08DC018D919C91049769F75A +:1019A000E02EF12C61E0812F0E940D01E114F10481 +:1019B00029F460E0812F0E94DF002BC0BFEFEB16FF +:1019C000F10411F461E0F6CFE12FF0E0E255FF4FB2 +:1019D000E491E33029F148F4E130B9F0E230D9F094 +:1019E000E0E8EE16F10474F7E4CFE73019F1E830DF +:1019F00049F1E430A9F780918000806280938000F3 +:101A0000F0928B00E0928A0004C084B5806884BDA7 +:101A100007BD80E09ECF84B5806284BD08BDF9CF4C +:101A200080918000806880938000F0928900E0922D +:101A30008800EFCF8091B00080688093B000009361 +:101A4000B300E7CF8091B00080628093B000009334 +:101A5000B400DFCF433079F0DC01ED91FC910084DC +:101A6000F185E02DF12CE12C10E000E023E030E0E6 +:101A7000452D65E0AFCCF7011281612FDC01149692 +:101A80008D919C910E9421040097E1F0039722E040 +:101A90000297C8F4812F0E943E0120E029839A8397 +:101AA0008B83D601ED91FC910084F185E02DB3E0AC +:101AB000EB2EF12C8E010F5F1F4F30E020E0452D03 +:101AC00065E0EFCC21E080E090E0E8CF443079F0B1 +:101AD000DC01ED91FC910084F185E02DF12CE12CED +:101AE00010E000E023E030E0452D66E073CCF70124 +:101AF0001281DC0114968D909C90612FC4010E948C +:101B00002104009799F481E08983D601ED91FC913D +:101B10000084F185E02DEE24E394F12C8E010F5F1B +:101B20001F4F30E020E0452D66E0BBCC059709F063 +:101B30008CC0F701038184E0053B30F7612FC401BD +:101B40000E94300897FDDFCF612FC4010E945B081F +:101B5000DC018D919C91059709F079C0B6E58B0E5B +:101B6000911C612FC4010E941109DC01ED91FC91CF +:101B7000E0818E2F90E0FC01EE0FFF1FE80FF91FB0 +:101B8000E85DFE4F808186FFBECF612FC4010E94B9 +:101B90001109DC01ED91FC9110811C3008F053C05B +:101BA000828148E5842E42E0942E881A910887FDB0 +:101BB00093941401220C331C220C331C818168E89D +:101BC000E62EF12CE81AF10887FDF394EE0CFF1CC9 +:101BD000EE0CFF1C37010F2C000C880899089101AE +:101BE000032C000C440B550B2619370948095909D9 +:101BF000A02FB0E00E949E1224EB30E040E050E0C5 +:101C00000E947F12BA01A901460D571D681D791D5A +:101C10004E155F052CF07101421553050CF47A0145 +:101C2000B2E0EB1AF108EE0CFF1C2FB7F894812FED +:101C300090E0FC01EE0FFF1FE80FF91FE85DFE4F7B +:101C4000F282E1822FBF80E05FCF82E05DCF83E050 +:101C50005BCFDC01ED91FC910084F185E02DF12C4E +:101C6000E12C10E000E022E030E0452D0995B4CBF6 +:101C70001F920F920FB60F9211242F933F938F93C1 +:101C80009F93AF93BF9380915F0190916001A0916A +:101C90006101B091620130915E0123E0230F2D3785 +:101CA00058F50196A11DB11D20935E0180935F013F +:101CB00090936001A0936101B093620180916301F0 +:101CC00090916401A0916501B09166010196A11DFA +:101CD000B11D8093630190936401A0936501B0935B +:101CE0006601BF91AF919F918F913F912F910F907E +:101CF0000FBE0F901F90189526E8230F0296A11D86 +:101D0000B11DD2CF1F920F920FB60F9211242F93B5 +:101D10003F934F935F936F937F938F939F93AF9373 +:101D2000BF93EF93FF9387E691E00E942C02FF910F +:101D3000EF91BF91AF919F918F917F916F915F9143 +:101D40004F913F912F910F900FBE0F901F901895BC +:101D50001F920F920FB60F9211242F938F939F9380 +:101D6000EF93FF93E0917701F09178018081E0910A +:101D70007D01F0917E0182FD1BC0908180918001E8 +:101D80008F5F8F7320918101821741F0E091800174 +:101D9000F0E0E959FE4F958F80938001FF91EF911C +:101DA0009F918F912F910F900FBE0F901F901895BC +:101DB0008081F4CF1F920F920FB60F9211242F93B0 +:101DC0003F934F935F936F937F938F939F93AF93C3 +:101DD000BF93CF93DF93EF93FF9380914D01C09119 +:101DE0004C01D0E087FF24C010928500109284003F +:101DF00080914D018F5F80934D0180914D01082EA0 +:101E0000000C990B8C179D0724F480914D018C30A8 +:101E1000C4F18091840090918500049680349C499F +:101E200008F47AC08091840090918500049676C071 +:101E300080914D01082E000C990B8C179D07C4F65C +:101E4000E0914D018E2FEE0F990BFC01EE0FFF1F5D +:101E5000E80FF91FE85DFE4F808186FFC9CFE09152 +:101E60004D018E2FEE0F990BFC01EE0FFF1FE80FB7 +:101E7000F91FE85DFE4F808160E08F730E94DF00F4 +:101E8000B7CF2091840030918500E0914D018E2FD5 +:101E9000EE0F990BFC01EE0FFF1FE80FF91FE85D35 +:101EA000FE4F81819281820F931F909389008093CE +:101EB0008800E0914D018E2FEE0F990BFC01EE0F83 +:101EC000FF1FE80FF91FE85DFE4F808186FF11C0FC +:101ED000E0914D018E2FEE0F990BFC01EE0FFF1FCD +:101EE000E80FF91FE85DFE4F808161E08F730E946B +:101EF000DF00FF91EF91DF91CF91BF91AF919F9163 +:101F00008F917F916F915F914F913F912F910F90A2 +:101F10000FBE0F901F90189580E49CE99093890064 +:101F2000809388008FEF80934D01E3CFCF92DF92B3 +:101F3000FF920F931F93CF93DF93E7E6F1E01382B5 +:101F4000128288EE93E0A0E0B0E084839583A683BC +:101F5000B7838AE191E09183808385EC90E0958757 +:101F6000848784EC90E09787868780EC90E0918B63 +:101F7000808B81EC90E0938B828B82EC90E0958B50 +:101F8000848B86EC90E0978B868B118E128E138E4D +:101F9000148EC4E0D2E000E110E01F830E83CC2455 +:101FA000CA94DC2CD986C8861B870A87FF24F39441 +:101FB000FC861E861D861A8B098BDC8ACB8A1E8BBB +:101FC0000D8BFF8A1C8E1B8E1A8E198F088F80E155 +:101FD00090E00E94EC12988B8F8718A30F8FDAA2E3 +:101FE000C9A21CA30BA3FDA21BA61AA619A618A67C +:101FF0001FA30EA380E290E00E94EC129E8F8D8FB3 +:10200000198218821D830C831BAB0AABDDAACCAAF4 +:102010001FAB0EABF8AE19AE1DAF0CAFDFAECEAE40 +:102020001093450200934402F092460210924B0234 +:1020300010924A02109249021093480200934702FC +:1020400080E190E00E94EC129BAF8AAF10934F02A8 +:1020500000934E02D0925102C0925002109353024C +:1020600000935202F09254021092590210925802B8 +:1020700010925702109356020093550280E190E0AF +:102080000E94EC1290934D0280934C021DA61CA658 +:1020900019AB08AB1093610200936002D092630207 +:1020A000C09262021093650200936402F09266028D +:1020B000109268021092670210936C0200936B02F8 +:1020C000D0926E02C0926D021093700200936F0264 +:1020D000F0927102109276021092750210927402C0 +:1020E000109373020093720280E190E00E94EC1260 +:1020F00090936A028093690210937A0200937902A6 +:10210000D0927C02C0927B0210937E0200937D02EB +:10211000F0927F0210928502109284021092830244 +:1021200010928202109381020093800280E290E07C +:102130000E94EC12909378028093770210925B02D7 +:1021400010925A0210935F0200935E02109389026C +:1021500000938802D0928B02C0928A0210938D0263 +:1021600000938C02F0928E021092940210929302CD +:1021700010929202109291021093900200938F029B +:1021800080E190E00E944804909387028093860249 +:10219000DF91CF911F910F91FF90DF90CF90089525 +:1021A000CF93DF93CDB7DEB760970FB6F894DEBF5D +:1021B0000FBECDBF789484B5826084BD84B5816044 +:1021C00084BD85B5826085BD85B5816085BD809102 +:1021D0006E00816080936E0010928100809181007A +:1021E0008260809381008091810081608093810072 +:1021F000809180008160809380008091B100846034 +:102200008093B1008091B00081608093B000809194 +:102210007A00846080937A0080917A008260809353 +:102220007A0080917A00816080937A0080917A00B0 +:10223000806880937A001092C10088E091E00E944B +:10224000EC128C018AE091E0D80111969C938E9358 +:1022500087E691E013969C938E93129784E092E028 +:1022600015969C938E931497F801EB5FFE4F1082A6 +:10227000319610823196108280915401811115C0DF +:102280008CED92E090934F0180934E018DEA91E0A6 +:1022900090935101809350018BEB92E09093530106 +:1022A0008093520181E0809354018EE491E09A83FF +:1022B00089831C830B83CE0101960E948105CE0188 +:1022C00001960E94160410935D0100935C0161E089 +:1022D0008DE00E940D0161E08DE00E94DF000E9410 +:1022E000780160E08DE00E94DF000E94780161E0EB +:1022F0008DE00E94DF000E94780160E08DE00E9486 +:10230000DF0060E08DE00E940D01D8011296ED9192 +:10231000FC91A089B18982E08C93A485B5851C923B +:10232000A685B78580E18C93108EA489B58986E057 +:102330008C93A289B3898C9180618C93A289B38993 +:102340008C9188608C93A289B3898C9180688C93DE +:102350000288F389E02D80818F7D80830E9478013F +:1023600030E020E050E040E060EF70E0C8010E9403 +:10237000E60280E0A82E80E0B82E6EE372E0CE0187 +:1023800001960E946904F12CE12C8C859D85E8164C +:10239000F90608F04FC0B701CE0101960E9400086F +:1023A000FC011081612F84E092E00E945B08DC0157 +:1023B0008D919C910197D1F5812F0E94B600082F35 +:1023C000612F80E392E00E945A09FC018081081786 +:1023D00069F1612F80E392E00E945A09DC010C93BD +:1023E000D12CC12C8091910290919202C816D906ED +:1023F000E8F4B60186E892E00E94CF05188B21E050 +:10240000013009F020E02F87DC01ED91FC91048080 +:10241000F581E02DAE01415F5F4FBE01605F7F4FF0 +:1024200002960995BFEFCB1ADB0ADCCFEFEFEE1A6D +:10243000FE0AABCFCE0101960E94A30900915C0178 +:1024400010915D01D80112968D919C91DC01ED9166 +:10245000FC910084F185E02D0995892BA1F0F8010C +:1024600082819381DC01ED91FC910284F385E02D62 +:102470000995D801ED91FC910190F081E02D682F34 +:10248000C8010995DFCFA114B10409F476CF0E94E9 +:102490001802882309F471CF0E9400006ECF80914A +:1024A000860290918702009731F00E94B504109245 +:1024B00087021092860283E992E00E9416048091BE +:1024C000770290917802009711F00E94881389E6B4 +:1024D00092E00E94A3098CE492E00E94A3098EE39B +:1024E00092E00E94A309809121029091220200971C +:1024F00011F00E94881383E192E00C94A309052E49 +:1025000097FB1EF400940E94961257FD07D00E947C +:10251000A91207FC03D04EF40C94961250954095E6 +:10252000309521953F4F4F4F5F4F0895909580957F +:10253000709561957F4F8F4F9F4F08950E94CB12EA +:10254000A59F900DB49F900DA49F800D911D112407 +:102550000895A1E21A2EAA1BBB1BFD010DC0AA1FE4 +:10256000BB1FEE1FFF1FA217B307E407F50720F0FC +:10257000A21BB30BE40BF50B661F771F881F991F77 +:102580001A9469F760957095809590959B01AC01C0 +:10259000BD01CF010895A29FB001B39FC001A39FC9 +:1025A000700D811D1124911DB29F700D811D11248C +:1025B000911D0895991B79E004C0991F961708F0A2 +:1025C000961B881F7A95C9F780950895EE0FFF1F17 +:1025D0000590F491E02D09940F931F93CF93DF930F +:1025E0008230910510F482E090E0E0919F02F0913A +:1025F000A00230E020E0B0E0A0E0309799F421158F +:10260000310509F44AC0281B390B24303105D8F5AF +:102610008A819B816115710589F1FB019383828316 +:10262000FE0111C040815181028113814817590771 +:10263000E0F04817590799F4109761F012960C933F +:10264000129713961C933296CF01DF91CF911F9171 +:102650000F91089500939F021093A002F4CF2115CB +:10266000310551F04217530738F0A901DB019A01F7 +:10267000BD01DF01F801C1CFEF01F9CF9093A002B6 +:1026800080939F02CDCFFE01E20FF31F81939193C0 +:102690002250310939832883D7CF20919D02309170 +:1026A0009E02232B41F420910201309103013093CB +:1026B0009E0220939D02209100013091010121157D +:1026C000310541F42DB73EB7409104015091050109 +:1026D000241B350BE0919D02F0919E02E217F30757 +:1026E000A0F42E1B3F0B2817390778F0AC014E5F82 +:1026F0005F4F2417350748F04E0F5F1F50939E021F +:1027000040939D02819391939FCFF0E0E0E09CCFB6 +:10271000CF93DF930097E9F0FC0132971382128286 +:10272000A0919F02B091A002ED0130E020E010974F +:10273000A1F420813181820F931F20919D0230915D +:102740009E022817390709F061C0F0939E02E093BA +:102750009D02DF91CF910895EA01CE17DF07E8F5DA +:102760004A815B819E0141155105B1F7E901FB8367 +:10277000EA8349915991C40FD51FEC17FD0761F405 +:10278000808191810296840F951FE9019983888346 +:10279000828193819B838A83F0E0E0E012968D91A1 +:1027A0009C9113970097B9F52D913C911197CD010C +:1027B0000296820F931F20919D0230919E0228174E +:1027C000390739F6309751F51092A00210929F0206 +:1027D000B0939E02A0939D02BCCFD383C28340815D +:1027E0005181840F951FC817D90761F44E5F5F4F61 +:1027F00088819981480F591F518340838A819B8129 +:10280000938382832115310509F0B0CFF093A002A4 +:10281000E0939F029ECFFD01DC01C0CF13821282A4 +:10282000D7CF10E0C2E6D0E004C0FE010E94E6125D +:0C2830002196C336D107C9F7F894FFCFFA +:10283C000000A102800000000000C2039C03910371 +:10284C00AB093903E602000000004E02AE01DB01C9 +:08285C009B020C02EA01FE01DF :00000001FF diff --git a/owlet/firmware/arduino-uno/firmware.hex b/owlet/firmware/arduino-uno/firmware.hex index d64a90001..5c856436f 100644 --- a/owlet/firmware/arduino-uno/firmware.hex +++ b/owlet/firmware/arduino-uno/firmware.hex @@ -1,8 +1,8 @@ :100000000C9463000C948B000C948B000C948B006C :100010000C948B000C948B000C948B000C948B0034 -:100020000C948B000C948B000C948B000C94ED0EB4 +:100020000C948B000C948B000C948B000C94DA0EC7 :100030000C948B000C948B000C948B000C948B0014 -:100040000C944B0E0C948B000C94BB0E0C94950EE0 +:100040000C94380E0C948B000C94A80E0C94820E19 :100050000C948B000C948B000C948B000C948B00F4 :100060000C948B000C948B000000000024002700EF :100070002A0000000000250028002B0000000000DE @@ -10,12 +10,12 @@ :100090000202020203030303030301020408102007 :1000A0004080010204081020010204081020000012 :1000B0000008000201000003040700000000000027 -:1000C0000000A90F621211241FBECFEFD8E0DEBFDF -:1000D000CDBF11E0A0E0B1E0E2E6F8E202C0059099 +:1000C0000000960F4F1211241FBECFEFD8E0DEBF05 +:1000D000CDBF11E0A0E0B1E0ECE3F8E202C0059092 :1000E0000D92A832B107D9F722E0A8E2B1E001C031 :1000F0001D92A13AB207E1F710E0C2E6D0E004C0D9 -:100100002197FE010E94F912C136D107C9F70E945A -:10011000E3100C9424140C940000833081F028F434 +:100100002197FE010E94E612C136D107C9F70E946D +:10011000D0100C9411140C940000833081F028F45A :10012000813099F08230A9F008958730A9F08830A5 :10013000C9F08430B1F4809180008F7D03C080913C :1001400080008F7780938000089584B58F7784BD79 @@ -136,12 +136,12 @@ :10087000220F331F858D968D280F391FF901808136 :10088000918108952F5F3F4FE1CF8585968508952B :10089000CF93DF93EC01CD3C8CE0D807A0F42AE0A5 -:1008A0002C9FC0012D9F900D112402960E94FF12D3 +:1008A0002C9FC0012D9F900D112402960E94EC12E6 :1008B000FC01C193D193CF012197D7FD07C01182CD :1008C00010823A96F9CF8FEF9FEFF0CFDF91CF9163 :1008D0000895EF92FF920F931F93CF93DF93EC0154 :1008E0008B0180E190E09F838E8381E088871D8665 -:1008F000FB01E184F284C7010E94FF12998388837F +:1008F000FB01E184F284C7010E94EC129983888392 :10090000892B61F1F801828193819B838A838481A1 :1009100095819D838C83868197819F838E8380853B :100920008887FA86E986838594859C878B87858569 @@ -156,7 +156,7 @@ :1009B000969587954DEC5CE4849F9001859F300D62 :1009C000949F300D11243F7746EF4203C001439FAF :1009D000900D11240297800F911FDF91CF911F91ED -:1009E0000F91FF90EF900C949B13DF91CF911F918B +:1009E0000F91FF90EF900C948813DF91CF911F919E :1009F0000F91FF90EF9008952F923F924F925F9248 :100A00006F927F928F929F92AF92BF92CF92DF921E :100A1000EF92FF920F931F93CF93DF938C016B01A3 @@ -198,11 +198,11 @@ :100C5000EB01F8012085211105C08C179D0738F0A4 :100C600081E0EBCF7E018C179D0708F47C01209773 :100C700021F16E018FEF9FEFC115F0E4DF0718F44B -:100C8000C601880F991F0E94FF125C010097A1F214 +:100C8000C601880F991F0E94EC125C010097A1F227 :100C9000DC01F8018081918130E020E0E216F3066A :100CA00081F0F901EE0FFF1FE80FF91F408151811C :100CB0004D935D932F5F3F4FF1CF60E1C62ED12C56 -:100CC000DFCF009711F00E949B13F801B182A08240 +:100CC000DFCF009711F00E948813F801B182A08253 :100CD000D286C18683859485C817D90708F6D4873C :100CE000C387BECF0F931F93CF93DF93EC018B018C :100CF00069857A850617170738F08E819F81680FFE @@ -221,12 +221,12 @@ :100DC000BF90AF909F908F90089586012885211144 :100DD00027C080179107B8F60115110539F15801A0 :100DE000011580E4180730F5C501880F991F0E948E -:100DF000FF124C01009739F2DC018881998130E0C3 +:100DF000EC124C01009739F2DC018881998130E0D6 :100E000020E0C216D306C9F0F901EE0FFF1FE80F6C :100E1000F91F408151814D935D932F5F3F4FF1CF7B :100E20006C0108171907C0F66801D6CF60E1A62E3D :100E3000B12CDACF8FEF9FEFDACF009711F00E943D -:100E40009B1399828882BA86A9868B859C85081710 +:100E4000881399828882BA86A9868B859C85081723 :100E5000190708F098CF1C870B8795CFEE0CFF1C65 :100E6000888199818E0D9F1DA3CFAF92BF92CF92A3 :100E7000DF92EF92FF920F931F93CF93DF938C013A @@ -236,10 +236,10 @@ :100EB000BF90AF900895EB01F8012085211105C086 :100EC0008C179D0738F081E0EBCF7E018C179D07D2 :100ED00008F47C016E01209719F480E1C82ED12C12 -:100EE000C6010E94FF125C010097C9F2FC01D80103 +:100EE000C6010E94EC125C010097C9F2FC01D80116 :100EF0008D919C9130E020E0E216F30641F0DC0198 :100F0000A20FB31F4C9141932F5F3F4FF5CF009736 -:100F100011F00E949B13F801B182A082C186D28693 +:100F100011F00E948813F801B182A082C186D286A6 :100F200083859485C817D90770F6D487C387CBCF3C :100F3000CF93FC0183859485C0E06817790750F54D :100F40008385948501976817790778F4808191816A @@ -307,345 +307,342 @@ :101320000F90DF91CF911F910F91FF90EF90DF9081 :10133000CF900895F801208131812F5F3F4F318395 :101340002083BC01DACFFC0180819181009711F0EC -:101350000C949B1308952F923F925F926F927F920D +:101350000C94881308952F923F925F926F927F9220 :101360008F929F92AF92BF92CF92DF92EF92FF92B5 :101370000F931F93CF93DF93CDB7DEB729970FB6A7 :10138000F894DEBF0FBECDBF6C017B01DB016C9119 -:1013900011965C90673008F06FC4E62FF0E0ED52D4 -:1013A000F64F0C94F912DA09100AF10B5F0C9E0C3F -:1013B0003D0D790DDC01ED91FC910084F185E02D6E +:1013900011965C90673008F05CC4E62FF0E0ED52E7 +:1013A000F64F0C94E612DA09110ADE0B4C0C8B0C8A +:1013B0002A0D660DDC01ED91FC910084F185E02D94 :1013C000423011F1F12CE12C10E000E023E030E09C :1013D000452D60E0C601099529960FB6F894DEBF49 :1013E0000FBECDBFDF91CF911F910F91FF90EF9076 :1013F000DF90CF90BF90AF909F908F907F906F9035 -:101400005F903F902F90089519821A824B8333E0AA -:10141000E32EF12C8E010F5F1F4F30E020E0D8CF7C -:10142000EDB7FEB7F987E887443079F0DC01ED913C -:10143000FC910084F185E02DF12CE12C10E000E01E -:1014400023E030E0452D61E0C5CFF70112818381B3 -:10145000282E312CD6011496ED90FC90823009F4A0 -:10146000F7C078F4882309F437C1813009F4E0C06B -:10147000612FC7010E945B08DC012D923C9280E045 -:10148000BEC0843009F4F1C008F4E7C0853081F7AC -:101490005701F6E5AF0EB11C712C612CC7018059C4 -:1014A0009F4F9F838E8345019FE0890E911CAE81E3 -:1014B000BF818D919C916816790650F4B301C401E7 -:1014C0000E940008FC0180811813DCC077FEDEC09A -:1014D00083E090E00E94FF124C0180914C018C301F -:1014E00008F0F6C091E0980F90934C01D4018C93D2 -:1014F00090E0FC01EE0FFF1FE80FF91FE85DFE4FC3 -:1015000088EB9BE092838183612FC5010E941109C2 -:10151000DC018D929C92612FC5010E941109FC0192 -:1015200080809180D4018C918C3008F055C061E0AE -:10153000812F0E940D01F4018081282F30E0F901F4 -:10154000EE0FFF1FE20FF31FE85DFE4F9081907CCE -:10155000212F2F73922B9083D40111961C921197F7 -:1015600012961C922CE0622F0E94ED12829FB00115 -:10157000112430E020E0AB01420F531FFA01EE0FBF -:10158000FF1FE40FF51FE85DFE4F908196FD16C02A -:101590002F5F3F4F2C30310571F781110FC0109232 -:1015A000800082E080938100109285001092840078 -:1015B000B19A80916F00826080936F00D401EC91AA -:1015C0008E2F90E0FC01EE0FFF1FE80FF91FE85D82 -:1015D000FE4F808180648083F40180818F3F09F019 -:1015E00047CF612FC5010E941109DC018D919C91AB -:1015F0000E949B13612FC5010E94A40885E0898386 -:10160000D601ED91FC910084F185E02DEE24E39468 -:10161000F12C8E010F5F1F4F30E020E0452D61E07F -:10162000C60109950FB6F894DEBF0FBECDBFD4CE6C -:1016300060E0812F0E940D01812F0E94B600082FCB -:10164000612FC7018C960E945A09FC01008310CFBC -:1016500061E0812F0E940D010BCF60E0812F0E947D -:101660000D01812F0E943E0103CF61E0812F0E9476 -:101670000D0161E0812F0E940D0160E0812F0E9429 -:10168000DF00F6CEFFEF6F1A7F0A11CF612FC50181 -:101690000E941109DC01ED91FC91E0818E2F90E018 -:1016A000FC01EE0FFF1FE80FF91FE85DFE4F808180 -:1016B0008F7B8083612FC5010E941109FC0180810D -:1016C00091810E949B13612FC5010E94A40800CF45 -:1016D0008FEFF401808318CFB12CA12CF701E059D2 -:1016E000FF4FFF83EE834701F6E58F0E911C340117 -:1016F0002FE0620E711CAE81BF818D919C91A81666 -:10170000B90650F4B501C3010E940008FC018081B4 -:1017100018131EC0B7FE20C0B12CA12C3701F5E470 -:101720006F0E711C47012AE3820E911CD3018D912B -:101730009C91A816B90650F4B501C4010E94000896 -:10174000FC01808118132AC0B7FE2CC060E081CF55 -:10175000FFEFAF1ABF0ACFCF612FC4010E9411095A -:10176000DC01ED91FC91E0818E2F90E0FC01EE0F09 -:10177000FF1FE80FF91FE85DFE4F80818F7B80839C -:10178000612FC4010E941109FC01808191810E9496 -:101790009B13612FC4010E94A408BECFFFEFAF1AB4 -:1017A000BF0AC4CFB12CA12CD3018D919C91A81656 -:1017B000B90660F6B501C4010E940008FC018081F1 -:1017C00018130BC0B501C701885B9F4F0E94980793 -:1017D000B501C4010E949807B9CFFFEFAF1ABF0A45 -:1017E000E3CF443079F0DC01ED91FC910084F18588 -:1017F000E02DF12CE12C10E000E023E030E0452D5D -:1018000062E0E8CDF70112819380DC011496ED903F -:10181000FC90612FC7010E9430080196C9F1612F29 -:10182000C7010E945B08FC0180819181029709F049 -:1018300042C001E0911001C000E0602F812F0E94A2 -:10184000DF00912C812C3701FDE86F0E711C22E81E -:10185000E20EF11CD3018D919C918816990668F5D2 -:10186000B401C7010E94CF051C830983DC01ED91FF -:10187000FC910480F581E02DAE014F5F5F4FBE010A -:101880006C5F7F4F02960995BFEF8B1A9B0AE2CFE0 -:1018900081E08D83D601ED91FC910084F185E02DEE -:1018A000EE24E394F12C8E010B5F1F4F30E020E01B -:1018B000452D62E0B5CE83E0ECCF80E0EACF433047 -:1018C00079F0DC01ED91FC910084F185E02DF12CA3 -:1018D000E12C10E000E023E030E0452D63E07ACD1C -:1018E000F7011281612FDC0114968D919C910E9469 -:1018F00021040097F1F001970297F0F4812F0E94E4 -:10190000B60021E0892B09F420E080E089832A8356 -:10191000D601ED91FC910084F185E02D02E0E02EEE -:10192000F12C8E010F5F1F4F30E020E0452D63E06A -:1019300077CE81E020E0EACF82E0FCCF443079F03E -:10194000DC01ED91FC910084F185E02DF12CE12C7E -:1019500010E000E023E030E0452D64E03BCDF701EE -:101960001281DC0114968D909C90612FC4010E941D -:101970002104009799F481E08983D601ED91FC91CF -:101980000084F185E02DEE24E394F12C8E010F5FAD -:101990001F4F30E020E0452D64E042CE049711F067 -:1019A00083E0EACFF7010381612FC4010E94300870 -:1019B000019609F3612FC4010E945B08DC018D913F -:1019C0009C91049769F7E02EF12C61E0812F0E9431 -:1019D0000D01E114F10429F460E0812F0E94DF0081 -:1019E0002BC0BFEFEB16F10411F461E0F6CFE12F4D -:1019F000F0E0E255FF4FE491E33029F148F4E130A3 -:101A0000B9F0E230D9F0E0E8EE16F10474F7E4CF73 -:101A1000E73019F1E83049F1E430A9F7809180000E -:101A2000806280938000F0928B00E0928A0004C074 -:101A300084B5806884BD07BD80E09ECF84B5806298 -:101A400084BD08BDF9CF80918000806880938000BC -:101A5000F0928900E0928800EFCF8091B00080681A -:101A60008093B0000093B300E7CF8091B000806214 -:101A70008093B0000093B400DFCF433079F0DC01F5 -:101A8000ED91FC910084F185E02DF12CE12C10E02A -:101A900000E023E030E0452D65E09CCCF7011281A9 -:101AA000612FDC0114968D919C910E942104009776 -:101AB000E1F0039722E00297C8F4812F0E943E01D3 -:101AC00020E029839A838B83D601ED91FC910084D9 -:101AD000F185E02DB3E0EB2EF12C8E010F5F1F4F4F -:101AE00030E020E0452D65E09BCD21E080E090E0F6 -:101AF000E8CF443079F0DC01ED91FC910084F18570 -:101B0000E02DF12CE12C10E000E023E030E0452D49 -:101B100066E060CCF7011281DC0114968D909C90F8 -:101B2000612FC4010E942104009799F481E0898308 -:101B3000D601ED91FC910084F185E02DEE24E39433 -:101B4000F12C8E010F5F1F4F30E020E0452D66E045 -:101B500067CD059709F08CC0F701038184E0053B50 -:101B600030F7612FC4010E94300897FDDFCF612F4D -:101B7000C4010E945B08DC018D919C91059709F0DE -:101B800079C0B6E58B0E911C612FC4010E9411092A -:101B9000DC01ED91FC91E0818E2F90E0FC01EE0FD5 -:101BA000FF1FE80FF91FE85DFE4F808186FFBECF63 -:101BB000612FC4010E941109DC01ED91FC9110819B -:101BC0001C3008F053C0828148E5842E42E0942EF8 -:101BD000881A910887FD93941401220C331C220C5F -:101BE000331C818168E8E62EF12CE81AF10887FDA4 -:101BF000F394EE0CFF1CEE0CFF1C37010F2C000CB5 -:101C0000880899089101032C000C440B550B2619E8 -:101C1000370948095909A02FB0E00E94B11224EBFE -:101C200030E040E050E00E949212BA01A901460D56 -:101C3000571D681D791D4E155F052CF07101421569 -:101C400053050CF47A01B2E0EB1AF108EE0CFF1C1C -:101C50002FB7F894812F90E0FC01EE0FFF1FE80FE3 -:101C6000F91FE85DFE4FF282E1822FBF80E05FCF77 -:101C700082E05DCF83E05BCFDC01ED91FC910084DD -:101C8000F185E02DF12CE12C10E000E022E030E0C5 -:101C9000452D0995A1CB1F920F920FB60F921124DB -:101CA0002F933F938F939F93AF93BF9380915F0147 -:101CB00090916001A0916101B091620130915E014B -:101CC00023E0230F2D3758F50196A11DB11D209358 -:101CD0005E0180935F0190936001A0936101B093D6 -:101CE00062018091630190916401A0916501B091BE -:101CF00066010196A11DB11D80936301909364015B -:101D0000A0936501B0936601BF91AF919F918F91B0 -:101D10003F912F910F900FBE0F901F90189526E8BE -:101D2000230F0296A11DB11DD2CF1F920F920FB6A5 -:101D30000F9211242F933F934F935F936F937F9351 -:101D40008F939F93AF93BF93EF93FF9387E691E0B9 -:101D50000E942C02FF91EF91BF91AF919F918F91C3 -:101D60007F916F915F914F913F912F910F900FBE97 -:101D70000F901F9018951F920F920FB60F9211247B -:101D80002F938F939F93EF93FF93E0917701F091BF -:101D900078018081E0917D01F0917E0182FD1BC080 -:101DA0009081809180018F5F8F73209181018217D4 -:101DB00041F0E0918001F0E0E959FE4F958F80936A -:101DC0008001FF91EF919F918F912F910F900FBE06 -:101DD0000F901F9018958081F4CF1F920F920FB62D -:101DE0000F9211242F933F934F935F936F937F93A1 -:101DF0008F939F93AF93BF93CF93DF93EF93FF9313 -:101E000080914D01C0914C01D0E087FF24C0109219 -:101E100085001092840080914D018F5F80934D0169 -:101E200080914D01082E000C990B8C179D0724F40E -:101E300080914D018C30C4F1809184009091850097 -:101E4000049680349C4908F47AC080918400909173 -:101E50008500049676C080914D01082E000C990BE8 -:101E60008C179D07C4F6E0914D018E2FEE0F990B54 -:101E7000FC01EE0FFF1FE80FF91FE85DFE4F8081A8 -:101E800086FFC9CFE0914D018E2FEE0F990BFC011B -:101E9000EE0FFF1FE80FF91FE85DFE4F808160E045 -:101EA0008F730E94DF00B7CF2091840030918500AE -:101EB000E0914D018E2FEE0F990BFC01EE0FFF1FED -:101EC000E80FF91FE85DFE4F81819281820F931F19 -:101ED0009093890080938800E0914D018E2FEE0F42 -:101EE000990BFC01EE0FFF1FE80FF91FE85DFE4F95 -:101EF000808186FF11C0E0914D018E2FEE0F990B6E -:101F0000FC01EE0FFF1FE80FF91FE85DFE4F808117 -:101F100061E08F730E94DF00FF91EF91DF91CF911D -:101F2000BF91AF919F918F917F916F915F914F91F1 -:101F30003F912F910F900FBE0F901F90189580E446 -:101F40009CE990938900809388008FEF80934D01E6 -:101F5000E3CFCF92DF92FF920F931F93CF93DF9344 -:101F6000E7E6F1E01382128288EE93E0A0E0B0E0B1 -:101F700084839583A683B7838AE191E091838083EC -:101F800085EC90E09587848784EC90E0978786873E -:101F900080EC90E0918B808B81EC90E0938B828B36 -:101FA00082EC90E0958B848B86EC90E0978B868B0F -:101FB000118E128E138E148EC4E0D2E000E110E078 -:101FC0001F830E83CC24CA94DC2CD986C8861B8739 -:101FD0000A87FF24F394FC861E861D861A8B098BC4 -:101FE000DC8ACB8A1E8B0D8BFF8A1C8E1B8E1A8E71 -:101FF000198F088F80E190E00E94FF12988B8F87E5 -:1020000018A30F8FDAA2C9A21CA30BA3FDA21BA6C3 -:102010001AA619A618A61FA30EA380E290E00E949C -:10202000FF129E8F8D8F198218821D830C831BAB2C -:102030000AABDDAACCAA1FAB0EABF8AE19AE1DAF32 -:102040000CAFDFAECEAE1093450200934402F09287 -:10205000460210924B0210924A02109249021093CB -:1020600048020093470280E190E00E94FF129BAF7C -:102070008AAF10934F0200934E02D0925102C09249 -:1020800050021093530200935202F09254021092A5 -:102090005902109258021092570210935602009360 -:1020A000550280E190E00E94FF1290934D028093D0 -:1020B0004C021DA61CA619AB08AB1093610200933D -:1020C0006002D0926302C092620210936502009394 -:1020D0006402F092660210926802109267021093F6 -:1020E0006C0200936B02D0926E02C0926D0210934C -:1020F000700200936F02F0927102109276021092B9 -:10210000750210927402109373020093720280E1C0 -:1021100090E00E94FF1290936A02809369021093EC -:102120007A0200937902D0927C02C0927B021093D3 -:102130007E0200937D02F0927F021092850210923F -:102140008402109283021092820210938102009303 -:10215000800280E290E00E94FF12909378028093C8 -:10216000770210925B0210925A0210935F02009362 -:102170005E021093890200938802D0928B02C09273 -:102180008A0210938D0200938C02F0928E021092BC -:102190009402109293021092920210929102109364 -:1021A000900200938F0280E190E00E944804909397 -:1021B000870280938602DF91CF911F910F91FF904C -:1021C000DF90CF900895CF93DF93CDB7DEB76097C0 -:1021D0000FB6F894DEBF0FBECDBF789484B5826091 -:1021E00084BD84B5816084BD85B5826085BD85B5BB -:1021F000816085BD80916E00816080936E00109239 -:1022000081008091810082608093810080918100B3 -:102210008160809381008091800081608093800044 -:102220008091B10084608093B1008091B0008160A2 -:102230008093B00080917A00846080937A008091CE -:102240007A00826080937A0080917A008160809326 -:102250007A0080917A00806880937A001092C100A1 -:1022600088E091E00E94FF128C018AE091E0D801A1 -:1022700011969C938E9387E691E013969C938E9390 -:10228000129784E092E015969C938E931497F80130 -:10229000EB5FFE4F10823196108231961082809152 -:1022A0005401811115C08CED92E090934F01809301 -:1022B0004E018DEA91E090935101809350018BEB98 -:1022C00092E0909353018093520181E080935401F6 -:1022D0008EE491E09A8389831C830B83CE0101965F -:1022E0000E948105CE0101960E94160410935D01A3 -:1022F00000935C0161E08DE00E940D0161E08DE0E2 -:102300000E94DF000E94780160E08DE00E94DF0003 -:102310000E94780161E08DE00E94DF000E94780158 -:1023200060E08DE00E94DF0060E08DE00E940D0122 -:10233000D8011296ED91FC91A089B18982E08C932D -:10234000A485B5851C92A685B78580E18C93108EF7 -:10235000A489B58986E08C93A289B3898C91806128 -:102360008C93A289B3898C9188608C93A289B3895C -:102370008C9180688C930288F389E02D80818F7D19 -:1023800080830E94780130E020E050E040E060EF80 -:1023900070E0C8010E94E60280E0A82E80E0B82E1E -:1023A0006EE372E0CE0101960E946904F12CE12CEB -:1023B0008C859D85E816F90608F04FC0B701CE015F -:1023C00001960E940008FC011081612F84E092E0D8 -:1023D0000E945B08DC018D919C910197D1F5812FC2 -:1023E0000E94B600082F612F80E392E00E945A09F4 -:1023F000FC018081081769F1612F80E392E00E945F -:102400005A09DC010C93D12CC12C8091910290913E -:102410009202C816D906E8F4B60186E892E00E9456 -:10242000CF05188B21E0013009F020E02F87DC0177 -:10243000ED91FC910480F581E02DAE01415F5F4F8D -:10244000BE01605F7F4F02960995BFEFCB1ADB0A92 -:10245000DCCFEFEFEE1AFE0AABCFCE0101960E9461 -:10246000A30900915C0110915D01D80112968D9134 -:102470009C91DC01ED91FC910084F185E02D0995A2 -:10248000892BA1F0F80182819381DC01ED91FC910F -:102490000284F385E02D0995D801ED91FC9101901E -:1024A000F081E02D682FC8010995DFCFA114B10498 -:1024B00009F476CF0E941802882309F471CF0E9494 -:1024C00000006ECF8091860290918702009731F0D4 -:1024D0000E94B504109287021092860283E992E06E -:1024E0000E9416048091770290917802009711F073 -:1024F0000E949B1389E692E00E94A3098CE492E07B -:102500000E94A3098EE392E00E94A3098091210218 -:1025100090912202009711F00E949B1383E192E0B8 -:102520000C94A309052E97FB1EF400940E94A91297 -:1025300057FD07D00E94BC1207FC03D04EF40C9448 -:10254000A91250954095309521953F4F4F4F5F4FC1 -:10255000089590958095709561957F4F8F4F9F4F0F -:1025600008950E94DE12A59F900DB49F900DA49F28 -:10257000800D911D11240895A1E21A2EAA1BBB1BE8 -:10258000FD010DC0AA1FBB1FEE1FFF1FA217B3073F -:10259000E407F50720F0A21BB30BE40BF50B661F55 -:1025A000771F881F991F1A9469F760957095809519 -:1025B00090959B01AC01BD01CF010895A29FB00190 -:1025C000B39FC001A39F700D811D1124911DB29F67 -:1025D000700D811D1124911D0895991B79E004C08F -:1025E000991F961708F0961B881F7A95C9F7809552 -:1025F0000895EE0FFF1F0590F491E02D09940F93BD -:102600001F93CF93DF938230910510F482E090E026 -:10261000E0919F02F091A00230E020E0B0E0A0E065 -:10262000309799F42115310509F44AC0281B390B5C -:1026300024303105D8F58A819B816115710589F1B6 -:10264000FB0193838283FE0111C04081518102818D -:10265000138148175907E0F04817590799F4109764 -:1026600061F012960C93129713961C933296CF0139 -:10267000DF91CF911F910F91089500939F021093C6 -:10268000A002F4CF2115310551F04217530738F05D -:10269000A901DB019A01BD01DF01F801C1CFEF0102 -:1026A000F9CF9093A00280939F02CDCFFE01E20F5D -:1026B000F31F819391932250310939832883D7CF17 -:1026C00020919D0230919E02232B41F42091020122 -:1026D0003091030130939E0220939D0220910001CE -:1026E000309101012115310541F42DB73EB74091DC -:1026F000040150910501241B350BE0919D02F091DE -:102700009E02E217F307A0F42E1B3F0B2817390790 -:1027100078F0AC014E5F5F4F2417350748F04E0F3D -:102720005F1F50939E0240939D02819391939FCF90 -:10273000F0E0E0E09CCFCF93DF930097E9F0FC015D -:10274000329713821282A0919F02B091A002ED01F4 -:1027500030E020E01097A1F420813181820F931F97 -:1027600020919D0230919E022817390709F061C01F -:10277000F0939E02E0939D02DF91CF910895EA01CC -:10278000CE17DF07E8F54A815B819E0141155105AF -:10279000B1F7E901FB83EA8349915991C40FD51F31 -:1027A000EC17FD0761F4808191810296840F951FDB -:1027B000E90199838883828193819B838A83F0E0F6 -:1027C000E0E012968D919C9113970097B9F52D91A9 -:1027D0003C911197CD010296820F931F20919D028B -:1027E00030919E022817390739F6309751F510922B -:1027F000A00210929F02B0939E02A0939D02BCCFB4 -:10280000D383C28340815181840F951FC817D90794 -:1028100061F44E5F5F4F88819981480F591F518342 -:1028200040838A819B81938382832115310509F03E -:10283000B0CFF093A002E0939F029ECFFD01DC0198 -:10284000C0CF13821282D7CF10E0C2E6D0E004C01E -:10285000FE010E94F9122196C336D107C9F7F894F8 -:02286000FFCFA8 -:102862000000A102800000000000C2039C0391034B -:10287200AB093903E602000000004E02AE01DB01A3 -:082882009B020C02EA01FE01B9 +:101400005F903F902F90089519821A8283E08B831A +:1014100033E0E32EF12C8E010F5F1F4F30E020E010 +:10142000D7CFEDB7FEB7F987E887443079F0DC0114 +:10143000ED91FC910084F185E02DF12CE12C10E080 +:1014400000E023E030E0452D61E0C4CFF7011281D8 +:101450008381282E312CD6011496ED90FC90823099 +:1014600009F4E3C030F5882309F423C1813009F47D +:10147000CCC0612FC7010E945B08DC012D923C9219 +:101480001982D601ED91FC910084F185E02DEE24C6 +:10149000E394F12C8E010F5F1F4F30E020E0452DCB +:1014A00061E0C60109950FB6F894DEBF0FBECDBF4F +:1014B00093CF843009F4C6C008F4BCC08530C9F6A7 +:1014C0005701F6E5AF0EB11C712C612CC701805994 +:1014D0009F4F9F838E8345019FE0890E911CAE81B3 +:1014E000BF818D919C916816790650F4B301C401B7 +:1014F0000E940008FC0180811813B1C077FEB3C0C0 +:1015000083E090E00E94EC124C0180914C018C3001 +:1015100008F0CBC091E0980F90934C01D4018C93CC +:1015200090E0FC01EE0FFF1FE80FF91FE85DFE4F92 +:1015300088EB9BE092838183612FC5010E94110992 +:10154000DC018D929C92612FC5010E941109FC0162 +:10155000A080B180D5018C918C3008F08ACF61E0F9 +:10156000812F0E940D01F5018081282F30E0F901C3 +:10157000EE0FFF1FE20FF31FE85DFE4F9081907C9E +:10158000212F2F73922B9083D50111961C921197C6 +:1015900012961C922CE0622F0E94DA12829FB001F8 +:1015A000112430E020E0AB01420F531FFA01EE0F8F +:1015B000FF1FE40FF51FE85DFE4F908196FD16C0FA +:1015C0002F5F3F4F2C30310571F781110FC0109202 +:1015D000800082E080938100109285001092840048 +:1015E000B19A80916F00826080936F00D501EC9179 +:1015F0008E2F90E0FC01EE0FFF1FE80FF91FE85D52 +:10160000FE4F80818064808334CF60E0812F0E9410 +:101610000D01812F0E94B600082F612FC7018C9603 +:101620000E945A09FC01008324CF61E0812F0E94AF +:101630000D011FCF60E0812F0E940D01812F0E94BC +:101640003E0117CF61E0812F0E940D0161E0812FE3 +:101650000E940D0160E0812F0E94DF000ACFFFEFA2 +:101660006F1A7F0A3CCF612FC5010E941109DC016E +:10167000ED91FC91E0818E2F90E0FC01EE0FFF1FB9 +:10168000E80FF91FE85DFE4F80818F7B8083612F1B +:10169000C5010E941109FC01808191810E9488137B +:1016A000612FC5010E94A4082BCF8FEFF401808326 +:1016B00043CFB12CA12CF701E059FF4FFF83EE83FC +:1016C0004701F6E58F0E911C34012FE0620E711C6C +:1016D000AE81BF818D919C91A816B90650F4B501D9 +:1016E000C3010E940008FC01808118131EC0B7FED0 +:1016F00020C0B12CA12C3701F5E46F0E711C4701FD +:101700002AE3820E911CD3018D919C91A816B906F3 +:1017100050F4B501C4010E940008FC018081181337 +:101720002AC0B7FE2CC060E081CFFFEFAF1ABF0A1E +:10173000CFCF612FC4010E941109DC01ED91FC9112 +:10174000E0818E2F90E0FC01EE0FFF1FE80FF91FE4 +:10175000E85DFE4F80818F7B8083612FC4010E94F2 +:101760001109FC01808191810E948813612FC401BD +:101770000E94A408BECFFFEFAF1ABF0AC4CFB12C9E +:10178000A12CD3018D919C91A816B90660F6B501E4 +:10179000C4010E940008FC01808118130BC0B50130 +:1017A000C701885B9F4F0E949807B501C4010E9442 +:1017B0009807B9CFFFEFAF1ABF0AE3CF443079F0F3 +:1017C000DC01ED91FC910084F185E02DF12CE12C00 +:1017D00010E000E023E030E0452D62E0FBCDF701B2 +:1017E00012819380DC011496ED90FC90612FC7016B +:1017F0000E9430080196C9F1612FC7010E945B0861 +:10180000FC0180819181029709F042C001E09110B2 +:1018100001C000E0602F812F0E94DF00912C812CFD +:101820003701FDE86F0E711C22E8E20EF11CD301B6 +:101830008D919C918816990668F5B401C7010E94A4 +:10184000CF051C830983DC01ED91FC910480F581B7 +:10185000E02DAE014F5F5F4FBE016C5F7F4F029680 +:101860000995BFEF8B1A9B0AE2CF81E08D83D601E9 +:10187000ED91FC910084F185E02DEE24E394F12CB0 +:101880008E010B5F1F4F30E020E0452D62E009CE56 +:1018900083E0ECCF80E0EACF433079F0DC01ED91DA +:1018A000FC910084F185E02DF12CE12C10E000E0AA +:1018B00023E030E0452D63E08DCDF7011281612FEB +:1018C000DC0114968D919C910E9421040097F1F007 +:1018D00001970297F0F4812F0E94B60021E0892B36 +:1018E00009F420E080E089832A83D601ED91FC9100 +:1018F0000084F185E02D02E0E02EF12C8E010F5FD7 +:101900001F4F30E020E0452D63E0CBCD81E020E0AB +:10191000EACF82E0FCCF443079F0DC01ED91FC911C +:101920000084F185E02DF12CE12C10E000E023E0B3 +:1019300030E0452D64E04ECDF7011281DC011496B4 +:101940008D909C90612FC4010E942104009799F40E +:1019500081E08983D601ED91FC910084F185E02D31 +:10196000EE24E394F12C8E010F5F1F4F30E020E056 +:10197000452D64E096CD049711F083E0EACFF7019E +:101980000381612FC4010E943008019609F3612F81 +:10199000C4010E945B08DC018D919C91049769F75A +:1019A000E02EF12C61E0812F0E940D01E114F10481 +:1019B00029F460E0812F0E94DF002BC0BFEFEB16FF +:1019C000F10411F461E0F6CFE12FF0E0E255FF4FB2 +:1019D000E491E33029F148F4E130B9F0E230D9F094 +:1019E000E0E8EE16F10474F7E4CFE73019F1E830DF +:1019F00049F1E430A9F780918000806280938000F3 +:101A0000F0928B00E0928A0004C084B5806884BDA7 +:101A100007BD80E09ECF84B5806284BD08BDF9CF4C +:101A200080918000806880938000F0928900E0922D +:101A30008800EFCF8091B00080688093B000009361 +:101A4000B300E7CF8091B00080628093B000009334 +:101A5000B400DFCF433079F0DC01ED91FC910084DC +:101A6000F185E02DF12CE12C10E000E023E030E0E6 +:101A7000452D65E0AFCCF7011281612FDC01149692 +:101A80008D919C910E9421040097E1F0039722E040 +:101A90000297C8F4812F0E943E0120E029839A8397 +:101AA0008B83D601ED91FC910084F185E02DB3E0AC +:101AB000EB2EF12C8E010F5F1F4F30E020E0452D03 +:101AC00065E0EFCC21E080E090E0E8CF443079F0B1 +:101AD000DC01ED91FC910084F185E02DF12CE12CED +:101AE00010E000E023E030E0452D66E073CCF70124 +:101AF0001281DC0114968D909C90612FC4010E948C +:101B00002104009799F481E08983D601ED91FC913D +:101B10000084F185E02DEE24E394F12C8E010F5F1B +:101B20001F4F30E020E0452D66E0BBCC059709F063 +:101B30008CC0F701038184E0053B30F7612FC401BD +:101B40000E94300897FDDFCF612FC4010E945B081F +:101B5000DC018D919C91059709F079C0B6E58B0E5B +:101B6000911C612FC4010E941109DC01ED91FC91CF +:101B7000E0818E2F90E0FC01EE0FFF1FE80FF91FB0 +:101B8000E85DFE4F808186FFBECF612FC4010E94B9 +:101B90001109DC01ED91FC9110811C3008F053C05B +:101BA000828148E5842E42E0942E881A910887FDB0 +:101BB00093941401220C331C220C331C818168E89D +:101BC000E62EF12CE81AF10887FDF394EE0CFF1CC9 +:101BD000EE0CFF1C37010F2C000C880899089101AE +:101BE000032C000C440B550B2619370948095909D9 +:101BF000A02FB0E00E949E1224EB30E040E050E0C5 +:101C00000E947F12BA01A901460D571D681D791D5A +:101C10004E155F052CF07101421553050CF47A0145 +:101C2000B2E0EB1AF108EE0CFF1C2FB7F894812FED +:101C300090E0FC01EE0FFF1FE80FF91FE85DFE4F7B +:101C4000F282E1822FBF80E05FCF82E05DCF83E050 +:101C50005BCFDC01ED91FC910084F185E02DF12C4E +:101C6000E12C10E000E022E030E0452D0995B4CBF6 +:101C70001F920F920FB60F9211242F933F938F93C1 +:101C80009F93AF93BF9380915F0190916001A0916A +:101C90006101B091620130915E0123E0230F2D3785 +:101CA00058F50196A11DB11D20935E0180935F013F +:101CB00090936001A0936101B093620180916301F0 +:101CC00090916401A0916501B09166010196A11DFA +:101CD000B11D8093630190936401A0936501B0935B +:101CE0006601BF91AF919F918F913F912F910F907E +:101CF0000FBE0F901F90189526E8230F0296A11D86 +:101D0000B11DD2CF1F920F920FB60F9211242F93B5 +:101D10003F934F935F936F937F938F939F93AF9373 +:101D2000BF93EF93FF9387E691E00E942C02FF910F +:101D3000EF91BF91AF919F918F917F916F915F9143 +:101D40004F913F912F910F900FBE0F901F901895BC +:101D50001F920F920FB60F9211242F938F939F9380 +:101D6000EF93FF93E0917701F09178018081E0910A +:101D70007D01F0917E0182FD1BC0908180918001E8 +:101D80008F5F8F7320918101821741F0E091800174 +:101D9000F0E0E959FE4F958F80938001FF91EF911C +:101DA0009F918F912F910F900FBE0F901F901895BC +:101DB0008081F4CF1F920F920FB60F9211242F93B0 +:101DC0003F934F935F936F937F938F939F93AF93C3 +:101DD000BF93CF93DF93EF93FF9380914D01C09119 +:101DE0004C01D0E087FF24C010928500109284003F +:101DF00080914D018F5F80934D0180914D01082EA0 +:101E0000000C990B8C179D0724F480914D018C30A8 +:101E1000C4F18091840090918500049680349C499F +:101E200008F47AC08091840090918500049676C071 +:101E300080914D01082E000C990B8C179D07C4F65C +:101E4000E0914D018E2FEE0F990BFC01EE0FFF1F5D +:101E5000E80FF91FE85DFE4F808186FFC9CFE09152 +:101E60004D018E2FEE0F990BFC01EE0FFF1FE80FB7 +:101E7000F91FE85DFE4F808160E08F730E94DF00F4 +:101E8000B7CF2091840030918500E0914D018E2FD5 +:101E9000EE0F990BFC01EE0FFF1FE80FF91FE85D35 +:101EA000FE4F81819281820F931F909389008093CE +:101EB0008800E0914D018E2FEE0F990BFC01EE0F83 +:101EC000FF1FE80FF91FE85DFE4F808186FF11C0FC +:101ED000E0914D018E2FEE0F990BFC01EE0FFF1FCD +:101EE000E80FF91FE85DFE4F808161E08F730E946B +:101EF000DF00FF91EF91DF91CF91BF91AF919F9163 +:101F00008F917F916F915F914F913F912F910F90A2 +:101F10000FBE0F901F90189580E49CE99093890064 +:101F2000809388008FEF80934D01E3CFCF92DF92B3 +:101F3000FF920F931F93CF93DF93E7E6F1E01382B5 +:101F4000128288EE93E0A0E0B0E084839583A683BC +:101F5000B7838AE191E09183808385EC90E0958757 +:101F6000848784EC90E09787868780EC90E0918B63 +:101F7000808B81EC90E0938B828B82EC90E0958B50 +:101F8000848B86EC90E0978B868B118E128E138E4D +:101F9000148EC4E0D2E000E110E01F830E83CC2455 +:101FA000CA94DC2CD986C8861B870A87FF24F39441 +:101FB000FC861E861D861A8B098BDC8ACB8A1E8BBB +:101FC0000D8BFF8A1C8E1B8E1A8E198F088F80E155 +:101FD00090E00E94EC12988B8F8718A30F8FDAA2E3 +:101FE000C9A21CA30BA3FDA21BA61AA619A618A67C +:101FF0001FA30EA380E290E00E94EC129E8F8D8FB3 +:10200000198218821D830C831BAB0AABDDAACCAAF4 +:102010001FAB0EABF8AE19AE1DAF0CAFDFAECEAE40 +:102020001093450200934402F092460210924B0234 +:1020300010924A02109249021093480200934702FC +:1020400080E190E00E94EC129BAF8AAF10934F02A8 +:1020500000934E02D0925102C0925002109353024C +:1020600000935202F09254021092590210925802B8 +:1020700010925702109356020093550280E190E0AF +:102080000E94EC1290934D0280934C021DA61CA658 +:1020900019AB08AB1093610200936002D092630207 +:1020A000C09262021093650200936402F09266028D +:1020B000109268021092670210936C0200936B02F8 +:1020C000D0926E02C0926D021093700200936F0264 +:1020D000F0927102109276021092750210927402C0 +:1020E000109373020093720280E190E00E94EC1260 +:1020F00090936A028093690210937A0200937902A6 +:10210000D0927C02C0927B0210937E0200937D02EB +:10211000F0927F0210928502109284021092830244 +:1021200010928202109381020093800280E290E07C +:102130000E94EC12909378028093770210925B02D7 +:1021400010925A0210935F0200935E02109389026C +:1021500000938802D0928B02C0928A0210938D0263 +:1021600000938C02F0928E021092940210929302CD +:1021700010929202109291021093900200938F029B +:1021800080E190E00E944804909387028093860249 +:10219000DF91CF911F910F91FF90DF90CF90089525 +:1021A000CF93DF93CDB7DEB760970FB6F894DEBF5D +:1021B0000FBECDBF789484B5826084BD84B5816044 +:1021C00084BD85B5826085BD85B5816085BD809102 +:1021D0006E00816080936E0010928100809181007A +:1021E0008260809381008091810081608093810072 +:1021F000809180008160809380008091B100846034 +:102200008093B1008091B00081608093B000809194 +:102210007A00846080937A0080917A008260809353 +:102220007A0080917A00816080937A0080917A00B0 +:10223000806880937A001092C10088E091E00E944B +:10224000EC128C018AE091E0D80111969C938E9358 +:1022500087E691E013969C938E93129784E092E028 +:1022600015969C938E931497F801EB5FFE4F1082A6 +:10227000319610823196108280915401811115C0DF +:102280008CED92E090934F0180934E018DEA91E0A6 +:1022900090935101809350018BEB92E09093530106 +:1022A0008093520181E0809354018EE491E09A83FF +:1022B00089831C830B83CE0101960E948105CE0188 +:1022C00001960E94160410935D0100935C0161E089 +:1022D0008DE00E940D0161E08DE00E94DF000E9410 +:1022E000780160E08DE00E94DF000E94780161E0EB +:1022F0008DE00E94DF000E94780160E08DE00E9486 +:10230000DF0060E08DE00E940D01D8011296ED9192 +:10231000FC91A089B18982E08C93A485B5851C923B +:10232000A685B78580E18C93108EA489B58986E057 +:102330008C93A289B3898C9180618C93A289B38993 +:102340008C9188608C93A289B3898C9180688C93DE +:102350000288F389E02D80818F7D80830E9478013F +:1023600030E020E050E040E060EF70E0C8010E9403 +:10237000E60280E0A82E80E0B82E6EE372E0CE0187 +:1023800001960E946904F12CE12C8C859D85E8164C +:10239000F90608F04FC0B701CE0101960E9400086F +:1023A000FC011081612F84E092E00E945B08DC0157 +:1023B0008D919C910197D1F5812F0E94B600082F35 +:1023C000612F80E392E00E945A09FC018081081786 +:1023D00069F1612F80E392E00E945A09DC010C93BD +:1023E000D12CC12C8091910290919202C816D906ED +:1023F000E8F4B60186E892E00E94CF05188B21E050 +:10240000013009F020E02F87DC01ED91FC91048080 +:10241000F581E02DAE01415F5F4FBE01605F7F4FF0 +:1024200002960995BFEFCB1ADB0ADCCFEFEFEE1A6D +:10243000FE0AABCFCE0101960E94A30900915C0178 +:1024400010915D01D80112968D919C91DC01ED9166 +:10245000FC910084F185E02D0995892BA1F0F8010C +:1024600082819381DC01ED91FC910284F385E02D62 +:102470000995D801ED91FC910190F081E02D682F34 +:10248000C8010995DFCFA114B10409F476CF0E94E9 +:102490001802882309F471CF0E9400006ECF80914A +:1024A000860290918702009731F00E94B504109245 +:1024B00087021092860283E992E00E9416048091BE +:1024C000770290917802009711F00E94881389E6B4 +:1024D00092E00E94A3098CE492E00E94A3098EE39B +:1024E00092E00E94A309809121029091220200971C +:1024F00011F00E94881383E192E00C94A309052E49 +:1025000097FB1EF400940E94961257FD07D00E947C +:10251000A91207FC03D04EF40C94961250954095E6 +:10252000309521953F4F4F4F5F4F0895909580957F +:10253000709561957F4F8F4F9F4F08950E94CB12EA +:10254000A59F900DB49F900DA49F800D911D112407 +:102550000895A1E21A2EAA1BBB1BFD010DC0AA1FE4 +:10256000BB1FEE1FFF1FA217B307E407F50720F0FC +:10257000A21BB30BE40BF50B661F771F881F991F77 +:102580001A9469F760957095809590959B01AC01C0 +:10259000BD01CF010895A29FB001B39FC001A39FC9 +:1025A000700D811D1124911DB29F700D811D11248C +:1025B000911D0895991B79E004C0991F961708F0A2 +:1025C000961B881F7A95C9F780950895EE0FFF1F17 +:1025D0000590F491E02D09940F931F93CF93DF930F +:1025E0008230910510F482E090E0E0919F02F0913A +:1025F000A00230E020E0B0E0A0E0309799F421158F +:10260000310509F44AC0281B390B24303105D8F5AF +:102610008A819B816115710589F1FB019383828316 +:10262000FE0111C040815181028113814817590771 +:10263000E0F04817590799F4109761F012960C933F +:10264000129713961C933296CF01DF91CF911F9171 +:102650000F91089500939F021093A002F4CF2115CB +:10266000310551F04217530738F0A901DB019A01F7 +:10267000BD01DF01F801C1CFEF01F9CF9093A002B6 +:1026800080939F02CDCFFE01E20FF31F81939193C0 +:102690002250310939832883D7CF20919D02309170 +:1026A0009E02232B41F420910201309103013093CB +:1026B0009E0220939D02209100013091010121157D +:1026C000310541F42DB73EB7409104015091050109 +:1026D000241B350BE0919D02F0919E02E217F30757 +:1026E000A0F42E1B3F0B2817390778F0AC014E5F82 +:1026F0005F4F2417350748F04E0F5F1F50939E021F +:1027000040939D02819391939FCFF0E0E0E09CCFB6 +:10271000CF93DF930097E9F0FC0132971382128286 +:10272000A0919F02B091A002ED0130E020E010974F +:10273000A1F420813181820F931F20919D0230915D +:102740009E022817390709F061C0F0939E02E093BA +:102750009D02DF91CF910895EA01CE17DF07E8F5DA +:102760004A815B819E0141155105B1F7E901FB8367 +:10277000EA8349915991C40FD51FEC17FD0761F405 +:10278000808191810296840F951FE9019983888346 +:10279000828193819B838A83F0E0E0E012968D91A1 +:1027A0009C9113970097B9F52D913C911197CD010C +:1027B0000296820F931F20919D0230919E0228174E +:1027C000390739F6309751F51092A00210929F0206 +:1027D000B0939E02A0939D02BCCFD383C28340815D +:1027E0005181840F951FC817D90761F44E5F5F4F61 +:1027F00088819981480F591F518340838A819B8129 +:10280000938382832115310509F0B0CFF093A002A4 +:10281000E0939F029ECFFD01DC01C0CF13821282A4 +:10282000D7CF10E0C2E6D0E004C0FE010E94E6125D +:0C2830002196C336D107C9F7F894FFCFFA +:10283C000000A102800000000000C2039C03910371 +:10284C00AB093903E602000000004E02AE01DB01C9 +:08285C009B020C02EA01FE01DF :00000001FF From 767baba7e49a85c6652066e0c43c1c493e9af2bf Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Mon, 2 May 2022 20:01:49 +0200 Subject: [PATCH 17/18] fix meta --- owlet/meta.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/owlet/meta.json b/owlet/meta.json index 04ecac227..f44c29ff7 100644 --- a/owlet/meta.json +++ b/owlet/meta.json @@ -4,6 +4,6 @@ "icon": "", "stability": "community", "offline": true, - "technologies": ["Serial Port", "Network"], - "categories": ["Sensor", "Relay", "Switch", "Gateway"] + "technologies": ["serial-port", "network"], + "categories": ["sensor", "diy", "switch"] } From 8eeeeb12f6600cea24da9d6b98dd40ab4d6bc11b Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sun, 8 May 2022 14:45:16 +0200 Subject: [PATCH 18/18] minor fixes --- owlet/integrationpluginowlet.cpp | 81 ++++++++++++++++++++------------ owlet/integrationpluginowlet.h | 6 +++ owlet/owletclient.cpp | 47 +++++++++++++++--- owlet/owletclient.h | 13 ++++- 4 files changed, 109 insertions(+), 38 deletions(-) diff --git a/owlet/integrationpluginowlet.cpp b/owlet/integrationpluginowlet.cpp index 62374b007..bd6da390a 100644 --- a/owlet/integrationpluginowlet.cpp +++ b/owlet/integrationpluginowlet.cpp @@ -44,6 +44,7 @@ #include #include #include +#include IntegrationPluginOwlet::IntegrationPluginOwlet() { @@ -852,7 +853,55 @@ void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) params.insert("ledCount", thing->paramValue(ws2812ThingLedCountParamTypeId).toUInt()); params.insert("ledMode", "WS2812Mode" + thing->paramValue(ws2812ThingLedModeParamTypeId).toString()); params.insert("ledClock", "WS2812Clock" + thing->paramValue(ws2812ThingLedClockParamTypeId).toString()); - client->sendCommand("GPIO.ConfigurePin", params); + int id = client->sendCommand("GPIO.ConfigurePin", params); + connect(client, &OwletClient::replyReceived, thing, [id, client, thing](int commandId, const QVariantMap &/*params*/){ + if (id != commandId) + return; + + qCDebug(dcOwlet()) << "Configuration sent..."; + QVariantMap params; + params.insert("id", thing->paramValue(ws2812ThingPinParamTypeId).toUInt()); + params.insert("power", thing->stateValue(ws2812PowerStateTypeId).toBool()); + params.insert("brightness", thing->stateValue(ws2812BrightnessStateTypeId).toInt()); + QColor color = thing->stateValue(ws2812ColorStateTypeId).value(); + params.insert("color", (color.rgb() & 0xFFFFFF)); + int effect = thing->stateValue(ws2812EffectStateTypeId).toInt(); + params.insert("effect", effect); + qCDebug(dcOwlet()) << "Initializing" << QJsonDocument::fromVariant(params).toJson(); + client->sendCommand("GPIO.ControlPin", params); + + connect(client, &OwletClient::notificationReceived, thing, [=](const QString &name, const QVariantMap ¶ms){ + qCDebug(dcOwlet()) << "***Notif" << name << params; + if (thing->thingClassId() == digitalInputThingClassId) { + if (params.value("id").toInt() == thing->paramValue(digitalInputThingPinParamTypeId)) { + thing->setStateValue(digitalInputPowerStateTypeId, params.value("power").toBool()); + } + } + if (thing->thingClassId() == digitalOutputThingClassId) { + if (params.value("id").toInt() == thing->paramValue(digitalOutputThingPinParamTypeId)) { + thing->setStateValue(digitalOutputPowerStateTypeId, params.value("power").toBool()); + } + } + if (thing->thingClassId() == ws2812ThingClassId) { + if (name == "GPIO.PinChanged") { + if (params.contains("power")) { + thing->setStateValue(ws2812PowerStateTypeId, params.value("power").toBool()); + } + if (params.contains("brightness")) { + thing->setStateValue(ws2812BrightnessStateTypeId, params.value("brightness").toInt()); + } + if (params.contains("color")) { + thing->setStateValue(ws2812ColorStateTypeId, params.value("color").value()); + } + if (params.contains("effect")) { + thing->setStateValue(ws2812EffectStateTypeId, params.value("effect").toInt()); + } + } + } + }); + + }); + } @@ -870,36 +919,6 @@ void IntegrationPluginOwlet::setupThing(ThingSetupInfo *info) thing->setStateValue("connected", false); }); - connect(client, &OwletClient::notificationReceived, this, [=](const QString &name, const QVariantMap ¶ms){ - qCDebug(dcOwlet()) << "***Notif" << name << params; - if (thing->thingClassId() == digitalInputThingClassId) { - if (params.value("id").toInt() == thing->paramValue(digitalInputThingPinParamTypeId)) { - thing->setStateValue(digitalInputPowerStateTypeId, params.value("power").toBool()); - } - } - if (thing->thingClassId() == digitalOutputThingClassId) { - if (params.value("id").toInt() == thing->paramValue(digitalOutputThingPinParamTypeId)) { - thing->setStateValue(digitalOutputPowerStateTypeId, params.value("power").toBool()); - } - } - if (thing->thingClassId() == ws2812ThingClassId) { - if (name == "GPIO.PinChanged") { - if (params.contains("power")) { - thing->setStateValue(ws2812PowerStateTypeId, params.value("power").toBool()); - } - if (params.contains("brightness")) { - thing->setStateValue(ws2812BrightnessStateTypeId, params.value("brightness").toInt()); - } - if (params.contains("color")) { - thing->setStateValue(ws2812ColorStateTypeId, params.value("color").value()); - } - if (params.contains("effect")) { - thing->setStateValue(ws2812EffectStateTypeId, params.value("effect").toInt()); - } - } - } - }); - client->transport()->connectTransport(); } diff --git a/owlet/integrationpluginowlet.h b/owlet/integrationpluginowlet.h index 5d4a34367..779fd4e29 100644 --- a/owlet/integrationpluginowlet.h +++ b/owlet/integrationpluginowlet.h @@ -55,6 +55,9 @@ class IntegrationPluginOwlet: public IntegrationPlugin void executeAction(ThingActionInfo *info) override; void thingRemoved(Thing *thing) override; +private: + void processActionQueue(Thing *thing); + private: ZeroConfServiceBrowser *m_zeroConfBrowser = nullptr; @@ -76,6 +79,9 @@ class IntegrationPluginOwlet: public IntegrationPlugin void setupArduinoChildThing(OwletSerialClient *client, quint8 pinId, OwletSerialClient::PinMode pinMode); void configurePin(OwletSerialClient *client, quint8 pinId, OwletSerialClient::PinMode pinMode); QString getPinName(Thing *parent, quint8 pinId); + + QHash> m_actionQueue; + QHash m_pendingActions; }; #endif // INTEGRATIONPLUGINOWLET_H diff --git a/owlet/owletclient.cpp b/owlet/owletclient.cpp index 266571d3a..e3a6d5790 100644 --- a/owlet/owletclient.cpp +++ b/owlet/owletclient.cpp @@ -11,6 +11,17 @@ OwletClient::OwletClient(OwletTransport *transport, QObject *parent) : { transport->setParent(this); + m_commandTimeoutTimer.setInterval(5000); + connect(&m_commandTimeoutTimer, &QTimer::timeout, this, [=](){ + if (m_pendingCommandId != -1) { + QVariantMap params; + params.insert("error", "TimeoutError"); + emit replyReceived(m_pendingCommandId, params); + m_pendingCommandId = -1; + sendNextRequest(); + } + }); + connect(m_transport, &OwletTransport::dataReceived, this, &OwletClient::dataReceived); connect(m_transport, &OwletTransport::error, this, &OwletClient::error); connect(m_transport, &OwletTransport::connectedChanged, this, [=](bool isConnected){ @@ -39,13 +50,18 @@ int OwletClient::sendCommand(const QString &method, const QVariantMap ¶ms) return -1; } - int id = ++m_commandId; + quint16 id = ++m_commandId; QVariantMap packet; packet.insert("id", id); packet.insert("method", method); packet.insert("params", params); - m_transport->sendData(QJsonDocument::fromVariant(packet).toJson(QJsonDocument::Compact)); + qCDebug(dcOwlet) << "Sending command" << qUtf8Printable(QJsonDocument::fromVariant(packet).toJson()); + Command cmd; + cmd.id = id; + cmd.payload = packet; + m_commandQueue.append(cmd); + sendNextRequest(); return id; } @@ -60,10 +76,9 @@ void OwletClient::dataReceived(const QByteArray &data) QJsonParseError error; QJsonDocument jsonDoc = QJsonDocument::fromJson(m_receiveBuffer.left(splitIndex), &error); if (error.error != QJsonParseError::NoError) { - // qWarning() << "Could not parse json data from nymea" << m_receiveBuffer.left(splitIndex) << error.errorString(); + qCWarning(dcOwlet) << "Could not parse json data from nymea" << m_receiveBuffer.left(splitIndex) << error.errorString(); return; } - // qDebug() << "received response" << qUtf8Printable(jsonDoc.toJson(QJsonDocument::Indented)); m_receiveBuffer = m_receiveBuffer.right(m_receiveBuffer.length() - splitIndex - 1); if (!m_receiveBuffer.isEmpty()) { staticMetaObject.invokeMethod(this, "dataReceived", Qt::QueuedConnection, Q_ARG(QByteArray, QByteArray())); @@ -72,11 +87,31 @@ void OwletClient::dataReceived(const QByteArray &data) QVariantMap packet = jsonDoc.toVariant().toMap(); if (packet.contains("notification")) { - qCDebug(dcOwlet()) << "Notification received:" << packet; + qCDebug(dcOwlet()) << "Notification received:" << qUtf8Printable(QJsonDocument::fromVariant(packet).toJson()); emit notificationReceived(packet.value("notification").toString(), packet.value("params").toMap()); } else if (packet.contains("id")) { - qCDebug(dcOwlet()) << "reply received:" << packet; + qCDebug(dcOwlet()) << "Reply received:" << qUtf8Printable(QJsonDocument::fromVariant(packet).toJson()); int id = packet.value("id").toInt(); + if (id == m_pendingCommandId) { + m_pendingCommandId = -1; + sendNextRequest(); + } emit replyReceived(id, packet.value("params").toMap()); + } else { + qCWarning(dcOwlet) << "Unhandled data from owlet" << qUtf8Printable(jsonDoc.toJson(QJsonDocument::Indented)); + } +} + +void OwletClient::sendNextRequest() +{ + if (m_commandQueue.isEmpty()) { + return; + } + if (m_pendingCommandId != -1) { + return; } + Command cmd = m_commandQueue.takeFirst(); + m_pendingCommandId = cmd.id; + m_transport->sendData(QJsonDocument::fromVariant(cmd.payload).toJson(QJsonDocument::Compact)); + m_commandTimeoutTimer.start(); } diff --git a/owlet/owletclient.h b/owlet/owletclient.h index 9e7012a23..3af506c56 100644 --- a/owlet/owletclient.h +++ b/owlet/owletclient.h @@ -4,6 +4,7 @@ #include #include #include +#include class OwletTransport; @@ -30,12 +31,22 @@ class OwletClient : public QObject private slots: void dataReceived(const QByteArray &data); + void sendNextRequest(); + private: + struct Command { + int id; + QVariantMap payload; + }; OwletTransport *m_transport = nullptr; - int m_commandId = 0; + quint16 m_commandId = 0; QByteArray m_receiveBuffer; + QList m_commandQueue; + qint32 m_pendingCommandId = -1; + QTimer m_commandTimeoutTimer; + }; #endif // OWLETCLIENT_H