BuddyC
Published © Apache-2.0

Zoned Climate Control with MediaTek's LinkIt™ Smart 7688

Control the temperature of the rooms you are actually in

IntermediateFull instructions provided7,401
Zoned Climate Control with MediaTek's LinkIt™ Smart 7688

Things used in this project

Story

Read more

Schematics

WiFi Temp Sensor

ATtiny85 or Arduino Nano pulling temps from a DHT11/22 and WiFi connected with an ESP8266.
Wifi temp sensor

Code

LinkIt Smart Duo WiFi Vent

C/C++
This sketch uses the Bridge and HTTP Client libraries from the Arduino Yun to poll a web server and open/close HVAC vents as needed.
/* 
 Adapted from Sweep servo example 
 by BARRAGAN <http://barraganstudio.com> 
    and
 Yun HTTP Client example
 created by Tom igoe  <http://www.arduino.cc/en/Tutorial/HttpClient>
*
* Both are in the public domain.
*
*
* Code Adapted for HAI (Home Automation w/ Intelligence) by Buddy Crotty
*
* This arduino sketch relies on a web server to do all the heavy lifting.  This can be
a seperate device like a Raspberry Pi, or you can run it on the MPU side of the LinkIt Smart in
OpenWRT.
*
* The web server collects temp readings from around the house and determins where hot/cold air
needs to go based on time of day, outside weather (including forcast), and home occupancy.
*
* It then outputs 'upstairs', 'downstairs', or 'wholehouse' depending on where the air needs
to be sent.  
*/

#include <Servo.h> 
#include <Bridge.h>
#include <HttpClient.h>
 
Servo upservo;      // create servo object to control upstairs servo 
Servo downservo;   // downstairs air vent damper servo            
 
int uppos = 0;      // variable to store the (upstairs) servo position 
int downpos = 0;    // downstairs servo position   
const char* host = "192.168.1.80";         // Internal IP of Home Automation Webserver
int dopenangle = 80;               // Number of degrees your servo needs to turn between open/close on the vent
int dcloseangle = 0;     
int uopenangle = 140;     
int ucloseangle = 0;     

void setup() 
{ 
  upservo.attach(9);      // Pin for Servo attached to upstairs air vent damper
  downservo.attach(10);   // Pin for Servo attached to downstairs air vent damper
  
  //start bridge to OpenWRT
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  Bridge.begin();
  digitalWrite(13, HIGH);
} 

void wholehouse()
{
  if (downpos <= dcloseangle){                                            // Make sure vent isn't already in position
   //open downstairs vent
    for(downpos = dcloseangle; downpos <= dopenangle; downpos += 1)       // Move from set close angle to open angle one step at a time
    {                                                                     
      downservo.write(downpos);                                           
      delay(20);                                                           // waits between steps until servo reaches position
    } 
  }

  if (uppos <= uopenangle) {
    //open upstairs vent
    for(uppos = ucloseangle; uppos <= uopenangle; uppos += 1)      
    {                                   
      upservo.write(uppos);              
      delay(20);                        
    }    
  }
}


void downstairs()
{
  if (downpos <= dopenangle) {
    //open downstairs vent
    for(downpos = dcloseangle; downpos <= dopenangle; downpos += 1)    
    {                                                                   
      downservo.write(downpos);                                   
      delay(20);                                                         
    } 
   }
  if (uppos >= ucloseangle){
    //close upstairs vent 
    for(uppos = uopenangle; uppos >= ucloseangle; uppos-= 1)      
    {                                   
      upservo.write(uppos);              
      delay(20);                        
    }
  }
}

void upstairs() 
{ 
  if (uppos <= uopenangle) {
     //open upstairs vent
    for(uppos = ucloseangle; uppos <= uopenangle; uppos += 1)      
    {                                   
      upservo.write(uppos);              
      delay(20);                        
    }    
  }
  if (downpos >= dcloseangle){  
    //close downstairs vent 
    for(downpos = dopenangle; downpos >= dcloseangle; downpos -= 1)      
    {                                   
      downservo.write(downpos);              
      delay(20);                        
    } 
  }
} 

void loop()
{
  HttpClient client;
  // Create and make a HTTP request:
  String cmd = "http://";
  cmd += host;
  cmd += "/vent.txt";
  client.get(cmd);
  // Read incoming bytes from the server 
  while (client.available()) {
    int c = client.read();
      if (c == '2') upstairs();
      if (c == '1') downstairs();
      if (c == '0') wholehouse();
  }
  delay(60000);
}

WiFi Temp Sensor

C/C++
Connected Temperature and Humidity sensor. Logs data to central Home Automation server.
/*
 *  Code Adapted for HAI (Home Automation w/ Intelligence) by Buddy Crotty
 *
 *  Sends data via HTTP GET requests to your HAI server
 *
 *  Connectivity is via software serial connection to an ESP8266 WiFi 
 *  interface already configured to connect to your wLAN,
 *  but you can uncomment out the WiFi settings to reset SSID/password
 *  
 */

const char* host = "192.168.1.80";         // Internal IP of Home Automation Webserver
const char* devID = "downstairs";           // Device ID (single word, no spaces, no special characters)
 
#include <SoftwareSerial.h>

SoftwareSerial ser(10, 11); // (RX, TX)      // Software serial for controling ESP8266 Module
                                             // Hardware serial for debugging

long utime = 300000;  // Time in between updates 
                      // 900000 = 15 minutes (for battery/solar power)
                      // 300000 = 5 minutes (for AC power)
                      // 5000 = 5 seconds (for testing)
                      // Must be longer than 10000 for ESP8266 to come out of sleep mode (battery mode)
                       
// Temperature and Humidity Sensor 
#include <DHT.h>
#define DHTPIN 2        //Pin for temp/humidity sensor
#define DHTTYPE DHT22   // DHT11, DHT22 (AM2302, or DHT21 (AM2301)
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
  ser.begin(9600);
  //ser.listen();

  /*
  // Uncomment to reset WiFi settings
    delay(1000);
    ser.println("AT+CWMODE=1");
    ser.println("AT+CWJAP=\"SSID\",\"Password\"");
  */
 
  ser.println("AT+RST");        // Reset ESP8266 since arduino was reset
  
  delay(10);
  dht.begin();                  // Start DHT
  
  Serial.println("Giving everything a chance to warm up");          //wait 25 seconds for WiFi to connect
  Serial.println("|-------------------------|");
  Serial.print("|");
  for(int x = 0; x < 25; x++){
    Serial.print("#");
    delay(1000); 
  }
  Serial.println("|");
  Serial.println("Done");
}

  float t = 0;
  int h = 0;
  float hi = 0;

void loop() {
  Serial.println();

    //Temp and Humidity  
    float t = dht.readTemperature(true);
    int h = dht.readHumidity();
    float hi = dht.computeHeatIndex(t, h);

// Output values being sent to ThingSpeak
  Serial.print("Temperature: "); 
  Serial.print(t);
  Serial.print(" *F\t");
  Serial.print("Heat Index: ");
  Serial.print(hi);
  Serial.println(" *F");  
  Serial.print("Humidity: "); 
  Serial.print(h);  
  Serial.println("%\t");  
  Serial.print("...connecting to ");
  Serial.println(host);  
  
  // TCP connection
  String cmd = "AT+CIPSTART=\"TCP\",\"";
  cmd += host;             
  cmd += "\",80";
  ser.println(cmd);
    delay(1000); 
  if(ser.find("Error")){
    Serial.println("AT+CIPSTART error");
    return;
  }
  else{
  }

  // prepare GET string
  String getStr = "GET /tempupdate.php?ID=";
  getStr += devID;
  getStr += "&field1="; //Temp
  getStr += t;
  getStr += "&field2="; //Humidity
  getStr += h;
  getStr += "&field3="; //Heat Index
  getStr += hi;
  getStr += "\r\n\r\n";

  Serial.print("Sending data URL: ");
  Serial.println(getStr);

  // send data length
  cmd = "AT+CIPSEND=";
  cmd += String(getStr.length());
  ser.println(cmd);

  if(ser.find(">")){
    ser.print(getStr);
    Serial.println("Success!");
  }
  else{
    ser.println("AT+CIPCLOSE");
    Serial.println("Connection Failed");        // alert user
  }

Serial.print("Next update in ");
Serial.print(utime / 1000);
Serial.println(" seconds");

delay(utime);         //wait between updates
    
}

Vent.php

PHP
Check status and manually override the vent configuration.
<html>
<head>
<style>
.myButton {
        -moz-box-shadow: 0px 10px 14px -7px #276873;
        -webkit-box-shadow: 0px 10px 14px -7px #276873;
        box-shadow: 0px 10px 14px -7px #276873;
        background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #599bb3), color-stop(1, #408c99));
        background:-moz-linear-gradient(top, #599bb3 5%, #408c99 100%);
        background:-webkit-linear-gradient(top, #599bb3 5%, #408c99 100%);
        background:-o-linear-gradient(top, #599bb3 5%, #408c99 100%);
        background:-ms-linear-gradient(top, #599bb3 5%, #408c99 100%);
        background:linear-gradient(to bottom, #599bb3 5%, #408c99 100%);
        filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#599bb3', endColorstr='#408c99',GradientType=0);
        background-color:#599bb3;
        -moz-border-radius:20px;
        -webkit-border-radius:20px;
        border-radius:20px;
        display:inline-block;
        cursor:pointer;
        color:#ffffff;
        font-family:Arial;
        font-size:100px;
        font-weight:bold;
        /*padding:13px 80px;*/
        padding: 50px 200px;
        text-align: center;
        text-decoration:none;
        text-shadow:0px 5px 0px #3d768a;
}
.myButton:hover {
        background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #408c99), color-stop(1, #599bb3));
        background:-moz-linear-gradient(top, #408c99 5%, #599bb3 100%);
        background:-webkit-linear-gradient(top, #408c99 5%, #599bb3 100%);
        background:-o-linear-gradient(top, #408c99 5%, #599bb3 100%);
        background:-ms-linear-gradient(top, #408c99 5%, #599bb3 100%);
        background:linear-gradient(to bottom, #408c99 5%, #599bb3 100%);
        filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#408c99', endColorstr='#599bb3',GradientType=0);
        background-color:#408c99;
}
.myButton:active {
        position:relative;
        top:1px;
}
</style>
<link rel="manifest" href="manifest.json">
</head>
<body>
<div align="center">
<a href="vent.php?zone=2" class="myButton">Upstairs Only</a><br><br>
<a href="vent.php?zone=0" class="myButton">Whole House </a><br><br>
<a href="vent.php?zone=1" class="myButton">Downstairs Only</a>
<br><br>
<?php
$myfile = fopen("vent.txt", "r") or die("Unable to open file!");
$status = fgets($myfile);
if ($status != "") print "<h1>Vents currently open for ";
if ($status === "0") print "the Whole House";
if ($status === "1") print "Downstairs Only";
if ($status === "2") print "Upstairs Only";
print "<br>";
fclose($myfile);
if ($_GET["zone"] == "");
else {
$myfile = fopen("vent.txt", "w+") or die("Unable to open file!");
if ($_GET["zone"] != "") print "<h1>Sending command to open vents for ";
if ($_GET["zone"] === "0") print "the Whole House";
if ($_GET["zone"] === "1") print "Downstairs Only";
if ($_GET["zone"] === "2") print "Upstairs Only";
print "</h1>";
fwrite($myfile, $_GET['zone']);
fclose($myfile);
}
?>
</div>
</body>
</html>

LinkIt Smart Vent Android WebApp

JSON
Manifest file so chrome on Android opens up the vent controller as a web app.
{
  "name": "LinkIt Smart Vent",
  "icons": [
    {
      "src": "LinkIt_icon_36.png",
      "sizes": "36x36",
      "type": "image/png",
      "density": 0.75
    },
    {
      "src": "LinkIt_icon_48.png",
      "sizes": "48x48",
      "type": "image/png",
      "density": 1.0
    },
    {
      "src": "LinkIt_icon_128.png",
      "sizes": "128x128",
      "type": "image/png",
      "density": 1.0
    },
    {
      "src": "LinkIt_icon_192.png",
      "sizes": "192x192",
      "type": "image/png",
      "density": 1.0
    }
  ],
  "start_url": "vent.php",
  "display": "standalone",
  "orientation": "portrait"
}

Credits

BuddyC

BuddyC

10 projects • 64 followers
I collect hobbies.
Contact

Comments