diff --git a/lib/PacketBuilder/include/PacketBuilder.h b/lib/PacketBuilder/include/PacketBuilder.h deleted file mode 100644 index 54df287..0000000 --- a/lib/PacketBuilder/include/PacketBuilder.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef PACKETBUILDER_H -#define PACKETBUILDER_H - -#include -#include - -class PacketBuilder { -public: - PacketBuilder(uint16_t address, uint8_t rollingCode1, uint8_t rollingCode2, uint8_t protocolVersion); - ~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 buildSetPositionPacket(uint8_t *buffer, uint16_t shadeID, float percentage); - void buildFetchPositionPacket(uint8_t *buffer, uint16_t shadeID); - -private: - uint16_t address; - uint8_t rollingCode1; - uint8_t rollingCode2; - uint8_t protocolVersion; - - 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 \ No newline at end of file diff --git a/lib/PacketBuilder/library.json b/lib/PacketBuilder/library.json deleted file mode 100644 index 1ec3598..0000000 --- a/lib/PacketBuilder/library.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "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" - } \ No newline at end of file diff --git a/lib/PacketBuilder/src/PacketBuilder.cpp b/lib/PacketBuilder/src/PacketBuilder.cpp deleted file mode 100644 index bd1a03a..0000000 --- a/lib/PacketBuilder/src/PacketBuilder.cpp +++ /dev/null @@ -1,170 +0,0 @@ -#include "PacketBuilder.h" - -PacketBuilder::PacketBuilder(uint16_t address, uint8_t rollingCode1, uint8_t rollingCode2, uint8_t protocolVersion) : - address(address), - rollingCode1(rollingCode1), - rollingCode2(rollingCode2), - protocolVersion(protocolVersion) -{ -} - -PacketBuilder::~PacketBuilder() -{ -} - -void PacketBuilder::buildUpPacket(uint8_t *buffer, uint16_t shadeID) -{ - setPacketSize(buffer, 0x11); - setConstants(buffer); - setProtocolVersion(buffer, protocolVersion); - 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, protocolVersion); - 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, protocolVersion); - setSourceAddress(buffer, address); - setDestinationAddress(buffer, shadeID); - setRollingCodes(buffer); - - buffer[16] = 0x52; // ? - buffer[17] = 0x53; // Command - buffer[18] = 0x00; // Empty? - - calculateCRC(buffer); - - incrementRollingCodes(); -} - -void PacketBuilder::buildSetPositionPacket(uint8_t *buffer, uint16_t shadeID, float percentage) -{ - setPacketSize(buffer, 0x15); - setConstants(buffer); - setProtocolVersion(buffer, protocolVersion); - setSourceAddress(buffer, address); - setDestinationAddress(buffer, shadeID); - setRollingCodes(buffer); - - buffer[16] = 0x3F; // Field command - buffer[17] = 0x5A; // Constant - - buffer[18] = 0x04; // Field of 4 bytes - buffer[19] = 0x40; // Field type (0x40 is set) - buffer[20] = 0x50; // ID of position field - - 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::buildFetchPositionPacket(uint8_t *buffer, uint16_t shadeID) { - setPacketSize(buffer, 0x13); - setConstants(buffer); - setProtocolVersion(buffer, protocolVersion); - setSourceAddress(buffer, address); - setDestinationAddress(buffer, shadeID); - setRollingCodes(buffer); - - buffer[16] = 0x3F; // Field command - buffer[17] = 0x5A; // Constant - - buffer[18] = 0x02; // Field of 2 bytes - buffer[19] = 0x3F; // Field type (0x3F is fetch) - buffer[20] = 0x50; // ID of position field - - 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++; -} \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 56b5d87..33a2421 100644 --- a/platformio.ini +++ b/platformio.ini @@ -24,10 +24,4 @@ lib_deps = plapointe6/EspMQTTClient@^1.13.3 - PacketReceiver=symlink://..\PowerViewSniffer\lib\PacketReceiver - - PacketCRC=symlink://..\PowerViewSniffer\lib\PacketCRC - - PacketBuilder - - PacketParser=symlink://..\PowerViewSniffer\lib\PacketParser + RFPowerView=https://git.mattway.com.au/matt/RFPowerView.git diff --git a/src/main.cpp b/src/main.cpp index 1567105..7f64b26 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,29 +1,17 @@ // sketch to sniff Hunter Douglas packets from a pebble remote or hub -#define CIRCULAR_BUFFER_INT_SAFE - #include -#include // library by TMRh20 #include -#include -#include -#include +#include #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 +// Copied from Powerview Hub userdata API +// eg: http://POWERVIEW_HUB_IP_ADDRESS/api/userdata/ and find the field labeled "rfID" +#define RF_ID (0x2EC8) -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, 0x06); -PacketBuilder hubPacketBuilder(0x0000, 0x3D, 0x96, 0x05); -PacketParser packetParser; +RFPowerView powerView(RF_CE_PIN, RF_CS_PIN, RF_IRQ_PIN, RF_ID); EspMQTTClient client( SECRET_WIFI_SSID, // Wifi SSID @@ -35,48 +23,18 @@ EspMQTTClient client( 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 processPacket(const Packet*); void setup() { Serial.begin(SER_BAUDRATE); Serial.println("Starting up"); - packetReceiver.setPacketCallback(processPacket); - - if (!radio.begin()) { - Serial.println("Failed to communicate with radio"); + powerView.setPacketCallback(processPacket); + if (!powerView.begin()) { + Serial.println("Failed to start RFPowerView"); + return; } - 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); @@ -87,96 +45,47 @@ void setup() { } void loop() { - packetReceiver.loop(); + powerView.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) { - Packet packet; - bool result = packetParser.parsePacket(buffer, packet); - if (result) { - if (packet.type == PacketType::FIELDS) { - FieldsParameters parameters = std::get(packet.parameters); - for (size_t i = 0; i < parameters.fields.size(); i++) { - Field field = parameters.fields[i]; - if (field.identifier == 0x50) { - if (packet.source == 0x4EF1) { - uint16_t value = std::get(field.value); - uint8_t position = (uint8_t)std::round(((float)value / 0xFFFF) * 100); - String payload = String(position); - client.publish("hotdog/test_mqtt_blind/position", payload, true); - } +void processPacket(const Packet *packet) { + if (packet->type == PacketType::FIELDS) { + FieldsParameters parameters = std::get(packet->parameters); + for (size_t i = 0; i < parameters.fields.size(); i++) { + Field field = parameters.fields[i]; + if (field.identifier == 0x50) { + if (packet->source == 0x4EF1) { + uint16_t value = std::get(field.value); + uint8_t position = (uint8_t)std::round(((float)value / 0xFFFF) * 100); + String payload = String(position); + client.publish("hotdog/test_mqtt_blind/position", payload, true); } } } } } -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(100); - 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 = 0x4EF1; if (payload == "OPEN") { - hubPacketBuilder.buildUpPacket(buffer, shadeID); - sendCommand(buffer); + // TODO: Build open Packet and send } else if (payload == "CLOSE") { - hubPacketBuilder.buildDownPacket(buffer, shadeID); - sendCommand(buffer); + // TODO: Build close Packet and send } else if (payload == "STOP") { - hubPacketBuilder.buildStopPacket(buffer, shadeID); - sendCommand(buffer); - hubPacketBuilder.buildFetchPositionPacket(buffer, shadeID); - sendCommand(buffer); + // TODO: Build stop Packet and send + // TODO: Schedule fetching position of blind } }); client.subscribe("hotdog/test_mqtt_blind/set_position", [] (const String &payload) { uint16_t shadeID = 0x4EF1; float percentage = payload.toInt() / 100.0f; - hubPacketBuilder.buildSetPositionPacket(buffer, shadeID, percentage); - sendCommand(buffer); + // TODO: Build set position Packet and send + // TODO: Schedule fetching position of blind }); client.publish("hotdog/availability", "online", true);