added w1 support for temperature sensors

This commit is contained in:
bernhard.trinnes 2020-08-19 17:27:41 +02:00
parent e26d38e155
commit fb4c09337d
7 changed files with 291 additions and 93 deletions

View File

@ -43,17 +43,55 @@ void IntegrationPluginOneWire::discoverThings(ThingDiscoveryInfo *info)
{ {
ThingClassId deviceClassId = info->thingClassId(); ThingClassId deviceClassId = info->thingClassId();
if (!m_w1Interface) {
m_w1Interface = new W1(this);
}
if (deviceClassId == temperatureSensorThingClassId || if (deviceClassId == temperatureSensorThingClassId ||
deviceClassId == singleChannelSwitchThingClassId || deviceClassId == singleChannelSwitchThingClassId ||
deviceClassId == dualChannelSwitchThingClassId || deviceClassId == dualChannelSwitchThingClassId ||
deviceClassId == eightChannelSwitchThingClassId) { deviceClassId == eightChannelSwitchThingClassId) {
if (myThings().filterByThingClassId(oneWireInterfaceThingClassId).isEmpty()) { if (myThings().filterByThingClassId(oneWireInterfaceThingClassId).isEmpty()) {
//No one wire interface intitialized if (!m_w1Interface->interfaceIsAvailable()) {
//: Error discovering one wire devices return info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("No one wire interface initialized. Please set up a one wire interface first."));
return info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("No one wire interface initialized. Please set up a one wire interface first.")); }
QStringList deviceList = m_w1Interface->discoverDevices();
Q_FOREACH(QString device, deviceList) {
if (device.startsWith("10") ||
device.startsWith("22") ||
device.startsWith("28") ||
device.startsWith("3B", Qt::CaseInsensitive)) {
QString type = "Unkown";
if (device.startsWith("10")) { //
type = "DS18S20";
} else if (device.startsWith("22")) { //
type = "DS1822";
} else if (device.startsWith("28")) { //
type = "DS18B20";
} else if (device.startsWith("3B", Qt::CaseInsensitive)) { //DS1825
type = "DS1825";
}
ThingDescriptor descriptor(temperatureSensorThingClassId, type, "One wire temperature sensor");
ParamList params;
params.append(Param(temperatureSensorThingAddressParamTypeId, device));
params.append(Param(temperatureSensorThingTypeParamTypeId, type));
foreach (Thing *existingThing, myThings().filterByThingClassId(temperatureSensorThingClassId)){
if (existingThing->paramValue(temperatureSensorThingAddressParamTypeId).toString() == device) {
descriptor.setThingId(existingThing->id());
break;
}
}
descriptor.setParams(params);
info->addThingDescriptor(descriptor);
}
}
return info->finish(Thing::ThingErrorNoError);
} }
foreach(Thing *parentDevice, myThings().filterByThingClassId(oneWireInterfaceThingClassId)) { foreach(Thing *parentDevice, myThings().filterByThingClassId(oneWireInterfaceThingClassId)) {
if (parentDevice->stateValue(oneWireInterfaceAutoAddStateTypeId).toBool()) { if (parentDevice->stateValue(oneWireInterfaceAutoAddStateTypeId).toBool()) {
//devices cannot be discovered since auto mode is enabled //devices cannot be discovered since auto mode is enabled
@ -64,18 +102,18 @@ void IntegrationPluginOneWire::discoverThings(ThingDiscoveryInfo *info)
m_runningDiscoveries.remove(parentDevice); m_runningDiscoveries.remove(parentDevice);
}); });
if (m_oneWireInterface) if (m_owfsInterface)
m_oneWireInterface->discoverDevices(); m_owfsInterface->discoverDevices();
} }
if (m_runningDiscoveries.isEmpty()) { if (m_runningDiscoveries.isEmpty()) {
info->finish(Thing::ThingErrorNoError, QT_TR_NOOP("All configured one wire interfaces are set up to automatically add new devices.")); info->finish(Thing::ThingErrorNoError, QT_TR_NOOP("All configured one wire interfaces are set up to automatically add new devices."));
} }
return; return;
} else {
qCWarning(dcOneWire()) << "Discovery called for a deviceclass which does not support discovery? Device class ID:" << info->thingClassId().toString();
info->finish(Thing::ThingErrorThingClassNotFound);
} }
qCWarning(dcOneWire()) << "Discovery called for a deviceclass which does not support discovery? Device class ID:" << info->thingClassId().toString();
info->finish(Thing::ThingErrorThingClassNotFound);
} }
@ -85,65 +123,71 @@ void IntegrationPluginOneWire::setupThing(ThingSetupInfo *info)
if (thing->thingClassId() == oneWireInterfaceThingClassId) { if (thing->thingClassId() == oneWireInterfaceThingClassId) {
qCDebug(dcOneWire) << "Setup one wire interface"; qCDebug(dcOneWire) << "Setup one wire interface";
if (m_oneWireInterface) { if (m_owfsInterface) {
qCWarning(dcOneWire) << "One wire interface already set up"; qCWarning(dcOneWire) << "One wire interface already set up";
//: Error setting up thing //: Error setting up thing
return info->finish(Thing::ThingErrorThingInUse, QT_TR_NOOP("There can only be one one wire interface per system.")); return info->finish(Thing::ThingErrorThingInUse, QT_TR_NOOP("There can only be one one wire interface per system."));
} }
m_oneWireInterface = new OneWire(this); m_owfsInterface = new Owfs(this);
QByteArray initArguments = thing->paramValue(oneWireInterfaceThingInitArgsParamTypeId).toByteArray(); QByteArray initArguments = thing->paramValue(oneWireInterfaceThingInitArgsParamTypeId).toByteArray();
if (!m_oneWireInterface->init(initArguments)){ if (!m_owfsInterface->init(initArguments)){
m_oneWireInterface->deleteLater(); m_owfsInterface->deleteLater();
m_oneWireInterface = nullptr; m_owfsInterface = nullptr;
//: Error setting up thing //: Error setting up thing
return info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("Error initializing one wire interface.")); return info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("Error initializing one wire interface."));
} }
connect(m_oneWireInterface, &OneWire::devicesDiscovered, this, &IntegrationPluginOneWire::onOneWireDevicesDiscovered); connect(m_owfsInterface, &Owfs::devicesDiscovered, this, &IntegrationPluginOneWire::onOneWireDevicesDiscovered);
return info->finish(Thing::ThingErrorNoError); return info->finish(Thing::ThingErrorNoError);
} }
if (thing->thingClassId() == temperatureSensorThingClassId) { if (thing->thingClassId() == temperatureSensorThingClassId) {
qCDebug(dcOneWire) << "Setup one wire temperature sensor" << thing->params(); qCDebug(dcOneWire) << "Setup one wire temperature sensor" << thing->params();
if (!m_oneWireInterface) { //in case the child was setup before the interface if (m_owfsInterface) { //in case the child was setup before the interface
double temperature = m_oneWireInterface->getTemperature(thing->paramValue(temperatureSensorThingAddressParamTypeId).toByteArray()); double temperature = m_owfsInterface->getTemperature(thing->paramValue(temperatureSensorThingAddressParamTypeId).toByteArray());
thing->setStateValue(temperatureSensorTemperatureStateTypeId, temperature); thing->setStateValue(temperatureSensorTemperatureStateTypeId, temperature);
return info->finish(Thing::ThingErrorNoError);
} else if (m_w1Interface) {
double temperature = m_w1Interface->getTemperature(thing->paramValue(temperatureSensorThingAddressParamTypeId).toByteArray());
thing->setStateValue(temperatureSensorTemperatureStateTypeId, temperature);
return info->finish(Thing::ThingErrorNoError);
} else {
return info->finish(Thing::ThingErrorHardwareNotAvailable, tr("No 1-Wire interface available"));
} }
return info->finish(Thing::ThingErrorNoError);
} }
if (thing->thingClassId() == singleChannelSwitchThingClassId) { if (thing->thingClassId() == singleChannelSwitchThingClassId) {
qCDebug(dcOneWire) << "Setup one wire switch" << thing->params(); qCDebug(dcOneWire) << "Setup one wire switch" << thing->params();
if (!m_oneWireInterface) { if (!m_owfsInterface) {
QByteArray address = thing->paramValue(singleChannelSwitchThingAddressParamTypeId).toByteArray(); QByteArray address = thing->paramValue(singleChannelSwitchThingAddressParamTypeId).toByteArray();
thing->setStateValue(singleChannelSwitchDigitalOutputStateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_A)); thing->setStateValue(singleChannelSwitchDigitalOutputStateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_A));
} }
return info->finish(Thing::ThingErrorNoError); return info->finish(Thing::ThingErrorNoError);
} }
if (thing->thingClassId() == dualChannelSwitchThingClassId) { if (thing->thingClassId() == dualChannelSwitchThingClassId) {
qCDebug(dcOneWire) << "Setup one wire dual switch" << thing->params(); qCDebug(dcOneWire) << "Setup one wire dual switch" << thing->params();
if (!m_oneWireInterface) { if (!m_owfsInterface) {
QByteArray address = thing->paramValue(dualChannelSwitchThingAddressParamTypeId).toByteArray(); QByteArray address = thing->paramValue(dualChannelSwitchThingAddressParamTypeId).toByteArray();
thing->setStateValue(dualChannelSwitchDigitalOutput1StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_A)); thing->setStateValue(dualChannelSwitchDigitalOutput1StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_A));
thing->setStateValue(dualChannelSwitchDigitalOutput2StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_B)); thing->setStateValue(dualChannelSwitchDigitalOutput2StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_B));
} }
return info->finish(Thing::ThingErrorNoError); return info->finish(Thing::ThingErrorNoError);
} }
if (thing->thingClassId() == eightChannelSwitchThingClassId) { if (thing->thingClassId() == eightChannelSwitchThingClassId) {
qCDebug(dcOneWire) << "Setup one wire eight channel switch" << thing->params(); qCDebug(dcOneWire) << "Setup one wire eight channel switch" << thing->params();
if (!m_oneWireInterface) { if (!m_owfsInterface) {
QByteArray address = thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray(); QByteArray address = thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray();
thing->setStateValue(eightChannelSwitchDigitalOutput1StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_A)); thing->setStateValue(eightChannelSwitchDigitalOutput1StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_A));
thing->setStateValue(eightChannelSwitchDigitalOutput2StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_B)); thing->setStateValue(eightChannelSwitchDigitalOutput2StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_B));
thing->setStateValue(eightChannelSwitchDigitalOutput3StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_C)); thing->setStateValue(eightChannelSwitchDigitalOutput3StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_C));
thing->setStateValue(eightChannelSwitchDigitalOutput4StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_D)); thing->setStateValue(eightChannelSwitchDigitalOutput4StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_D));
thing->setStateValue(eightChannelSwitchDigitalOutput5StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_E)); thing->setStateValue(eightChannelSwitchDigitalOutput5StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_E));
thing->setStateValue(eightChannelSwitchDigitalOutput6StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_F)); thing->setStateValue(eightChannelSwitchDigitalOutput6StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_F));
thing->setStateValue(eightChannelSwitchDigitalOutput7StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_G)); thing->setStateValue(eightChannelSwitchDigitalOutput7StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_G));
thing->setStateValue(eightChannelSwitchDigitalOutput8StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_H)); thing->setStateValue(eightChannelSwitchDigitalOutput8StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_H));
} }
return info->finish(Thing::ThingErrorNoError); return info->finish(Thing::ThingErrorNoError);
} }
@ -175,7 +219,7 @@ void IntegrationPluginOneWire::executeAction(ThingActionInfo *info)
if (thing->thingClassId() == singleChannelSwitchThingClassId) { if (thing->thingClassId() == singleChannelSwitchThingClassId) {
if (action.actionTypeId() == singleChannelSwitchDigitalOutputActionTypeId){ if (action.actionTypeId() == singleChannelSwitchDigitalOutputActionTypeId){
m_oneWireInterface->setSwitchOutput(thing->paramValue(singleChannelSwitchThingAddressParamTypeId).toByteArray(), OneWire::SwitchChannel::PIO_A, action.param(singleChannelSwitchDigitalOutputActionDigitalOutputParamTypeId).value().toBool()); m_owfsInterface->setSwitchOutput(thing->paramValue(singleChannelSwitchThingAddressParamTypeId).toByteArray(), Owfs::SwitchChannel::PIO_A, action.param(singleChannelSwitchDigitalOutputActionDigitalOutputParamTypeId).value().toBool());
return info->finish(Thing::ThingErrorNoError); return info->finish(Thing::ThingErrorNoError);
} }
@ -184,11 +228,11 @@ void IntegrationPluginOneWire::executeAction(ThingActionInfo *info)
if (thing->thingClassId() == dualChannelSwitchThingClassId) { if (thing->thingClassId() == dualChannelSwitchThingClassId) {
if (action.actionTypeId() == dualChannelSwitchDigitalOutput1ActionTypeId){ if (action.actionTypeId() == dualChannelSwitchDigitalOutput1ActionTypeId){
m_oneWireInterface->setSwitchOutput(thing->paramValue(dualChannelSwitchThingAddressParamTypeId).toByteArray(), OneWire::SwitchChannel::PIO_A, action.param(dualChannelSwitchDigitalOutput1ActionDigitalOutput1ParamTypeId).value().toBool()); m_owfsInterface->setSwitchOutput(thing->paramValue(dualChannelSwitchThingAddressParamTypeId).toByteArray(), Owfs::SwitchChannel::PIO_A, action.param(dualChannelSwitchDigitalOutput1ActionDigitalOutput1ParamTypeId).value().toBool());
return info->finish(Thing::ThingErrorNoError); return info->finish(Thing::ThingErrorNoError);
} }
if (action.actionTypeId() == dualChannelSwitchDigitalOutput2ActionTypeId){ if (action.actionTypeId() == dualChannelSwitchDigitalOutput2ActionTypeId){
m_oneWireInterface->setSwitchOutput(thing->paramValue(dualChannelSwitchThingAddressParamTypeId).toByteArray(), OneWire::SwitchChannel::PIO_B, action.param(dualChannelSwitchDigitalOutput2ActionDigitalOutput2ParamTypeId).value().toBool()); m_owfsInterface->setSwitchOutput(thing->paramValue(dualChannelSwitchThingAddressParamTypeId).toByteArray(), Owfs::SwitchChannel::PIO_B, action.param(dualChannelSwitchDigitalOutput2ActionDigitalOutput2ParamTypeId).value().toBool());
return info->finish(Thing::ThingErrorNoError); return info->finish(Thing::ThingErrorNoError);
} }
return info->finish(Thing::ThingErrorActionTypeNotFound); return info->finish(Thing::ThingErrorActionTypeNotFound);
@ -196,35 +240,35 @@ void IntegrationPluginOneWire::executeAction(ThingActionInfo *info)
if (thing->thingClassId() == eightChannelSwitchThingClassId) { if (thing->thingClassId() == eightChannelSwitchThingClassId) {
if (action.actionTypeId() == eightChannelSwitchDigitalOutput1ActionTypeId){ if (action.actionTypeId() == eightChannelSwitchDigitalOutput1ActionTypeId){
m_oneWireInterface->setSwitchOutput(thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray(), OneWire::SwitchChannel::PIO_A, action.param(eightChannelSwitchDigitalOutput1ActionDigitalOutput1ParamTypeId).value().toBool()); m_owfsInterface->setSwitchOutput(thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray(), Owfs::SwitchChannel::PIO_A, action.param(eightChannelSwitchDigitalOutput1ActionDigitalOutput1ParamTypeId).value().toBool());
return info->finish(Thing::ThingErrorNoError); return info->finish(Thing::ThingErrorNoError);
} }
if (action.actionTypeId() == eightChannelSwitchDigitalOutput2ActionTypeId){ if (action.actionTypeId() == eightChannelSwitchDigitalOutput2ActionTypeId){
m_oneWireInterface->setSwitchOutput(thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray(), OneWire::SwitchChannel::PIO_B, action.param(eightChannelSwitchDigitalOutput2ActionDigitalOutput2ParamTypeId).value().toBool()); m_owfsInterface->setSwitchOutput(thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray(), Owfs::SwitchChannel::PIO_B, action.param(eightChannelSwitchDigitalOutput2ActionDigitalOutput2ParamTypeId).value().toBool());
return info->finish(Thing::ThingErrorNoError); return info->finish(Thing::ThingErrorNoError);
} }
if (action.actionTypeId() == eightChannelSwitchDigitalOutput3ActionTypeId){ if (action.actionTypeId() == eightChannelSwitchDigitalOutput3ActionTypeId){
m_oneWireInterface->setSwitchOutput(thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray(), OneWire::SwitchChannel::PIO_C, action.param(eightChannelSwitchDigitalOutput3ActionDigitalOutput3ParamTypeId).value().toBool()); m_owfsInterface->setSwitchOutput(thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray(), Owfs::SwitchChannel::PIO_C, action.param(eightChannelSwitchDigitalOutput3ActionDigitalOutput3ParamTypeId).value().toBool());
return info->finish(Thing::ThingErrorNoError); return info->finish(Thing::ThingErrorNoError);
} }
if (action.actionTypeId() == eightChannelSwitchDigitalOutput4ActionTypeId){ if (action.actionTypeId() == eightChannelSwitchDigitalOutput4ActionTypeId){
m_oneWireInterface->setSwitchOutput(thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray(), OneWire::SwitchChannel::PIO_D, action.param(eightChannelSwitchDigitalOutput4ActionDigitalOutput4ParamTypeId).value().toBool()); m_owfsInterface->setSwitchOutput(thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray(), Owfs::SwitchChannel::PIO_D, action.param(eightChannelSwitchDigitalOutput4ActionDigitalOutput4ParamTypeId).value().toBool());
return info->finish(Thing::ThingErrorNoError); return info->finish(Thing::ThingErrorNoError);
} }
if (action.actionTypeId() == eightChannelSwitchDigitalOutput5ActionTypeId){ if (action.actionTypeId() == eightChannelSwitchDigitalOutput5ActionTypeId){
m_oneWireInterface->setSwitchOutput(thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray(), OneWire::SwitchChannel::PIO_E, action.param(eightChannelSwitchDigitalOutput5ActionDigitalOutput5ParamTypeId).value().toBool()); m_owfsInterface->setSwitchOutput(thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray(), Owfs::SwitchChannel::PIO_E, action.param(eightChannelSwitchDigitalOutput5ActionDigitalOutput5ParamTypeId).value().toBool());
return info->finish(Thing::ThingErrorNoError); return info->finish(Thing::ThingErrorNoError);
} }
if (action.actionTypeId() == eightChannelSwitchDigitalOutput6ActionTypeId){ if (action.actionTypeId() == eightChannelSwitchDigitalOutput6ActionTypeId){
m_oneWireInterface->setSwitchOutput(thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray(), OneWire::SwitchChannel::PIO_F, action.param(eightChannelSwitchDigitalOutput6ActionDigitalOutput6ParamTypeId).value().toBool()); m_owfsInterface->setSwitchOutput(thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray(), Owfs::SwitchChannel::PIO_F, action.param(eightChannelSwitchDigitalOutput6ActionDigitalOutput6ParamTypeId).value().toBool());
return info->finish(Thing::ThingErrorNoError); return info->finish(Thing::ThingErrorNoError);
} }
if (action.actionTypeId() == eightChannelSwitchDigitalOutput7ActionTypeId){ if (action.actionTypeId() == eightChannelSwitchDigitalOutput7ActionTypeId){
m_oneWireInterface->setSwitchOutput(thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray(), OneWire::SwitchChannel::PIO_G, action.param(eightChannelSwitchDigitalOutput7ActionDigitalOutput7ParamTypeId).value().toBool()); m_owfsInterface->setSwitchOutput(thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray(), Owfs::SwitchChannel::PIO_G, action.param(eightChannelSwitchDigitalOutput7ActionDigitalOutput7ParamTypeId).value().toBool());
return info->finish(Thing::ThingErrorNoError); return info->finish(Thing::ThingErrorNoError);
} }
if (action.actionTypeId() == eightChannelSwitchDigitalOutput8ActionTypeId){ if (action.actionTypeId() == eightChannelSwitchDigitalOutput8ActionTypeId){
m_oneWireInterface->setSwitchOutput(thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray(), OneWire::SwitchChannel::PIO_H, action.param(eightChannelSwitchDigitalOutput8ActionDigitalOutput8ParamTypeId).value().toBool()); m_owfsInterface->setSwitchOutput(thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray(), Owfs::SwitchChannel::PIO_H, action.param(eightChannelSwitchDigitalOutput8ActionDigitalOutput8ParamTypeId).value().toBool());
return info->finish(Thing::ThingErrorNoError); return info->finish(Thing::ThingErrorNoError);
} }
return info->finish(Thing::ThingErrorActionTypeNotFound); return info->finish(Thing::ThingErrorActionTypeNotFound);
@ -236,8 +280,8 @@ void IntegrationPluginOneWire::executeAction(ThingActionInfo *info)
void IntegrationPluginOneWire::thingRemoved(Thing *thing) void IntegrationPluginOneWire::thingRemoved(Thing *thing)
{ {
if (thing->thingClassId() == oneWireInterfaceThingClassId) { if (thing->thingClassId() == oneWireInterfaceThingClassId) {
m_oneWireInterface->deleteLater(); m_owfsInterface->deleteLater();
m_oneWireInterface = nullptr; m_owfsInterface = nullptr;
return; return;
} }
@ -252,52 +296,52 @@ void IntegrationPluginOneWire::onPluginTimer()
{ {
foreach (Thing *thing, myThings()) { foreach (Thing *thing, myThings()) {
if (thing->thingClassId() == oneWireInterfaceThingClassId) { if (thing->thingClassId() == oneWireInterfaceThingClassId) {
thing->setStateValue(oneWireInterfaceConnectedStateTypeId, m_oneWireInterface->interfaceIsAvailable()); thing->setStateValue(oneWireInterfaceConnectedStateTypeId, m_owfsInterface->interfaceIsAvailable());
if (thing->stateValue(oneWireInterfaceAutoAddStateTypeId).toBool()) { if (thing->stateValue(oneWireInterfaceAutoAddStateTypeId).toBool()) {
m_oneWireInterface->discoverDevices(); m_owfsInterface->discoverDevices();
} }
} }
if (thing->thingClassId() == temperatureSensorThingClassId) { if (thing->thingClassId() == temperatureSensorThingClassId) {
QByteArray address = thing->paramValue(temperatureSensorThingAddressParamTypeId).toByteArray(); QByteArray address = thing->paramValue(temperatureSensorThingAddressParamTypeId).toByteArray();
double temperature = m_oneWireInterface->getTemperature(address); double temperature = m_owfsInterface->getTemperature(address);
thing->setStateValue(temperatureSensorTemperatureStateTypeId, temperature); thing->setStateValue(temperatureSensorTemperatureStateTypeId, temperature);
} }
if (thing->thingClassId() == singleChannelSwitchThingClassId) { if (thing->thingClassId() == singleChannelSwitchThingClassId) {
QByteArray address = thing->paramValue(singleChannelSwitchThingAddressParamTypeId).toByteArray(); QByteArray address = thing->paramValue(singleChannelSwitchThingAddressParamTypeId).toByteArray();
thing->setStateValue(singleChannelSwitchDigitalOutputStateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_A)); thing->setStateValue(singleChannelSwitchDigitalOutputStateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_A));
} }
if (thing->thingClassId() == dualChannelSwitchThingClassId) { if (thing->thingClassId() == dualChannelSwitchThingClassId) {
QByteArray address = thing->paramValue(dualChannelSwitchThingAddressParamTypeId).toByteArray(); QByteArray address = thing->paramValue(dualChannelSwitchThingAddressParamTypeId).toByteArray();
thing->setStateValue(dualChannelSwitchDigitalOutput1StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_A)); thing->setStateValue(dualChannelSwitchDigitalOutput1StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_A));
thing->setStateValue(dualChannelSwitchDigitalOutput2StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_B)); thing->setStateValue(dualChannelSwitchDigitalOutput2StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_B));
} }
if (thing->thingClassId() == eightChannelSwitchThingClassId) { if (thing->thingClassId() == eightChannelSwitchThingClassId) {
QByteArray address = thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray(); QByteArray address = thing->paramValue(eightChannelSwitchThingAddressParamTypeId).toByteArray();
thing->setStateValue(eightChannelSwitchDigitalOutput1StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_A)); thing->setStateValue(eightChannelSwitchDigitalOutput1StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_A));
thing->setStateValue(eightChannelSwitchDigitalOutput2StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_B)); thing->setStateValue(eightChannelSwitchDigitalOutput2StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_B));
thing->setStateValue(eightChannelSwitchDigitalOutput3StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_C)); thing->setStateValue(eightChannelSwitchDigitalOutput3StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_C));
thing->setStateValue(eightChannelSwitchDigitalOutput4StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_D)); thing->setStateValue(eightChannelSwitchDigitalOutput4StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_D));
thing->setStateValue(eightChannelSwitchDigitalOutput5StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_E)); thing->setStateValue(eightChannelSwitchDigitalOutput5StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_E));
thing->setStateValue(eightChannelSwitchDigitalOutput6StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_F)); thing->setStateValue(eightChannelSwitchDigitalOutput6StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_F));
thing->setStateValue(eightChannelSwitchDigitalOutput7StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_G)); thing->setStateValue(eightChannelSwitchDigitalOutput7StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_G));
thing->setStateValue(eightChannelSwitchDigitalOutput8StateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_H)); thing->setStateValue(eightChannelSwitchDigitalOutput8StateTypeId, m_owfsInterface->getSwitchOutput(address, Owfs::SwitchChannel::PIO_H));
} }
} }
} }
void IntegrationPluginOneWire::onOneWireDevicesDiscovered(QList<OneWire::OneWireDevice> oneWireDevices) void IntegrationPluginOneWire::onOneWireDevicesDiscovered(QList<Owfs::OwfsDevice> oneWireDevices)
{ {
foreach(Thing *parentDevice, myThings().filterByThingClassId(oneWireInterfaceThingClassId)) { foreach(Thing *parentDevice, myThings().filterByThingClassId(oneWireInterfaceThingClassId)) {
bool autoDiscoverEnabled = parentDevice->stateValue(oneWireInterfaceAutoAddStateTypeId).toBool(); bool autoDiscoverEnabled = parentDevice->stateValue(oneWireInterfaceAutoAddStateTypeId).toBool();
ThingDescriptors descriptors; ThingDescriptors descriptors;
foreach (OneWire::OneWireDevice oneWireDevice, oneWireDevices){ foreach (Owfs::OwfsDevice oneWireDevice, oneWireDevices){
switch (oneWireDevice.family) { switch (oneWireDevice.family) {
//https://github.com/owfs/owfs-doc/wiki/1Wire-Device-List //https://github.com/owfs/owfs-doc/wiki/1Wire-Device-List
case 0x10: //DS18S20 case 0x10: //DS18S20

View File

@ -33,7 +33,8 @@
#include "plugintimer.h" #include "plugintimer.h"
#include "integrations/integrationplugin.h" #include "integrations/integrationplugin.h"
#include "onewire.h" #include "owfs.h"
#include "w1.h"
#include <QHash> #include <QHash>
@ -54,13 +55,14 @@ public:
private: private:
PluginTimer *m_pluginTimer = nullptr; PluginTimer *m_pluginTimer = nullptr;
OneWire *m_oneWireInterface = nullptr; Owfs *m_owfsInterface = nullptr;
W1 *m_w1Interface = nullptr;
QHash<Thing*, ThingDiscoveryInfo*> m_runningDiscoveries; QHash<Thing*, ThingDiscoveryInfo*> m_runningDiscoveries;
private slots: private slots:
void onPluginTimer(); void onPluginTimer();
void onOneWireDevicesDiscovered(QList<OneWire::OneWireDevice> devices); void onOneWireDevicesDiscovered(QList<Owfs::OwfsDevice> devices);
}; };
#endif // INTEGRATIONPLUGINONEWIRE_H #endif // INTEGRATIONPLUGINONEWIRE_H

View File

@ -8,10 +8,11 @@ LIBS += \
SOURCES += \ SOURCES += \
integrationpluginonewire.cpp \ integrationpluginonewire.cpp \
onewire.cpp \ owfs.cpp \
w1.cpp \
HEADERS += \ HEADERS += \
integrationpluginonewire.h \ integrationpluginonewire.h \
onewire.h \ owfs.h \
w1.h \

View File

@ -28,21 +28,21 @@
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "onewire.h" #include "owfs.h"
#include "extern-plugininfo.h" #include "extern-plugininfo.h"
OneWire::OneWire(QObject *parent) : Owfs::Owfs(QObject *parent) :
QObject(parent) QObject(parent)
{ {
} }
OneWire::~OneWire() Owfs::~Owfs()
{ {
OW_finish(); OW_finish();
} }
bool OneWire::init(const QByteArray &owfsInitArguments) bool Owfs::init(const QByteArray &owfsInitArguments)
{ {
//QByteArray initArguments; //QByteArray initArguments;
//Test OWFS arguments //Test OWFS arguments
@ -52,6 +52,9 @@ bool OneWire::init(const QByteArray &owfsInitArguments)
//Test i2c //Test i2c
//initArguments.append("--i2c=ALL:ALL"); //initArguments.append("--i2c=ALL:ALL");
// W1 Kernel Module
//inifArguments.append("--w1");
if (OW_init(owfsInitArguments) < 0) { if (OW_init(owfsInitArguments) < 0) {
qWarning(dcOneWire()) << "ERROR initialising one wire" << strerror(errno); qWarning(dcOneWire()) << "ERROR initialising one wire" << strerror(errno);
return false; return false;
@ -60,7 +63,7 @@ bool OneWire::init(const QByteArray &owfsInitArguments)
return true; return true;
} }
bool OneWire::discoverDevices() bool Owfs::discoverDevices()
{ {
char *dirBuffer = nullptr; char *dirBuffer = nullptr;
size_t dirLength ; size_t dirLength ;
@ -75,7 +78,7 @@ bool OneWire::discoverDevices()
dirMembers = QByteArray(dirBuffer, dirLength).split(','); dirMembers = QByteArray(dirBuffer, dirLength).split(',');
free(dirBuffer); free(dirBuffer);
QList<OneWireDevice> oneWireDevices; QList<OwfsDevice> owfsDevices;
foreach(QByteArray member, dirMembers) { foreach(QByteArray member, dirMembers) {
/* Other system members: /* Other system members:
@ -93,24 +96,24 @@ bool OneWire::discoverDevices()
if (family != 0) { if (family != 0) {
member.remove(member.indexOf('/'), 1); member.remove(member.indexOf('/'), 1);
QByteArray type; QByteArray type;
OneWireDevice thing; OwfsDevice thing;
thing.family = family; thing.family = family;
thing.address = member; thing.address = member;
thing.id = member.split('.').last(); thing.id = member.split('.').last();
thing.type = getValue(member, "type"); thing.type = getValue(member, "type");
oneWireDevices.append(thing); owfsDevices.append(thing);
} }
} }
emit devicesDiscovered(oneWireDevices); emit devicesDiscovered(owfsDevices);
return true; return true;
} }
bool OneWire::interfaceIsAvailable() bool Owfs::interfaceIsAvailable()
{ {
return true; return true;
} }
bool OneWire::isConnected(const QByteArray &address) bool Owfs::isConnected(const QByteArray &address)
{ {
Q_UNUSED(address) Q_UNUSED(address)
QByteArray fullPath; QByteArray fullPath;
@ -125,7 +128,7 @@ bool OneWire::isConnected(const QByteArray &address)
/* Takes a path and filename and prints the 1-wire value */ /* Takes a path and filename and prints the 1-wire value */
/* makes sure the bridging "/" in the path is correct */ /* makes sure the bridging "/" in the path is correct */
/* watches for total length and free allocated space */ /* watches for total length and free allocated space */
QByteArray OneWire::getValue(const QByteArray &address, const QByteArray &type) QByteArray Owfs::getValue(const QByteArray &address, const QByteArray &type)
{ {
char * getBuffer ; char * getBuffer ;
size_t getLength ; size_t getLength ;
@ -150,7 +153,7 @@ QByteArray OneWire::getValue(const QByteArray &address, const QByteArray &type)
return value; return value;
} }
void OneWire::setValue(const QByteArray &address, const QByteArray &type, const QByteArray &value) void Owfs::setValue(const QByteArray &address, const QByteArray &type, const QByteArray &value)
{ {
Q_UNUSED(value) Q_UNUSED(value)
QByteArray devicePath; QByteArray devicePath;
@ -167,20 +170,20 @@ void OneWire::setValue(const QByteArray &address, const QByteArray &type, const
} }
} }
double OneWire::getTemperature(const QByteArray &address) double Owfs::getTemperature(const QByteArray &address)
{ {
QByteArray temperature = getValue(address, "temperature"); QByteArray temperature = getValue(address, "temperature");
qDebug(dcOneWire()) << "Temperature" << temperature << temperature.replace(',','.').toDouble(); qDebug(dcOneWire()) << "Temperature" << temperature << temperature.replace(',','.').toDouble();
return temperature.toDouble(); return temperature.toDouble();
} }
QByteArray OneWire::getType(const QByteArray &address) QByteArray Owfs::getType(const QByteArray &address)
{ {
QByteArray type = getValue(address, "type"); QByteArray type = getValue(address, "type");
return type; return type;
} }
bool OneWire::getSwitchOutput(const QByteArray &address, SwitchChannel channel) bool Owfs::getSwitchOutput(const QByteArray &address, SwitchChannel channel)
{ {
QByteArray c; QByteArray c;
c.append("PIO."); c.append("PIO.");
@ -215,7 +218,7 @@ bool OneWire::getSwitchOutput(const QByteArray &address, SwitchChannel channel)
return state.toInt(); return state.toInt();
} }
bool OneWire::getSwitchInput(const QByteArray &address, SwitchChannel channel) bool Owfs::getSwitchInput(const QByteArray &address, SwitchChannel channel)
{ {
QByteArray c; QByteArray c;
c.append("sensed."); c.append("sensed.");
@ -250,7 +253,7 @@ bool OneWire::getSwitchInput(const QByteArray &address, SwitchChannel channel)
return state.toInt(); return state.toInt();
} }
void OneWire::setSwitchOutput(const QByteArray &address, SwitchChannel channel, bool state) void Owfs::setSwitchOutput(const QByteArray &address, SwitchChannel channel, bool state)
{ {
QByteArray c; QByteArray c;
c.append("PIO."); c.append("PIO.");

View File

@ -28,18 +28,18 @@
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ONEWIRE_H #ifndef OWFS_H
#define ONEWIRE_H #define OWFS_H
#include "owcapi.h" #include "owcapi.h"
#include <QObject> #include <QObject>
class OneWire : public QObject class Owfs : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
enum OneWireProperty { enum OwfsProperty {
Address, //The entire 64-bit unique ID Address, //The entire 64-bit unique ID
Crc, //The 8-bit error correction Crc, //The 8-bit error correction
Family, //The 8-bit family code Family, //The 8-bit family code
@ -59,15 +59,15 @@ public:
PIO_H PIO_H
}; };
struct OneWireDevice { struct OwfsDevice {
QByteArray address; QByteArray address;
int family; int family;
QByteArray id; QByteArray id;
QByteArray type; QByteArray type;
}; };
explicit OneWire(QObject *parent = nullptr); explicit Owfs(QObject *parent = nullptr);
~OneWire(); ~Owfs();
bool init(const QByteArray &owfsInitArguments); bool init(const QByteArray &owfsInitArguments);
QByteArray getPath(); QByteArray getPath();
@ -87,7 +87,7 @@ private:
void setValue(const QByteArray &address, const QByteArray &deviceType, const QByteArray &value); void setValue(const QByteArray &address, const QByteArray &deviceType, const QByteArray &value);
signals: signals:
void devicesDiscovered(QList<OneWireDevice> devices); void devicesDiscovered(QList<OwfsDevice> devices);
}; };
#endif // ONEWIRE_H #endif // OWFS_H

91
onewire/w1.cpp Normal file
View File

@ -0,0 +1,91 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, 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 <https://www.gnu.org/licenses/>.
*
* 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 "w1.h"
#include "extern-plugininfo.h"
W1::W1(QObject *parent) :
QObject(parent)
{
}
QStringList W1::discoverDevices()
{
QStringList deviceList;
QDir w1SysFSDir("/sys/bus/w1/devices/");
if (!w1SysFSDir.exists()) {
qCDebug(dcOneWire()) << "W1 kernel not loaded";
return deviceList;
}
w1SysFSDir.setFilter(QDir::Dirs | QDir::NoSymLinks);
w1SysFSDir.setSorting(QDir::Name);
QFileInfoList list = w1SysFSDir.entryInfoList();
for (int i = 0; i < list.size(); ++i) {
QFileInfo fileInfo = list.at(i);
qCDebug(dcOneWire()) << "Found W1 bus master" << fileInfo.fileName() << fileInfo.filePath();
m_w1BusMasters.append(QDir(fileInfo.filePath()));
}
Q_FOREACH(QDir busMaster, m_w1BusMasters) {
busMaster.setFilter(QDir::Dirs | QDir::NoSymLinks);
busMaster.setSorting(QDir::Name);
QFileInfoList list = busMaster.entryInfoList();
for (int i = 0; i < list.size(); ++i) {
QFileInfo fileInfo = list.at(i);
deviceList.append(fileInfo.fileName());
}
}
return deviceList;
}
bool W1::interfaceIsAvailable()
{
QDir w1SysFSDir("/sys/bus/w1/devices/");
return w1SysFSDir.exists();
}
double W1::getTemperature(const QString &address)
{
Q_FOREACH(QDir busMaster, m_w1BusMasters) {
QDir temperatureSensor(busMaster.dirName()+address);
if (temperatureSensor.exists()) {
qCDebug(dcOneWire()) << "Temperature" << address;
QFile temperature(temperatureSensor.dirName()+"/temperature");
if (!temperature.open(QIODevice::ReadOnly | QIODevice::Text))
return 0;
return temperature.readLine().toInt()/1000.00;
}
}
return 0;
}

57
onewire/w1.h Normal file
View File

@ -0,0 +1,57 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, 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 <https://www.gnu.org/licenses/>.
*
* 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 W1_H
#define W1_H
#include <QObject>
#include <QDir>
#include <QFile>
class W1 : public QObject
{
Q_OBJECT
public:
explicit W1(QObject *parent = nullptr);
~W1();
QString getPath();
QStringList discoverDevices();
bool interfaceIsAvailable();
double getTemperature(const QString &address);
QList<QDir> m_w1BusMasters;
private:
QByteArray m_path;
};
#endif // W1_H