Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Graph widget to show historical data #4601

Closed
Closed
Show file tree
Hide file tree
Changes from 59 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
3bef3d1
Here is a simple Graph to show historical data, which adds a feature …
ivorsmorenburg Sep 1, 2024
c66f918
Fix Lint
ivorsmorenburg Sep 2, 2024
50c3a9b
Fix Lint
ivorsmorenburg Sep 2, 2024
db72ae6
Merge remote-tracking branch 'origin/feature/issue-1529' into feature…
ivorsmorenburg Sep 2, 2024
9da3c3b
Fix Lint
ivorsmorenburg Sep 2, 2024
46a6f50
Adds dependencies to compile
ivorsmorenburg Sep 2, 2024
24937fa
Resolves some comments in PR
ivorsmorenburg Sep 3, 2024
c55bec6
Fix linting format again :)
ivorsmorenburg Sep 3, 2024
e90737d
Fix linting format again :)
ivorsmorenburg Sep 3, 2024
1a6a28f
Adds Test Step
ivorsmorenburg Sep 3, 2024
2a93ee3
Merge remote-tracking branch 'origin/feature/issue-1529' into feature…
ivorsmorenburg Sep 3, 2024
8bd32e4
Adds some structure to add some unit testing
ivorsmorenburg Sep 3, 2024
7964d28
Adds instrumentation tests
ivorsmorenburg Sep 3, 2024
dce8731
Nicer UI
ivorsmorenburg Sep 4, 2024
10f8801
Nicer UI Adding sampling and range
ivorsmorenburg Sep 4, 2024
778fbfa
Nicer UI Adding sampling and range
ivorsmorenburg Sep 4, 2024
d3b7e63
Nicer UI Adding sampling and range
ivorsmorenburg Sep 4, 2024
b2e2d57
Nicer UI Adding sampling and range
ivorsmorenburg Sep 4, 2024
93a2188
Nicer UI Adding sampling and range
ivorsmorenburg Sep 4, 2024
a35d353
Merge branch 'master' into feature/issue-1529
ivorsmorenburg Sep 4, 2024
e5736e1
Some Improvements on GraphWidget Updates
ivorsmorenburg Sep 5, 2024
7bb42ba
Merge remote-tracking branch 'origin/feature/issue-1529' into feature…
ivorsmorenburg Sep 5, 2024
09eb68f
Some Improvements on GraphWidget Updates
ivorsmorenburg Sep 5, 2024
0fc814c
Some Improvements on GraphWidget Updates
ivorsmorenburg Sep 5, 2024
99dfe12
Some Linting.. I think it will be super useful to add pre-commit hook…
ivorsmorenburg Sep 5, 2024
26d04ec
ReRun tests
ivorsmorenburg Sep 5, 2024
ef59cbe
Removed debug db library for testing purposes
ivorsmorenburg Sep 5, 2024
6828e5a
Removed preview layout as we are using preview image
ivorsmorenburg Sep 5, 2024
7a04973
Addressed some comments
ivorsmorenburg Sep 5, 2024
b6de5e0
Revert changes to simplify the PR
ivorsmorenburg Sep 7, 2024
fc15421
Revert changes to simplify the PR
ivorsmorenburg Sep 7, 2024
ba34989
Revert changes to simplify the PR
ivorsmorenburg Sep 7, 2024
c48e186
KtLint
ivorsmorenburg Sep 8, 2024
292dbfb
Merge branch 'master' into feature/issue-1529
ivorsmorenburg Sep 8, 2024
6f213b0
Applied Comments
ivorsmorenburg Sep 8, 2024
7677988
Adds Description dyn Color
ivorsmorenburg Sep 8, 2024
414cb12
Adds Support for Historic Data
ivorsmorenburg Sep 9, 2024
2b91fb5
Adds Support for Historic Data
ivorsmorenburg Sep 9, 2024
3e8d0ab
Merge branch 'master' into feature/issue-1529
ivorsmorenburg Sep 9, 2024
fd4b765
Update strings.xml
ivorsmorenburg Sep 9, 2024
d1adbc3
Addressed some more comments 🚀
ivorsmorenburg Sep 9, 2024
ffb74a8
Addressed some more comments 🚀
ivorsmorenburg Sep 9, 2024
34fae8d
Addressed some more comments 🚀
ivorsmorenburg Sep 9, 2024
1369df2
UI Enhancements 🧑‍🎨
ivorsmorenburg Sep 9, 2024
08e4cdf
Addressed some more comments 🚀
ivorsmorenburg Sep 9, 2024
86fcbad
Addressed some more comments 🚀
ivorsmorenburg Sep 9, 2024
29b5e7f
UI Enhancements 🧑‍🎨
ivorsmorenburg Sep 10, 2024
aa5f147
Addressed some more comments 🚀
ivorsmorenburg Sep 10, 2024
291b865
Merge branch 'master' into feature/issue-1529
ivorsmorenburg Sep 10, 2024
46e6b3f
Re-adds library to make the project compile referring to @jpelgrom co…
ivorsmorenburg Sep 10, 2024
a528d1b
Refresh Logic for Graph if misses data based on average on lastChange…
ivorsmorenburg Sep 10, 2024
12a562d
KtLint & Graph Mode to show data like Home Assistant
ivorsmorenburg Sep 10, 2024
5da5b8d
Graph Mode switch, addressed comment, UI enhancements
ivorsmorenburg Sep 10, 2024
a9af392
Linting attempt to fic
ivorsmorenburg Sep 11, 2024
1d2b65b
Linting attempt to fic
ivorsmorenburg Sep 11, 2024
3e5091b
Test
ivorsmorenburg Sep 11, 2024
4fe4b25
File revert fix
ivorsmorenburg Sep 11, 2024
389833a
Merge branch 'master' into feature/issue-1529
ivorsmorenburg Sep 11, 2024
cb3b7cf
Attempt to fix query history everytime the views are painted
ivorsmorenburg Sep 11, 2024
b5e9b55
Some refactoring and cleanup
ivorsmorenburg Sep 11, 2024
1a58d1e
Addressed comments
ivorsmorenburg Sep 11, 2024
37bb653
Merge branch 'master' into feature/issue-1529
ivorsmorenburg Sep 11, 2024
9ff623e
Addressed comments
ivorsmorenburg Sep 11, 2024
98ac005
KtLint
ivorsmorenburg Sep 11, 2024
f61cbee
Enhancements
ivorsmorenburg Sep 11, 2024
02c57d5
Enhancements
ivorsmorenburg Sep 12, 2024
724ae27
Addressed comments
ivorsmorenburg Sep 12, 2024
4f2995d
Merge branch 'master' into feature/issue-1529
ivorsmorenburg Sep 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ android {

dependencies {
implementation(project(":common"))
implementation(libs.mpgraph)

coreLibraryDesugaring(libs.tools.desugar.jdk)

Expand Down
22 changes: 22 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,20 @@
android:resource="@xml/entity_widget_info" />
</receiver>

<receiver
android:name=".widgets.graph.GraphWidget"
android:exported="false"
android:label="@string/widget_graph_image_description">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="io.homeassistant.companion.android.widgets.GraphWidget.RECEIVE_DATA" />
</intent-filter>

<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/graph_widget_info" />
</receiver>

<receiver android:name=".widgets.mediaplayer.MediaPlayerControlsWidget" android:label="@string/widget_media_player_description"
android:exported="false">
<intent-filter>
Expand Down Expand Up @@ -209,6 +223,14 @@
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<activity
android:name=".widgets.graph.GraphWidgetConfigureActivity"
android:configChanges="orientation|screenSize"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<activity android:name=".widgets.mediaplayer.MediaPlayerControlsWidgetConfigureActivity"
android:configChanges="orientation|screenSize"
android:exported="true">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import io.homeassistant.companion.android.util.LifecycleHandler
import io.homeassistant.companion.android.websocket.WebsocketBroadcastReceiver
import io.homeassistant.companion.android.widgets.button.ButtonWidget
import io.homeassistant.companion.android.widgets.entity.EntityWidget
import io.homeassistant.companion.android.widgets.graph.GraphWidget
import io.homeassistant.companion.android.widgets.mediaplayer.MediaPlayerControlsWidget
import io.homeassistant.companion.android.widgets.template.TemplateWidget
import javax.inject.Inject
Expand Down Expand Up @@ -277,6 +278,7 @@ open class HomeAssistantApplication : Application() {
// Update widgets when the screen turns on, updates are skipped if widgets were not added
val buttonWidget = ButtonWidget()
val entityWidget = EntityWidget()
val graphWidget = GraphWidget()
val mediaPlayerWidget = MediaPlayerControlsWidget()
val templateWidget = TemplateWidget()

Expand All @@ -286,6 +288,7 @@ open class HomeAssistantApplication : Application() {

ContextCompat.registerReceiver(this, buttonWidget, screenIntentFilter, ContextCompat.RECEIVER_NOT_EXPORTED)
ContextCompat.registerReceiver(this, entityWidget, screenIntentFilter, ContextCompat.RECEIVER_NOT_EXPORTED)
ContextCompat.registerReceiver(this, graphWidget, screenIntentFilter, ContextCompat.RECEIVER_NOT_EXPORTED)
ContextCompat.registerReceiver(this, mediaPlayerWidget, screenIntentFilter, ContextCompat.RECEIVER_NOT_EXPORTED)
ContextCompat.registerReceiver(this, templateWidget, screenIntentFilter, ContextCompat.RECEIVER_NOT_EXPORTED)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import io.homeassistant.companion.android.database.widget.CameraWidgetDao
import io.homeassistant.companion.android.database.widget.MediaPlayerControlsWidgetDao
import io.homeassistant.companion.android.database.widget.StaticWidgetDao
import io.homeassistant.companion.android.database.widget.TemplateWidgetDao
import io.homeassistant.companion.android.database.widget.graph.GraphWidgetDao
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch
Expand All @@ -25,6 +26,7 @@ class ManageWidgetsViewModel @Inject constructor(
buttonWidgetDao: ButtonWidgetDao,
cameraWidgetDao: CameraWidgetDao,
staticWidgetDao: StaticWidgetDao,
graphWidgetDao: GraphWidgetDao,
mediaPlayerControlsWidgetDao: MediaPlayerControlsWidgetDao,
templateWidgetDao: TemplateWidgetDao,
application: Application
Expand All @@ -39,6 +41,7 @@ class ManageWidgetsViewModel @Inject constructor(
val buttonWidgetList = buttonWidgetDao.getAllFlow().collectAsState()
val cameraWidgetList = cameraWidgetDao.getAllFlow().collectAsState()
val staticWidgetList = staticWidgetDao.getAllFlow().collectAsState()
val graphWidgetList = graphWidgetDao.getAllFlow().collectAsState()
val mediaWidgetList = mediaPlayerControlsWidgetDao.getAllFlow().collectAsState()
val templateWidgetList = templateWidgetDao.getAllFlow().collectAsState()
val supportsAddingWidgets: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,15 @@ import io.homeassistant.companion.android.util.compose.MdcAlertDialog
import io.homeassistant.companion.android.widgets.button.ButtonWidgetConfigureActivity
import io.homeassistant.companion.android.widgets.camera.CameraWidgetConfigureActivity
import io.homeassistant.companion.android.widgets.entity.EntityWidgetConfigureActivity
import io.homeassistant.companion.android.widgets.graph.GraphWidgetConfigureActivity
import io.homeassistant.companion.android.widgets.mediaplayer.MediaPlayerControlsWidgetConfigureActivity
import io.homeassistant.companion.android.widgets.template.TemplateWidgetConfigureActivity

enum class WidgetType(val widgetIcon: IIcon) {
BUTTON(CommunityMaterial.Icon2.cmd_gesture_tap),
CAMERA(CommunityMaterial.Icon.cmd_camera_image),
STATE(CommunityMaterial.Icon3.cmd_shape),
GRAPH(CommunityMaterial.Icon2.cmd_file_chart),
MEDIA(CommunityMaterial.Icon3.cmd_play_box_multiple),
TEMPLATE(CommunityMaterial.Icon.cmd_code_braces);

Expand All @@ -57,6 +59,7 @@ enum class WidgetType(val widgetIcon: IIcon) {
CAMERA -> CameraWidgetConfigureActivity::class.java
MEDIA -> MediaPlayerControlsWidgetConfigureActivity::class.java
STATE -> EntityWidgetConfigureActivity::class.java
GRAPH -> GraphWidgetConfigureActivity::class.java
TEMPLATE -> TemplateWidgetConfigureActivity::class.java
}
}
Expand All @@ -82,6 +85,7 @@ fun ManageWidgetsView(
stringResource(R.string.widget_button_image_description) to WidgetType.BUTTON,
stringResource(R.string.widget_camera_description) to WidgetType.CAMERA,
stringResource(R.string.widget_static_image_description) to WidgetType.STATE,
stringResource(R.string.widget_graph_image_description) to WidgetType.GRAPH,
stringResource(R.string.widget_media_player_description) to WidgetType.MEDIA,
stringResource(R.string.template_widget) to WidgetType.TEMPLATE
).sortedBy { it.first }
Expand Down Expand Up @@ -110,7 +114,7 @@ fun ManageWidgetsView(
) {
if (viewModel.buttonWidgetList.value.isEmpty() && viewModel.staticWidgetList.value.isEmpty() &&
viewModel.mediaWidgetList.value.isEmpty() && viewModel.templateWidgetList.value.isEmpty() &&
viewModel.cameraWidgetList.value.isEmpty()
viewModel.cameraWidgetList.value.isEmpty() && viewModel.graphWidgetList.value.isEmpty()
) {
item {
EmptyState(
Expand Down Expand Up @@ -144,6 +148,15 @@ fun ManageWidgetsView(
if (!label.isNullOrEmpty()) label else "${item.entityId} ${item.stateSeparator} ${item.attributeIds.orEmpty()}"
}
)
widgetItems(
viewModel.graphWidgetList.value,
widgetType = WidgetType.GRAPH,
title = R.string.graph_state_widgets,
widgetLabel = { item ->
val label = item.label
if (!label.isNullOrEmpty()) label else item.entityId
}
)
widgetItems(
viewModel.mediaWidgetList.value,
widgetType = WidgetType.MEDIA,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,14 @@ import android.widget.Toast
import io.homeassistant.companion.android.BaseActivity
import io.homeassistant.companion.android.common.R
import io.homeassistant.companion.android.common.data.servers.ServerManager
import io.homeassistant.companion.android.database.widget.WidgetDao
import javax.inject.Inject

abstract class BaseWidgetConfigureActivity : BaseActivity() {

@Inject
lateinit var serverManager: ServerManager

protected var appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID

abstract val dao: WidgetDao

abstract val serverSelect: View
abstract val serverSelectList: Spinner

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ abstract class BaseWidgetProvider : AppWidgetProvider() {

companion object {
const val UPDATE_VIEW =
"io.homeassistant.companion.android.widgets.template.BaseWidgetProvider.UPDATE_VIEW"
"io.homeassistant.companion.android.widgets.BaseWidgetProvider.UPDATE_VIEW"
const val RECEIVE_DATA =
"io.homeassistant.companion.android.widgets.template.TemplateWidget.RECEIVE_DATA"
"io.homeassistant.companion.android.widgets.BaseWidgetProvider.RECEIVE_DATA"

var widgetScope: CoroutineScope? = null
val widgetEntities = mutableMapOf<Int, List<String>>()
Expand Down Expand Up @@ -63,6 +63,7 @@ abstract class BaseWidgetProvider : AppWidgetProvider() {
widgetScope?.launch {
val views = getWidgetRemoteViews(context, appWidgetId)
appWidgetManager.updateAppWidget(appWidgetId, views)
onRemoteViewsUpdated(context, appWidgetId, appWidgetManager)
}
}
}
Expand All @@ -82,6 +83,7 @@ abstract class BaseWidgetProvider : AppWidgetProvider() {
)
onScreenOn(context)
}

Intent.ACTION_SCREEN_ON -> onScreenOn(context)
Intent.ACTION_SCREEN_OFF -> onScreenOff()
}
Expand Down Expand Up @@ -185,4 +187,5 @@ abstract class BaseWidgetProvider : AppWidgetProvider() {
abstract suspend fun getAllWidgetIdsWithEntities(context: Context): Map<Int, Pair<Int, List<String>>>
abstract fun saveEntityConfiguration(context: Context, extras: Bundle?, appWidgetId: Int)
abstract suspend fun onEntityStateChanged(context: Context, appWidgetId: Int, entity: Entity<*>)
open suspend fun onRemoteViewsUpdated(context: Context, appWidgetId: Int, appWidgetManager: AppWidgetManager) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() {

@Inject
lateinit var buttonWidgetDao: ButtonWidgetDao
override val dao get() = buttonWidgetDao

private var actions = mutableMapOf<Int, HashMap<String, Action>>()
private var entities = mutableMapOf<Int, HashMap<String, Entity<Any>>>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ class CameraWidgetConfigureActivity : BaseWidgetConfigureActivity() {

@Inject
lateinit var cameraWidgetDao: CameraWidgetDao
override val dao get() = cameraWidgetDao

private var entityAdapter: SingleItemArrayAdapter<Entity<Any>>? = null

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ class EntityWidgetConfigureActivity : BaseWidgetConfigureActivity() {

@Inject
lateinit var staticWidgetDao: StaticWidgetDao
override val dao get() = staticWidgetDao

private var entities = mutableMapOf<Int, List<Entity<Any>>>()

Expand Down
Loading