/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 . * * 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 "modbustcpmaster.h" #include "extern-plugininfo.h" #include Q_DECLARE_LOGGING_CATEGORY(dcModbus) Q_LOGGING_CATEGORY(dcModbus, "Modbus") ModbusTCPMaster::ModbusTCPMaster(QHostAddress IPv4Address, int port, QObject *parent) : QObject(parent), m_IPv4Address(IPv4Address), m_port(port) { } ModbusTCPMaster::~ModbusTCPMaster() { if (m_mb != NULL) { modbus_close(m_mb); } modbus_free(m_mb); } bool ModbusTCPMaster::createInterface() { // TCP connction to target device qCDebug(dcModbus()) << "Setting up TCP connecion" << m_IPv4Address.toString() << "port:" << m_port; const char *address = m_IPv4Address.toString().toLatin1().data(); m_mb = modbus_new_tcp(address, m_port); if(m_mb == nullptr){ qCWarning(dcMypv()) << "Error modbus TCP: " << modbus_strerror(errno) ; return false; } // Extend the timeout to 3 seconds //struct timeval response_timeout; //response_timeout.tv_sec = 3; //response_timeout.tv_usec = 0; //modbus_set_response_timeout(m_mb, &response_timeout); if(modbus_connect(m_mb) == -1){ qCWarning(dcMypv()) << "Error connecting modbus:" << modbus_strerror(errno) ; return false; } return true; } int ModbusTCPMaster::port() { return m_port; } bool ModbusTCPMaster::setIPv4Address(QHostAddress ipv4Address) { m_IPv4Address = ipv4Address; if (!createInterface()) { return false; } return true; } bool ModbusTCPMaster::setPort(int port) { m_port = port; if (!createInterface()) { return false; } return true; } QHostAddress ModbusTCPMaster::ipv4Address() { return m_IPv4Address; } bool ModbusTCPMaster::setCoil(int slaveAddress, int coilAddress, bool status) { if (m_mb == nullptr) { if (!createInterface()) return false; } if(modbus_set_slave(m_mb, slaveAddress) == -1){ qCWarning(dcMypv()) << "Error setting slave ID" << slaveAddress << "Reason:" << modbus_strerror(errno) ; return false; } if (modbus_write_bit(m_mb, coilAddress, status) == -1) { qCWarning(dcMypv()) << "Could not write Coil" << coilAddress << "Reason:" << modbus_strerror(errno); return false; } return true; } bool ModbusTCPMaster::setRegister(int slaveAddress, int registerAddress, int data) { if (m_mb == nullptr) { if (!createInterface()) return false; } if(modbus_set_slave(m_mb, slaveAddress) == -1){ qCWarning(dcMypv()) << "Error setting slave ID" << slaveAddress << "Reason:" << modbus_strerror(errno) ; return false; } if (modbus_write_register(m_mb, registerAddress, data) == -1) { qCWarning(dcMypv()) << "Could not write Register" << registerAddress << "Reason:" << modbus_strerror(errno); return false; } return true; } bool ModbusTCPMaster::getCoil(int slaveAddress, int coilAddress, bool *result) { if (m_mb == nullptr) { if (!createInterface()) return false; } if(modbus_set_slave(m_mb, slaveAddress) == -1){ qCWarning(dcMypv()) << "Error setting slave ID" << slaveAddress << "Reason:" << modbus_strerror(errno) ; return false; } uint8_t status; if (modbus_read_bits(m_mb, coilAddress, 1, &status) == -1){ qCWarning(dcMypv()) << "Could not read bits" << coilAddress << "Reason:"<< modbus_strerror(errno); return false; } *result = (bool)status; return true; } bool ModbusTCPMaster::getRegister(int slaveAddress, int registerAddress, int *result) { uint16_t data; if (m_mb == nullptr) { if (!createInterface()) return false; } if(modbus_set_slave(m_mb, slaveAddress) == -1){ qCWarning(dcMypv()) << "Error setting slave ID" << slaveAddress << "Reason:" << modbus_strerror(errno) ; return false; } if (modbus_read_registers(m_mb, registerAddress, 1, &data) == -1){ qCWarning(dcMypv()) << "Could not read register" << registerAddress << "Reason:" << modbus_strerror(errno); return false; } *result = data; return true; }