jeroen1602 / lighthouse_pm Goto Github PK
View Code? Open in Web Editor NEWA Flutter app for controlling the power state of Valve Index® lighthouses
License: Other
A Flutter app for controlling the power state of Valve Index® lighthouses
License: Other
Hi jeroen1602
Firstly of course thank you so much for this program, I've been struggling with the "sometimes working" power-options in SteamVR for the basestations, I tried lighthouse-manager and it also just worked sometimes, but your program works 100% of the time and it's amazing, so thank you.
I just had a general unrelated question and I wasn't sure how to contact you, so feel free to delete this issue/close it, but if ever you can help me:
I'm trying to control a Bluetooth low-energy RGB LED strip in a program I'm writing. I've managed to use gatttool on my Raspberry Pi to read all the "handles" and "UUID"s for my device, but I'm wondering, how on earth am I supposed to know which handle does what?? So more specifically for you, I'm wondering how did you figure out what "commands" to send to the base stations to turn them on/off, and to read their state??? Is it just trial and error, or there's a trick??
Thanks a lot once again and if this sort of question is not welcome feel free to delete!!
Phil
Currently dark theme just copies it's state from the system, but this only works for Android 10+ and iOS 13+.
The user should be able to select their own preferred setting.
For future features it may be useful to store some user data.
Add a local database, something like Room but for Flutter.
Currently the is scanning function is only ever done through Flutter blue, but it should be part of the specific back end
Android has the ability to add shortcuts. This is quite useful to change the state of a lighthouse group described in #7.
Add shortcut support for even quicker state changes.
Look into adding a quick setting tile.
When refreshing the device list the currently visible devices get removed, but the active connection used for live-updating the
power state doesn't actually close (for some reason).
This is probably due to me using an old android, but: when I install the app (and give it permissions) I try to open it. Nothing happens. The app simply does not start. I sometimes see the screen flash either black or white and then return to the menu.
Phone: https://www.evolveo.com/en/strongphone-q7-lte with Android 5.1.1
Version: 32bit ARM version, the 1.0.0 +2
Tried:
Dart is moving over to adding null safety to it's code and Flutter is also migrating to it. To minimize nullpointer bugs, null safety needs to be implemented. For now it can be done with a simple code hint (adding a /* ? */
for nullable). But once the feature is rolled out in stable it needs to be implemented properly.
Most people like their apps to support a dark theme mode.
Add support for a dark theme
In light mode the dialog text is the same as the background color, thus not showing anything.
Add the fix for package visibility that Android 11 now enforces.
https://developer.android.com/training/basics/intents/package-visibility
The floating action button theme has been deprecated and should be replaced with FloatingActionButtonThemeData
. As described in this document. (The document has been grieved a lot so make sure to select viewing mode in the top right.)
Sometimes a lighthouse reports it's power state as 0x01 even though it is on instead of booting. The user should still be able to send a shutdown command if they really want to.
A shortcut to physically identify the lighthouse would be great, especially when troubleshooting.
Since the app is made with Flutter it should be relatively easy to create a build for iOS.
I however don't have the required devices to do this, so it would be nice if there was someone who could pick this up.
Revert back from #70 since it doesn't work correctly.
On some devices the lighthouses don't show up when location services aren't enabled. This may confuse people causing them to not use the app even though it may work for them.
Currently the lighthouse device only allows for the Valve index lighthouses, but it would be nice to add easily add support for other device types.
Change the lighthouse provider to allow for this.
Currently when a user clicks the scan button the app will ask for the location permissions without any explanation.
This could confuse people since they would be wondering why an app used for changing their lighthouse power state might need the location permissions.
Add a dialog explaining the need for location permissions.
Add a dialog for redirecting to permissions settings if permission has been permanently denied.
Not sure if I want to support this, but it might be something for the future.
Add localization support
Some things don't look nice yet because of hard coded colors.
Since I made the Reddit post there have been people saying in the comments that the app can't find their lighthouses. This issue is here to get a list of devices that have trouble finding the lighthouses.
But first a small checklist to see if the issue can be resolved.
If these steps didn't help then please comment below that you are having this problem. When you comment please provide your phone's model and the version of Android you are running. This can be found in settings under about this phone, most of the time at the bottom of the settings list. Also check if you can find the lighthouses in your devices Bluetooth list, they should start with LHB-
flowed by some random characters different for every lighthouse.
Currently the lighthouses show up as LHB-XXXXXXXX
this is not a very friendly name (especially since they don't get sorted in the devices list).
Make it possible for users to add a nickname to their lighthouses.
Some people may want to put their lighthouse into stand-by instead of sleep.
Some people are reporting seeing devices double. This shouldn't happen, it may be a concurrency thing. Let's make sure it isn't that.
Currently the app polls the Lighthouses devices every second. This may cause lag for people with a lot of lighthouses, or on older devices. So add an option to change the update interval
LighthouseDevice
classA back end should report the permissions it needs to function, this way the app may use different back ends in the future.
Many dialog windows have a different order of positive "yes" button and negative "no/ cancel" button. This makes it annoying for users to quickly use the app and causes miss clicks.
Since most people are right handed let's add all the positive "yes" buttons on the right side of the dialog and all the negative "no/ cancel" buttons to the left side.
Files to look at:
Make sure that the negative and positive action are in the same order for all dialogs.
Currently the app has the default Flutter icon.
Add a custom app icon for Android and iOS.
It would be nice to have the app release on F-Droid if possible.
Here's a link to their FAQ about getting your app included in the repo.
It seems the Google Play version it severely behind all the recent changes, are there any plans to update it soon? I would prefer to not have to build it myself.
I think having a home screen widget to toggle the base station power would be nice. I was thinking it would look like a power button and could be configured to control a single base station or multiple base stations.
Every users always has at least 2 lighthouses that all have to change power state at the same time. In order to make this task easier.
Add an option to group lighthouses together to change their states all at once.
A help page might be useful to help people who just installed the app use it.
This is on a cheap Samsung J3 Orbit (SM-S367VL) running Android 9. I can read the Characteristic using BLE Scanner, so the hardware appears to be working fine. When I scan for available lighthouses using the latest code ( commit 331ddd3 ) it successfully finds the available V2 Lighthouse devices, but does not succeed in reading the power state. The backtrace below is generated when reading the Bluetooth characteristic is attempted:
2020-09-03 12:55:30.068 15945-15945/com.jeroen1602.lighthouse_pm D/ViewRootImpl@66b9cb1[MainActivity]: Relayout returned: old=[0,0][720,1280] new=[0,0][720,1280] result=0x1 surface={true 3576477696} changed=false
2020-09-03 12:55:31.171 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothAdapter: STATE_ON
2020-09-03 12:55:31.174 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothAdapter: STATE_ON
2020-09-03 12:55:31.174 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothLeScanner: could not find callback wrapper
2020-09-03 12:55:31.403 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothAdapter: STATE_ON
2020-09-03 12:55:31.405 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothAdapter: STATE_ON
2020-09-03 12:55:31.603 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothAdapter: STATE_ON
2020-09-03 12:55:31.605 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothAdapter: BLE support array set: 010011
2020-09-03 12:55:31.606 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothLeScanner: Start Scan with callback
2020-09-03 12:55:32.166 15945-15968/com.jeroen1602.lighthouse_pm D/BluetoothLeScanner: onScannerRegistered() - status=0 scannerId=10 mScannerId=0
2020-09-03 12:55:32.488 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: Trying to connect to device with name: LHB-DEEEFEE0
2020-09-03 12:55:32.497 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: Trying to connect to device with name: LHB-241D89DB
2020-09-03 12:55:32.507 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: Connecting to device: C3:8B:5A:87:2B:94
2020-09-03 12:55:32.522 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: Connecting to device: E9:8E:B8:0E:80:E5
2020-09-03 12:55:32.534 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothManager: getConnectedDevices
2020-09-03 12:55:32.549 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothAdapter: STATE_ON
2020-09-03 12:55:32.557 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothGatt: connect() - device: C3:8B:5A:87:2B:94, auto: true
2020-09-03 12:55:32.558 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothAdapter: isSecureModeEnabled
2020-09-03 12:55:32.560 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothGatt: registerApp()
2020-09-03 12:55:32.561 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothGatt: registerApp() - UUID=51e59be4-bc6a-4e50-8196-753924c441a9
2020-09-03 12:55:32.575 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothManager: getConnectedDevices
2020-09-03 12:55:32.575 15945-15970/com.jeroen1602.lighthouse_pm D/BluetoothGatt: onClientRegistered() - status=0 clientIf=11
2020-09-03 12:55:32.593 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothAdapter: STATE_ON
2020-09-03 12:55:32.598 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothGatt: connect() - device: E9:8E:B8:0E:80:E5, auto: true
2020-09-03 12:55:32.598 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothAdapter: isSecureModeEnabled
2020-09-03 12:55:32.599 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothGatt: registerApp()
2020-09-03 12:55:32.600 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothGatt: registerApp() - UUID=b2a1407a-33e4-43fe-95bc-243b196d7aaa
2020-09-03 12:55:32.608 15945-15968/com.jeroen1602.lighthouse_pm D/BluetoothGatt: onClientRegistered() - status=0 clientIf=12
2020-09-03 12:55:32.631 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothManager: getConnectionState()
2020-09-03 12:55:32.631 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothManager: getConnectedDevices
2020-09-03 12:55:32.644 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothManager: getConnectionState()
2020-09-03 12:55:32.644 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothManager: getConnectedDevices
2020-09-03 12:55:33.572 15945-15970/com.jeroen1602.lighthouse_pm D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=11 device=C3:8B:5A:87:2B:94
2020-09-03 12:55:33.578 15945-15970/com.jeroen1602.lighthouse_pm D/FlutterBluePlugin: [onConnectionStateChange] status: 0 newState: 2
2020-09-03 12:55:33.648 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: Finding service for device: C3:8B:5A:87:2B:94
2020-09-03 12:55:33.657 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothManager: getConnectionState()
2020-09-03 12:55:33.657 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothManager: getConnectedDevices
2020-09-03 12:55:33.673 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothGatt: discoverServices() - device: C3:8B:5A:87:2B:94
2020-09-03 12:55:33.853 15945-15970/com.jeroen1602.lighthouse_pm D/BluetoothGatt: onConnectionUpdated() - Device=C3:8B:5A:87:2B:94 interval=6 latency=0 timeout=500 status=0
2020-09-03 12:55:34.315 15945-15970/com.jeroen1602.lighthouse_pm D/BluetoothGatt: onSearchComplete() = Device=C3:8B:5A:87:2B:94 Status=0
2020-09-03 12:55:34.317 15945-15970/com.jeroen1602.lighthouse_pm D/FlutterBluePlugin: [onServicesDiscovered] count: 6 status: 0
2020-09-03 12:55:34.371 15945-15970/com.jeroen1602.lighthouse_pm D/BluetoothGatt: onConnectionUpdated() - Device=C3:8B:5A:87:2B:94 interval=36 latency=0 timeout=500 status=0
2020-09-03 12:55:34.952 15945-15970/com.jeroen1602.lighthouse_pm D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=12 device=E9:8E:B8:0E:80:E5
2020-09-03 12:55:34.961 15945-15970/com.jeroen1602.lighthouse_pm D/FlutterBluePlugin: [onConnectionStateChange] status: 0 newState: 2
2020-09-03 12:55:34.981 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: Finding service for device: E9:8E:B8:0E:80:E5
2020-09-03 12:55:34.990 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothManager: getConnectionState()
2020-09-03 12:55:34.990 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothManager: getConnectedDevices
2020-09-03 12:55:35.004 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothGatt: discoverServices() - device: E9:8E:B8:0E:80:E5
2020-09-03 12:55:35.247 15945-15970/com.jeroen1602.lighthouse_pm D/BluetoothGatt: onConnectionUpdated() - Device=E9:8E:B8:0E:80:E5 interval=6 latency=0 timeout=500 status=0
2020-09-03 12:55:35.560 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothManager: getConnectionState()
2020-09-03 12:55:35.560 15945-15945/com.jeroen1602.lighthouse_pm D/BluetoothManager: getConnectedDevices
2020-09-03 12:55:35.605 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: remoteId: C3:8B:5A:87:2B:94 characteristicUuid: 00001525-1212-efde-1523-785feabcd124 serviceUuid: 00001523-1212-efde-1523-785feabcd124
2020-09-03 12:55:35.627 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: PlatformException(read_characteristic_error, unknown reason, may occur if readCharacteristic was called before last read finished., null)
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:572:7)
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:161:18)
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: <asynchronous suspension>
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #2 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:334:12)
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #3 BluetoothCharacteristic.read (package:flutter_blue/src/bluetooth_characteristic.dart:83:10)
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #4 LighthouseV2Device.getCurrentState (package:lighthouse_pm/lighthouseProvider/devices/LighthouseV2Device.dart:28:45)
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: <asynchronous suspension>
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #5 LighthouseDevice._startPowerStateStream.<anonymous closure> (package:lighthouse_pm/lighthouseProvider/LighthouseDevice.dart:122:11)
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #6 _rootRunUnary (dart:async/zone.dart:1198:47)
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #7 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #8 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #9 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:357:11)
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #10 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:285:7)
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #11 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:808:19)
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #12 _StreamController._add (dart:async/stream_controller.dart:682:7)
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #13 _StreamController.add (dart:async/stream_controller.dart:624:5)
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #14 new Stream.periodic.<anonymous closure>.sendEvent (dart:async/stream.dart:358:22)
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #15 _rootRunUnary (dart:async/zone.dart:1198:47)
2020-09-03 12:55:35.631 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #16 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
2020-09-03 12:55:35.632 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #17 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
2020-09-03 12:55:35.632 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #18 _CustomZone.bindUnaryCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1042:26)
2020-09-03 12:55:35.632 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #19 _rootRunUnary (dart:async/zone.dart:1206:13)
2020-09-03 12:55:35.632 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #20 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
2020-09-03 12:55:35.632 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #21 _CustomZone.bindUnaryCallback.<anonymous closure> (dart:async/zone.dart:1026:26)
2020-09-03 12:55:35.632 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #22 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:397:19)
2020-09-03 12:55:35.632 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #23 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:428:5)
2020-09-03 12:55:35.632 15945-15998/com.jeroen1602.lighthouse_pm I/flutter: #24 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
2020-09-03 12:55:35.738 15945-15970/com.jeroen1602.lighthouse_pm D/BluetoothGatt: onSearchComplete() = Device=E9:8E:B8:0E:80:E5 Status=0
Add a small about page with the following features:
Leave the reports for unknown power state here.
0xFF
then the app doesn't know yet what the state is, give it a bit more time.If this still appears look at #32.
Please leave the reports in the following formate:
App version: x.x.x
Device Type: xxxxx
Firmware version: xxxxx
Current reported state: 0xxx
Sometimes the power state has not been retrieved yet or there is a problem retrieving it. To make sure a user can still use the app it needs a little dialog where the user can select what they want to sent to their lighthouses.
Software versions of the lighthouse firmware may change the reported states.
Some phones may not like communicating that quickly with the lighthouse.
Add dialog for when the powerstate is unknown.
Add help out option where people can report the unsupported state.
Kind of a weird request, but I was curious if it would be possible to add Tasker tasks for waking up saved Lighthouses on Android. I had the idea of setting up an Assistant command to wake up my Lighthouses for convenience's sake.
Some things to do for the next update.
Add tips about:
Add a padding at the bottom of the devices list so the devices don't get obstructed by the scan button.
Currently the app uses a boolean to make sure no 2 or more characteristic reads happen at once, this works but it's not the cleanest way. It also doesn't lock for writing to the lighthouses.
So we might get somewhere by reading the 0000CB01-0000-1000-8000-00805F9B34FB
characteristic. and using 0x001503020B
for on and 0x0012000100
for off.
Also steam VR uses a bit of a different method to turn the base stations on. They send an on command with a timeout, and if they don't send the same command again within the timeout then the base station will turn off. But there is also a mode for just turning it on, and the app uses that mode.
Originally posted by @jeroen1602 in #15 (comment)
The standby mode for the lighthouses is actually motors on and lasers off. Currently the app only support sleep (motors off, laser off). So it should be renamed.
Currently the Bluetooth not enabled page is a copy from flutter_blue's example app. It does it's thing but it doesn't really fit the rest of the app.
Change the Bluetooth not enabled page so it still works with other pages like in issue #2
Add a button to go to settings on both Android and iOS.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.