Post

How I (Almost) Built an IoT Smart Light Sensor in Java… and What I Learned

How I (Almost) Built an IoT Smart Light Sensor in Java… and What I Learned

The Problem: An Java Networking Exam Question About a Smart Light Sensor

It started as a straightforward exam question:

“You are tasked with developing a Java command-line application that communicates with a smart home IoT device. The device is built on embedded C firmware and runs a lightweight communication driver called ‘Light control v.2.3’. It listens for incoming connections on IP address 192.168.1.100 and port 5000. The device expects a single byte of data: Sending 1 turns ON the smart light, and sending 0 turns OFF the smart light.”

Seemed simple enough. I knew I had to use sockets, so I wrote a program that:
✅ Created a server socket on port 5000.
✅ Created a client socket to connect to 5000.
✅ Sent data (1 or 0) to indicate the light’s state.

Sounds great, right?

Well… I completely misunderstood the question. 💀


Where I Went Wrong

Here is what I wrote as my answer for this question. I thought it required a server implementation instead of a client one and confidently typed all of this out:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import java.io.*;
import java.net.*;

public class ClassExample {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(5000);
            Socket socket = new Socket("191.162.1.10", 5000);

            serverSocket.accept();

            BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter output = new PrintWriter(socket.getOutputStream(), true);

            int data; 
            data = input.read();
            if (data == 1) {
                System.out.println("The light sensor is turned ON");
            }
            else if (data == 0) {
                System.out.println("The light sensor is turned OFF");
            }
            else {
                System.out.println("Error. Expected input is 1 or 0");
            }

            serverSocket.close();
            socket.close;
        }
        catch(IOException e) {
            e.printStackTrace();
        }
    }
}

This is obviously wrong. I had the right idea, kind of, but my implementation was totally off.

1️⃣ I Accidentally Made Both a Server and a Client in One Program

This was really my biggest mistake. My code tried to be both the client and the server at the same time. I wrote:

1
2
ServerSocket serverSocket = new ServerSocket(5000);
Socket socket = new Socket("192.168.1.100", 5000);

🚨 Mistake:

  • A server listens for connections. A client connects to a server.
  • The server doesn’t need to create a client socket; it just waits for clients to connect.
  • Instead of Socket socket = new Socket(...), I should’ve used serverSocket.accept() to wait for a client.

2️⃣ I Used Byte Instead of int for Input

Since the question asked for “a single byte of data,” I declared my variable like this:

1
2
Byte data; 
data = input.read();

🚨 Mistake:

  • Byte in Java is a wrapper class, not a primitive type.
  • input.read() returns an integer (ASCII value), not a Byte.

Fix: Change Byte to int:

1
int data = input.read();

✅ The Correct Client-Side Code

If I had understood this question correctly, here’s what my answer would look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

public class LightSensorClient {
    public static void main(String[] args) {
        String deviceIP = "192.168.1.100"; // IP of the IoT device
        int port = 5000; // The device listens on this port

        try (Socket socket = new Socket(deviceIP, port)) {
            OutputStream outputStream = socket.getOutputStream();
            Scanner scanner = new Scanner(System.in);

            System.out.print("Enter sensor value (1 for ON, 0 for OFF): ");
            int userInput = scanner.nextInt();

            if (userInput == 1 || userInput == 0) {
                outputStream.write(userInput); // Send a single byte (1 or 0)
                outputStream.flush();
                System.out.println("Command sent successfully.");
            } else {
                System.out.println("Invalid input. Please enter 1 or 0.");
            }

            scanner.close();
        } catch (Exception e) {
            System.out.println("Error: Unable to connect to the IoT device.");
            e.printStackTrace();
        }
    }
}

This Implemetation:

  • Connects to the IoT device on IP 192.168.1.100, port 5000.
  • Asks the user for 1 or 0.
  • Sends the value as a single byte to the device.

What I Learned

  • Always read the question carefully. The IoT device itself was the server, meaning I only needed to write a client.
  • When communicating with IoT devices, check if the device expects raw byte data instead of string data. I unfortunately couldn’t run the code during the exam, so there was no way for me to actually check.
  • Don’t overcomplicate the solution—focus only on what’s asked! I feel so stupid for making such a noob mistake, but sh*t happens. Hopefully I’ll get a few marks for at least having the right idea, sort of.
This post is licensed under CC BY 4.0 by the author.