import java.io.IOException;

import jcontrol.comm.FT1_2;
import jcontrol.comm.FT1_2EventListener;
import jcontrol.comm.RS232Selector;
import jcontrol.io.Backlight;
import jcontrol.io.Buzzer;
import jcontrol.io.Display;
import jcontrol.io.Keyboard;

/**
 * <p>PowerLineExample_App shows how to send UDATs using
 * power-line communication with the JControl/PLUI.</p>
 * 
 * <p>(C) DOMOLOGIC Home Automation GmbH 2003</p>
 */
public class PowerLineExample_App implements FT1_2EventListener {
  
  /** FT1.2 protocol */
  static FT1_2 ft12;

  /** System buzzer */   
  Buzzer buzzer = new Buzzer();

  // some BCU data types
    
  /** data request */
  static final byte L_DATA_req       = 0x11;
  /** data indication */
  static final byte L_DATA_ind       = 0x49;
  /** data confirm */
  static final byte L_DATA_con       = 0x4E;
  
  /** 
   * Init FT1.2 protocol 
   */
  public PowerLineExample_App() {
    // switch RS232 to power-line modem
    RS232Selector.selectPort(RS232Selector.INTERNAL);
    // turn on backlight
    Backlight.setBrightness(Backlight.MAX_BRIGHTNESS); 
        
    try {
      // instantiate FT1_2 protocol
      ft12 = new FT1_2();
      // set ourself as the FT1_2EventListener
      ft12.setListener(this);
      // call user interface
      userInterface();
    } catch (java.io.IOException e) {
      // 2 second error beep
      buzzer.on((short)300, (short)2000);
      // read errorcode to reset error flag
      ft12.errorCode();
    }    
  }
  
  
  /**
   * FT1.2 event listener. This method is called any time
   * a power-line datagram drops in.
   * 
   * @see jcontrol.comm.FT1_2EventListener#onIndication(byte[], int)
   */
  public void onIndication(byte[] udat, int control) {
    try {
       switch(control){
         case FT1_2.CF_PRM_SEND_UDAT:
           ft12.sendACK(udat);
           break;
         case FT1_2.CF_PRM_REQ_STATUS:
           ft12.sendResponse(null);
           break;
         case FT1_2.CF_PRM_REQ_CLASS1:
           byte[] buf=new byte[10];
           ft12.sendResponse(buf);
           break;
       }
     } catch(IOException e){}
  }
    
  
  /**
   * Send a power-line UDAT that turns the remote plug on.
   * We assume that the plug is programmed to network address 0x6000.
   */
  void plugOn() {
    ft12.sendUDAT(new byte[] { L_DATA_req,   // link layer command
                                0x0c,         // priority
                                0x00, 0x00,   // src address
                                0x60, 0x00,   // dst address
                                (byte)0xF1,   // NPCI
                                0x00,         // TPCI
                                (byte)0x81 }  // command 'ON'
                 );
  }
  
  /**
   * Send a power-line UDAT that turns the remote plug off.
   * We assume that the plug is programmed to network address 0x6000.
   */
  void plugOff() {
    ft12.sendUDAT(new byte[] { L_DATA_req,   // link layer command
                                0x0c,         // priority
                                0x00, 0x00,   // src address
                                0x60, 0x00,   // dst address
                                (byte)0xF1,   // NPCI
                                0x00,         // TPCI
                                (byte)0x80 }  // command 'OFF'
                 );
  }


  /**
   * A simple keyboard listener. 
   */
  void userInterface() {
    Display lcd = new Display();
    lcd.drawString("PowerLineExample", 0, 0);
    lcd.drawString("Press 'UP'   to turn plug on",0,20);
    lcd.drawString("Press 'DOWN' to turn plug off",0,30);
    
    Keyboard keys = new Keyboard();
    for(;;) {
      switch (keys.read()) {
        case 'U': // turn plug on
          plugOn();
          buzzer.on((short)1000, (short)100);
          break;
          
        case 'D': // turn plug off
          plugOff();
          buzzer.on((short)300, (short)100);
          break;
          
        default:
      }
    }
  }


  /**
   * Main method. Program execution starts here.
   */
  public static void main(String[] args) {
    new PowerLineExample_App();
  }
}
