monta-app / ocpp-emulator

An open source OCPP Charge Point Emulator built using Kotlin Multiplatform and Jetbrains Compose
https://monta.com
Apache License 2.0
89 stars 4 forks source link

Application for Windows 11 v 2.3.1 Crashes when clicking "Stop transaction" #7

Closed smeatond closed 2 months ago

smeatond commented 3 months ago

I have just downloaded the latest exe from https://github.com/monta-app/ocpp-emulator/releases/tag/v2.3.1

Whenever I click on "Stop transaction" the application just crashes.

Here is my chargers details: image

gaetjen commented 3 months ago

Hm, I can't reproduce this (on Windows 10). Are there any error messages or stack traces in the application.log file (in /monta directory) you can share?

If instead of pressing the "Stop transaction" button you go from "Ready" to "Unplugged", does it also crash?

smeatond commented 3 months ago

Thanks for the reply @gaetjen I can go "ready" to "unplugged" fine.

Where should I find the "monta" directory? I can only find a "OCPPEmulator" directory in c drive:

image

And no application.log available.

gaetjen commented 3 months ago

It should be at C:\Users\<your_username>\monta.

smeatond commented 3 months ago

Here is the logs: Actions I did was click on start transaction then stop.

07:40:53.506 [AWT-EventQueue-0] INFO  c.m.o.e.logger.ChargePointLogger - [0] Sent message: StartTransaction
07:40:53.506 [DefaultDispatcher-worker-6] TRACE c.m.o.e.logger.ChargePointLogger - [0] [
  2,
  "fb411b93-8e09-4b74-b77b-80ca52171c0c",
  "StartTransaction",
  {
    "connectorId" : 1,
    "idTag" : "",
    "meterStart" : 0,
    "timestamp" : "2024-06-19T19:40:51Z"
  }
]

07:40:53.739 [DefaultDispatcher-worker-10] TRACE c.m.o.e.logger.ChargePointLogger - [0] [
  3,
  "fb411b93-8e09-4b74-b77b-80ca52171c0c",
  {
    "idTagInfo" : {
      "status" : "Accepted"
    },
    "transactionId" : 23
  }
]

07:40:53.739 [DefaultDispatcher-worker-10] WARN  c.m.library.ocpp.client.OcppClient - deferredCache not found for confirmation uniqueId=fb411b93-8e09-4b74-b77b-80ca52171c0c
07:41:00.111 [AWT-EventQueue-0] ERROR c.m.o.e.common.WindowExtensions - Window Exception
java.lang.NullPointerException: null
    at com.monta.ocpp.emulator.v16.view.interceptor.SendMessageWindowKt.defaultPayload(SendMessageWindow.kt:317)
    at com.monta.ocpp.emulator.v16.view.interceptor.InterceptorConfigComponentKt$InterceptionConfigRow$1$1$2.invoke(InterceptorConfigComponent.kt:117)
    at com.monta.ocpp.emulator.v16.view.interceptor.InterceptorConfigComponentKt$InterceptionConfigRow$1$1$2.invoke(InterceptorConfigComponent.kt:113)
    at androidx.compose.foundation.ClickablePointerInputNode$pointerInput$3.invoke-k-4lQ0M(Clickable.kt:991)
    at androidx.compose.foundation.ClickablePointerInputNode$pointerInput$3.invoke(Clickable.kt:984)
    at androidx.compose.foundation.gestures.TapGestureDetectorKt$detectTapAndPress$2$1.invokeSuspend(TapGestureDetector.kt:258)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:175)
    at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:164)
    at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:470)
    at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:504)
    at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:493)
    at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:364)
    at androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNodeImpl$PointerEventHandlerCoroutine.offerPointerEvent(SuspendingPointerInputFilter.kt:672)
    at androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNodeImpl.dispatchPointerEvent(SuspendingPointerInputFilter.kt:549)
    at androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNodeImpl.onPointerEvent-H0pRuoY(SuspendingPointerInputFilter.kt:571)
    at androidx.compose.foundation.AbstractClickablePointerInputNode.onPointerEvent-H0pRuoY(Clickable.kt:950)
    at androidx.compose.foundation.AbstractClickableNode.onPointerEvent-H0pRuoY(Clickable.kt:798)
    at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:326)
    at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:312)
    at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:312)
    at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:312)
    at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:312)
    at androidx.compose.ui.input.pointer.NodeParent.dispatchMainEventPass(HitPathTracker.kt:187)
    at androidx.compose.ui.input.pointer.HitPathTracker.dispatchChanges(HitPathTracker.kt:106)
    at androidx.compose.ui.input.pointer.PointerInputEventProcessor.process-BIzXfog(PointerInputEventProcessor.kt:114)
    at androidx.compose.ui.node.RootNodeOwner.onPointerInput(RootNodeOwner.skiko.kt:208)
    at androidx.compose.ui.scene.MultiLayerComposeSceneImpl.processRelease(MultiLayerComposeScene.skiko.kt:315)
    at androidx.compose.ui.scene.MultiLayerComposeSceneImpl.processPointerInputEvent(MultiLayerComposeScene.skiko.kt:230)
    at androidx.compose.ui.scene.BaseComposeScene$inputHandler$2.invoke(BaseComposeScene.skiko.kt:61)
    at androidx.compose.ui.scene.BaseComposeScene$inputHandler$2.invoke(BaseComposeScene.skiko.kt:61)
    at androidx.compose.ui.input.pointer.SyntheticEventSender.sendInternal(SyntheticEventSender.skiko.kt:175)
    at androidx.compose.ui.input.pointer.SyntheticEventSender.send(SyntheticEventSender.skiko.kt:79)
    at androidx.compose.ui.scene.ComposeSceneInputHandler.onPointerEvent-WlEVilQ(ComposeSceneInputHandler.skiko.kt:118)
    at androidx.compose.ui.scene.ComposeSceneInputHandler.onPointerEvent-BGSDPeU(ComposeSceneInputHandler.skiko.kt:84)
    at androidx.compose.ui.scene.BaseComposeScene.sendPointerEvent-BGSDPeU(BaseComposeScene.skiko.kt:182)
    at androidx.compose.ui.scene.ComposeScene.sendPointerEvent-BGSDPeU$default(ComposeScene.skiko.kt:180)
    at androidx.compose.ui.scene.ComposeSceneMediator_desktopKt.onMouseEvent-d-4ec7I(ComposeSceneMediator.desktop.kt:663)
    at androidx.compose.ui.scene.ComposeSceneMediator_desktopKt.access$onMouseEvent-d-4ec7I(ComposeSceneMediator.desktop.kt:1)
    at androidx.compose.ui.scene.ComposeSceneMediator.onMouseEvent(ComposeSceneMediator.desktop.kt:363)
    at androidx.compose.ui.scene.ComposeSceneMediator.access$onMouseEvent(ComposeSceneMediator.desktop.kt:64)
    at androidx.compose.ui.scene.ComposeSceneMediator$mouseListener$1.mouseReleased(ComposeSceneMediator.desktop.kt:168)
    at java.desktop/java.awt.Component.processMouseEvent(Unknown Source)
    at java.desktop/java.awt.Component.processEvent(Unknown Source)
    at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
    at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
    at java.base/java.security.AccessController.doPrivileged(Unknown Source)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
    at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
    at java.base/java.security.AccessController.doPrivileged(Unknown Source)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
07:41:00.120 [AWT-EventQueue-0] DEBUG c.m.o.e.v.d.util.DatabaseExtensions - closing hook entityClass=com.monta.ocpp.emulator.v16.data.entity.ChargePointDAO$Companion, id=1
07:41:00.120 [AWT-EventQueue-0] DEBUG c.m.o.e.v.d.util.DatabaseExtensions - closing hook entityClass=com.monta.ocpp.emulator.v16.data.entity.ChargePointDAO$Companion, id=null
07:41:00.120 [AWT-EventQueue-0] DEBUG c.m.o.e.v.d.util.DatabaseExtensions - closing hook entityClass=com.monta.ocpp.emulator.v16.data.entity.ChargePointConnectorDAO$Companion, id=1
07:41:00.310 [DefaultDispatcher-worker-9] INFO  c.m.o.e.v.s.o.c.ConnectionManager - Disconnecting chargePointId=1
07:41:00.311 [DefaultDispatcher-worker-9] INFO  c.m.o.e.v.s.ocpp.SchedulerService - stopping scheduler
07:41:00.311 [DefaultDispatcher-worker-9] TRACE c.m.o.e.logger.ChargePointLogger - [0] [
  2,
  "34d170be-f108-439d-be41-ac048ddd9d27",
  "StatusNotification",
  {
    "connectorId" : 0,
    "errorCode" : "NoError",
    "info" : "Disconnecting",
    "status" : "Unavailable",
    "timestamp" : "2024-06-20T07:41:00+12"
  }
]

07:41:00.320 [DefaultDispatcher-worker-4] TRACE c.m.o.e.logger.ChargePointLogger - [0] [
  3,
  "34d170be-f108-439d-be41-ac048ddd9d27",
  { }
]

07:41:00.340 [DefaultDispatcher-worker-3] INFO  c.m.o.e.logger.ChargePointLogger - [0] Disconnected
07:41:00.349 [DefaultDispatcher-worker-3] WARN  c.m.o.e.logger.ChargePointLogger - [0] Unable to connect to server, will not attempt to reconnect
gaetjen commented 3 months ago

Thanks for the logs, I can actually reproduce this. I didn't realize you were using the functions in the drawer. :slightly_smiling_face:

PR for fix here: #8

I also added a little explanation about the functions in the drawer to the readme. The tl;dr is, unless you're specifically trying to replicate buggy behavior, you'll usually be better off controlling the charge point through the normal interface. Here is the explanation I added:

What's up with the 🤓?

Clicking the icon gives access to "message interception". The primary purpose is to have a high degree of control over which messages are sent and received by the charge point. That way it is possible to replicate potentially buggy behavior or custom implementations in a one-off manner without needing to change the actual programming of the charge point. For "normal operation" of the charge point the standard interface should be sufficient.

Also note that the message interception functions are not hooked up to the internal machinery of the charge point. For example, sending a StopTransaction message will not actually change the state of an ongoing charge to be stopped. That means using these functions also makes it very easy to put the charge point into a state that does not match up with what the CSMS is expecting, which can quickly lead to unexpected behavior.

smeatond commented 3 months ago

Great thank you! You can always trust other developers or even users to break your app with the unintended way of using it.

Montrichard commented 2 weeks ago

Just found this issue, I think the same applies on Mac, just raised #27