-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge PR #494: WIP: New Plugin: nymea owlets
- Loading branch information
Showing
29 changed files
with
7,032 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationpluginowlet.so | ||
owlet/firmware usr/share/nymea/owlet/firmware |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,6 +52,7 @@ PLUGIN_DIRS = \ | |
openuv \ | ||
openweathermap \ | ||
osdomotics \ | ||
owlet \ | ||
philipshue \ | ||
powerfox \ | ||
pushbullet \ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
#include "arduinoflasher.h" | ||
#include "extern-plugininfo.h" | ||
|
||
#include <QDir> | ||
#include <QJsonDocument> | ||
|
||
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#ifndef ARDUINOFLASHER_H | ||
#define ARDUINOFLASHER_H | ||
|
||
#include <QObject> | ||
#include <QFileInfo> | ||
#include <QProcess> | ||
|
||
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 |
Oops, something went wrong.