added 1,2,8 channel switch discovery

This commit is contained in:
nymea 2019-07-19 08:18:05 +02:00
parent 9de7ca9b39
commit 8046484a91
4 changed files with 227 additions and 27 deletions

View File

@ -117,11 +117,11 @@ Device::DeviceSetupStatus DevicePluginOneWire::setupDevice(Device *device)
return Device::DeviceSetupStatusSuccess;
}
if (device->deviceClassId() == switchDeviceClassId) {
if (device->deviceClassId() == singleChannelSwitchDeviceClassId) {
qCDebug(dcOneWire) << "Setup one wire switch" << device->params();
if (!m_oneWireInterface) {
QByteArray address = device->paramValue(switchDeviceAddressParamTypeId).toByteArray();
device->setStateValue(switchDigitalOutputStateTypeId, m_oneWireInterface->getSwitchState(address));
QByteArray address = device->paramValue(singleChannelSwitchDeviceAddressParamTypeId).toByteArray();
device->setStateValue(singleChannelSwitchDigitalOutputStateTypeId, m_oneWireInterface->getSwitchOutput(address, OneWire::SwitchChannel::PIO_A));
}
return Device::DeviceSetupStatusSuccess;
}
@ -139,10 +139,9 @@ Device::DeviceError DevicePluginOneWire::executeAction(Device *device, const Act
return Device::DeviceErrorActionTypeNotFound;
}
if (device->deviceClassId() == switchDeviceClassId) {
if (action.actionTypeId() == switchDigitalOutputActionTypeId){
m_oneWireInterface->setSwitchState(device->paramValue(switchDeviceAddressParamTypeId).toByteArray(), action.param(switchDigitalOutputActionDigitalOutputParamTypeId).value().toBool());
if (device->deviceClassId() == singleChannelSwitchDeviceClassId) {
if (action.actionTypeId() == singleChannelSwitchDigitalOutputActionTypeId){
m_oneWireInterface->setSwitchOutput(device->paramValue(singleChannelSwitchDeviceAddressParamTypeId).toByteArray(), OneWire::SwitchChannel::PIO_A, action.param(singleChannelSwitchDigitalOutputActionDigitalOutputParamTypeId).value().toBool());
return Device::DeviceErrorNoError;
}
@ -192,12 +191,15 @@ void DevicePluginOneWire::onOneWireDevicesDiscovered(QList<OneWire::OneWireDevic
bool autoDiscoverEnabled = parentDevice->stateValue(oneWireInterfaceAutoAddStateTypeId).toBool();
QList<DeviceDescriptor> temperatureDeviceDescriptors;
QList<DeviceDescriptor> singleChannelSwitchDeviceDescriptors;
QList<DeviceDescriptor> dualChannelSwitchDeviceDescriptors;
QList<DeviceDescriptor> eightChannelSwitchDeviceDescriptors;
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
case 0x3b: {//DS1825, MAX31826, MAX31850
DeviceDescriptor descriptor(temperatureSensorDeviceClassId, oneWireDevice.type, "One wire temperature sensor", parentDevice->id());
ParamList params;
params.append(Param(temperatureSensorDeviceAddressParamTypeId, oneWireDevice.address));
@ -212,13 +214,76 @@ void DevicePluginOneWire::onOneWireDevicesDiscovered(QList<OneWire::OneWireDevic
temperatureDeviceDescriptors.append(descriptor);
break;
}
case 0x05: { //single channel switch
DeviceDescriptor descriptor(singleChannelSwitchDeviceClassId, oneWireDevice.type, "One wire single channel switch", parentDevice->id());
ParamList params;
params.append(Param(singleChannelSwitchDeviceAddressParamTypeId, oneWireDevice.address));
params.append(Param(singleChannelSwitchDeviceTypeParamTypeId, oneWireDevice.type));
foreach (Device *existingDevice, myDevices().filterByDeviceClassId(singleChannelSwitchDeviceClassId)){
if (existingDevice->paramValue(singleChannelSwitchDeviceAddressParamTypeId).toString() == oneWireDevice.address) {
descriptor.setDeviceId(existingDevice->id());
break;
}
}
descriptor.setParams(params);
singleChannelSwitchDeviceDescriptors.append(descriptor);
break;
}
case 0x12:
case 0x3a: {//dual channel switch
DeviceDescriptor descriptor(dualChannelSwitchDeviceClassId, oneWireDevice.type, "One wire dual channel switch", parentDevice->id());
ParamList params;
params.append(Param(dualChannelSwitchDeviceAddressParamTypeId, oneWireDevice.address));
params.append(Param(dualChannelSwitchDeviceTypeParamTypeId, oneWireDevice.type));
foreach (Device *existingDevice, myDevices().filterByDeviceClassId(dualChannelSwitchDeviceClassId)){
if (existingDevice->paramValue(dualChannelSwitchDeviceAddressParamTypeId).toString() == oneWireDevice.address) {
descriptor.setDeviceId(existingDevice->id());
break;
}
}
descriptor.setParams(params);
dualChannelSwitchDeviceDescriptors.append(descriptor);
break;
}
case 0x29: { //eight channel switch
DeviceDescriptor descriptor(eightChannelSwitchDeviceClassId, oneWireDevice.type, "One wire eight channel switch", parentDevice->id());
ParamList params;
params.append(Param(eightChannelSwitchDeviceAddressParamTypeId, oneWireDevice.address));
params.append(Param(eightChannelSwitchDeviceTypeParamTypeId, oneWireDevice.type));
foreach (Device *existingDevice, myDevices().filterByDeviceClassId(eightChannelSwitchDeviceClassId)){
if (existingDevice->paramValue(eightChannelSwitchDeviceAddressParamTypeId).toString() == oneWireDevice.address) {
descriptor.setDeviceId(existingDevice->id());
break;
}
}
descriptor.setParams(params);
eightChannelSwitchDeviceDescriptors.append(descriptor);
break;
}
default:
qDebug(dcOneWire()) << "Unknown Device discovered" << oneWireDevice.type << oneWireDevice.address;
break;
}
}
if (autoDiscoverEnabled) {
if (!temperatureDeviceDescriptors.isEmpty())
emit autoDevicesAppeared(temperatureSensorDeviceClassId, temperatureDeviceDescriptors);
if (!singleChannelSwitchDeviceDescriptors.isEmpty())
emit autoDevicesAppeared(singleChannelSwitchDeviceClassId, singleChannelSwitchDeviceDescriptors);
if (!dualChannelSwitchDeviceDescriptors.isEmpty())
emit autoDevicesAppeared(dualChannelSwitchDeviceClassId, temperatureDeviceDescriptors);
if (!temperatureDeviceDescriptors.isEmpty())
emit autoDevicesAppeared(temperatureSensorDeviceClassId, temperatureDeviceDescriptors);
} else {
if (!temperatureDeviceDescriptors.isEmpty())
emit devicesDiscovered(temperatureSensorDeviceClassId, temperatureDeviceDescriptors);
if (!singleChannelSwitchDeviceDescriptors.isEmpty())
emit devicesDiscovered(singleChannelSwitchDeviceClassId, singleChannelSwitchDeviceDescriptors);
if (!dualChannelSwitchDeviceDescriptors.isEmpty())
emit devicesDiscovered(dualChannelSwitchDeviceClassId, temperatureDeviceDescriptors);
if (!temperatureDeviceDescriptors.isEmpty())
emit devicesDiscovered(temperatureSensorDeviceClassId, temperatureDeviceDescriptors);
}
break;
}

View File

@ -104,7 +104,15 @@
],
"stateTypes": [
{
}
"id": "ca10a9fd-e4e0-4608-a2d2-6a4ce9644f40",
"name": "digitalOutput",
"displayName": "Digital output",
"displayNameEvent": "Digital output changed",
"displayNameAction": "Set digital output",
"type": "bool",
"defaultValue": false,
"writable": true
}
]
},
{
@ -132,6 +140,25 @@
],
"stateTypes": [
{
"id": "f8b6b4a7-355c-4580-a676-8a4d0d619ff9",
"name": "digitalOutput1",
"displayName": "Digital output 1",
"displayNameEvent": "Digital output 1 changed",
"displayNameAction": "Set digital output 1",
"type": "bool",
"defaultValue": false,
"writable": true
},
{
"id": "82a78aed-5994-4af5-aecb-1806be5de1f3",
"name": "digitalOutput2",
"displayName": "Digital output 2",
"displayNameEvent": "Digital output 2 changed",
"displayNameAction": "Set digital output 2",
"type": "bool",
"defaultValue": false,
"writable": true
}
]
},

View File

@ -141,11 +141,21 @@ QByteArray OneWire::getValue(const QByteArray &address, const QByteArray &type)
return value;
}
void OneWire::setValue(const QByteArray &address, const QByteArray &deviceType, const QByteArray &value)
void OneWire::setValue(const QByteArray &address, const QByteArray &type, const QByteArray &value)
{
Q_UNUSED(address)
Q_UNUSED(deviceType)
Q_UNUSED(value)
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_put(devicePath, value, value.length()) < 0) {
qWarning(dcOneWire()) << "ERROR reading" << devicePath << strerror(errno);
}
}
double OneWire::getTemperature(const QByteArray &address)
@ -167,20 +177,107 @@ QByteArray OneWire::getType(const QByteArray &address)
return type;
}
bool OneWire::getSwitchState(const QByteArray &address)
bool OneWire::getSwitchOutput(const QByteArray &address, SwitchChannel channel)
{
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");
QByteArray c;
c.append("PIO.");
switch (channel) {
case PIO_A:
c.append('A');
break;
case PIO_B:
c.append('B');
break;
case PIO_C:
c.append('C');
break;
case PIO_D:
c.append('D');
break;
case PIO_E:
c.append('E');
break;
case PIO_F:
c.append('F');
break;
case PIO_G:
c.append('G');
break;
case PIO_H:
c.append('H');
break;
}
QByteArray state = getValue(address, c);
qDebug(dcOneWire()) << "Switch state" << state.toInt();
return state.toInt();
}
bool OneWire::getSwitchInput(const QByteArray &address, SwitchChannel channel)
{
QByteArray c;
c.append("sensed.");
switch (channel) {
case PIO_A:
c.append('A');
break;
case PIO_B:
c.append('B');
break;
case PIO_C:
c.append('C');
break;
case PIO_D:
c.append('D');
break;
case PIO_E:
c.append('E');
break;
case PIO_F:
c.append('F');
break;
case PIO_G:
c.append('G');
break;
case PIO_H:
c.append('H');
break;
}
QByteArray state = getValue(address, c);
qDebug(dcOneWire()) << "Switch state" << state.toInt();
return state.toInt();
}
void OneWire::setSwitchOutput(const QByteArray &address, SwitchChannel channel, bool state)
{
QByteArray c;
c.append("PIO.");
switch (channel) {
case PIO_A:
c.append('A');
break;
case PIO_B:
c.append('B');
break;
case PIO_C:
c.append('C');
break;
case PIO_D:
c.append('D');
break;
case PIO_E:
c.append('E');
break;
case PIO_F:
c.append('F');
break;
case PIO_G:
c.append('G');
break;
case PIO_H:
c.append('H');
break;
}
setValue(address, c, QVariant(state).toByteArray());
}

View File

@ -40,6 +40,17 @@ public:
Type //Part name assigned by Dallas Semi. E.g. DS2401
};
enum SwitchChannel {
PIO_A,
PIO_B,
PIO_C,
PIO_D,
PIO_E,
PIO_F,
PIO_G,
PIO_H
};
struct OneWireDevice {
QByteArray address;
int family;
@ -59,9 +70,9 @@ public:
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);
bool getSwitchOutput(const QByteArray &address, SwitchChannel channel);
void setSwitchOutput(const QByteArray &address, SwitchChannel channel, bool state);
bool getSwitchInput(const QByteArray &address, SwitchChannel channel);
private:
QByteArray m_deviceLocation;