/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright (C) 2018 Bernhard Trinnes . * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /*! \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 #include //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 oneWireDevices) { foreach(Device *parentDevice, myDevices().filterByDeviceClassId(oneWireInterfaceDeviceClassId)) { bool autoDiscoverEnabled = parentDevice->stateValue(oneWireInterfaceAutoAddStateTypeId).toBool(); QList 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*/