/**
*
* @author greg (at) myrobotlab.org
*
* This file is part of MyRobotLab (http://myrobotlab.org).
*
* MyRobotLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version (subject to the "Classpath" exception
* as provided in the LICENSE.txt file that accompanied this code).
*
* MyRobotLab is distributed in the hope that it will be useful or fun,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* All libraries in thirdParty bundle are subject to their own license
* requirements - please refer to http://myrobotlab.org/libraries for
* details.
*
* Enjoy !
*
* */
package org.myrobotlab.service;
import org.myrobotlab.framework.Service;
import org.myrobotlab.framework.ServiceType;
import org.myrobotlab.logging.Level;
import org.myrobotlab.logging.LoggerFactory;
import org.myrobotlab.logging.LoggingFactory;
import org.slf4j.Logger;
/**
*
* PICAXE - this service is for the PICAXE microcontroller.
*
* http://www.picaxe.com/
*
* Currently supports: Arduino Duemilanove -
* http://arduino.cc/en/Main/ArduinoBoardDuemilanove
*
* - Find Arduino Message set - DigitalWrite (pin, data?) - ArduinoProgram
* HashMap<Key, Program> - loadProgram (Key) - key - default key & program
*
* References: http://www.arduino.cc/playground/Main/RotaryEncoders
*
*/
public class Picaxe extends Service // implements SerialPortEventListener,
// DigitalIO, AnalogIO, ServoController
{
public class PICAXEThread implements Runnable {
public Thread thread = null;
public boolean isRunning = true;
PICAXEThread() {
thread = new Thread(this, getName() + "_ticking_thread");
thread.start();
}
@Override
public void run() {
try {
while (isRunning == true) {
if (pulseDataType == PulseDataType.increment) {
invoke("pulse", pulseDataInteger);
++pulseDataInteger;
} else if (pulseDataType == PulseDataType.integer) {
invoke("pulse", pulseDataInteger);
} else if (pulseDataType == PulseDataType.none) {
invoke("pulse");
} else if (pulseDataType == PulseDataType.string) {
invoke("pulse", pulseDataString);
}
Thread.sleep(interval);
}
} catch (InterruptedException e) {
log.info("PICAXEThread interrupt");
isRunning = false;
}
}
}
// types
public enum PulseDataType {
none, integer, increment, string
}
private static final long serialVersionUID = 1L;
public final static Logger log = LoggerFactory.getLogger(Picaxe.class.getCanonicalName());
// fields
public int interval = 1000;
public PulseDataType pulseDataType = PulseDataType.none;
public String pulseDataString = null;
public int pulseDataInteger;;
public transient PICAXEThread myPICAXE = null;
public static void main(String[] args) throws Exception {
LoggingFactory.init(Level.DEBUG);
// RemoteAdapter remote = new RemoteAdapter("remote");
// remote.startService();
// test
Picaxe PICAXE = new Picaxe("PICAXE");
PICAXE.startService();
RemoteAdapter remote = new RemoteAdapter("remote");
remote.startService();
// PICAXE.addListener("pulse", "log", "log", Integer.class);
// GUIService gui = new GUIService("gui");
// gui.startService();
//
/*
* FileOutputStream fos = null; ObjectOutputStream out = null; try {
*
* fos = new FileOutputStream("test.backup"); out = new
* ObjectOutputStream(fos); out.writeObject(remote); out.writeObject(log);
* out.writeObject(PICAXE); out.writeObject(gui); out.close();
*
*
* log.startService();
*
* PICAXE.startService(); PICAXE.startPICAXE();
*
* gui.startService();
*
*
* } catch (Exception e) { log.error(e.getMessage());
* log.error(stackToString(e)); }
*/
}
public Picaxe(String n) {
super(n);
}
public Picaxe getState() {
return this;
}
// new state functions begin --------------------------
@Override
public Picaxe publishState() {
return this;
}
public void pulse() {
}
public Integer pulse(Integer count) {
log.info("pulse " + count);
return count;
}
public String pulse(String d) {
return d;
}
public void setInterval(Integer milliseconds) {
interval = milliseconds;
}
public Integer setPulseDataInteger(Integer s) {
pulseDataInteger = s;
return s;
}
public String setPulseDataString(String s) {
pulseDataString = s;
return s;
}
// TODO - how
public void setPulseDataType(PulseDataType t) {
pulseDataType = t;
}
// TODO - reflectively do it in Service? !?
// No - the overhead of a Service warrants a data only proxy - so to
// a single container class "PICAXEData data = new PICAXEData()" could allow
// easy maintenance and extensibility - possibly even reflective sync if
// names are maintained
public Picaxe setState(Picaxe o) {
this.interval = o.interval;
this.pulseDataInteger = o.pulseDataInteger;
this.pulseDataString = o.pulseDataString;
// this.myPICAXE = o.myPICAXE;
this.pulseDataType = o.pulseDataType;
return o;
}
// new state functions end ----------------------------
public void setType(PulseDataType t) {
pulseDataType = t;
}
// TODO - enum pretty unsuccessful as
// type does not make it through Action
public void setType(String t) {
if (t.compareTo("none") == 0) {
pulseDataType = PulseDataType.none;
} else if (t.compareTo("increment") == 0) {
pulseDataType = PulseDataType.increment;
} else if (t.compareTo("string") == 0) {
pulseDataType = PulseDataType.string;
} else if (t.compareTo("integer") == 0) {
pulseDataType = PulseDataType.integer;
} else {
log.error("unknown type " + t);
}
}
public void startPICAXE() {
if (myPICAXE == null) {
myPICAXE = new PICAXEThread();
}
}
public void stopPICAXE() {
if (myPICAXE != null) {
log.info("stopping " + getName() + " myPICAXE");
myPICAXE.isRunning = false;
myPICAXE.thread.interrupt();
myPICAXE.thread = null;
myPICAXE = null;
}
}
@Override
public void stopService() {
stopPICAXE();
super.stopService();
}
/**
* This static method returns all the details of the class without it having
* to be constructed. It has description, categories, dependencies, and peer
* definitions.
*
* @return ServiceType - returns all the data
*
*/
static public ServiceType getMetaData() {
ServiceType meta = new ServiceType(Picaxe.class.getCanonicalName());
meta.addDescription("Picaxe microcontroller");
meta.addCategory("microcontroller");
meta.addPeer("serial", "Serial", "serial service");
return meta;
}
}