Skip to content

Commit

Permalink
Merge pull request #115 from jeroen1602/105-cannot-add-10-base-statio…
Browse files Browse the repository at this point in the history
…ns---will-n

Fixed cannot add vive base station
  • Loading branch information
jeroen1602 authored May 24, 2021
2 parents 662ed7b + 13ead6b commit 75b7dfe
Show file tree
Hide file tree
Showing 28 changed files with 488 additions and 332 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Version 1.3.0+9 R.C

- Vive base station ids are now bound to the device id instead to the device name.
This way everyone can store whatever id without restrictions, fixing the bug for some people.
This has the effect that all stored ids are now gone (sorry about that).
- (Web) Added more info to the Bluetooth adapter unavailable.
- (Web) Added 404 page not found.
- (Web) Added support for web.
Expand Down
22 changes: 17 additions & 5 deletions lib/data/Database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ export 'shared/shared.dart';
part 'Database.g.dart';

class NicknamesLastSeenJoin {
NicknamesLastSeenJoin(this.macAddress, this.nickname, this.lastSeen);
NicknamesLastSeenJoin(this.deviceId, this.nickname, this.lastSeen);

final String macAddress;
final String deviceId;
final String nickname;
final DateTime? lastSeen;
}
Expand All @@ -43,19 +43,31 @@ class LighthouseDatabase extends _$LighthouseDatabase {
LighthouseDatabase(QueryExecutor e) : super(e);

@override
int get schemaVersion => 3;
int get schemaVersion => 4;

@override
MigrationStrategy get migration => MigrationStrategy(onCreate: (Migrator m) {
return m.createAll();
}, onUpgrade: (Migrator m, int from, int to) async {
if (from == 1 && (to >= 2 && to <= 3)) {
if (from == 1 && (to >= 2 && to <= 4)) {
await m.renameColumn(simpleSettings, 'id', simpleSettings.settingsId);
}
if ((from >= 1 && from <= 2) && (to == 3)) {
if ((from >= 1 && from <= 2) && (to >= 3 && to <= 4)) {
await m.createTable(groups);
await m.createTable(groupEntries);
}
if ((from >= 1 && from <= 3) && (to == 4)) {
await m.renameColumn(nicknames, 'mac_address', nicknames.deviceId);
await m.renameColumn(
lastSeenDevices, 'mac_address', lastSeenDevices.deviceId);
if (from >= 3 && from <= 3) {
// groups table already exists so we need to rename, otherwise it will be created
await m.renameColumn(
groupEntries, 'mac_address', groupEntries.deviceId);
}
await m.deleteTable('vive_base_station_ids');
await m.createTable(viveBaseStationIds);
}
}, beforeOpen: (details) async {
await this.customStatement('PRAGMA foreign_keys = ON');
});
Expand Down
22 changes: 11 additions & 11 deletions lib/data/dao/GroupDao.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ class GroupDao extends DatabaseAccessor<LighthouseDatabase>
(List<Group> groups, List<GroupEntry> entries) {
final combinedGroups = <GroupWithEntries>[];
for (final group in groups) {
final macs = entries
final deviceIds = entries
.where((value) => value.groupId == group.id)
.map((e) => e.macAddress)
.map((e) => e.deviceId)
.toList();
combinedGroups.add(GroupWithEntries(group, macs));
combinedGroups.add(GroupWithEntries(group, deviceIds));
}
return combinedGroups;
});
Expand All @@ -46,9 +46,9 @@ class GroupDao extends DatabaseAccessor<LighthouseDatabase>

return Rx.combineLatest2(groupStream, groupEntriesStream,
(Group group, List<GroupEntry> entries) {
final macs =
entries.map((entry) => entry.macAddress).toList(growable: true);
return GroupWithEntries(group, macs);
final deviceIds =
entries.map((entry) => entry.deviceId).toList(growable: true);
return GroupWithEntries(group, deviceIds);
});
}

Expand All @@ -65,9 +65,9 @@ class GroupDao extends DatabaseAccessor<LighthouseDatabase>
.go();

// Insert all the new entries.
for (final item in entry.macs) {
for (final deviceId in entry.deviceIds) {
await into(groupEntries).insert(
GroupEntry(macAddress: item, groupId: group.id),
GroupEntry(deviceId: deviceId, groupId: group.id),
mode: InsertMode.insertOrReplace);
}
});
Expand All @@ -93,14 +93,14 @@ class GroupDao extends DatabaseAccessor<LighthouseDatabase>
});
}

Future<void> deleteGroupEntry(String macAddress) {
Future<void> deleteGroupEntry(String deviceId) {
return (delete(groupEntries)
..where((entry) => entry.macAddress.equals(macAddress)))
..where((entry) => entry.deviceId.equals(deviceId)))
.go();
}

Future<void> deleteGroupEntries(List<String> entries) {
return (delete(groupEntries)..where((tbl) => tbl.macAddress.isIn(entries)))
return (delete(groupEntries)..where((tbl) => tbl.deviceId.isIn(entries)))
.go();
}

Expand Down
16 changes: 8 additions & 8 deletions lib/data/dao/NicknameDao.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ class NicknameDao extends DatabaseAccessor<LighthouseDatabase>

Stream<List<Nickname>> get watchSavedNicknames => select(nicknames).watch();

Stream<Nickname?> watchNicknameForMacAddress(String macAddress) {
macAddress = macAddress.toUpperCase();
return (select(nicknames)..where((n) => n.macAddress.equals(macAddress)))
Stream<Nickname?> watchNicknameForDeviceIds(String deviceId) {
deviceId = deviceId.toUpperCase();
return (select(nicknames)..where((n) => n.deviceId.equals(deviceId)))
.watch()
.map((list) {
if (list.isEmpty) {
Expand All @@ -29,8 +29,8 @@ class NicknameDao extends DatabaseAccessor<LighthouseDatabase>
return into(nicknames).insert(nickname, mode: InsertMode.insertOrReplace);
}

Future<void> deleteNicknames(List<String> macAddresses) {
return (delete(nicknames)..where((t) => t.macAddress.isIn(macAddresses)))
Future<void> deleteNicknames(List<String> deviceIds) {
return (delete(nicknames)..where((t) => t.deviceId.isIn(deviceIds)))
.go();
}

Expand All @@ -47,11 +47,11 @@ class NicknameDao extends DatabaseAccessor<LighthouseDatabase>
Stream<List<NicknamesLastSeenJoin>> watchSavedNicknamesWithLastSeen() {
final query = select(nicknames).join([
leftOuterJoin(lastSeenDevices,
lastSeenDevices.macAddress.equalsExp(nicknames.macAddress))
lastSeenDevices.deviceId.equalsExp(nicknames.deviceId))
]);
return query.watch().map((rows) {
return rows.map((row) {
return NicknamesLastSeenJoin(row.read(nicknames.macAddress)!,
return NicknamesLastSeenJoin(row.read(nicknames.deviceId)!,
row.read(nicknames.nickname)!, row.read(lastSeenDevices.lastSeen));
}).toList();
});
Expand All @@ -63,7 +63,7 @@ class NicknameDao extends DatabaseAccessor<LighthouseDatabase>

Future<void> deleteLastSeen(LastSeenDevice lastSeen) {
return (delete(lastSeenDevices)
..where((tbl) => tbl.macAddress.equals(lastSeen.macAddress)))
..where((tbl) => tbl.deviceId.equals(lastSeen.deviceId)))
.go();
}
}
60 changes: 20 additions & 40 deletions lib/data/dao/ViveBaseStationDao.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,45 +12,30 @@ class ViveBaseStationDao extends DatabaseAccessor<LighthouseDatabase>
ViveBaseStationDao(LighthouseDatabase attachedDatabase)
: super(attachedDatabase);

Future<int?> getIdOnSubset(int subset) {
assert((subset & 0xFFFF) == subset,
'Subset should only be the lower 2 bytes. Subset was: 0x${subset.toRadixString(16)}');
return select(viveBaseStationIds).get().then((baseStationIds) {
for (final baseStationId in baseStationIds) {
if ((baseStationId.id & 0xFFFF) == subset) {
return baseStationId.id;
}
}
return null;
});
Future<int?> getId(String deviceId) {
return (select(viveBaseStationIds)
..where((tbl) => tbl.deviceId.equals(deviceId)))
.getSingleOrNull()
.then((value) => value?.baseStationId);
}

Stream<List<int>> getIdsAsStream() {
return select(viveBaseStationIds).watch().map((event) {
if (event.isEmpty) {
return [];
}
final out = List<int>.filled(event.length, 0);
for (int i = 0; i < event.length; i++) {
out[i] = event[i].id;
}
return out;
});
Stream<List<ViveBaseStationId>> getViveBaseStationIdsAsStream() {
return select(viveBaseStationIds).watch();
}

Future<void> insertId(int id) {
Future<void> insertId(String deviceId, int id) {
assert((id & 0xFFFFFFFF) == id,
'Id should be at most 4 bytes, Id was: 0x${id.toRadixString(16)}');
'Id should be at most 4 bytes, Id was: 0x${id.toRadixString(16).padLeft(8, '0').toUpperCase()}');

return into(viveBaseStationIds)
.insert(ViveBaseStationId(id: id), mode: InsertMode.insertOrReplace);
return into(viveBaseStationIds).insert(
ViveBaseStationId(deviceId: deviceId, baseStationId: id),
mode: InsertMode.insertOrReplace);
}

Future<void> deleteId(int id) {
assert((id & 0xFFFFFFFF) == id,
'Id should be at most 4 bytes, Id was: 0x${id.toRadixString(16)}');

return (delete(viveBaseStationIds)..where((tbl) => tbl.id.equals(id))).go();
Future<void> deleteId(String deviceId) {
return (delete(viveBaseStationIds)
..where((tbl) => tbl.deviceId.equals(deviceId)))
.go();
}

Future<void> deleteIds() {
Expand All @@ -63,16 +48,11 @@ class ViveBaseStationDao extends DatabaseAccessor<LighthouseDatabase>
return select(viveBaseStationIds).watch();
}

Future<void> insertIdNoValidate(int id) {
Future<void> insertIdNoValidate(String deviceId, int id) {
debugPrint(
'WARNING using insertIdNoValidate, this should not happen in release mode!');
return into(viveBaseStationIds)
.insert(ViveBaseStationId(id: id), mode: InsertMode.insertOrReplace);
}

Future<void> deleteIdNoValidate(int id) {
debugPrint(
'WARNING using deleteIdNoValidate, this should not happen in release mode!');
return (delete(viveBaseStationIds)..where((tbl) => tbl.id.equals(id))).go();
return into(viveBaseStationIds).insert(
ViveBaseStationId(deviceId: deviceId, baseStationId: id),
mode: InsertMode.insertOrReplace);
}
}
10 changes: 4 additions & 6 deletions lib/data/tables/GroupTable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,18 @@ class Groups extends Table {

@DataClassName('GroupEntry')
class GroupEntries extends Table {
// TextColumn get macAddress => text().withLength(min: 17, max: 17)();
// TODO: rename to device id.
TextColumn get macAddress => text().withLength(min: 17, max: 37)();
TextColumn get deviceId => text().withLength(min: 17, max: 37)();

IntColumn get groupId =>
integer().customConstraint('NOT NULL REFERENCES "groups"(id) ON DELETE CASCADE ON UPDATE CASCADE')();

@override
Set<Column> get primaryKey => {macAddress};
Set<Column> get primaryKey => {deviceId};
}

class GroupWithEntries {
final Group group;
final List<String> macs;
final List<String> deviceIds;

GroupWithEntries(this.group, this.macs);
GroupWithEntries(this.group, this.deviceIds);
}
6 changes: 2 additions & 4 deletions lib/data/tables/LastSeenDevicesTable.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import 'package:moor/moor.dart';

class LastSeenDevices extends Table {
// TextColumn get macAddress => text().withLength(min: 17, max: 17)();
// TODO: rename to device id.
TextColumn get macAddress => text().withLength(min: 17, max: 37)();
TextColumn get deviceId => text().withLength(min: 17, max: 37)();

DateTimeColumn get lastSeen =>
dateTime().clientDefault(() => DateTime.now())();

@override
Set<Column> get primaryKey => {macAddress};
Set<Column> get primaryKey => {deviceId};
}
12 changes: 5 additions & 7 deletions lib/data/tables/NicknameTable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,25 @@ import 'package:lighthouse_pm/data/Database.dart';
import 'package:moor/moor.dart';

class Nicknames extends Table {
// TextColumn get macAddress => text().withLength(min: 17, max: 17)();
// TODO: rename to device id.
TextColumn get macAddress => text().withLength(min: 17, max: 37)();
TextColumn get deviceId => text().withLength(min: 17, max: 37)();

TextColumn get nickname => text()();

@override
Set<Column> get primaryKey => {macAddress};
Set<Column> get primaryKey => {deviceId};
}

class NicknamesHelper {
final String macAddress;
final String deviceId;
final String? nickname;

NicknamesHelper({required this.macAddress, this.nickname});
NicknamesHelper({required this.deviceId, this.nickname});

Nickname? toNickname() {
final nickname = this.nickname;
if (nickname == null) {
return null;
}
return Nickname(macAddress: this.macAddress, nickname: nickname);
return Nickname(deviceId: this.deviceId, nickname: nickname);
}
}
6 changes: 4 additions & 2 deletions lib/data/tables/ViveBaseStationIdTable.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import 'package:moor/moor.dart';

class ViveBaseStationIds extends Table {
IntColumn get id => integer()();
TextColumn get deviceId => text().withLength(min: 17, max: 37)();

IntColumn get baseStationId => integer()();

@override
Set<Column> get primaryKey => {id};
Set<Column> get primaryKey => {deviceId};
}
2 changes: 1 addition & 1 deletion lib/lighthouseProvider/LighthouseProvider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ class LighthouseProvider {
}, orElse: () => null) !=
null) {
debugPrint(
'Found a device that has already been found! mac: ${newDevice.deviceIdentifier}, name: ${newDevice.name}');
'Found a device that has already been found! Device id: ${newDevice.deviceIdentifier}, name: ${newDevice.name}');
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ class FlutterBlueLighthouseBackEnd extends BLELighthouseBackEnd {
await _devicesMutex.acquire();
if (lighthouseDevice == null) {
debugPrint(
'Found a non valid device! Mac: ${scanResult.device.id.toString()}');
'Found a non valid device! Device id: ${scanResult.device.id.toString()}');
this._rejectedDevices.add(deviceIdentifier);
} else {
this._foundDeviceSubject.add(lighthouseDevice);
Expand Down
13 changes: 4 additions & 9 deletions lib/lighthouseProvider/deviceExtensions/ClearIdExtension.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,20 @@ import 'DeviceExtension.dart';
class ClearIdExtension extends DeviceExtension {
ClearIdExtension(
{required ViveBaseStationDao viveDao,
required int deviceIdEnd,
required String deviceId,
required VoidCallback clearId})
: super(
toolTip: 'Clear id',
icon: Text('ID'),
updateListAfter: true,
onTap: () async {
final id = await viveDao.getIdOnSubset(deviceIdEnd);
if (id != null) {
await viveDao.deleteId(id);
}
await viveDao.deleteId(deviceId);
clearId();
}) {
assert(
deviceIdEnd & 0xFFFF == deviceIdEnd, 'Device id end should be 2 bytes');
streamEnabledFunction = () {
return viveDao.getIdsAsStream().map((events) {
return viveDao.getViveBaseStationIdsAsStream().map((events) {
for (final event in events) {
if (event & 0xFFFF == deviceIdEnd) {
if (event.deviceId == deviceId) {
return true;
}
}
Expand Down
Loading

0 comments on commit 75b7dfe

Please sign in to comment.