Migrate Hotdog to RFPowerView
This commit is contained in:
147
src/main.cpp
147
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 <Arduino.h>
|
||||
#include <RF24.h> // library by TMRh20
|
||||
#include <EspMQTTClient.h>
|
||||
#include <PacketReceiver.h>
|
||||
#include <PacketBuilder.h>
|
||||
#include <PacketParser.h>
|
||||
#include <RFPowerView.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
|
||||
// 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<FieldsParameters>(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<uint16_t>(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<FieldsParameters>(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<uint16_t>(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);
|
||||
|
||||
Reference in New Issue
Block a user