[P124] Add plugin Output - I2C Multi Relay

This commit is contained in:
Ton Huisman
2021-11-18 23:13:08 +01:00
parent 92988988a0
commit 26caea93b8
18 changed files with 987 additions and 2 deletions
@@ -0,0 +1,8 @@
build:
tags:
- nas
script:
- wget -c https://files.seeedstudio.com/arduino/seeed-arduino-ci.sh
- chmod +x seeed-arduino-ci.sh
- bash $PWD/seeed-arduino-ci.sh test
@@ -0,0 +1,21 @@
language: generic
dist: bionic
sudo: false
cache:
directories:
- ~/arduino_ide
- ~/.arduino15/packages/
before_install:
- wget -c https://files.seeedstudio.com/arduino/seeed-arduino-ci.sh
script:
- chmod +x seeed-arduino-ci.sh
- cat $PWD/seeed-arduino-ci.sh
- bash $PWD/seeed-arduino-ci.sh test
notifications:
email:
on_success: change
on_failure: change
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015 Seeed Studio
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,84 @@
# Multi_Channel_Relay_Arduino_Library [![Build Status](https://travis-ci.com/Seeed-Studio/Multi_Channel_Relay_Arduino_Library.svg?branch=master)](https://travis-ci.com/Seeed-Studio/Multi_Channel_Relay_Arduino_Library)
This is the Arduino library for Seeed multi channel relay.
<!-- <img src= width=400> -->
<!-- [Grove - OLED Display 0.96"](https://www.seeedstudio.com/s/Grove-OLED-Display-0.96%22-p-781.html) -->
<!-- Description for this product -->
### How to use this library
you can download from Arduino Library Manager or directlly download from this repository.
Connect the 8-channel Solid state relay v1.0 to Arduino board's I2C port, compile and upload four_channel_relay_control.ino. Open the serial monitor the relay should go as expected some massage should show as below:
```
Channel 1 on
Channel 2 on
Channel 3 on
Channel 4 on
Turn all channels on, State: 1111
Turn 1 3 channels on, State: 101
Turn 2 4 channels on, State: 1010
Turn off all channels, State: 0
```
- Upload eight_channel_relay_control.ino, open the serial monitor and show the below logs:
```
Channel 1 on
Channel 2 on
Channel 3 on
Channel 4 on
Channel 5 on
Channel 6 on
Channel 7 on
Channel 8 on
Turn all channels on, State: 11111111
Turn 1 3 5 7 channels on, State: 1010101
Turn 2 4 6 8 channels on, State: 10101010
Turn off all channels, State: 0
```
- This module can be set I2C address by software, open change_i2c_address.ino modify new_i2c_address as you want; compile and upload the sketch, open the serial monitor and show the below logs:
```
Scanning...
I2C device found at address 0x11 !
Found 1 devices
Address 0x21 has been saved to flash.
```
- Read firmware version of the module by example read_firmware_version.ino. Serial logs as below:
```
firmware version: 0x1
```
### Functionalities
- The relay board is an I2C device, device address is changeable, refer to **changeI2CAddress(uint8_t new_addr, uint8_t old_addr)** .
- Use **getChannelState()** to know the state of every channel.
- Use **getFirmwareVersion()** to recognize firmware burn in the on board MCU.
- Use **channelCtrl(uint8_t state)** to change all channel immediately, the **state** parameter represents channel 1 to 8.
- Use **turn_on_channel(uint8_t channel)** to turn on single channel.
- Use **turn_off_channel(uint8_t channel)** to turn off single channel.
- External functionality **scanI2CDevice()**, use for scan device address.
<!-- For more information, please refer to [Grove_OLED_Display_128X64 wiki][1] -->
----
This software is written by lambor for seeed studio and is licensed under The MIT License.<br>
Contributing to this software is warmly welcomed. You can do this basically by<br>
[forking](https://help.github.com/articles/fork-a-repo), committing modifications and then [pulling requests](https://help.github.com/articles/using-pull-requests) (follow the links above<br>
for operating guide). Adding change log and your contact into file header is encouraged.<br>
Thanks for your contribution.
Seeed is a hardware innovation platform for makers to grow inspirations into differentiating products. By working closely with technology providers of all scale, Seeed provides accessible technologies with quality, speed and supply chain knowledge. When prototypes are ready to iterate, Seeed helps productize 1 to 1,000 pcs using in-house engineering, supply chain management and agile manufacture forces. Seeed also team up with incubators, Chinese tech ecosystem, investors and distribution channels to portal Maker startups beyond.
[1]:http://wiki.seeedstudio.com/Grove-OLED_Display_0.96inch/
<!-- [![Analytics](https://ga-beacon.appspot.com/UA-46589105-3/OLED_Display_128X64)](https://github.com/igrigorik/ga-beacon) -->
@@ -0,0 +1,45 @@
/**
When running this sketch please make sure there is only one
Multi Channel Relay module connected to your board, otherwise
it may not work to change module address, or cause other
unpredictable issue.
*/
#include <multi_channel_relay.h>
int new_i2c_address = 0x21;
Multi_Channel_Relay relay;
void setup() {
uint8_t old_address = 0;
uint8_t retry = 0;
DEBUG_PRINT.begin(9600);
while (!DEBUG_PRINT);
// // Set I2C address by default and start relay
relay.begin();
/* Scan I2C device detect device address */
while ((retry++ < 10) && (old_address == 0x00)) {
old_address = relay.scanI2CDevice();
delay(100);
}
if ((0x00 == old_address) || (0xff == old_address)) {
while (1);
}
relay.changeI2CAddress(old_address, new_i2c_address); /* Set I2C address and save to Flash */
DEBUG_PRINT.print("Address 0x");
DEBUG_PRINT.print(new_i2c_address, HEX);
DEBUG_PRINT.println(" has been saved to flash.");
}
void loop() {
}
@@ -0,0 +1,95 @@
#include <multi_channel_relay.h>
/**
channle: 8 7 6 5 4 3 2 1
state: 0b00000000 -> 0x00 (all off)
state: 0b11111111 -> 0xff (all on)
*/
Multi_Channel_Relay relay;
void setup() {
DEBUG_PRINT.begin(9600);
while (!DEBUG_PRINT);
// Set I2C address and start relay
relay.begin(0x11);
/* Begin Controlling Relay */
DEBUG_PRINT.println("Channel 1 on");
relay.turn_on_channel(1);
delay(500);
DEBUG_PRINT.println("Channel 2 on");
relay.turn_off_channel(1);
relay.turn_on_channel(2);
delay(500);
DEBUG_PRINT.println("Channel 3 on");
relay.turn_off_channel(2);
relay.turn_on_channel(3);
delay(500);
DEBUG_PRINT.println("Channel 4 on");
relay.turn_off_channel(3);
relay.turn_on_channel(4);
delay(500);
DEBUG_PRINT.println("Channel 5 on");
relay.turn_off_channel(4);
relay.turn_on_channel(5);
delay(500);
DEBUG_PRINT.println("Channel 6 on");
relay.turn_off_channel(5);
relay.turn_on_channel(6);
delay(500);
DEBUG_PRINT.println("Channel 7 on");
relay.turn_off_channel(6);
relay.turn_on_channel(7);
delay(500);
DEBUG_PRINT.println("Channel 8 on");
relay.turn_off_channel(7);
relay.turn_on_channel(8);
delay(500);
relay.turn_off_channel(8);
relay.channelCtrl(CHANNLE1_BIT |
CHANNLE2_BIT |
CHANNLE3_BIT |
CHANNLE4_BIT |
CHANNLE5_BIT |
CHANNLE6_BIT |
CHANNLE7_BIT |
CHANNLE8_BIT);
DEBUG_PRINT.print("Turn all channels on, State: ");
DEBUG_PRINT.println(relay.getChannelState(), BIN);
delay(2000);
relay.channelCtrl(CHANNLE1_BIT |
CHANNLE3_BIT |
CHANNLE5_BIT |
CHANNLE7_BIT);
DEBUG_PRINT.print("Turn 1 3 5 7 channels on, State: ");
DEBUG_PRINT.println(relay.getChannelState(), BIN);
delay(2000);
relay.channelCtrl(CHANNLE2_BIT |
CHANNLE4_BIT |
CHANNLE6_BIT |
CHANNLE8_BIT);
DEBUG_PRINT.print("Turn 2 4 6 8 channels on, State: ");
DEBUG_PRINT.println(relay.getChannelState(), BIN);
delay(2000);
relay.channelCtrl(0);
DEBUG_PRINT.print("Turn off all channels, State: ");
DEBUG_PRINT.println(relay.getChannelState(), BIN);
delay(2000);
}
void loop() {
}
@@ -0,0 +1,70 @@
#include <multi_channel_relay.h>
/**
channle: 4 3 2 1
state: 0b0000 -> 0x00 (all off)
state: 0b1111 -> 0x0f (all on)
*/
Multi_Channel_Relay relay;
void setup() {
DEBUG_PRINT.begin(9600);
while (!DEBUG_PRINT);
// Set I2C address and start relay
relay.begin(0x11);
/* Begin Controlling Relay */
DEBUG_PRINT.println("Channel 1 on");
relay.turn_on_channel(1);
delay(500);
DEBUG_PRINT.println("Channel 2 on");
relay.turn_off_channel(1);
relay.turn_on_channel(2);
delay(500);
DEBUG_PRINT.println("Channel 3 on");
relay.turn_off_channel(2);
relay.turn_on_channel(3);
delay(500);
DEBUG_PRINT.println("Channel 4 on");
relay.turn_off_channel(3);
relay.turn_on_channel(4);
delay(500);
relay.turn_off_channel(4);
relay.channelCtrl(CHANNLE1_BIT |
CHANNLE2_BIT |
CHANNLE3_BIT |
CHANNLE4_BIT);
DEBUG_PRINT.print("Turn all channels on, State: ");
DEBUG_PRINT.println(relay.getChannelState(), BIN);
delay(2000);
relay.channelCtrl(CHANNLE1_BIT |
CHANNLE3_BIT);
DEBUG_PRINT.print("Turn 1 3 channels on, State: ");
DEBUG_PRINT.println(relay.getChannelState(), BIN);
delay(2000);
relay.channelCtrl(CHANNLE2_BIT |
CHANNLE4_BIT);
DEBUG_PRINT.print("Turn 2 4 channels on, State: ");
DEBUG_PRINT.println(relay.getChannelState(), BIN);
delay(2000);
relay.channelCtrl(0);
DEBUG_PRINT.print("Turn off all channels, State: ");
DEBUG_PRINT.println(relay.getChannelState(), BIN);
delay(2000);
}
void loop() {
}
@@ -0,0 +1,23 @@
#include <multi_channel_relay.h>
#define USE_8_CHANNELS (1)
Multi_Channel_Relay relay;
void setup() {
DEBUG_PRINT.begin(9600);
while (!DEBUG_PRINT);
// Set I2C address and start relay
relay.begin(0x11);
/* Read firmware version */
DEBUG_PRINT.print("firmware version: ");
DEBUG_PRINT.print("0x");
DEBUG_PRINT.print(relay.getFirmwareVersion(), HEX);
DEBUG_PRINT.println();
}
void loop() {
}
@@ -0,0 +1,6 @@
changeI2CAddress KEYWORD2
getChannelState KEYWORD2
getFirmwareVersion KEYWORD2
channelCtrl KEYWORD2
turn_on_channel KEYWORD2
turn_off_channel KEYWORD2
@@ -0,0 +1,9 @@
name=Multi Channel Relay Arduino Library
version=1.1.0
author=Seeed Studio
maintainer=Seeed Studio <techsupport@seeed.cc>
sentence=Arduino library to control Multi Channel Rely.
paragraph=Arduino library to control Multi Channel Rely.
category=Device Control
url=https://github.com/Seeed-Studio/Multi_Channel_Relay_Arduino_Library
architectures=*
@@ -0,0 +1,134 @@
/*
multi_channel_relay.h
Seeed multi channel relay Arduino library
Copyright (c) 2018 Seeed Technology Co., Ltd.
Author : lambor
Create Time : June 2018
Change Log :
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, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <multi_channel_relay.h>
Multi_Channel_Relay::Multi_Channel_Relay() {
}
void Multi_Channel_Relay::begin(int address) {
// Wire.begin(); Handled by ESPEasy already
channel_state = 0;
_i2cAddr = address;
}
uint8_t Multi_Channel_Relay::getFirmwareVersion(void) {
Wire.beginTransmission(_i2cAddr);
Wire.write(CMD_READ_FIRMWARE_VER);
Wire.endTransmission();
Wire.requestFrom(_i2cAddr, 1);
//while(!Wire.available());
return Wire.read();
}
void Multi_Channel_Relay::changeI2CAddress(uint8_t old_addr, uint8_t new_addr) {
Wire.beginTransmission(old_addr);
Wire.write(CMD_SAVE_I2C_ADDR);
Wire.write(new_addr);
Wire.endTransmission();
_i2cAddr = new_addr;
}
uint8_t Multi_Channel_Relay::getChannelState(void) {
return channel_state;
}
void Multi_Channel_Relay::channelCtrl(uint8_t state) {
channel_state = state;
Wire.beginTransmission(_i2cAddr);
Wire.write(CMD_CHANNEL_CTRL);
Wire.write(channel_state);
Wire.endTransmission();
}
void Multi_Channel_Relay::turn_on_channel(uint8_t channel) {
channel_state |= (1 << (channel - 1));
Wire.beginTransmission(_i2cAddr);
Wire.write(CMD_CHANNEL_CTRL);
Wire.write(channel_state);
Wire.endTransmission();
}
void Multi_Channel_Relay::turn_off_channel(uint8_t channel) {
channel_state &= ~(1 << (channel - 1));
Wire.beginTransmission(_i2cAddr);
Wire.write(CMD_CHANNEL_CTRL);
Wire.write(channel_state);
Wire.endTransmission();
}
// uint8_t Multi_Channel_Relay::scanI2CDevice(void) {
// byte error = 0, address = 0, result = 0;
// int nDevices;
// DEBUG_PRINT.println("Scanning...");
// nDevices = 0;
// for (address = 1; address <= 127; address++) {
// // The i2c_scanner uses the return value of
// // the Write.endTransmisstion to see if
// // a device did acknowledge to the address.
// Wire.beginTransmission(address);
// error = Wire.endTransmission();
// if (error == 0) {
// result = address;
// DEBUG_PRINT.print("I2C device found at address 0x");
// if (address < 16) {
// DEBUG_PRINT.print("0");
// }
// DEBUG_PRINT.print(address, HEX);
// DEBUG_PRINT.println(" !");
// nDevices++;
// } else if (error == 4) {
// DEBUG_PRINT.print("Unknown error at address 0x");
// if (address < 16) {
// DEBUG_PRINT.print("0");
// }
// DEBUG_PRINT.println(address, HEX);
// }
// }
// if (nDevices == 0) {
// DEBUG_PRINT.println("No I2C devices found\n");
// result = 0x00;
// } else {
// DEBUG_PRINT.print("Found ");
// DEBUG_PRINT.print(nDevices);
// DEBUG_PRINT.print(" devices\n");
// if (nDevices != 1) {
// result = 0x00;
// }
// }
// return result;
// return 0;
// }
@@ -0,0 +1,129 @@
/*
multi_channel_relay.cpp
Seeed multi channel relay Arduino library
Copyright (c) 2018 Seeed Technology Co., Ltd.
Author : lambor
Create Time : June 2018
Change Log :
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, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef MULTI_CHANNEL_RELAY_H
#define MULTI_CHANNEL_RELAY_H
// Architecture specific include
// #if defined(ARDUINO_ARCH_AVR)
// #define DEBUG_PRINT Serial
// #elif defined(ARDUINO_ARCH_SAM)
// #define DEBUG_PRINT SerialUSB
// #elif defined(ARDUINO_ARCH_SAMD)
// #define DEBUG_PRINT SerialUSB
// #elif defined(ARDUINO_ARCH_STM32F4)
// #define DEBUG_PRINT SerialUSB
// #else
// #pragma message("Not match any architecture.")
// #define DEBUG_PRINT Serial
// #endif
#include <Arduino.h>
#include <Wire.h>
#define CHANNLE1_BIT 0x01
#define CHANNLE2_BIT 0x02
#define CHANNLE3_BIT 0x04
#define CHANNLE4_BIT 0x08
#define CHANNLE5_BIT 0x10
#define CHANNLE6_BIT 0x20
#define CHANNLE7_BIT 0x40
#define CHANNLE8_BIT 0x80
#define CMD_CHANNEL_CTRL 0x10
#define CMD_SAVE_I2C_ADDR 0x11
#define CMD_READ_I2C_ADDR 0x12
#define CMD_READ_FIRMWARE_VER 0x13
class Multi_Channel_Relay {
public:
Multi_Channel_Relay();
/**
Begin Multi Channel Relay by a I2C address.
@param address can be changed by changeI2CAddress. Please refer to example change_i2c_address
*/
void begin(int address = 0x11);
/**
@brief Change device address from old_addr to new_addr.
@param new_addr, the address to use.
old_addr, the original address
@return None
*/
void changeI2CAddress(uint8_t new_addr, uint8_t old_addr);
/**
/brief Get channel state
/return One byte value to indicate channel state
the bits range from 0 to 7 represents channel 1 to 8
*/
uint8_t getChannelState(void);
/**
@brief Read firmware version from on board MCU
@param
@return Firmware version in byte
*/
uint8_t getFirmwareVersion(void);
/**
@brief Control relay channels
@param state, use one Byte to represent 8 channel
@return None
*/
void channelCtrl(uint8_t state);
/**
@brief Turn on one of 8 channels
@param channel, channel to control with (range form 1 to 8)
@return None
*/
void turn_on_channel(uint8_t channel);
/**
@brief Turn off on of 8 channels
@param channel, channel to control with (range form 1 to 8)
@return None
*/
void turn_off_channel(uint8_t channel);
// /**
// @brief Scan I2C device, return the address if there is only one i2c device
// @param
// @return device address
// */
// uint8_t scanI2CDevice(void);
private:
int _i2cAddr; // This is the I2C address you want to use
int channel_state; // Value to save channel state
};
#endif
+1 -1
View File
@@ -10,7 +10,7 @@ lib_ignore = ESP8266WiFi, ESP8266Ping, ESP8266WebServer, ESP8266H
[esp32_common]
extends = common, core_esp32_3_3_0
lib_deps = td-er/ESPeasySerial @ 2.0.7, adafruit/Adafruit ILI9341 @ ^1.5.6, Adafruit GFX Library, LOLIN_EPD, Adafruit BusIO, VL53L0X @ 1.3.0, SparkFun VL53L1X 4m Laser Distance Sensor @ 1.2.9, td-er/SparkFun MAX1704x Fuel Gauge Arduino Library @ ^1.0.1, ArduinoOTA, ESP32HTTPUpdateServer
lib_deps = td-er/ESPeasySerial @ 2.0.7, adafruit/Adafruit ILI9341 @ ^1.5.6, Adafruit GFX Library, LOLIN_EPD, Adafruit BusIO, VL53L0X @ 1.3.0, SparkFun VL53L1X 4m Laser Distance Sensor @ 1.2.9, td-er/SparkFun MAX1704x Fuel Gauge Arduino Library @ ^1.0.1, ArduinoOTA, ESP32HTTPUpdateServer, Multi Channel Relay Arduino Library
lib_ignore = ${esp32_always.lib_ignore}, ESP32_ping, IRremoteESP8266, HeatpumpIR
board_build.f_flash = 80000000L
board_build.flash_mode = dout
+1 -1
View File
@@ -52,7 +52,7 @@ extends = common
board_build.f_cpu = 80000000L
build_flags = ${debug_flags.build_flags} ${mqtt_flags.build_flags} -DHTTPCLIENT_1_1_COMPATIBLE=0
build_unflags = -DDEBUG_ESP_PORT
lib_deps = td-er/ESPeasySerial @ 2.0.7, adafruit/Adafruit ILI9341 @ ^1.5.6, Adafruit GFX Library, LOLIN_EPD, Adafruit BusIO, bblanchon/ArduinoJson @ ^6.17.2, VL53L0X @ 1.3.0, SparkFun VL53L1X 4m Laser Distance Sensor @ 1.2.9, td-er/RABurton ESP8266 Mutex @ ^1.0.2, td-er/SparkFun MAX1704x Fuel Gauge Arduino Library @ ^1.0.1, ESP8266HTTPUpdateServer
lib_deps = td-er/ESPeasySerial @ 2.0.7, adafruit/Adafruit ILI9341 @ ^1.5.6, Adafruit GFX Library, LOLIN_EPD, Adafruit BusIO, bblanchon/ArduinoJson @ ^6.17.2, VL53L0X @ 1.3.0, SparkFun VL53L1X 4m Laser Distance Sensor @ 1.2.9, td-er/RABurton ESP8266 Mutex @ ^1.0.2, td-er/SparkFun MAX1704x Fuel Gauge Arduino Library @ ^1.0.1, ESP8266HTTPUpdateServer, Multi Channel Relay Arduino Library
lib_ignore = ${esp82xx_defaults.lib_ignore}, IRremoteESP8266, HeatpumpIR, LittleFS(esp8266), ServoESP32, TinyWireM
board = esp12e
monitor_filters = esp8266_exception_decoder
+231
View File
@@ -0,0 +1,231 @@
#include "_Plugin_Helper.h"
#ifdef USES_P124
// #######################################################################################################
// ########################### Plugin 124 I2C Multi Relay module ###############################
// #######################################################################################################
/** Changelog:
* 2021-11-18 tonhuisman: Implement settings,
* Implement write commands:
* multirelay,on,<channel> (channel 1..8, max. accepted as configured)
* multirelay,off,<channel>
* multirelay,set,<bit-relay-8..1> (value in decimal, 0xnn hex or 0bnnnnnnnn binary)
* Add binary state to Devices screen, when plugin enabled.
* 2021-11-17 tonhuisman: Initial plugin development.
*/
# define PLUGIN_124
# define PLUGIN_ID_124 124
# define PLUGIN_NAME_124 "Output - I2C Multi Relay [TESTING]"
# define PLUGIN_VALUENAME1_124 "State"
# include "./src/PluginStructs/P124_data_struct.h"
boolean Plugin_124(uint8_t function, struct EventStruct *event, String& string)
{
boolean success = false;
switch (function)
{
case PLUGIN_DEVICE_ADD:
{
Device[++deviceCount].Number = PLUGIN_ID_124;
Device[deviceCount].Type = DEVICE_TYPE_I2C;
Device[deviceCount].VType = Sensor_VType::SENSOR_TYPE_SINGLE;
Device[deviceCount].Ports = 0;
Device[deviceCount].PullUpOption = false;
Device[deviceCount].InverseLogicOption = false;
Device[deviceCount].FormulaOption = true;
Device[deviceCount].ValueCount = 1;
Device[deviceCount].SendDataOption = true;
Device[deviceCount].TimerOption = true;
Device[deviceCount].TimerOptional = true;
break;
}
case PLUGIN_GET_DEVICENAME:
{
string = F(PLUGIN_NAME_124);
break;
}
case PLUGIN_GET_DEVICEVALUENAMES:
{
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_124));
break;
}
case PLUGIN_I2C_HAS_ADDRESS:
{
success = (event->Par1 == 0x11);
break;
}
case PLUGIN_SET_DEFAULTS:
{
ExtraTaskSettings.TaskDeviceValueDecimals[0] = 0; // No decimals needed
break;
}
case PLUGIN_WEBFORM_LOAD:
{
const __FlashStringHelper *optionsMode2[] = {
F("2 relays"),
F("4 relays"),
F("8 relays") };
int optionValuesMode2[] { 2, 4, 8 };
addFormSelector(F("Number of relays"), F("plugin_124_relays"), 3, optionsMode2, optionValuesMode2, P124_CONFIG_RELAY_COUNT, true);
const __FlashStringHelper *yesNoOptions[] = {
F("No"),
F("Yes")
};
int yesNoValues[] = { 0, 1 };
addFormSelector(F("Initialize relays on startup"),
getPluginCustomArgName(P124_FLAGS_INIT_RELAYS), 2, yesNoOptions, yesNoValues,
bitRead(P124_CONFIG_FLAGS, P124_FLAGS_INIT_RELAYS) ? 1 : 0, true);
String label;
if (bitRead(P124_CONFIG_FLAGS, P124_FLAGS_INIT_RELAYS)) {
for (int i = 0; i < P124_CONFIG_RELAY_COUNT; i++) {
label = F("Relay ");
label += i + 1;
label += F(" initial state (on/off)");
addFormCheckBox(label, getPluginCustomArgName(i), bitRead(P124_CONFIG_FLAGS, i));
}
}
success = true;
break;
}
case PLUGIN_WEBFORM_SAVE:
{
P124_CONFIG_RELAY_COUNT = getFormItemInt(F("plugin_124_relays"));
uint32_t lSettings = 0u;
bitWrite(lSettings, P124_FLAGS_INIT_RELAYS, getFormItemInt(getPluginCustomArgName(P124_FLAGS_INIT_RELAYS)) == 1);
if (lSettings != 0) {
for (int i = 0; i < P124_CONFIG_RELAY_COUNT; i++) {
bitWrite(lSettings, i, isFormItemChecked(getPluginCustomArgName(i)));
}
}
P124_CONFIG_FLAGS = lSettings;
success = true;
break;
}
case PLUGIN_INIT:
{
initPluginTaskData(event->TaskIndex, new (std::nothrow) P124_data_struct(PCONFIG(0)));
P124_data_struct *P124_data = static_cast<P124_data_struct *>(getPluginTaskData(event->TaskIndex));
if (nullptr == P124_data) {
return success;
}
if (P124_data->isInitialized()) {
String log;
log.reserve(46);
log = F("MultiRelay: Initialized, firmware version: ");
log += P124_data->getFirmwareVersion();
addLog(LOG_LEVEL_INFO, log);
if (bitRead(P124_CONFIG_FLAGS, P124_FLAGS_INIT_RELAYS)) {
P124_data->channelCtrl(P124_CONFIG_FLAGS & 0xFF); // Set relays state
UserVar[event->BaseVarIndex] = P124_data->getChannelState(); // Get relays state
}
success = true;
} else {
addLog(LOG_LEVEL_ERROR, F("MultiRelay: Initialization error!"));
}
break;
}
case PLUGIN_READ:
{
P124_data_struct *P124_data = static_cast<P124_data_struct *>(getPluginTaskData(event->TaskIndex));
if (nullptr == P124_data) {
return success;
}
if (P124_data->isInitialized()) {
UserVar[event->BaseVarIndex] = P124_data->getChannelState(); // Get relays state
success = true;
}
break;
}
case PLUGIN_WEBFORM_SHOW_VALUES:
{
P124_data_struct *P124_data = static_cast<P124_data_struct *>(getPluginTaskData(event->TaskIndex));
if ((nullptr != P124_data) && P124_data->isInitialized()) {
uint8_t varNr = 1; // VARS_PER_TASK;
String label = F("Relay state ");
label += P124_CONFIG_RELAY_COUNT;
label += F("..");
label += 1;
String state = F("0b ");
uint32_t val = UserVar[event->BaseVarIndex];
val &= 0xff;
val |= (0x1 << P124_CONFIG_RELAY_COUNT);
state += ull2String(val, 2);
state.remove(3, 1); // Delete leading 1 we added
pluginWebformShowValue(event->TaskIndex, varNr++, label, state, true);
// success = true;
}
break;
}
case PLUGIN_WRITE:
{
P124_data_struct *P124_data = static_cast<P124_data_struct *>(getPluginTaskData(event->TaskIndex));
if (nullptr == P124_data) {
return success;
}
# ifdef P124_DEBUG_LOG
addLog(LOG_LEVEL_INFO, string);
String log = F("Par1..3:");
log += event->Par1;
log += ',';
log += event->Par2;
log += ',';
log += event->Par3;
addLog(LOG_LEVEL_INFO, log);
# endif // ifdef P124_DEBUG_LOG
String command = parseString(string, 1);
if (P124_data->isInitialized() &&
command.equals(F("multirelay"))) {
String subcommand = parseString(string, 2);
if (subcommand.equals(F("on"))) {
success = P124_data->turn_on_channel(event->Par2);
} else if (subcommand.equals(F("off"))) {
success = P124_data->turn_off_channel(event->Par2);
} else if (subcommand.equals(F("set"))) {
success = P124_data->channelCtrl(event->Par2);
}
if (success) {
UserVar[event->BaseVarIndex] = P124_data->getChannelState(); // Get relays state
}
}
break;
}
}
return success;
}
#endif // ifdef USES_P124
@@ -0,0 +1,61 @@
#include "../PluginStructs/P124_data_struct.h"
#ifdef USES_P124
// **************************************************************************/
// Constructor
// **************************************************************************/
P124_data_struct::P124_data_struct(uint8_t relayCount)
: _relayCount(relayCount) {
relay = new (std::nothrow) Multi_Channel_Relay(); // Use default address
}
// **************************************************************************/
// Destructor
// **************************************************************************/
P124_data_struct::~P124_data_struct() {
if (isInitialized()) {
delete relay;
relay = nullptr;
}
}
uint8_t P124_data_struct::getChannelState() {
if (isInitialized()) {
return relay->getChannelState();
}
return 0u;
}
uint8_t P124_data_struct::getFirmwareVersion() {
if (isInitialized()) {
return relay->getFirmwareVersion();
}
return 0u;
}
bool P124_data_struct::channelCtrl(uint8_t state) {
if (isInitialized()) {
relay->channelCtrl(state);
return true;
}
return false;
}
bool P124_data_struct::turn_on_channel(uint8_t channel) {
if (isInitialized() && (validChannel(channel))) {
relay->turn_on_channel(channel);
return true;
}
return false;
}
bool P124_data_struct::turn_off_channel(uint8_t channel) {
if (isInitialized() && (validChannel(channel))) {
relay->turn_off_channel(channel);
return true;
}
return false;
}
#endif // ifdef USES_P124
+45
View File
@@ -0,0 +1,45 @@
#ifndef PLUGINSTRUCTS_P124_DATA_STRUCT_H
#define PLUGINSTRUCTS_P124_DATA_STRUCT_H
#include "../../_Plugin_Helper.h"
#ifdef USES_P124
# include <multi_channel_relay.h>
// # define P124_DEBUG_LOG // Enable for some (extra) logging
# define P124_CONFIG_RELAY_COUNT PCONFIG(0)
# define P124_CONFIG_FLAGS PCONFIG_LONG(0)
# define P124_FLAGS_INIT_RELAYS 8 // 0..7 hold the on/off state of each relay
struct P124_data_struct : public PluginTaskData_base {
public:
P124_data_struct(uint8_t relayCount);
P124_data_struct() = delete;
~P124_data_struct();
bool isInitialized() {
return relay != nullptr;
}
uint8_t getChannelState();
uint8_t getFirmwareVersion();
bool channelCtrl(uint8_t state);
bool turn_on_channel(uint8_t channel);
bool turn_off_channel(uint8_t channel);
private:
bool validChannel(uint channel) {
return channel > 0 && channel <= _relayCount;
}
Multi_Channel_Relay *relay = nullptr;
uint8_t _relayCount;
};
#endif // ifdef USES_P124
#endif // ifndef PLUGINSTRUCTS_P124_DATA_STRUCT_H
+3
View File
@@ -176,6 +176,9 @@ String getKnownI2Cdevice(uint8_t address) {
switch (address)
{
case 0x11:
result += F("I2C_MultiRelay");
break;
case 0x20:
case 0x21:
case 0x22: