IOIO, télécommande SMS

J'ai reçu ma carte IOIO...
Descriptif ici
Première mise en marche en suivant ce tuto: https://www.sparkfun.com/tutorials/280
échec.....
En fouillant un peu, je trouve et installe cette appli: https://play.google.com/store/apps/details?id=ioio.example.ioiohardwaretester
Hard test
Non seulement cette appli fonctionne, cad commande la led de la carte mais elle m'informe que le firmware eest 330 alors que j'utilisais la dernière bibliothèque conseillée 504 (d'ou l'échec)
Miracle: en utilisant la bonne bibliothèque 0330 tout marche comme dans les livres....
On verra la mise à jour 504 plus tard, cela se fait sous dos et la carte n'est pas reconnue  par windows 8...
Je me suis alors lancée pour une télécommande par SMS, la voila
tlc4r
Pas de gros soucis, j'ai juste utilisé les sorties 1 à 4 connectées sur une carte 4 relais
Pour le soft: j'ai enrichi mon SMS launcher de cette procédure:

public void TraiteIOIO(Context c, String body) {
        Toast.makeText(c, "Launcher say IOIO: " + body, Toast.LENGTH_SHORT).show();
        Intent i;
        // lance l'activity et transmet la commande
        try {
            i = c.getPackageManager().getLaunchIntentForPackage("ioio.examples.tlc4r");
            if (i == null)
                throw new PackageManager.NameNotFoundException();
            i.addCategory(Intent.CATEGORY_LAUNCHER);
            i.putExtra("ioio", body); 
            c.startActivity(i);
        } catch (PackageManager.NameNotFoundException e) {
            // affiche que l'appli n'es pas présente sur le tel
            Toast.makeText(c, "Appli non trouvée...", Toast.LENGTH_LONG).show();
        }
    }

si ce Launcher intercepte ioio dans un sms, il lance l'appli tlc4r avec le sms en intent
L'appli tlc4r est IOIOHello modifiée
public class MainActivity extends IOIOActivity implements OnClickListener {
    int duree = 10;
    Timer t;
    TimerTask task;
    public String cmde="rien",r="-";
    TextView tv1;
    Intent intent;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        cmde="ioio120";
        setContentView(R.layout.main);
        tv1 = (TextView) findViewById(R.id.textView1);
        tv1.setTextSize(40);
        findViewById(R.id.button1).setOnClickListener(this);;
    }

    public void getCommande() {
        intent = getIntent();
        if (intent != null) cmde = intent.getStringExtra("ioio").toString();
        Toast.makeText(getApplicationContext(), "reçu=" + cmde,    Toast.LENGTH_LONG).show();
    }

    @Override
    public void onResume() {
        super.onResume();
        try {
            getCommande();         
        } catch (Exception e) {       }
        r="-";
        duree=0;
        if (cmde.contains("ioio")) {
            r=cmde.substring(4,5);//le relai
            String d=cmde.substring(5,cmde.length());//la durée
            duree=Integer.parseInt(d);
        }
        tv1.setText(cmde+"\nrelai n° "+r+" durée:"+duree);
        if (duree>0) startTimer();
    }

    public void startTimer() {
        t = new Timer();
        task = new TimerTask() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tv1.setText(cmde+"\nrelai n° "+r+" durée:"+duree);
                        if (duree > 0)
                            duree -= 1;
                        else {
                            tv1.setText("Fini");
                            t.cancel();
                            t.purge();
                            cmde = "rien";
                            quitter();
                        }
                    }
                });
            }
    };
        t.scheduleAtFixedRate(task, 0, 1000);
    }
......

la syntaxe du sms est ioio+RelaiSurUnChiffre+duréeEnSecondes
par exemple ioio1900, relai 1mis en marche pendant 900 secondes

Version BT...

L'inconvénient de cette version est que le téléphone est toujours en charge...
Pour que l'accu soit déchargé puis chargé réguliérement je suis passé à une version ou la communication avec ioio se fait en Bluetooth
tlcioiobt
Deux relais sont utilisés, un pour la télécommande, l'autre pour la charge du téléphone (câble USB blanc)
Il faut suivre en permanence l'état de la charge et agir si elle est <10 % ou >98%

package ioio.examples.hello_service;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.IBinder;
import android.widget.Toast;
import ioio.lib.api.DigitalOutput;
import ioio.lib.api.IOIO;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import ioio.lib.util.android.IOIOService;

public class HelloIOIOService extends IOIOService {
    boolean charge = false;
    int niveau = 50, level, duree = 20;
    Context c;
    Handler mHandler;
    BatteryReceiver EcouteurBatterie;
    float batteryLevel;
    Intent batteryIntent;
    String cmde = "rien";

    @Override
    protected IOIOLooper createIOIOLooper() {
        return new BaseIOIOLooper() {
            private DigitalOutput led_, led1, led2;

            @Override
            protected void setup() throws ConnectionLostException, InterruptedException {
                led_ = ioio_.openDigitalOutput(IOIO.LED_PIN);
                led1 = ioio_.openDigitalOutput(1);
                led2 = ioio_.openDigitalOutput(2);
            }
           
            public void TraiteCharge() throws ConnectionLostException{
                if (level > 98) charge = false;
                if (level < 10) charge = true;
                led1.write(!charge);   
            }
           
            public void TraiteRelai() throws ConnectionLostException {
                led2.write(!(duree>0));
                if (duree > 0)     duree--;
                else
                    try {
                        FileUtil f = new FileUtil("ioio");
                        if (f.SDCardFichierExiste()) {
                            cmde = f.loadTextFromSdcard();
                            if (cmde.contains("rien")) duree=-1;
                            else
                               {String sduree=cmde.substring(5, cmde.length());
                               try {
                                    duree = Integer.parseInt(sduree);
                                    mHandler.post(new Runnable() {
                                        public void run() {
                                        Toast.makeText(HelloIOIOService.this,"Durée reçue:"+duree, Toast.LENGTH_LONG).show();
                                        }
                                    });
                                } catch(NumberFormatException nfe) {nfe.printStackTrace();}
                                f.saveTextInSdcard("ioio rien");}
                        }
                    } catch (Exception e) {    e.printStackTrace();}
            }
           
            @Override
            public void loop() throws ConnectionLostException, InterruptedException {
                TraiteCharge();
                TraiteRelai();
                led_.write(false);
                Thread.sleep(500);
                led_.write(true);
                Thread.sleep(500);
                }
        };
    }

     private class BatteryReceiver extends BroadcastReceiver { 
         @Override 
         public void onReceive(Context arg0, Intent arg1) { 
              if (arg1.getAction().equalsIgnoreCase(Intent.ACTION_BATTERY_LOW) 
                        || arg1.getAction().equalsIgnoreCase( 
                                  Intent.ACTION_BATTERY_CHANGED) 
                        || arg1.getAction().equalsIgnoreCase( 
                                  Intent.ACTION_BATTERY_OKAY)) { 
                   level = arg1.getIntExtra("level", 0); 
                   batteryLevel = getBatteryLevel(batteryIntent);
                   mHandler.post(new Runnable() {
                        public void run() {
                        Toast.makeText(HelloIOIOService.this,"Niveau batterie : "+level//+" "+batteryLevel
                                ,Toast.LENGTH_LONG).show();
                        }
                    });
              } 
         }}
   
   
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        c=this;
        Toast.makeText(c, "IOIO SMS en route...", Toast.LENGTH_SHORT).show();
        NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        if (intent != null && intent.getAction() != null
                && intent.getAction().equals("stop")) {
            // User clicked the notification. Need to stop the service.
            nm.cancel(0);
            stopSelf();
        } else {
            // Service starting. Create a notification.
            Notification notification = new Notification(
                    R.drawable.ic_bat2, "IOIO service running",
                    System.currentTimeMillis());
            notification
                    .setLatestEventInfo(this, "IOIO Service", "Click to stop",
                            PendingIntent.getService(this, 0, new Intent(
                                    "stop", null, this, this.getClass()), 0));
            notification.flags |= Notification.FLAG_ONGOING_EVENT;
            nm.notify(0, notification);
        }
   
    }
   
    public float getBatteryLevel(Intent batteryIntent) { 
         int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); 
         int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); 
         if (level == -1 || scale == -1) { 
              return 50.0f; 
         } 
         return ((float) level / (float) scale) * 100.0f; 
    } 
     
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
   
    @Override
    public void onCreate() {
        super.onCreate();
        mHandler = new Handler();
        EcouteurBatterie = new BatteryReceiver(); 
        IntentFilter mIntentFilter = new IntentFilter(); 
        mIntentFilter.addAction(Intent.ACTION_BATTERY_LOW); 
        mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); 
        mIntentFilter.addAction(Intent.ACTION_BATTERY_OKAY); 
        batteryIntent = registerReceiver(EcouteurBatterie, mIntentFilter);
        batteryLevel = getBatteryLevel(batteryIntent);
    }

    @Override
    public void onDestroy(){
        super.onDestroy();
        unregisterReceiver(EcouteurBatterie);
    }
}