Move from slow JSON to much quicker byte transfer

This commit is contained in:
Robert Marshall 2021-12-22 09:28:42 +00:00
parent 5615108b5d
commit 51f3c87c30
3 changed files with 84 additions and 27 deletions

View file

@ -28,7 +28,6 @@ android {
} }
dependencies { dependencies {
implementation 'com.google.code.gson:gson:2.8.8'
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0' implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'androidx.constraintlayout:constraintlayout:2.0.4'

View file

@ -1,12 +1,14 @@
package uk.robware.vanlights; package uk.robware.vanlights;
public class Light { public class Light {
public byte id;
public String name; public String name;
public boolean on; public boolean on;
public float brightness = 1; public float brightness = 1;
public int timer; public int timer;
public Light(String lightName) { public Light(byte id, String lightName) {
this.id = id;
name=lightName; name=lightName;
} }
} }

View file

@ -12,8 +12,7 @@ import android.os.Binder;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import com.google.gson.Gson; import java.nio.ByteBuffer;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
@ -21,13 +20,18 @@ import java.util.UUID;
public class LightsService extends Service { public class LightsService extends Service {
private final IBinder binder = new LightsBinder(); private final IBinder binder = new LightsBinder();
private Map<String, Light> _lights= new HashMap<>(); private Map<String, Light> _lights= new HashMap<>();
private Map<Integer, Light> _lightsById= new HashMap<>();
private MainActivity _mainActivity; private MainActivity _mainActivity;
public LightsService(){ public LightsService(){
_lights.put("seating", new Light("seating")); _lights.put("seating", new Light((byte) 1, "seating"));
_lights.put("kitchen", new Light("kitchen")); _lights.put("kitchen", new Light((byte) 2, "kitchen"));
_lights.put("bathroom", new Light("bathroom")); _lights.put("bathroom", new Light((byte) 3, "bathroom"));
_lights.put("awning", new Light("awning")); _lights.put("awning", new Light((byte) 4, "awning"));
for (Light light : _lights.values()) {
_lightsById.put(Integer.valueOf(light.id), light);
}
} }
public class LightsBinder extends Binder { public class LightsBinder extends Binder {
@ -79,21 +83,34 @@ public class LightsService extends Service {
} }
}; };
private void readControllerData(BluetoothGattCharacteristic characteristic) { public int bytesToInt(byte[] bytes) {
byte[] value = characteristic.getValue(); ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES);
if (value.length == 0) buffer.put(bytes);
return; buffer.flip();//need flip
return buffer.getInt();
String jsonString = new String(value);
Gson json = new Gson();
Light[] lights = new Light[0];
lights = json.fromJson(jsonString, lights.getClass());
for (Light light : lights) {
_lights.put(light.name, light);
} }
if (_mainActivity!=null) public float bytesToFloat(byte[] bytes) {
_mainActivity.dataReadCallback(_lights); ByteBuffer buffer = ByteBuffer.allocate(Float.BYTES);
buffer.put(bytes);
buffer.flip();//need flip
return buffer.getFloat();
}
private void readControllerData(BluetoothGattCharacteristic characteristic) {
// byte[] value = characteristic.getValue();
// if (value.length == 0)
// return;
//
// for (int i=0; i<value.length;i+=10){
// Light light=_lightsById.get(Integer.valueOf(value[i]));
// light.on=value[i+1]==1;
// light.brightness=bytesToFloat(new byte[]{value[i+2],value[i+3],value[i+4],value[i+5]});
// light.timer=bytesToInt(new byte[]{value[i+6],value[i+7],value[i+8],value[i+9]});
// }
//
// if (_mainActivity!=null)
// _mainActivity.dataReadCallback(_lights);
} }
public void registerUI(MainActivity mainActivity){ public void registerUI(MainActivity mainActivity){
@ -109,10 +126,49 @@ public class LightsService extends Service {
_gatt.disconnect(); _gatt.disconnect();
} }
public byte[] intToBytes(int x) {
ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES);
buffer.putInt(x);
return buffer.array();
}
public byte[] floatToBytes(float x) {
ByteBuffer buffer = ByteBuffer.allocate(Float.BYTES);
buffer.putFloat(x);
return buffer.array();
}
private byte[] getLightDataAsBytes() {
byte[] data=new byte[10 * _lights.size()];
int dataIndex=0;
for (Light light : _lights.values()) {
data[dataIndex]= light.id;
data[dataIndex+1]= (byte) (light.on?1:0);
int brightnessByteIndex=0;
byte[] brightnessToBytes = intToBytes((int) (light.brightness*100));
for (byte brightnessByte: brightnessToBytes) {
data[dataIndex + 2 + brightnessByteIndex] = brightnessByte;
brightnessByteIndex++;
}
int timerByteIndex=0;
byte[] timerToBytes = intToBytes(light.timer);
for (byte timerByte: timerToBytes) {
data[dataIndex + 6 + timerByteIndex] = timerByte;
timerByteIndex++;
}
dataIndex+=10;
}
return data;
}
public boolean sendUpdate() { public boolean sendUpdate() {
Gson json=new Gson(); byte[] data=getLightDataAsBytes();
String value = json.toJson(_lights.values()); return write(data);
return write(value);
} }
public void updateState(String name, boolean state) { public void updateState(String name, boolean state) {
@ -131,7 +187,7 @@ public class LightsService extends Service {
light.timer=totalSeconds; light.timer=totalSeconds;
} }
private boolean write(String value){ private boolean write(byte[] value){
if (_characteristic==null || _gatt==null) if (_characteristic==null || _gatt==null)
return false; return false;
_characteristic.setValue(value); _characteristic.setValue(value);