refactored android example
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
package net.irext.ircontrol.controller;
|
||||
|
||||
import android.content.Context;
|
||||
import net.irext.ircontrol.controller.implementable.IRemote;
|
||||
|
||||
public class ArduinoRemote implements IRemote {
|
||||
|
||||
Context mContext;
|
||||
ArduinoSocket mArduinoSocket;
|
||||
|
||||
public ArduinoRemote(Context context, ArduinoSocket socket) {
|
||||
mContext = context;
|
||||
mArduinoSocket = socket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int irControl(int category, int subCategory, int keyCode) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.irext.ircontrol.utils;
|
||||
package net.irext.ircontrol.controller;
|
||||
|
||||
import android.util.Log;
|
||||
import android.util.Patterns;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
@@ -10,11 +11,11 @@ import java.net.Socket;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* Filename: IRSocketEmitter.java
|
||||
* Filename: ArduinoSocket.java
|
||||
* Description: Handle socket communication with external IR emitter
|
||||
*/
|
||||
public class IRSocketEmitter {
|
||||
private static final String TAG = IRSocketEmitter.class.getSimpleName();
|
||||
public class ArduinoSocket {
|
||||
private static final String TAG = ArduinoSocket.class.getSimpleName();
|
||||
|
||||
public static final int EMITTER_DISCONNECTED = 0;
|
||||
public static final int EMITTER_CONNECTED = 1;
|
||||
@@ -42,7 +43,7 @@ public class IRSocketEmitter {
|
||||
void onResponse(String response);
|
||||
}
|
||||
|
||||
public IRSocketEmitter(IRSocketEmitterCallback callback) {
|
||||
public ArduinoSocket(IRSocketEmitterCallback callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
@@ -164,4 +165,11 @@ public class IRSocketEmitter {
|
||||
public void processECtrl(String response) {
|
||||
// Handle control response if needed
|
||||
}
|
||||
|
||||
public static boolean isValidIPv4(String ip) {
|
||||
if (ip == null) {
|
||||
return false;
|
||||
}
|
||||
return Patterns.IP_ADDRESS.matcher(ip).matches();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package net.irext.ircontrol.controller;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.ConsumerIrManager;
|
||||
import net.irext.decode.sdk.bean.ACStatus;
|
||||
import net.irext.decode.sdk.utils.Constants;
|
||||
import net.irext.ircontrol.R;
|
||||
import net.irext.ircontrol.utils.ToastUtils;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static net.irext.ircontrol.controller.implementable.IRemote.*;
|
||||
|
||||
public class ControlUtils {
|
||||
|
||||
public static int translateKeyCode(int category, int keyCode, ACStatus acStatus) {
|
||||
int inputKeyCode = 0;
|
||||
|
||||
if (Constants.CategoryID.AIR_CONDITIONER.getValue() == category) {
|
||||
acStatus.setAcPower(Constants.ACPower.POWER_OFF.getValue());
|
||||
acStatus.setAcMode(Constants.ACMode.MODE_COOL.getValue());
|
||||
acStatus.setAcTemp(Constants.ACTemperature.TEMP_24.getValue());
|
||||
acStatus.setAcWindSpeed(Constants.ACWindSpeed.SPEED_AUTO.getValue());
|
||||
acStatus.setAcWindDir(Constants.ACSwing.SWING_ON.getValue());
|
||||
acStatus.setChangeWindDir(0);
|
||||
acStatus.setAcDisplay(0);
|
||||
acStatus.setAcTimer(0);
|
||||
acStatus.setAcSleep(0);
|
||||
|
||||
switch(keyCode) {
|
||||
case KEY_POWER:
|
||||
// power key --> change power
|
||||
inputKeyCode = Constants.ACFunction.FUNCTION_SWITCH_POWER.getValue();
|
||||
break;
|
||||
case KEY_UP:
|
||||
// up key --> change wind speed
|
||||
inputKeyCode = Constants.ACFunction.FUNCTION_SWITCH_WIND_SPEED.getValue();
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
// down key --> change wind dir
|
||||
inputKeyCode = Constants.ACFunction.FUNCTION_SWITCH_WIND_DIR.getValue();
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
// right key --> change mode
|
||||
inputKeyCode = Constants.ACFunction.FUNCTION_CHANGE_MODE.getValue();
|
||||
break;
|
||||
case KEY_OK:
|
||||
// center key --> fix wind dir
|
||||
inputKeyCode = Constants.ACFunction.FUNCTION_SWITCH_SWING.getValue();
|
||||
break;
|
||||
case KEY_PLUS:
|
||||
// plus key --> temp up
|
||||
inputKeyCode = Constants.ACFunction.FUNCTION_TEMPERATURE_UP.getValue();
|
||||
break;
|
||||
case KEY_MINUS:
|
||||
// minus key --> temp down
|
||||
inputKeyCode = Constants.ACFunction.FUNCTION_TEMPERATURE_DOWN.getValue();
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
inputKeyCode = keyCode;
|
||||
}
|
||||
return inputKeyCode;
|
||||
}
|
||||
|
||||
public static void transmitIr(Context context, int []decoded) {
|
||||
// debug decoded value
|
||||
StringBuilder decodedValue = new StringBuilder();
|
||||
for (int i = 0; i < Objects.requireNonNull(decoded).length; i++) {
|
||||
decodedValue.append(decoded[i]);
|
||||
decodedValue.append(",");
|
||||
}
|
||||
// send decoded integer array to IR emitter
|
||||
ConsumerIrManager irEmitter =
|
||||
(ConsumerIrManager) context.getSystemService(Context.CONSUMER_IR_SERVICE);
|
||||
if (null != irEmitter && irEmitter.hasIrEmitter()) {
|
||||
if (decoded.length > 0) {
|
||||
irEmitter.transmit(38000, decoded);
|
||||
}
|
||||
} else {
|
||||
ToastUtils.showToast(context, context.getString(R.string.ir_not_supported), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package net.irext.ircontrol.controller;
|
||||
|
||||
import android.content.Context;
|
||||
import net.irext.decode.sdk.IRDecode;
|
||||
import net.irext.decode.sdk.bean.ACStatus;
|
||||
import net.irext.ircontrol.controller.implementable.IRemote;
|
||||
|
||||
public class PhoneRemote implements IRemote {
|
||||
|
||||
IRDecode mIRDecode;
|
||||
|
||||
Context mContext;
|
||||
public PhoneRemote(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int irControl(int category, int subCategory, int keyCode) {
|
||||
int []decoded;
|
||||
ACStatus acStatus = new ACStatus();
|
||||
int inputKeyCode = ControlUtils.translateKeyCode(category, keyCode, acStatus);
|
||||
decoded = mIRDecode.decodeBinary(inputKeyCode, acStatus);
|
||||
ControlUtils.transmitIr(mContext, decoded);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package net.irext.ircontrol.controller.implementable;
|
||||
|
||||
import android.content.Context;
|
||||
import net.irext.decode.sdk.IRDecode;
|
||||
|
||||
public interface IRemote {
|
||||
|
||||
public static final int KEY_POWER = 0;
|
||||
public static final int KEY_UP = 1;
|
||||
public static final int KEY_DOWN = 2;
|
||||
public static final int KEY_LEFT = 3;
|
||||
public static final int KEY_RIGHT = 4;
|
||||
public static final int KEY_OK = 5;
|
||||
public static final int KEY_PLUS = 6;
|
||||
public static final int KEY_MINUS = 7;
|
||||
public static final int KEY_BACK = 8;
|
||||
public static final int KEY_HOME = 9;
|
||||
public static final int KEY_MENU = 10;
|
||||
|
||||
int irControl(int category, int subCategory, int keyCode);
|
||||
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package net.irext.ircontrol.ui.fragment;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.hardware.ConsumerIrManager;
|
||||
import android.os.*;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -13,21 +12,18 @@ import android.widget.*;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import net.irext.decode.sdk.IRDecode;
|
||||
import net.irext.decode.sdk.bean.ACStatus;
|
||||
import net.irext.decode.sdk.utils.Constants;
|
||||
import net.irext.ircontrol.R;
|
||||
import net.irext.ircontrol.bean.RemoteControl;
|
||||
import net.irext.ircontrol.controller.ArduinoRemote;
|
||||
import net.irext.ircontrol.controller.ArduinoSocket;
|
||||
import net.irext.ircontrol.controller.PhoneRemote;
|
||||
import net.irext.ircontrol.controller.implementable.IRemote;
|
||||
import net.irext.ircontrol.ui.activity.ControlActivity;
|
||||
import net.irext.ircontrol.utils.FileUtils;
|
||||
import net.irext.ircontrol.utils.MessageUtil;
|
||||
import net.irext.ircontrol.utils.ToastUtils;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Objects;
|
||||
|
||||
import net.irext.ircontrol.utils.IRSocketEmitter;
|
||||
|
||||
/**
|
||||
* Filename: ControlFragment.java
|
||||
@@ -48,19 +44,7 @@ public class ControlFragment extends Fragment implements View.OnClickListener {
|
||||
|
||||
private static final int CMD_GET_REMOTE_CONTROL = 0;
|
||||
|
||||
private static final int KEY_POWER = 0;
|
||||
private static final int KEY_UP = 1;
|
||||
private static final int KEY_DOWN = 2;
|
||||
private static final int KEY_LEFT = 3;
|
||||
private static final int KEY_RIGHT = 4;
|
||||
private static final int KEY_OK = 5;
|
||||
private static final int KEY_PLUS = 6;
|
||||
private static final int KEY_MINUS = 7;
|
||||
private static final int KEY_BACK = 8;
|
||||
private static final int KEY_HOME = 9;
|
||||
private static final int KEY_MENU = 10;
|
||||
|
||||
private IRSocketEmitter mIRSocketEmitter;
|
||||
private ArduinoSocket mArduinoSocket;
|
||||
|
||||
private MsgHandler mHandler;
|
||||
|
||||
@@ -115,8 +99,8 @@ public class ControlFragment extends Fragment implements View.OnClickListener {
|
||||
mBtnConnect = view.findViewById(R.id.btn_connect_emitter);
|
||||
mVWConnectStatus = view.findViewById(R.id.vw_connect_status);
|
||||
|
||||
// Initialize IRSocketEmitter with callback
|
||||
mIRSocketEmitter = new IRSocketEmitter(new IRSocketEmitter.IRSocketEmitterCallback() {
|
||||
// Initialize ArduinoSocket with callback
|
||||
mArduinoSocket = new ArduinoSocket(new ArduinoSocket.IRSocketEmitterCallback() {
|
||||
@Override
|
||||
public void onConnected() {
|
||||
onEmitterConnected();
|
||||
@@ -139,11 +123,12 @@ public class ControlFragment extends Fragment implements View.OnClickListener {
|
||||
public void onClick(View v) {
|
||||
vibrate(mParent);
|
||||
String emitterIp = mEtEmitterIp.getText().toString();
|
||||
if (isIpAddress(emitterIp)) {
|
||||
if (!ArduinoSocket.isValidIPv4(emitterIp)) {
|
||||
Log.e(TAG, "IP address is invalid: " + emitterIp);
|
||||
ToastUtils.showToast(mParent, mParent.getString(R.string.input_emitter_ip_address), null);
|
||||
return;
|
||||
}
|
||||
mIRSocketEmitter.connectToEmitter(emitterIp, String.valueOf(IRSocketEmitter.EMITTER_PORT));
|
||||
mArduinoSocket.connectToEmitter(emitterIp, String.valueOf(ArduinoSocket.EMITTER_PORT));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -189,66 +174,6 @@ public class ControlFragment extends Fragment implements View.OnClickListener {
|
||||
mIRDecode.closeBinary();
|
||||
}
|
||||
|
||||
private int[] irControl(int keyCode) {
|
||||
int inputKeyCode;
|
||||
ACStatus acStatus = new ACStatus();
|
||||
/* decode SDK - decode according to key code */
|
||||
if (Constants.CategoryID.AIR_CONDITIONER.getValue() ==
|
||||
mCurrentRemoteControl.getCategoryId()) {
|
||||
acStatus.setAcPower(Constants.ACPower.POWER_OFF.getValue());
|
||||
acStatus.setAcMode(Constants.ACMode.MODE_COOL.getValue());
|
||||
acStatus.setAcTemp(Constants.ACTemperature.TEMP_24.getValue());
|
||||
acStatus.setAcWindSpeed(Constants.ACWindSpeed.SPEED_AUTO.getValue());
|
||||
acStatus.setAcWindDir(Constants.ACSwing.SWING_ON.getValue());
|
||||
acStatus.setChangeWindDir(0);
|
||||
acStatus.setAcDisplay(0);
|
||||
acStatus.setAcTimer(0);
|
||||
acStatus.setAcSleep(0);
|
||||
|
||||
switch(keyCode) {
|
||||
case KEY_POWER:
|
||||
// power key --> change power
|
||||
inputKeyCode = Constants.ACFunction.FUNCTION_SWITCH_POWER.getValue();
|
||||
break;
|
||||
case KEY_UP:
|
||||
// up key --> change wind speed
|
||||
inputKeyCode = Constants.ACFunction.FUNCTION_SWITCH_WIND_SPEED.getValue();
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
// down key --> change wind dir
|
||||
inputKeyCode = Constants.ACFunction.FUNCTION_SWITCH_WIND_DIR.getValue();
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
// right key --> change mode
|
||||
inputKeyCode = Constants.ACFunction.FUNCTION_CHANGE_MODE.getValue();
|
||||
break;
|
||||
case KEY_OK:
|
||||
// center key --> fix wind dir
|
||||
inputKeyCode = Constants.ACFunction.FUNCTION_SWITCH_SWING.getValue();
|
||||
break;
|
||||
case KEY_PLUS:
|
||||
// plus key --> temp up
|
||||
inputKeyCode = Constants.ACFunction.FUNCTION_TEMPERATURE_UP.getValue();
|
||||
break;
|
||||
case KEY_MINUS:
|
||||
// minus key --> temp down
|
||||
inputKeyCode = Constants.ACFunction.FUNCTION_TEMPERATURE_DOWN.getValue();
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
inputKeyCode = keyCode;
|
||||
}
|
||||
|
||||
/* decode SDK - decode from binary */
|
||||
/* translate key code for AC according to the mapping above */
|
||||
/* ac status is useless for decoding devices other than AC, it's an optional parameter */
|
||||
/* change wind dir is an optional parameter, set to 0 as default */
|
||||
return mIRDecode.decodeBinary(inputKeyCode, acStatus);
|
||||
}
|
||||
|
||||
private void onEmitterConnected() {
|
||||
Log.d(TAG, "the emitter is connected");
|
||||
mParent.runOnUiThread(() -> {
|
||||
@@ -265,14 +190,14 @@ public class ControlFragment extends Fragment implements View.OnClickListener {
|
||||
}
|
||||
|
||||
private void processEHello(String response) {
|
||||
mIRSocketEmitter.sendHelloToEmitter();
|
||||
mArduinoSocket.sendHelloToEmitter();
|
||||
}
|
||||
|
||||
private void processEBin(String response) {
|
||||
String binFileName = FileUtils.binDir + FileUtils.FILE_NAME_PREFIX +
|
||||
mCurrentRemoteControl.getRemoteMap() + FileUtils.FILE_NAME_EXT;
|
||||
byte []binContent = FileUtils.getByteArrayFromFile(binFileName);
|
||||
mIRSocketEmitter.sendBinToEmitter(binContent, mCurrentRemoteControl.getCategoryId(), mCurrentRemoteControl.getSubCategory());
|
||||
mArduinoSocket.sendBinToEmitter(binContent, mCurrentRemoteControl.getCategoryId(), mCurrentRemoteControl.getSubCategory());
|
||||
}
|
||||
|
||||
private void processECtrl(String response) {
|
||||
@@ -281,11 +206,11 @@ public class ControlFragment extends Fragment implements View.OnClickListener {
|
||||
|
||||
private void onEmitterResponse(String response) {
|
||||
Log.d(TAG, "emitter: " + response);
|
||||
if (response.startsWith(IRSocketEmitter.E_RESPONSE_HELLO)) {
|
||||
if (response.startsWith(ArduinoSocket.E_RESPONSE_HELLO)) {
|
||||
processEHello(response);
|
||||
} else if (response.startsWith(IRSocketEmitter.E_RESPONSE_BIN)) {
|
||||
} else if (response.startsWith(ArduinoSocket.E_RESPONSE_BIN)) {
|
||||
processEBin(response);
|
||||
} else if (response.startsWith(IRSocketEmitter.E_RESPONSE_CTRL)) {
|
||||
} else if (response.startsWith(ArduinoSocket.E_RESPONSE_CTRL)) {
|
||||
processECtrl(response);
|
||||
} else {
|
||||
Log.e(TAG, "unexpected response : " + response);
|
||||
@@ -296,63 +221,39 @@ public class ControlFragment extends Fragment implements View.OnClickListener {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
vibrate(mParent);
|
||||
// decode directly in mobile phone
|
||||
int []decoded = null;
|
||||
IRemote remote = null;
|
||||
int keyCode = 0;
|
||||
int id = v.getId();
|
||||
if (id == R.id.iv_power) {
|
||||
decoded = irControl(KEY_POWER);
|
||||
keyCode = IRemote.KEY_POWER;
|
||||
} else if (id == R.id.iv_up) {
|
||||
decoded = irControl(KEY_UP);
|
||||
keyCode = IRemote.KEY_UP;
|
||||
} else if (id == R.id.iv_down) {
|
||||
decoded = irControl(KEY_DOWN);
|
||||
keyCode = IRemote.KEY_DOWN;
|
||||
} else if (id == R.id.iv_left) {
|
||||
decoded = irControl(KEY_LEFT);
|
||||
keyCode = IRemote.KEY_LEFT;
|
||||
} else if (id == R.id.iv_right) {
|
||||
decoded = irControl(KEY_RIGHT);
|
||||
keyCode = IRemote.KEY_RIGHT;
|
||||
} else if (id == R.id.iv_ok) {
|
||||
decoded = irControl(KEY_OK);
|
||||
keyCode = IRemote.KEY_OK;
|
||||
} else if (id == R.id.iv_plus) {
|
||||
decoded = irControl(KEY_PLUS);
|
||||
keyCode = IRemote.KEY_PLUS;
|
||||
} else if (id == R.id.iv_minus) {
|
||||
decoded = irControl(KEY_MINUS);
|
||||
keyCode = IRemote.KEY_MINUS;
|
||||
} else if (id == R.id.iv_back) {
|
||||
decoded = irControl(KEY_BACK);
|
||||
keyCode = IRemote.KEY_BACK;
|
||||
} else if (id == R.id.iv_home) {
|
||||
decoded = irControl(KEY_HOME);
|
||||
keyCode = IRemote.KEY_HOME;
|
||||
} else if (id == R.id.iv_menu) {
|
||||
decoded = irControl(KEY_MENU);
|
||||
keyCode = IRemote.KEY_MENU;
|
||||
}
|
||||
|
||||
// debug decoded value
|
||||
StringBuilder decodedValue = new StringBuilder();
|
||||
for (int i = 0; i < Objects.requireNonNull(decoded).length; i++) {
|
||||
decodedValue.append(decoded[i]);
|
||||
decodedValue.append(",");
|
||||
}
|
||||
Log.d(TAG, "decodedValue : " + decodedValue);
|
||||
if (mIRSocketEmitter.isConnected()) {
|
||||
Log.d(TAG, "emitter available, send decoded to emitter");
|
||||
mIRSocketEmitter.sendDecodedToEmitter(decodedValue.toString());
|
||||
}
|
||||
// send decoded integer array to IR emitter
|
||||
ConsumerIrManager irEmitter =
|
||||
(ConsumerIrManager) mParent.getSystemService(Context.CONSUMER_IR_SERVICE);
|
||||
if (null != irEmitter && irEmitter.hasIrEmitter()) {
|
||||
if (decoded.length > 0) {
|
||||
irEmitter.transmit(38000, decoded);
|
||||
}
|
||||
if (mArduinoSocket.isConnected()) {
|
||||
remote = new ArduinoRemote(mParent, mArduinoSocket);
|
||||
} else {
|
||||
ToastUtils.showToast(mParent, this.getString(R.string.ir_not_supported), null);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isIpAddress(String ipAddress) {
|
||||
try {
|
||||
InetAddress inetAddress = InetAddress.getByName(ipAddress);
|
||||
return Objects.equals(inetAddress.getHostAddress(), ipAddress);
|
||||
} catch (UnknownHostException e) {
|
||||
return false;
|
||||
remote = new PhoneRemote(mParent);
|
||||
}
|
||||
remote.irControl(mCurrentRemoteControl.getCategoryId(), mCurrentRemoteControl.getSubCategory(), keyCode);
|
||||
}
|
||||
|
||||
private static class MsgHandler extends Handler {
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
#include <cstdint>
|
||||
|
||||
// Wi-Fi Configs
|
||||
// #define SECRET_SSID "Maomao的小房子"
|
||||
// #define SECRET_PASS "Maomao121207"
|
||||
#define SECRET_SSID "maomao"
|
||||
#define SECRET_PASS "20121207"
|
||||
#define SECRET_SSID "Maomao的小房子"
|
||||
#define SECRET_PASS "Maomao121207"
|
||||
// #define SECRET_SSID "maomao"
|
||||
// #define SECRET_PASS "20121207"
|
||||
|
||||
// LED Matrix Definitions
|
||||
constexpr uint32_t chip[] = {
|
||||
|
||||
Reference in New Issue
Block a user