Convert Hotdog sketch to PlatformIO

This commit is contained in:
2023-12-11 07:11:17 +11:00
parent 981c28f72e
commit f80cc9a6b9
15 changed files with 502 additions and 395 deletions

6
.gitignore vendored
View File

@@ -1 +1,5 @@
arduino_secrets.h
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

10
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

View File

@@ -1,191 +0,0 @@
#include "PacketCRC.h"
#define LENGTH_17 (0x11)
#define LENGTH_21 (0x15)
#define LENGTH_25 (0x19)
#define VERSION_5 (0x05)
#define VERSION_6 (0x06)
#define REMOTE_ID (0x369E)
#define HUB_ID (0x0000)
uint8_t remoteRollingCode1 = 0xAC;
uint8_t remoteRollingCode2 = 0x82;
uint8_t hubRollingCode1 = 0x00;
uint8_t hubRollingCode2 = 0x00;
uint8_t buf[32];
PacketCRC packetCRC;
void setPacketLength(uint8_t);
void setConstants();
void setSourceAddress(uint16_t);
void setTargetAddress(uint16_t);
void setRollingCodes();
void setProtocolVersion(uint8_t);
void calculateCRC();
void constructUpPacket(uint16_t shadeID)
{
setPacketLength(LENGTH_17);
setConstants();
setSourceAddress(REMOTE_ID);
setTargetAddress(shadeID);
setRollingCodes();
setProtocolVersion(VERSION_6);
buf[16] = 0x52; // ?
buf[17] = 0x55; // Command
buf[18] = 0x00; // Empty?
calculateCRC();
}
void constructDownPacket(uint16_t shadeID)
{
setPacketLength(LENGTH_17);
setConstants();
setSourceAddress(REMOTE_ID);
setTargetAddress(shadeID);
setRollingCodes();
setProtocolVersion(VERSION_6);
buf[16] = 0x52; // ?
buf[17] = 0x44; // Command
buf[18] = 0x00; // Empty?
calculateCRC();
}
void constructStopPacket(uint16_t shadeID)
{
setPacketLength(LENGTH_17);
setConstants();
setSourceAddress(REMOTE_ID);
setTargetAddress(shadeID);
setRollingCodes();
setProtocolVersion(VERSION_6);
buf[16] = 0x52; // ?
buf[17] = 0x53; // Command
buf[18] = 0x00; // Empty?
calculateCRC();
}
void constructPositionPacket(uint16_t shadeID, float percentage)
{
setPacketLength(LENGTH_21);
setConstants();
setSourceAddress(HUB_ID);
setTargetAddress(shadeID);
setRollingCodes();
setProtocolVersion(VERSION_5);
buf[16] = 0x3F; // Command
buf[17] = 0x5A; // Empty?
buf[18] = 0x04; // Constant in this size packet?
buf[19] = 0x40; // Constant in this size packet?
buf[20] = 0x50; // Constant in this size packet?
uint16_t position = (uint16_t)(0xFFFF * percentage);
buf[21] = (uint8_t)(position & 0x00FF);
buf[22] = (uint8_t)((position & 0xFF00) >> 8);
calculateCRC();
}
void setPacketLength(uint8_t length) {
buf[1] = length; // Packet size
}
void setConstants() {
buf[0] = 0xC0; // Header byte
buf[2] = 0x00; // Constant when sending, can be 0x10 when receiving a packet
buf[3] = 0x05; // Constant
buf[5] = 0xFF; // Constant
buf[6] = 0xFF; // Constant
buf[9] = 0x86; // Constant?
}
void setSourceAddress(uint16_t sourceID) {
// Physical source address (could be the address of a repeater when receiving a packet)
buf[7] = (uint8_t)((sourceID & 0xFF00) >> 8);
buf[8] = (uint8_t)(sourceID & 0x00FF);
// Logical source address (usually the same as the physical source address)
buf[14] = (uint8_t)((sourceID & 0xFF00) >> 8);
buf[15] = (uint8_t)(sourceID & 0x00FF);
}
void setTargetAddress(uint16_t targetID) {
// Logical target address
buf[12] = (uint8_t)((targetID & 0xFF00) >> 8);
buf[13] = (uint8_t)(targetID & 0x00FF);
}
void setRollingCodes() {
uint16_t physicalSourceID = (buf[7] << 8) | buf[8];
uint8_t rollingCode1 = 0x00;
if (physicalSourceID == REMOTE_ID) {
rollingCode1 = remoteRollingCode1;
} else if (physicalSourceID == HUB_ID) {
rollingCode1 = hubRollingCode1;
}
uint16_t logicalSourceID = (buf[14] << 8) | buf[15];
uint8_t rollingCode2 = 0x00;
if (physicalSourceID == REMOTE_ID) {
rollingCode2 = remoteRollingCode2;
} else if (physicalSourceID == HUB_ID) {
rollingCode2 = hubRollingCode2;
}
buf[4] = rollingCode1; // Rolling code 1
buf[11] = rollingCode2; // Rolling code 2
}
void incrementRollingCodes() {
uint16_t physicalSourceID = (buf[7] << 8) | buf[8];
uint8_t rollingCode1 = 0x00;
if (physicalSourceID == REMOTE_ID) {
remoteRollingCode1++;
} else if (physicalSourceID == HUB_ID) {
hubRollingCode1++;
}
uint16_t logicalSourceID = (buf[14] << 8) | buf[15];
uint8_t rollingCode2 = 0x00;
if (physicalSourceID == REMOTE_ID) {
remoteRollingCode2++;
} else if (physicalSourceID == HUB_ID) {
hubRollingCode2++;
}
}
void setProtocolVersion(uint8_t version) {
buf[10] = version; // Protocol version?
}
void calculateCRC() { // must be called after the buffer has been filled
uint8_t length = buf[1];
uint16_t result = packetCRC.calculate(buf);
uint8_t checksum1 = (uint8_t)((result & 0xFF00) >> 8);
uint8_t checksum2 = (uint8_t)(result & 0x00FF);
buf[length + 2] = checksum1; // Checksum
buf[length + 3] = checksum2; // Checksum
}

View File

@@ -1,134 +0,0 @@
#include "arduino_secrets.h"
#include "HDPacketBuilder.h"
#include <EspMQTTClient.h>
#include <RF24.h> // library by TMRh20
#define SER_BAUDRATE (115200)
// pins for: esp8266 NodeMCU v3 dev board
#define RF_CE_PIN (5) // pins for: esp
#define RF_CS_PIN (15) // pins for: esp
#define RF_IRQ_PIN (4) // run a jumper from IRQ pin to pin 2
RF24 radio(RF_CE_PIN, RF_CS_PIN);
// Copied from Powerview Hub userdata API (eg: http://POWERVIEW_HUB_IP_ADDRESS/api/userdata/ and find the field labeled "rfID")
static const uint16_t rfID = 0x2EC8;
EspMQTTClient client(
SECRET_WIFI_SSID, // Wifi SSID
SECRET_WIFI_PASSWORD, // Wifi Password
SECRET_MQTT_SERVER_IP, // MQTT Broker server IP
SECRET_MQTT_USERNAME, // MQTT Username
SECRET_MQTT_PASSWORD, // MQTT Password
"hotdog", // MQTT Client ID
1883
);
void setup() {
for (int i = 0; i < 32; i++) {
buf[i] = 0x00;
}
Serial.begin(SER_BAUDRATE);
client.setKeepAlive(10);
client.enableLastWillMessage("hotdog/availability", "offline", true);
client.enableDebuggingMessages();
radio.begin();
radioTransmitSetup();
Serial.println("Ready");
}
void onConnectionEstablished() {
client.subscribe("hotdog/test_mqtt_blind/set", [] (const String &payload) {
uint16_t shadeID = 0x0400;
if (payload == "OPEN") {
constructUpPacket(shadeID);
printPacket(buf);
Serial.println();
sendCommand(buf);
} else if (payload == "CLOSE") {
constructDownPacket(shadeID);
printPacket(buf);
Serial.println();
sendCommand(buf);
} else if (payload == "STOP") {
constructStopPacket(shadeID);
printPacket(buf);
Serial.println();
sendCommand(buf);
}
});
client.subscribe("hotdog/test_mqtt_blind/set_position", [] (const String &payload) {
});
client.publish("hotdog/availability", "online", true);
}
void loop() {
client.loop();
}
void radioTransmitSetup() {
radio.stopListening();
radio.powerDown();
radio.begin();
delay(100);
Serial.println();
radio.setChannel(0x07); //shooting for 2.407 GHz
radio.setDataRate(RF24_1MBPS); //can go at 250kbs, 1Mbs, 2Mbs
radio.setPALevel(RF24_PA_HIGH); //transmit power
radio.disableCRC();
radio.setAutoAck(false);
radio.setAddressWidth(3);
radio.setRetries(0, 0);
radio.openWritingPipe(rfID);
radio.powerUp();
//radio.printDetails();
//radio.printPrettyDetails();
Serial.println("Ready to Transmit");
}
void sendCommand(byte * byteArray) //transmit a command
{
uint8_t bytecount = byteArray[1] + 4;
for (int j = 1; j < 5; j++) {
radio.setAddressWidth(3);
radio.disableCRC();
radio.setAutoAck(false);
radio.openWritingPipe(rfID);
for (int i = 1; i < 200; i++) {
radio.writeFast(byteArray, bytecount);
}
delay(500);
radio.flush_tx();
radio.txStandBy();
}
incrementRollingCodes();
}
void printHex(const uint8_t num) { //print a byte as two hex chars
if (num < 0x10) {
Serial.print("0");
}
Serial.print(num, HEX);
}
void printByteArray(const uint8_t * byteArray, const int arraySize) { //print a byte array as hex chars
for (int i = 0; i < arraySize; i++) {
printHex(byteArray[i]);
}
}
void printPacket(const uint8_t *buffer) {
uint8_t length = buffer[1] + 4;
printByteArray(buffer, length);
}

View File

@@ -1,51 +0,0 @@
#include "PacketCRC.h"
PacketCRC::PacketCRC() : crc(CRC16(0x755B, 0x0, 0xBA68, false, false)) {
// Constructor implementation (if needed)
}
PacketCRC::~PacketCRC() {
// Destructor implementation (if needed)
}
bool PacketCRC::check(const uint8_t* packet) {
uint8_t length = packet[1];
switch(length) {
case 0x11:
case 0x15:
case 0x19:
break;
default:
return false;
}
uint16_t result = calculate(packet);
uint8_t checksum1 = (uint8_t)((result & 0xFF00) >> 8);
uint8_t checksum2 = (uint8_t)(result & 0x00FF);
if (packet[length + 2] == checksum1 && packet[length + 3] == checksum2) {
return true;
}
return false;
}
uint16_t PacketCRC::calculate(const uint8_t* packet) {
crc.restart();
uint8_t length = packet[1];
switch(length) {
case 0x11:
crc.setXorOut(0x539E);
break;
case 0x15:
crc.setXorOut(0x3B0E);
break;
case 0x19:
crc.setXorOut(0x5C02);
break;
default:
return 0x0000;
}
crc.add(packet, length + 2);
return crc.calc();
}

View File

@@ -1,18 +0,0 @@
#ifndef PACKET_CRC_H
#define PACKET_CRC_H
#include <CRC16.h>
class PacketCRC {
public:
PacketCRC();
~PacketCRC();
// Method to calculate CRC for a packet
bool check(const uint8_t* packet);
uint16_t calculate(const uint8_t* packet);
private:
CRC16 crc;
};
#endif // PACKET_CRC_H

39
include/README Normal file
View File

@@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

View File

@@ -0,0 +1,34 @@
#ifndef PACKETBUILDER_H
#define PACKETBUILDER_H
#include <Arduino.h>
#include <PacketCRC.h>
class PacketBuilder {
public:
PacketBuilder(uint16_t address, uint8_t rollingCode1, uint8_t rollingCode2);
~PacketBuilder();
void buildUpPacket(uint8_t *buffer, uint16_t shadeID);
void buildDownPacket(uint8_t *buffer, uint16_t shadeID);
void buildStopPacket(uint8_t *buffer, uint16_t shadeID);
void buildPositionPacket(uint8_t *buffer, uint16_t shadeID, float percentage);
private:
uint16_t address;
uint8_t rollingCode1;
uint8_t rollingCode2;
PacketCRC packetCRC;
void setPacketSize(uint8_t *buffer, uint8_t);
void setConstants(uint8_t *buffer);
void setSourceAddress(uint8_t *buffer, uint16_t);
void setDestinationAddress(uint8_t *buffer, uint16_t);
void setRollingCodes(uint8_t *buffer);
void setProtocolVersion(uint8_t *buffer, uint8_t);
void calculateCRC(uint8_t *buffer);
void incrementRollingCodes();
};
#endif // PACKETBUILDER_H

View File

@@ -0,0 +1,18 @@
{
"name": "PacketBuilder",
"version": "0.0.1",
"description": "A tool for building PowerView packets",
"keywords": "powerview, hunterdouglas",
"authors":
[
{
"name": "Matt Way",
"email": "mattyway@gmail.com"
}
],
"license": "MIT",
"dependencies": {
"PacketCRC": "*"
},
"frameworks": "arduino"
}

View File

@@ -0,0 +1,149 @@
#include "PacketBuilder.h"
PacketBuilder::PacketBuilder(uint16_t address, uint8_t rollingCode1, uint8_t rollingCode2) :
address(address),
rollingCode1(rollingCode1),
rollingCode2(rollingCode2)
{
}
PacketBuilder::~PacketBuilder()
{
}
void PacketBuilder::buildUpPacket(uint8_t *buffer, uint16_t shadeID)
{
setPacketSize(buffer, 0x11);
setConstants(buffer);
setProtocolVersion(buffer, 0x06);
setSourceAddress(buffer, address);
setDestinationAddress(buffer, shadeID);
setRollingCodes(buffer);
buffer[16] = 0x52; // ?
buffer[17] = 0x55; // Command
buffer[18] = 0x00; // Empty?
calculateCRC(buffer);
incrementRollingCodes();
}
void PacketBuilder::buildDownPacket(uint8_t *buffer, uint16_t shadeID)
{
setPacketSize(buffer, 0x11);
setConstants(buffer);
setProtocolVersion(buffer, 0x06);
setSourceAddress(buffer, address);
setDestinationAddress(buffer, shadeID);
setRollingCodes(buffer);
buffer[16] = 0x52; // ?
buffer[17] = 0x44; // Command
buffer[18] = 0x00; // Empty?
calculateCRC(buffer);
incrementRollingCodes();
}
void PacketBuilder::buildStopPacket(uint8_t *buffer, uint16_t shadeID)
{
setPacketSize(buffer, 0x11);
setConstants(buffer);
setProtocolVersion(buffer, 0x06);
setSourceAddress(buffer, address);
setDestinationAddress(buffer, shadeID);
setRollingCodes(buffer);
buffer[16] = 0x52; // ?
buffer[17] = 0x53; // Command
buffer[18] = 0x00; // Empty?
calculateCRC(buffer);
incrementRollingCodes();
}
void PacketBuilder::buildPositionPacket(uint8_t *buffer, uint16_t shadeID, float percentage)
{
setPacketSize(buffer, 0x15);
setConstants(buffer);
setProtocolVersion(buffer, 0x05);
setSourceAddress(buffer, address);
setDestinationAddress(buffer, shadeID);
setRollingCodes(buffer);
buffer[16] = 0x3F; // Command
buffer[17] = 0x5A; // Empty?
buffer[18] = 0x04; // Constant in this size packet?
buffer[19] = 0x40; // Constant in this size packet?
buffer[20] = 0x50; // Constant in this size packet?
uint16_t position = (uint16_t)(0xFFFF * percentage);
buffer[21] = (uint8_t)(position & 0x00FF);
buffer[22] = (uint8_t)((position & 0xFF00) >> 8);
calculateCRC(buffer);
incrementRollingCodes();
}
void PacketBuilder::setPacketSize(uint8_t *buffer, uint8_t length) {
buffer[1] = length; // Packet size
}
void PacketBuilder::setConstants(uint8_t *buffer) {
buffer[0] = 0xC0; // Header byte
buffer[2] = 0x00; // Constant when sending, can be 0x10 when receiving a packet
buffer[3] = 0x05; // Constant
buffer[5] = 0xFF; // Constant
buffer[6] = 0xFF; // Constant
buffer[9] = 0x86; // Constant?
}
void PacketBuilder::setSourceAddress(uint8_t *buffer, uint16_t sourceID) {
// Physical source address (could be the address of a repeater when receiving a packet)
buffer[7] = (uint8_t)((sourceID & 0xFF00) >> 8);
buffer[8] = (uint8_t)(sourceID & 0x00FF);
// Logical source address (usually the same as the physical source address)
buffer[14] = (uint8_t)((sourceID & 0xFF00) >> 8);
buffer[15] = (uint8_t)(sourceID & 0x00FF);
}
void PacketBuilder::setDestinationAddress(uint8_t *buffer, uint16_t targetID) {
// Logical target address
buffer[12] = (uint8_t)((targetID & 0xFF00) >> 8);
buffer[13] = (uint8_t)(targetID & 0x00FF);
}
void PacketBuilder::setRollingCodes(uint8_t *buffer) {
buffer[4] = rollingCode1; // Rolling code 1
buffer[11] = rollingCode2; // Rolling code 2
}
void PacketBuilder::setProtocolVersion(uint8_t *buffer, uint8_t version) {
buffer[10] = version; // Protocol version?
}
void PacketBuilder::calculateCRC(uint8_t *buffer) { // must be called after the buffer has been filled
uint8_t length = buffer[1];
uint16_t result = packetCRC.calculate(buffer);
uint8_t checksum1 = (uint8_t)((result & 0xFF00) >> 8);
uint8_t checksum2 = (uint8_t)(result & 0x00FF);
buffer[length + 2] = checksum1; // Checksum
buffer[length + 3] = checksum2; // Checksum
}
void PacketBuilder::incrementRollingCodes() {
rollingCode1++;
rollingCode2++;
}

46
lib/README Normal file
View File

@@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

31
platformio.ini Normal file
View File

@@ -0,0 +1,31 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:nodemcuv2]
platform = espressif8266
board = nodemcuv2
framework = arduino
build_flags =
-D RF_CE_PIN=5
-D RF_CS_PIN=15
-D RF_IRQ_PIN=4
[env]
monitor_speed = 115200
lib_deps =
nrf24/RF24@^1.4.8
plapointe6/EspMQTTClient@^1.13.3
PacketReceiver=symlink://..\PowerViewSniffer\lib\PacketReceiver
PacketCRC=symlink://..\PowerViewSniffer\lib\PacketCRC
PacketBuilder

1
src/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
secrets.h

158
src/main.cpp Normal file
View File

@@ -0,0 +1,158 @@
// sketch to sniff Hunter Douglas packets from a pebble remote or hub
#define CIRCULAR_BUFFER_INT_SAFE
#include <Arduino.h>
#include <RF24.h> // library by TMRh20
#include <EspMQTTClient.h>
#include <PacketReceiver.h>
#include <PacketBuilder.h>
#include "secrets.h"
#define SER_BAUDRATE (115200)
#define DEFAULT_RF_CHANNEL (7) //this is the channel HD shades use
#define DEFAULT_RF_DATARATE (RF24_1MBPS) //this is the speed HD shades use
RF24 radio(RF_CE_PIN, RF_CS_PIN);
// Copied from Powerview Hub userdata API (eg: http://POWERVIEW_HUB_IP_ADDRESS/api/userdata/ and find the field labeled "rfID")
static const uint8_t rfID[2] = { 0xC8, 0x2E }; // 0x2EC8
PacketReceiver packetReceiver(&radio);
PacketBuilder remotePacketBuilder(0x369E, 0xAC, 0x82);
EspMQTTClient client(
SECRET_WIFI_SSID, // Wifi SSID
SECRET_WIFI_PASSWORD, // Wifi Password
SECRET_MQTT_SERVER_IP, // MQTT Broker server IP
SECRET_MQTT_USERNAME, // MQTT Username
SECRET_MQTT_PASSWORD, // MQTT Password
"hotdog", // MQTT Client ID
1883
);
uint8_t buffer[32];
// put function declarations here:
static void
#ifdef ARDUINO_ARCH_ESP8266
IRAM_ATTR
#endif
handleNrfIrq();
void radioListenSetup();
void radioTransmitSetup();
void processPacket(const uint8_t*);
void sendCommand(const uint8_t*);
void setup() {
Serial.begin(SER_BAUDRATE);
Serial.println("Starting up");
packetReceiver.setReceivedCallback(processPacket);
if (!radio.begin()) {
Serial.println("Failed to communicate with radio");
}
Serial.println("Connected to radio");
radio.setChannel(DEFAULT_RF_CHANNEL);
radio.setDataRate(DEFAULT_RF_DATARATE);
radio.setAutoAck(false);
radio.disableCRC();
radio.setRetries(0, 0);
radio.setPayloadSize(32);
radio.setAddressWidth(2);
radio.powerUp();
pinMode(RF_IRQ_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(RF_IRQ_PIN), handleNrfIrq, FALLING);
radioListenSetup();
client.setKeepAlive(10);
client.enableLastWillMessage("hotdog/availability", "offline", true);
client.enableDebuggingMessages();
delay(100);
Serial.println("Ready");
}
void loop() {
packetReceiver.loop();
client.loop();
}
// put function definitions here:
static void handleNrfIrq() {
packetReceiver.read();
}
void radioListenSetup() {
radio.openReadingPipe(0, rfID);
radio.startListening();
Serial.println("Listening");
interrupts();
}
void radioTransmitSetup() {
radio.stopListening();
radio.setPALevel(RF24_PA_HIGH, true);
radio.openWritingPipe(rfID);
radio.powerUp();
Serial.println("Ready to Transmit");
}
void processPacket(const uint8_t *buffer) {
Serial.println("Got packet");
}
void sendCommand(uint8_t *buffer) //transmit a command
{
radioTransmitSetup();
uint8_t bytecount = buffer[1] + 4;
for (int j = 1; j < 5; j++) {
radio.openWritingPipe(rfID);
for (int i = 1; i < 200; i++) {
radio.writeFast(buffer, bytecount);
}
delay(500);
radio.flush_tx();
radio.txStandBy();
}
radioListenSetup();
}
void onConnectionEstablished() {
Serial.println("Connection established");
client.subscribe("hotdog/test_mqtt_blind/set", [] (const String &payload) {
uint16_t shadeID = 0x0400;
if (payload == "OPEN") {
remotePacketBuilder.buildUpPacket(buffer, shadeID);
sendCommand(buffer);
} else if (payload == "CLOSE") {
remotePacketBuilder.buildDownPacket(buffer, shadeID);
sendCommand(buffer);
} else if (payload == "STOP") {
remotePacketBuilder.buildStopPacket(buffer, shadeID);
sendCommand(buffer);
}
});
client.subscribe("hotdog/test_mqtt_blind/set_position", [] (const String &payload) {
});
client.publish("hotdog/availability", "online", true);
}

11
test/README Normal file
View File

@@ -0,0 +1,11 @@
This directory is intended for PlatformIO Test Runner and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html