Things used in this project

Hardware components:
Amazon Alexa Echo Dot 2nd generation
×1
Photon new
Particle Photon
×1
optocoupler sharp pc817
×1
sunfounder 2 channel relay
×1
Software apps and online services:
Screen%20shot%202015 07 20%20at%206.10.26%20pm
Amazon Web Services AWS Lambda

Schematics

shortening pins 1&2 and 3&4 routes the audio to the internal speaker
Inkedimg 5070 li 9g1rl8jrc2
Optocoupler interface to amplifier 12V trigger
Optocoupler schem bwt4hveo9y

Code

Photon code for Alexa internal speaker control (and serial controller)Arduino
/*
  Krell- serial controller
  Waldemar Sakalus - SAKA
  version 01022018
 */

unsigned long resetTimer = millis();

TCPClient node;
byte nodeIP[] = { 192, 168, 1, 182 }; //put your Node_IP_address
String nodeResponse;

String nodeStatus = "Status";
String nodePlay = "Play";
String nodePause = "Pause";
String nodeSkip = "Skip";
String nodeBack = "Back";

const unsigned long smartInterval = 1000; //1s probing time, how often Node is checked whether playing/ stopped
unsigned long smartTimer = millis();

String nodeState = "";
String previousState = "";

int builtInLED = 7;
int ampOpto = D3;
int relayControl = D4;

byte triggerPreviousState;
byte alexaSpeaker = LOW;


void setup() {
    Serial1.blockOnOverrun(false);
    Serial1.begin(9600, SERIAL_8N1);
    Particle.function("KrellSerial", controlAmplifier);
    Particle.function("Node", controlNode);
    
    pinMode(builtInLED, OUTPUT);
    pinMode(ampOpto, INPUT);
    pinMode(relayControl, OUTPUT);
    
    triggerPreviousState = digitalRead(ampOpto);
    checkAmp();
    digitalWrite(relayControl, HIGH);
}

void loop() {
    if (digitalRead(ampOpto) != triggerPreviousState) {
        if (!checkAmp()) digitalWrite(relayControl, HIGH);
        triggerPreviousState = digitalRead(ampOpto);
    }
    if (smartTimer < millis()) {
        nodeCommand(nodeStatus);
        nodeState = tryExtractString(readNodeResponse(),"<state>","</state>");
        if (previousState != nodeState) {
            if (nodeState == "play" || nodeState == "stream") {
                Serial1.println("1PWRZ");
                Serial1.println("SS2MZ");
            }
            else if (nodeState == "pause") {
                Serial1.println("0PWRZ");
            }
            previousState = nodeState;
        }
        smartTimer = millis() + smartInterval;
    }
    
    // Reset after 12h of operation
    // ==================================
    if (millis() - resetTimer > 43200000) {
        System.reset();
    }
}

int controlAmplifier(String command)
{
    if (command != NULL) {
        if (command.startsWith("0PWRZ")) {
            Serial1.println("SS1MZ"); //defaults to input S1 before switching amplifier off
            Serial1.flush();
            //if (command.endsWith("bluesoundOff")) {
            stopNode();
            //}
            Serial1.println("0PWRZ");
            resetAlexaSpeaker;
        }
        else if (!(command.startsWith("1PWRZ"))) {
            Serial1.println(command);
            if (command.startsWith("SS2MZ")) startNode();
            else if (command.startsWith("SS1MZ") || command.startsWith("SS2MZ")) stopNode();
        }
        else if (command.startsWith("1PWRZ")) {
            Serial1.println("1PWRZ");
            Serial1.flush();
            if (command.endsWith("stereoOn")){
                Serial1.println("SS3MZ"); //defaults to input S3
                digitalWrite(relayControl, LOW);
                alexaSpeaker = HIGH;
            }
            else if (command.endsWith("recordOn")) {
                Serial1.println("SS1MZ"); //defaults to input S1
                resetAlexaSpeaker; 
            }
            else if (command.endsWith("bluesoundOn")) {
                Serial1.println("SS2MZ"); //defaults to input S2
                startNode();
                resetAlexaSpeaker;
            }
        }
        return 1;
    }
    else return -1;
}

void resetAlexaSpeaker()
{
    if (alexaSpeaker) {
        digitalWrite(relayControl, HIGH);
        alexaSpeaker = LOW;
    }
}

int controlNode(String command)
{
    if (command != NULL) {
        if (command == "Play") nodeCommand(nodePlay);
        else if (command == "Pause") nodeCommand(nodePause);
        else if (command == "Stop") nodeCommand(nodePause);
        else if (command == "Next") nodeCommand(nodeSkip);
        else if (command == "Previous") nodeCommand(nodeBack);
        return 1;
    }
    else return -1;
}

void startNode() {
    nodeCommand(nodeStatus);
    nodeState = tryExtractString(readNodeResponse(),"<state>","</state>");
    if (nodeState == "pause") nodeCommand(nodePlay);
}

void stopNode() {
    nodeCommand(nodeStatus);
    nodeState = tryExtractString(readNodeResponse(),"<state>","</state>");
    if (nodeState == "play" || nodeState == "stream") nodeCommand(nodePause);
}

void nodeCommand(String command)
{
    if (node.connect(nodeIP, 11000))
    {
        String post = "GET /";
        post += command;
        post += " HTTP/1.1\r\n";
        post += "Host: ";
        post += nodeIPString();
        post += ":1400\r\n";
        post += "Cache-Control: no-cache\r\n\r\n";
        //Serial.println(post);
        node.print(post);

        delay(10);
    }
    else Serial.println("connection failed");
}

byte checkAmp () {
    byte ampRead = digitalRead(ampOpto);
    if (ampRead) {
        digitalWrite(builtInLED, LOW);
        return LOW;
    }
    else {
        digitalWrite(builtInLED, HIGH);
        return HIGH;
    }
}

String readNodeResponse() {
    unsigned long lastdata = millis();
    String nodeResponse = "";
    while (node.connected()  || (millis()-lastdata < 500)) { //500ms timeout
        if (node.available()) {
            char c = node.read();
            nodeResponse += c;
            lastdata = millis();
        }
    }
    node.flush();
    node.stop();
    return nodeResponse;
}


String nodeIPString(){
    String addressIP = "";
    for (int i = 0; i < 4; i++) {
        addressIP += nodeIP[i];
        if (i < 3) {
            addressIP += ".";
        }
    }
    return addressIP;
}

String tryExtractString(String str, const char* start, const char* end) {
    if (str == NULL) {
        return "";
    }

    int idx = str.indexOf(start);
    if (idx < 0) {
        return "";
    }

    int endIdx = str.indexOf(end);
    if (endIdx < 0) {
        return "";
    }

    return str.substring(idx + strlen(start), endIdx);
}

Credits

Bd7f5fc87bfd40aaa639c1a3792cadd2
Waldemar Sakalus
3 projects • 16 followers
Contact

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Add projectSign up / Login