Homy is here

During the last couple of years, I was giving lots of thoughts to a fully automated house. Usually I was amazed by different ideas, usage of diverse technologies and concepts, but never tried to really apply some of these in my apartment. This changed couple of months ago, and after the first home automation project, I already have couple of more ideas.

It all started when I found this device in a shop nearby:

I spent couple of days mounting these guys all around my apartment. At the end, I presented three remote controls to my wife: one for living room, one for administration room and one for our bedroom. She was skeptic at first, but later realized the benefits.

After couple of weeks I couldn’t resist from opening one of those remotes 🙂 What I found inside was HS1527 in the heart of the device. Next instinctive step was googgling for HS1527 remote control which led me to one really interesting discussion on JeeLabs webpage. There I discovered the magic device: JeeNode USB (v3):

Couple of days after ordering, I received my own JeeNode (+candy :D). Since JeeNode uses FTDI chip I downloaded and installed drivers from FTDI site. Using RealTerm software I quickly connected to the gadget and start playing with pre-installed program. That was fun, but not exactly what I had on mind. I downloaded IDE from Arduino web site, and after couple of hours of the programing, using the code I found in JeeLabs discussion, the first light was remotely turned on and off 🙂

// Homy Control

#include <ctype.h>
#include <Ports.h>
#include <RF12.h>

#define Tck 350

long devIds[16] = {28202, 28202, 28202, 28202, 912938, 912938, 912938, 912938, 416811, 416811, 416811, 416811};
int chanIds[16] = {    0,     4,     2,     1,      0,      4,      2,      1,      0,      4,      2,      1};

static void sendHigh()
{
  rf12_onOff(1);
  delayMicroseconds(Tck+150);
  rf12_onOff(0);
  delayMicroseconds(3*Tck-200);
}

static void sendLow()
{
  rf12_onOff(1);
  delayMicroseconds(3*Tck+150);
  rf12_onOff(0);
  delayMicroseconds(Tck-200);
}

static void sendBit(boolean data)
{
  if (data)
    sendHigh();
  else
    sendLow();
}

static void sendPreamble()
{
  rf12_onOff(1);
  delayMicroseconds(Tck+150);
  rf12_onOff(0);
  delayMicroseconds(31*Tck-200);
}

static void sendPacket(long C, int D)
{
    sendPreamble();
    for(int b = 19; b > -1; b--) sendBit((C >> b) & 0b1);
    for(int b = 3; b > -1; b--) sendBit((D >> b) & 0b1);
}

static void turn(long deviceId, int channel, boolean on)
{
  int count = 5;
  while (count--)
    sendPacket(deviceId, (on ? 0b0000 : 0b1000) | (channel & 0b0111));
}

static void train(long deviceId, int channel)
{
  int count = 100;
  while (count--)
      sendPacket(deviceId, 0b1000 | (channel & 0b0111));
}

static void led(byte on) {
    pinMode(9, OUTPUT);
    digitalWrite(9, !on);
}

char getc()
{
  while (Serial.available()==0) {}
  return Serial.read();
}

int device(char c)
{
  c = toupper(c);
  if (c>='0' && c<='9')
    return (int)(c-48);
  if (c>='A' && c<='F')
    return (int)(c-55);

  return -1;
}

void setup() {
  Serial.begin(57600);
  rf12_initialize(0, RF12_433MHZ);
  Serial.println("Homy Control");
  Serial.println();
  Serial.println("Syntax :");
  Serial.println(" [0|1|X|Z]<device>");
  Serial.println();
  Serial.println(" where :");
  Serial.println("    0 - turn off");
  Serial.println("    1 - turn on");
  Serial.println("    X - turn all off for device group");
  Serial.println("    Z - hook device");
  Serial.println("    <device> - device code (hex digit)");
  Serial.println();
}

void loop() {

  Serial.print(">");

  char fc = getc();
  int dev;

  switch(toupper(fc))
  {
    case 'Z':
        dev = device(getc());
        led(1);
        train(devIds[dev],chanIds[dev]);
        Serial.print("Train ");Serial.print(devIds[dev]);Serial.print(" ");Serial.println(chanIds[dev]);
        led(0);
      break;

    case '1':
        dev = device(getc());
        turn(devIds[dev],chanIds[dev],1);
        Serial.print("On ");Serial.print(devIds[dev]);Serial.print(" ");Serial.println(chanIds[dev]);
      break;

    case '0':
        dev = device(getc());
        turn(devIds[dev],chanIds[dev],0);
        Serial.print("Off ");Serial.print(devIds[dev]);Serial.print(" ");Serial.println(chanIds[dev]);
      break;

    case 'X':
        dev = device(getc());
        turn(devIds[dev],7,1);
        Serial.print("Off ALL ");Serial.println(devIds[dev]);
      break;

    default:
        led(1);
        Serial.println("*");
        led(0);
      break;
  }
}

Since the antenna shipped with JeeNode was for 868 MHz RF signals, the range was pretty poor. I replaced that antenna with 165mm one, that is optimal length of whip antenna for frequencies of 433 MHz. The range boosted and now all the lights in my apartment were covered. I showed my new baby to my wife, and explained her that if she types 11 in console, light will turn on. She gave me strange look. We named this project Homy.

Next step was software part for my home computer. After whole weekend of programming, the result was Windows application that talks to JeeNode using COM port communication and exposes web service for further integration.

Also, in order to access service from my PC, I developed a client that communicates with Homy Control Service using web services:

By then my wife was pretty angry since I spent whole weekend programming, so I had to do something about it. She recently became an owner of iPhone, so logical step was to bring the fun there. Using jQTouch, a jQuery plugin for developing for iPhone, a simple web application was born:

After this, we started playing like two kids, each of us with its own controller. I think neighbors must have been shocked, since the lights were going on and off the whole night.

Another thing that took me additional night of thinking and programming was how to determine the IDs of the existing remote controllers, so we can use the in parallel.

At the end, here is short video demonstration of Homy:

© 2010, Quo Vadis ?. All rights reserved.

Loading

14 thoughts on “Homy is here”

  1. Hi Dusan,

    Just found your blog with some (very) interesting projects.
    Regarding this one, I would like to ask two questions:

    – It seems to me that the devices you bought were remote controlled wall sockets. How did you install them on your ceiling lamps? Did you take them apart? Or do you have some specific socket to the lamps?

    – Is there any tiny possibility for you to share the code for your apps?

    Thank you, for sharing such great projects.

    1. Hi Miguel,

      I am glad you like the projects.

      Yes you are right. There are wall sockets, and I had to strip plastic parts and hook them directly to ceiling wires.

      Regarding then source code, let me know which part you are interested in, and I can share it via email.

      Cheers.

      1. Hi Dušan,

        I have been watching your log since I discovered it and posted my question(s). I just realized that you’ve replied my post “inside” itself. I was expecting that your answer appeared above my post. Sorry that I didn’t answer before. In fact I was losing my hope in getting any kind of feedback from you. (I thought that you were not updating anymore this blog).

        Anyway, I am “collecting” some bits to reproduce your Grundtall project as a first step. Not only for me but also to track my son’s weight (it has 6 years old). I am also planning to add a sonar (supported above our head) to measure the height of the person being weighted, and since the system will server at least three people, I will try to add a way to identify which person is using the scale (I’m thinking in using smart tags)…

        Regarding the code, I was referring the code you have created for this project “The Homy” that enables you to control the lights around your house with your phone. It seems to me that you have an iPhone app (I would need an Android one) and a central application, apparently windows based.
        If you can and are willing to, I would be more than happy if you could share it with me at: agmvault at gmail dot com.

        1. Hello Dušan,

          I didn’t receive anything in my mailbox.
          I understand that you do not want/could share the project. If that is the case I just ask you to let me know (it could be by e-mail).
          Since you didn’t say anything, I don’t know if I am just being annoying in your blog…

          Thank you

          1. Holidays season 🙂 Check your inbox.

  2. Hi Dule, didnt see your blog till now, I really like this. Will keep an eye on it 🙂
    Let us know hows family expanding going 😉

    1. Hi Mike,

      I used C# and .NET together with Microsoft Visual Studio. You can use Express edition which is free.

      Good luck …

  3. Hi there,

    nice work with the UI, I’ve been playing with this the last few days myself. Been using JeeLabs products for a year or so now, great stuff.

    Just wanted to ask, is there a chance you’d be willing to share your jQTouch code for the client? I’m pretty good with HW but not much of a web developer, so any inspiration would be hugely helpful…

    thanks

    1. Hi Göran,

      Thanks. JeeNodes are really great and funny.

      Check you email 🙂

      Cheers

  4. Bravo Dusane ovo su mi pricali Buca i Nidza ihteo sam to da proverim i veoma mi se svidja.Samo to kod nas jos ne moze da zazivi.puno pozdrava za tebe i komsiku.

  5. Nice article. Jeenodes are great. So how did you determine the IDs of the controllers?

    1. Hi Nick, that was small project itself 🙂

      Basically, I connected the output pin from HS1527 chip directly to a input pin of JeeNode and then scanned signal when button is pressed. Using specs for HS1527 packet, it is easy to find the ID of the device. Just in my case logical levels from the output pin were inverted (0 for 1 and 1 for 0).

      Here is the code:

      #include <Ports.h>
      #include <RF12.h>
      
      #define  vMAX  1010
      
      char getc()
      {
      	while (Serial.available()==0) {}
      	return Serial.read();
      }
        
      void setup() 
      {
      	Serial.begin(9600);
      	pinMode(3, INPUT);
      }
      
      int sensorValue = 0;
      
      byte v[vMAX];
      int vi = 0;
      
      void loop() {
      	Serial.println("Press button on the remote to scan");
        
      	while(analogRead(3)<512);
      	vi = 0;
        
      	Serial.print("Starting...");
      	long s = millis();
        
      	while (vi < vMAX)
          	    v[vi++] = (analogRead(3) >> 2);
        
      	s = millis()-s;
      
      	Serial.print("   ... done [");Serial.print(s);Serial.println("ms]");
        
      	long deviceId;
              int groupId;
              
      	int ci;
      
      	vi = 0;
      	while (vi<vMAX)
      	{
      		int hb = vi;
      		while (v[vi]>=128) vi++;
      		int he = vi;
      
      		int lb = vi;
      		while (v[vi]<128) vi++;
      		int le = vi;
          
      		int h = he-hb;
      		int l = le-lb;
          
      		int val;
                      
      		if (h>2*l) val = 0;
      		if (2*h<l) val = 1;
      
      		if (20*h<l) 
      		{
      			Serial.println();
      			deviceId = 0;
                              groupId = 0;
      			ci=0;
                              continue;
      		}
      
      		Serial.print(val); 
      		
      		if (ci < 20) 
      		{
      			deviceId = (deviceId * 2) + val;
      		}
      
      		if (ci == 19) 
      		{
      			Serial.print(" [");  Serial.print(deviceId);        Serial.print("] - ");
      		}
      		
      		if (ci == 20)
      		{
      			if (val == 1)
                              {
                                  Serial.print(" [OFF] - ");
                              }
                              else
                              {
                                  Serial.print(" [ON]  - ");
                              }
      		}
                      if (ci > 20 && ci < 24)
                      {
                              groupId = (groupId * 2) + val;
                      }
                      if (ci == 23)
                      {
                          Serial.print(" ["); Serial.print(groupId);        Serial.print("]");
                      }
                      
              	ci++;
      	}
      
      	Serial.println();
      }
      
      
      
  6. lol… sounds interesting… nice hoby.. uhmm, homy, i wanted to say 😉
    just keep on going!!! and try not to neglect your lady too much, otherwise everything will go out the window ;))

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.