package com.knutejohnson.pi;

import java.io.*;
import java.net.*;
import java.nio.charset.*;
import java.nio.file.*;
import java.util.*;

/**
 * TemperatureSenderDHT11 is a complimentary program to Thermometer to
 * transmit data from a Pi with a DHTxx device attached.
 * TemperatureSenderDHT11 sends the data via multicast packet to the
 * Thermometer program.  TemperatureSenderDHT11 is designed to be run
 * repeatedly by cron but may be run from the command line for testing.
 * The program has two command line options that are required, the
 * location/description to be displayed with the temperature on the
 * Thermometer program and the channel number.  Valid channel numbers are 0
 * through 5.  Spaces can be included in the location by enclosing the option
 * with quotes (ie java -jar TemperatureSenderDHT11.jar "Living Room" 0).
 *
 * @version 0.11 - 4 January 2019
 * @author  Knute Johnson
 */
public class TemperatureSenderDHT11 {
    /** Program version */
    private static final String VERSION = "0.11";

    /** Program date */
    private static final String DATE = "4 January 2019";

    /** Destination port for multicast data packets */
    private static final int PORT = 56789;

    /** Multicast IP address */
    private static final String IPADDR = "239.0.0.123";

    /**
     * Program entry point, checks for valid command line arguments, reads the
     * temperature data from the DHTxx device and sends that data to the
     * Thermometer program.
     *
     * @param   args    command line arguments (see above)
     */
    public static void main(String... args) {
        if (args.length == 2) {
            try {
                String location = args[0];
                int channel = Integer.parseInt(args[1]);
                if (channel < 0 || channel > 5)
                    throw new NumberFormatException("channel not 0-5");
                Path tempPath = FileSystems.getDefault().getPath(
                 "/sys/bus/iio/devices/iio:device0/in_temp_input");

                try (BufferedReader br = Files.newBufferedReader(tempPath)) {
                    String tempStr = null;
                    // try reading 10 times because sometimes it doesn't work
                    for (int i=0; i<10; i++) {
                        try {
                            tempStr = br.readLine();
                            break;
                        } catch (IOException ioe ) {
                            try {
                                Thread.sleep(700);
                            } catch (InterruptedException ie) {
                                ie.printStackTrace();
                            }
                        }
                    }
                    // pack the location, channel number and temperature into
                    // a UTF-8 string and send it twice with a half second
                    // pause because sometimes the packets get lost
                    try (MulticastSocket socket = new MulticastSocket(PORT)) {
                        String str = String.format("%s,%d,%s",
                         location,channel,tempStr);
                        DatagramPacket packet = new DatagramPacket(
                         str.getBytes(StandardCharsets.UTF_8),
                         str.length(),InetAddress.getByName(IPADDR),PORT);
                        // send the data, wait 1/4 sec and send again
                        socket.send(packet);
                        Thread.sleep(250);
                        socket.send(packet);
                    } catch (IOException|InterruptedException ex) {
                        ex.printStackTrace();
                    }
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            } catch (NumberFormatException nfe) {
                nfe.printStackTrace();
            }
        } else {
            System.out.println("Usage: java -jar TemperatureSenderDHT11.jar " +
             "location channel(0-5)");
        }
    }
}