added one wire plug-in
This commit is contained in:
parent
c061316ee9
commit
09738d80ee
@ -29,6 +29,7 @@ PLUGIN_DIRS = \
|
|||||||
mqttclient \
|
mqttclient \
|
||||||
netatmo \
|
netatmo \
|
||||||
networkdetector \
|
networkdetector \
|
||||||
|
onewire \
|
||||||
openweathermap \
|
openweathermap \
|
||||||
osdomotics \
|
osdomotics \
|
||||||
philipshue \
|
philipshue \
|
||||||
|
|||||||
272
onewire/devicepluginonewire.cpp
Normal file
272
onewire/devicepluginonewire.cpp
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* *
|
||||||
|
* Copyright (C) 2018 Bernhard Trinnes <bernhard.trinnes@guh.io *
|
||||||
|
* *
|
||||||
|
* This file is part of nymea. *
|
||||||
|
* *
|
||||||
|
* This library is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU Lesser General Public *
|
||||||
|
* License as published by the Free Software Foundation; either *
|
||||||
|
* version 2.1 of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This library 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 library; If not, see *
|
||||||
|
* <http://www.gnu.org/licenses/>. *
|
||||||
|
* *
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\page onewire.html
|
||||||
|
\title One wire
|
||||||
|
\brief Plugin for one wire devices.
|
||||||
|
|
||||||
|
\ingroup plugins
|
||||||
|
\ingroup nymea-plugins
|
||||||
|
|
||||||
|
This plugin allows to receive data from the onw wire file system.
|
||||||
|
|
||||||
|
\chapter Plugin properties
|
||||||
|
Following JSON file contains the definition and the description of all available \l{DeviceClass}{DeviceClasses}
|
||||||
|
and \l{Vendor}{Vendors} of this \l{DevicePlugin}.
|
||||||
|
|
||||||
|
For more details how to read this JSON file please check out the documentation for \l{The plugin JSON File}.
|
||||||
|
|
||||||
|
\quotefile plugins/deviceplugins/OneWire/devicepluginOneWire.json
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "devicepluginonewire.h"
|
||||||
|
#include "devices/device.h"
|
||||||
|
#include "plugininfo.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
|
||||||
|
//https://github.com/owfs
|
||||||
|
//https://github.com/owfs/owfs-doc/wiki
|
||||||
|
|
||||||
|
DevicePluginOneWire::DevicePluginOneWire()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Device::DeviceError DevicePluginOneWire::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms)
|
||||||
|
{
|
||||||
|
Q_UNUSED(params);
|
||||||
|
|
||||||
|
if (deviceClassId == temperatureSensorDeviceClassId) {
|
||||||
|
|
||||||
|
foreach(Device *parentDevice, myDevices().filterByDeviceClassId(oneWireInterfaceDeviceClassId)) {
|
||||||
|
if (parentDevice->stateValue(oneWireInterfaceAutoAddStateTypeId).toBool()) {
|
||||||
|
//devices cannot be discovered since auto mode is enabled
|
||||||
|
return Device::DeviceErrorNoError;
|
||||||
|
} else {
|
||||||
|
if (m_oneWireInterface)
|
||||||
|
m_oneWireInterface->discoverDevices();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Device::DeviceErrorAsync;
|
||||||
|
}
|
||||||
|
return Device::DeviceErrorDeviceClassNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Device::DeviceSetupStatus DevicePluginOneWire::setupDevice(Device *device)
|
||||||
|
{
|
||||||
|
if(!m_pluginTimer) {
|
||||||
|
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(10);
|
||||||
|
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginOneWire::onPluginTimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->deviceClassId() == oneWireInterfaceDeviceClassId) {
|
||||||
|
qCDebug(dcOneWire) << "Setup one wire interface";
|
||||||
|
|
||||||
|
/*if(!myDevices().filterByDeviceClassId(oneWireInterfaceDeviceClassId).isEmpty()) {
|
||||||
|
qCWarning(dcOneWire) << "Only one one wire interfaces allowed";
|
||||||
|
return Device::DeviceSetupStatusFailure;
|
||||||
|
}*/
|
||||||
|
m_oneWireInterface = new OneWire(device->paramValue(oneWireInterfaceDevicePathParamTypeId).toByteArray(), this);
|
||||||
|
|
||||||
|
if (!m_oneWireInterface->init()){
|
||||||
|
m_oneWireInterface->deleteLater();
|
||||||
|
return Device::DeviceSetupStatusFailure;
|
||||||
|
}
|
||||||
|
connect(m_oneWireInterface, &OneWire::devicesDiscovered, this, &DevicePluginOneWire::onOneWireDevicesDiscovered);
|
||||||
|
return Device::DeviceSetupStatusSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->deviceClassId() == temperatureSensorDeviceClassId) {
|
||||||
|
|
||||||
|
qCDebug(dcOneWire) << "Setup one wire temperature sensor" << device->params();
|
||||||
|
if (!m_oneWireInterface) { //in case the child was setup before the interface
|
||||||
|
double temperature = m_oneWireInterface->getTemperature(device->paramValue(temperatureSensorDeviceAddressParamTypeId).toByteArray());
|
||||||
|
device->setStateValue(temperatureSensorTemperatureStateTypeId, temperature);
|
||||||
|
}
|
||||||
|
return Device::DeviceSetupStatusSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->deviceClassId() == iButtonDeviceClassId) {
|
||||||
|
qCDebug(dcOneWire) << "Setup one wire iButton" << device->params();
|
||||||
|
if (!m_oneWireInterface) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return Device::DeviceSetupStatusSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->deviceClassId() == switchDeviceClassId) {
|
||||||
|
qCDebug(dcOneWire) << "Setup one wire switch" << device->params();
|
||||||
|
if (!m_oneWireInterface) {
|
||||||
|
QByteArray address = device->paramValue(switchDeviceAddressParamTypeId).toByteArray();
|
||||||
|
device->setStateValue(switchDigitalOutputStateTypeId, m_oneWireInterface->getSwitchState(address));
|
||||||
|
}
|
||||||
|
return Device::DeviceSetupStatusSuccess;
|
||||||
|
}
|
||||||
|
return Device::DeviceSetupStatusFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
Device::DeviceError DevicePluginOneWire::executeAction(Device *device, const Action &action)
|
||||||
|
{
|
||||||
|
Q_UNUSED(action)
|
||||||
|
if (device->deviceClassId() == oneWireInterfaceDeviceClassId) {
|
||||||
|
if (action.actionTypeId() == oneWireInterfaceAutoAddActionTypeId){
|
||||||
|
device->setStateValue(oneWireInterfaceAutoAddStateTypeId, action.param(oneWireInterfaceAutoAddActionAutoAddParamTypeId).value());
|
||||||
|
return Device::DeviceErrorNoError;
|
||||||
|
}
|
||||||
|
return Device::DeviceErrorActionTypeNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->deviceClassId() == switchDeviceClassId) {
|
||||||
|
|
||||||
|
if (action.actionTypeId() == switchDigitalOutputActionTypeId){
|
||||||
|
m_oneWireInterface->setSwitchState(device->paramValue(switchDeviceAddressParamTypeId).toByteArray(), action.param(switchDigitalOutputActionDigitalOutputParamTypeId).value().toBool());
|
||||||
|
|
||||||
|
return Device::DeviceErrorNoError;
|
||||||
|
}
|
||||||
|
return Device::DeviceErrorActionTypeNotFound;
|
||||||
|
}
|
||||||
|
return Device::DeviceErrorNoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DevicePluginOneWire::deviceRemoved(Device *device)
|
||||||
|
{
|
||||||
|
if (device->deviceClassId() == oneWireInterfaceDeviceClassId) {
|
||||||
|
m_oneWireInterface->deleteLater();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myDevices().empty()) {
|
||||||
|
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DevicePluginOneWire::onPluginTimer()
|
||||||
|
{
|
||||||
|
foreach (Device *device, myDevices()) {
|
||||||
|
if (device->deviceClassId() == oneWireInterfaceDeviceClassId) {
|
||||||
|
device->setStateValue(oneWireInterfaceConnectedStateTypeId, m_oneWireInterface->interfaceIsAvailable());
|
||||||
|
|
||||||
|
if (device->stateValue(oneWireInterfaceAutoAddStateTypeId).toBool()) {
|
||||||
|
m_oneWireInterface->discoverDevices();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->deviceClassId() == temperatureSensorDeviceClassId) {
|
||||||
|
QByteArray address = device->paramValue(temperatureSensorDeviceAddressParamTypeId).toByteArray();
|
||||||
|
|
||||||
|
double temperature = m_oneWireInterface->getTemperature(address);
|
||||||
|
device->setStateValue(temperatureSensorTemperatureStateTypeId, temperature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginOneWire::onOneWireDevicesDiscovered(QList<OneWire::OneWireDevice> oneWireDevices)
|
||||||
|
{
|
||||||
|
foreach(Device *parentDevice, myDevices().filterByDeviceClassId(oneWireInterfaceDeviceClassId)) {
|
||||||
|
|
||||||
|
bool autoDiscoverEnabled = parentDevice->stateValue(oneWireInterfaceAutoAddStateTypeId).toBool();
|
||||||
|
QList<DeviceDescriptor> temperatureDeviceDescriptors;
|
||||||
|
foreach (OneWire::OneWireDevice oneWireDevice, oneWireDevices){
|
||||||
|
switch (oneWireDevice.family) {
|
||||||
|
//https://github.com/owfs/owfs-doc/wiki/1Wire-Device-List
|
||||||
|
case 0x10: //DS18S20
|
||||||
|
case 0x28: //DS18B20
|
||||||
|
case 0x3b: //DS1825, MAX31826, MAX31850
|
||||||
|
DeviceDescriptor descriptor(temperatureSensorDeviceClassId, oneWireDevice.type, "One wire temperature sensor", parentDevice->id());
|
||||||
|
ParamList params;
|
||||||
|
params.append(Param(temperatureSensorDeviceAddressParamTypeId, oneWireDevice.address));
|
||||||
|
params.append(Param(temperatureSensorDeviceTypeParamTypeId, oneWireDevice.type));
|
||||||
|
foreach (Device *existingDevice, myDevices().filterByDeviceClassId(temperatureSensorDeviceClassId)){
|
||||||
|
if (existingDevice->paramValue(temperatureSensorDeviceAddressParamTypeId).toString() == oneWireDevice.address) {
|
||||||
|
descriptor.setDeviceId(existingDevice->id());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
descriptor.setParams(params);
|
||||||
|
temperatureDeviceDescriptors.append(descriptor);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (autoDiscoverEnabled) {
|
||||||
|
if (!temperatureDeviceDescriptors.isEmpty())
|
||||||
|
emit autoDevicesAppeared(temperatureSensorDeviceClassId, temperatureDeviceDescriptors);
|
||||||
|
} else {
|
||||||
|
if (!temperatureDeviceDescriptors.isEmpty())
|
||||||
|
emit devicesDiscovered(temperatureSensorDeviceClassId, temperatureDeviceDescriptors);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* foreach(QByteArray member, dirMembers) {
|
||||||
|
int family = member.split('.').first().toInt(nullptr, 16);
|
||||||
|
qDebug(dcOneWire()) << "Member" << member << member.left(2) << family;
|
||||||
|
member.remove(member.indexOf('/'), 1);
|
||||||
|
QByteArray type;
|
||||||
|
switch (family) {
|
||||||
|
//https://github.com/owfs/owfs-doc/wiki/1Wire-Device-List
|
||||||
|
case 0x10: //DS18S20
|
||||||
|
case 0x28: //DS18B20
|
||||||
|
case 0x3b: //DS1825, MAX31826, MAX31850
|
||||||
|
OneWireDevice device;
|
||||||
|
device.family =family;
|
||||||
|
device.Address = member.split('.').last();
|
||||||
|
device.Type = getValue(member, "type");
|
||||||
|
oneWireDevices.append(device);
|
||||||
|
qDebug(dcOneWire()) << "Discovered temperature sensor" << type << member;
|
||||||
|
break;
|
||||||
|
case 0x05:
|
||||||
|
case 0x12:
|
||||||
|
case 0x1C:
|
||||||
|
case 0x3A:
|
||||||
|
OneWireDevice device;
|
||||||
|
device.family =family;
|
||||||
|
device.Address = member.split('.').last();
|
||||||
|
device.Type = getValue(member, "type");
|
||||||
|
oneWireDevices.append(device);
|
||||||
|
qDebug(dcOneWire()) << "Discovered temperature sensor" << type << member;
|
||||||
|
qDebug(dcOneWire()) << "Discovered switch" << type << member;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x08: //DS1992 1kbit Memory iButton
|
||||||
|
case 0x06: //DS1993 4kbit Memory iButton
|
||||||
|
case 0x0A: //DS1995 16kbit Memory iButton
|
||||||
|
case 0x0C: //DS1996 64kbit Memory iButton
|
||||||
|
type = getValue(member, "type");
|
||||||
|
qDebug(dcOneWire()) << "Discovered ID device" << type << member;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//type = getValue(member, "type");
|
||||||
|
//qDebug(dcOneWire()) << "Discovered unknown " << type << member;
|
||||||
|
//emit unknownDeviceDiscovered(member, type);
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!oneWireDevices.isEmpty*/
|
||||||
56
onewire/devicepluginonewire.h
Normal file
56
onewire/devicepluginonewire.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* *
|
||||||
|
* Copyright (C) 2018 Bernhard Trinnes <bernhard.trinnes@guh.io> *
|
||||||
|
* *
|
||||||
|
* This file is part of nymea. *
|
||||||
|
* *
|
||||||
|
* This library is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU Lesser General Public *
|
||||||
|
* License as published by the Free Software Foundation; either *
|
||||||
|
* version 2.1 of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This library 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 library; If not, see *
|
||||||
|
* <http://www.gnu.org/licenses/>. *
|
||||||
|
* *
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef DEVICEPLUGINONEWIRE_H
|
||||||
|
#define DEVICEPLUGINONEWIRE_H
|
||||||
|
|
||||||
|
#include "plugintimer.h"
|
||||||
|
#include "devices/deviceplugin.h"
|
||||||
|
#include "onewire.h"
|
||||||
|
|
||||||
|
#include <QHash>
|
||||||
|
|
||||||
|
class DevicePluginOneWire : public DevicePlugin
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PLUGIN_METADATA(IID "io.nymea.DevicePlugin" FILE "devicepluginonewire.json")
|
||||||
|
Q_INTERFACES(DevicePlugin)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DevicePluginOneWire();
|
||||||
|
|
||||||
|
Device::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override;
|
||||||
|
Device::DeviceSetupStatus setupDevice(Device *device) override;
|
||||||
|
Device::DeviceError executeAction(Device *device, const Action &action) override;
|
||||||
|
void deviceRemoved(Device *device) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
PluginTimer *m_pluginTimer = nullptr;
|
||||||
|
OneWire *m_oneWireInterface = nullptr;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onPluginTimer();
|
||||||
|
|
||||||
|
void onOneWireDevicesDiscovered(QList<OneWire::OneWireDevice> devices);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DEVICEPLUGINONEWIRE_H
|
||||||
155
onewire/devicepluginonewire.json
Normal file
155
onewire/devicepluginonewire.json
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
{
|
||||||
|
"displayName": "One Wire",
|
||||||
|
"name": "OneWire",
|
||||||
|
"id": "2c697fb7-0645-466d-9cb9-aa1922c85bee",
|
||||||
|
"vendors": [
|
||||||
|
{
|
||||||
|
"displayName": "One wire",
|
||||||
|
"name": "oneWire",
|
||||||
|
"id": "cecc5fae-29cf-40c0-b1f8-0af2dc8e8a63",
|
||||||
|
"deviceClasses": [
|
||||||
|
{
|
||||||
|
"id": "c36c68d9-6182-4ae1-972d-b8b5e0cf185f",
|
||||||
|
"name": "oneWireInterface",
|
||||||
|
"displayName": "One wire interface",
|
||||||
|
"interfaces": ["connectable"],
|
||||||
|
"createMethods": ["user"],
|
||||||
|
"paramTypes": [
|
||||||
|
{
|
||||||
|
"id": "a0e773ff-fd19-499e-96f0-830168229cd3",
|
||||||
|
"name": "path",
|
||||||
|
"displayName": "Path",
|
||||||
|
"type": "QString",
|
||||||
|
"defaultValue": "/dev/ttyS0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateTypes": [
|
||||||
|
{
|
||||||
|
"id": "d0ded173-c382-4ee3-8e24-3647b4e16afa",
|
||||||
|
"name": "connected",
|
||||||
|
"displayName": "connected",
|
||||||
|
"displayNameEvent": "connected changed",
|
||||||
|
"defaultValue": false,
|
||||||
|
"type": "bool"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "64baf50e-8ed4-4526-8b92-7e4662d6fa39",
|
||||||
|
"name": "autoAdd",
|
||||||
|
"displayName": "Auto add one wire devices",
|
||||||
|
"displayNameAction": "Set auto add mode",
|
||||||
|
"displayNameEvent": "Auto add one wire devices changed",
|
||||||
|
"defaultValue": false,
|
||||||
|
"type": "bool",
|
||||||
|
"writable": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "e13beb24-953c-48b3-9262-7cde31d42ef5",
|
||||||
|
"name": "temperatureSensor",
|
||||||
|
"displayName": "Temperature Sensor",
|
||||||
|
"interfaces": ["temperaturesensor"],
|
||||||
|
"createMethods": ["discovery"],
|
||||||
|
"paramTypes": [
|
||||||
|
{
|
||||||
|
"id": "b4368f34-d9bb-496f-84ba-091bd4b6a332",
|
||||||
|
"name": "address",
|
||||||
|
"displayName": "Address",
|
||||||
|
"type": "QString",
|
||||||
|
"readOnly": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5005822d-6a32-4bb8-9b77-f79da7382f76",
|
||||||
|
"name": "type",
|
||||||
|
"displayName": "Type",
|
||||||
|
"type": "QString",
|
||||||
|
"inputType": "TextLine",
|
||||||
|
"readOnly": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateTypes": [
|
||||||
|
{
|
||||||
|
"id": "b04ee2a5-9b27-4ffc-9e12-7e05f5a41690",
|
||||||
|
"name": "temperature",
|
||||||
|
"displayName": "temperature",
|
||||||
|
"displayNameEvent": "temperature changed",
|
||||||
|
"unit": "DegreeCelsius",
|
||||||
|
"type": "double",
|
||||||
|
"defaultValue": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "71691119-3bda-4424-b853-1a00f21086e1",
|
||||||
|
"name": "switch",
|
||||||
|
"displayName": "Switch",
|
||||||
|
"interfaces": [ ],
|
||||||
|
"createMethods": ["discovery"],
|
||||||
|
"paramTypes": [
|
||||||
|
{
|
||||||
|
"id": "e3e6e596-0cd4-42a3-8401-ccf6349314b7",
|
||||||
|
"name": "address",
|
||||||
|
"displayName": "Address",
|
||||||
|
"type": "QString",
|
||||||
|
"readOnly": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "34c8f771-4141-4183-9eaf-becbaf362ac8",
|
||||||
|
"name": "type",
|
||||||
|
"displayName": "Type",
|
||||||
|
"type": "QString",
|
||||||
|
"inputType": "TextLine",
|
||||||
|
"readOnly": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateTypes": [
|
||||||
|
{
|
||||||
|
"id": "78fa12c0-246c-4112-8be6-5943d3c3cda5",
|
||||||
|
"name": "digitalOutput",
|
||||||
|
"displayName": "Digital output",
|
||||||
|
"displayNameEvent": "Digital output changed",
|
||||||
|
"displayNameAction": "Set digital output",
|
||||||
|
"type": "bool",
|
||||||
|
"defaultValue": false,
|
||||||
|
"writable": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "22aff41f-0f48-40f2-aa4e-bb251723be1c",
|
||||||
|
"name": "iButton",
|
||||||
|
"displayName": "iButton",
|
||||||
|
"interfaces": [ ],
|
||||||
|
"createMethods": ["discovery"],
|
||||||
|
"paramTypes": [
|
||||||
|
{
|
||||||
|
"id": "759e919c-8af2-43dd-af99-9b8c59321050",
|
||||||
|
"name": "address",
|
||||||
|
"displayName": "Address",
|
||||||
|
"type": "QString",
|
||||||
|
"readOnly": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5ca8d942-4ef2-47be-8ac9-be2ee19e168d",
|
||||||
|
"name": "type",
|
||||||
|
"displayName": "Type",
|
||||||
|
"type": "QString",
|
||||||
|
"inputType": "TextLine",
|
||||||
|
"readOnly": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateTypes": [
|
||||||
|
],
|
||||||
|
"eventTypes": [
|
||||||
|
{
|
||||||
|
|
||||||
|
"id": "61d69bec-c948-4703-9686-8762381d0ae4",
|
||||||
|
"name": "authenticated",
|
||||||
|
"displayName": "Authenticated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
188
onewire/onewire.cpp
Normal file
188
onewire/onewire.cpp
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* *
|
||||||
|
* Copyright (C) 2018 Bernhard Trinnes <bernhard.trinnes@guh.io> *
|
||||||
|
* *
|
||||||
|
* This file is part of nymea. *
|
||||||
|
* *
|
||||||
|
* This library is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU Lesser General Public *
|
||||||
|
* License as published by the Free Software Foundation; either *
|
||||||
|
* version 2.1 of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This library 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 library; If not, see *
|
||||||
|
* <http://www.gnu.org/licenses/>. *
|
||||||
|
* *
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "onewire.h"
|
||||||
|
#include "extern-plugininfo.h"
|
||||||
|
|
||||||
|
OneWire::OneWire(const QByteArray &deviceLocation, QObject *parent) :
|
||||||
|
QObject(parent),
|
||||||
|
m_deviceLocation(deviceLocation)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
OneWire::~OneWire()
|
||||||
|
{
|
||||||
|
OW_finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OneWire::init()
|
||||||
|
{
|
||||||
|
QByteArray initArguments;
|
||||||
|
initArguments.append("--fake 28 --fake 10");
|
||||||
|
if (OW_init(initArguments) < 0) {
|
||||||
|
qWarning(dcOneWire()) << "ERROR initialising one wire" << strerror(errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_path = "/";
|
||||||
|
|
||||||
|
/*QByteArray defaultPath = "/";
|
||||||
|
size_t dir_length ;
|
||||||
|
char *dir_buffer = nullptr;
|
||||||
|
if (OW_get(defaultPath, &dir_buffer, &dir_length) < 0) {
|
||||||
|
qWarning(dcOneWire()) << "ERROR initialising one wire" << strerror(errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_path = QByteArray(dir_buffer, dir_length);
|
||||||
|
if(m_path[0] != '/') {
|
||||||
|
m_path.prepend('/');
|
||||||
|
}
|
||||||
|
m_path.append('\0');
|
||||||
|
qDebug(dcOneWire()) << "Path:" << m_path;
|
||||||
|
free(dir_buffer);*/
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OneWire::discoverDevices()
|
||||||
|
{
|
||||||
|
char *dirBuffer = nullptr;
|
||||||
|
size_t dirLength ;
|
||||||
|
|
||||||
|
if (OW_get(m_path, &dirBuffer, &dirLength) < 0) {
|
||||||
|
qWarning(dcOneWire()) << "DIRECTORY ERROR" << strerror(errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
qDebug(dcOneWire()) << "Directory has members" << dirBuffer;
|
||||||
|
|
||||||
|
QList<QByteArray> dirMembers ;
|
||||||
|
dirMembers = QByteArray(dirBuffer, dirLength).split(',');
|
||||||
|
free(dirBuffer);
|
||||||
|
|
||||||
|
QList<OneWireDevice> oneWireDevices;
|
||||||
|
foreach(QByteArray member, dirMembers) {
|
||||||
|
int family = member.split('.').first().toInt(nullptr, 16);
|
||||||
|
if (family != 0) {
|
||||||
|
qDebug(dcOneWire()) << "Member" << member << member.left(2) << family;
|
||||||
|
member.remove(member.indexOf('/'), 1);
|
||||||
|
QByteArray type;
|
||||||
|
OneWireDevice device;
|
||||||
|
device.family = family;
|
||||||
|
device.address = member;
|
||||||
|
device.id = member.split('.').last();
|
||||||
|
device.type = getValue(member, "type");
|
||||||
|
oneWireDevices.append(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!oneWireDevices.isEmpty()) {
|
||||||
|
emit devicesDiscovered(oneWireDevices);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OneWire::interfaceIsAvailable()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OneWire::isConnected(const QByteArray &address)
|
||||||
|
{
|
||||||
|
Q_UNUSED(address)
|
||||||
|
QByteArray fullPath;
|
||||||
|
fullPath.append(m_path);
|
||||||
|
fullPath.append(address);
|
||||||
|
fullPath.append('\0');
|
||||||
|
if(OW_present(fullPath) < 0)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Takes a path and filename and prints the 1-wire value */
|
||||||
|
/* makes sure the bridging "/" in the path is correct */
|
||||||
|
/* watches for total length and free allocated space */
|
||||||
|
QByteArray OneWire::getValue(const QByteArray &address, const QByteArray &type)
|
||||||
|
{
|
||||||
|
char * getBuffer ;
|
||||||
|
size_t getLength ;
|
||||||
|
|
||||||
|
QByteArray devicePath;
|
||||||
|
devicePath.append(m_path);
|
||||||
|
if(!m_path.endsWith('/'))
|
||||||
|
devicePath.append('/');
|
||||||
|
devicePath.append(address);
|
||||||
|
devicePath.append('/');
|
||||||
|
devicePath.append(type);
|
||||||
|
devicePath.append('\0');
|
||||||
|
|
||||||
|
if (OW_get(devicePath, &getBuffer, &getLength) < 0) {
|
||||||
|
qWarning(dcOneWire()) << "ERROR reading" << devicePath << strerror(errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug(dcOneWire()) << "Device value" << devicePath << getBuffer;
|
||||||
|
|
||||||
|
QByteArray value = QByteArray(getBuffer, getLength);
|
||||||
|
free(getBuffer);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OneWire::setValue(const QByteArray &address, const QByteArray &deviceType, const QByteArray &value)
|
||||||
|
{
|
||||||
|
Q_UNUSED(address)
|
||||||
|
Q_UNUSED(deviceType)
|
||||||
|
Q_UNUSED(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
double OneWire::getTemperature(const QByteArray &address)
|
||||||
|
{
|
||||||
|
QByteArray temperature = getValue(address, "temperature");
|
||||||
|
qDebug(dcOneWire()) << "Temperature" << temperature << temperature.replace(',','.').toDouble();
|
||||||
|
return temperature.toDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray OneWire::readMemory(const QByteArray &address)
|
||||||
|
{
|
||||||
|
//getValue
|
||||||
|
return address; //TODDO
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray OneWire::getType(const QByteArray &address)
|
||||||
|
{
|
||||||
|
QByteArray type = getValue(address, "type");
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OneWire::getSwitchState(const QByteArray &address)
|
||||||
|
{
|
||||||
|
QByteArray state = getValue(address, "switch_state");
|
||||||
|
qDebug(dcOneWire()) << "Switch state" << state;
|
||||||
|
return 0; //TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void OneWire::setSwitchState(const QByteArray &address, bool state)
|
||||||
|
{
|
||||||
|
if (state) {
|
||||||
|
setValue(address, "switch_state", "TRUE");
|
||||||
|
} else {
|
||||||
|
setValue(address, "switch_state", "FALSE");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
76
onewire/onewire.h
Normal file
76
onewire/onewire.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* *
|
||||||
|
* Copyright (C) 2018 Bernhard Trinnes <bernhard.trinnes@guh.io> *
|
||||||
|
* *
|
||||||
|
* This file is part of nymea. *
|
||||||
|
* *
|
||||||
|
* This library is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU Lesser General Public *
|
||||||
|
* License as published by the Free Software Foundation; either *
|
||||||
|
* version 2.1 of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This library 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 library; If not, see *
|
||||||
|
* <http://www.gnu.org/licenses/>. *
|
||||||
|
* *
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef ONEWIRE_H
|
||||||
|
#define ONEWIRE_H
|
||||||
|
|
||||||
|
#include "owcapi.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class OneWire : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum OneWireProperty {
|
||||||
|
Address, //The entire 64-bit unique ID
|
||||||
|
Crc, //The 8-bit error correction
|
||||||
|
Family, //The 8-bit family code
|
||||||
|
Id, //The 48-bit middle portion of the unique ID number.
|
||||||
|
Locator, //Uses an extension of the 1-wire design from iButtonLink company that associated 1-wire physical connections with a unique 1-wire code.
|
||||||
|
Type //Part name assigned by Dallas Semi. E.g. DS2401
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OneWireDevice {
|
||||||
|
QByteArray address;
|
||||||
|
int family;
|
||||||
|
QByteArray id;
|
||||||
|
QByteArray type;
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit OneWire(const QByteArray &deviceLocation, QObject *parent = nullptr);
|
||||||
|
~OneWire();
|
||||||
|
bool init();
|
||||||
|
|
||||||
|
QByteArray getPath();
|
||||||
|
bool discoverDevices();
|
||||||
|
bool interfaceIsAvailable();
|
||||||
|
bool isConnected(const QByteArray &address);
|
||||||
|
|
||||||
|
double getTemperature(const QByteArray &address);
|
||||||
|
QByteArray getType(const QByteArray &address);
|
||||||
|
QByteArray readMemory(const QByteArray &address);
|
||||||
|
bool getSwitchState(const QByteArray &address);
|
||||||
|
void setSwitchState(const QByteArray &address, bool state);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
QByteArray m_deviceLocation;
|
||||||
|
QByteArray m_path;
|
||||||
|
QByteArray getValue(const QByteArray &address, const QByteArray &deviceType);
|
||||||
|
void setValue(const QByteArray &address, const QByteArray &deviceType, const QByteArray &value);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void devicesDiscovered(QList<OneWireDevice> devices);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ONEWIRE_H
|
||||||
17
onewire/onewire.pro
Normal file
17
onewire/onewire.pro
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
include(../plugins.pri)
|
||||||
|
|
||||||
|
TARGET = $$qtLibraryTarget(nymea_devicepluginonewire)
|
||||||
|
|
||||||
|
LIBS += \
|
||||||
|
-low \
|
||||||
|
-lowcapi \
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
devicepluginonewire.cpp \
|
||||||
|
onewire.cpp \
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
devicepluginonewire.h \
|
||||||
|
onewire.h \
|
||||||
|
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user