The place where random ideas get written down and lost in time.

2021-08-18 - Bearing B3 Features

Category DEV

Now that we have a basic “marked locations” list in B3, it’s time to review the UI and adjust.

The goal was to do it in Kotlin, and that’s been done.

One issue was the “Marked Locations” wording, which seems problematic. Isn’t there something better… “waypoints” seem like a better name.

So let’s do a few changes:

  • Vocabulary:
    • A “Location” is just a raw GPS location coordinate (latitude + longitude).
    • A “Waypoint” is a location coordinate combined with a name.
  • Screen “Marked Locations” ⇒ “Waypoints”
    • “Marked Location” ⇒ “Selected Waypoint”
    • “Location N” ⇒ “Waypoint N”
    • Rename class Mark to Waypoint / Waypoints / WaypointsAdapter.
  • Screen “Compass”
    • “Marked Location” ⇒ “Target Location”
      • (that should make it more obvious it’s the target of the bearing)
    • Menu Recall / Edit ⇒ keep as-is for now.

We’ll keep the wording as “Location” (Target vs GPS) in the Compass screen.


2021-08-11 - Android Testing : AndroidX “AndroidJUnit4” vs Robolectric

Category DEV

I feel like a case of deja vu so I need to write this down.

  • Robolectric: simulating an Android runtime working on top of the JVM, local dev machine. No emulator needed.
    • Used to be simple and straightforward. Since Robolectric 4 and recent android gradle updates, some things have been deprecated / changed making it harder to use.
  • AndroidX runner “AndroidJUnitRunner” tests which go in androidTest folder: run on device or emulator, and are essentially the modern version of the instrumentation tests.
  • AndroidX runner “AndroidJUnit4” tests which go in androidTest folder: run on device or emulator too ⇒ the test folder name indicates which build rule is used and where the test runs.
  • AndroidX runner “MockitoJUnitRunner” tests which go in the test folder: run on JVM.
    • This is provided by mockito-core and is basically a JUnit runner that also happens to auto-init all the @Mock instances. ⇒ Just a convenience over the usual Mock rule, no relation to Android framework.
    • How much of the Android framework can be used with that? ⇒ none
  • Robolectric with AndroidX tests:

What I have done for Cab v2:

  • Build.gradle > defaultConfig > testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
  • ServersActivityTest:
    • @RunWith(AndroidJUnit4.class)
      @Config(application = TestMainApp.class)
      ApplicationProvider.getApplicationContext()
      ActivityScenario.launch(MainActivity.class)
  • The cabv2 TestMainApp derives from the LegacyMainApp and replaces the IAppComponent by the ITestAppComponent for testing. That’s how test modules are injected in the app.

Since updating B3, I was getting errors:

  • “robolectric RuntimeException Method not mocked”
  • They are “solved” by adding this to app gradle:
    • testOptions > unitTests >  returnDefaultValues = true
  • Which in turn creates another error: “java.lang.ClassNotFoundException: android.content.res.ApkAssets”
  • Real solution: following https://github.com/robolectric/robolectric/issues/4740
    • The dumb solution is to remove the m2 robolectric cache so that it gets downloaded again.


2021-08-08 - Gradle Wrapper + Maven Repo Offline caching

Category DEV

https://softwareengineering.stackexchange.com/questions/331817/self-contained-projects-gradle-maven-dependencies-offline

This explains:

  • How to use an offline version of the Gradle wrapper.
  • How to use an offline version of a project’s Maven repo dependencies (cached once).


2021-08-05 - Summer Project: Bearing + Kotlin

Category DEV

Kotlin / rig4k is a good potential idea but really a project based around GDoc downloads & APIs sounds like a painful thing to do in PA. It requires internet connection (duh). But also GDoc APIs are notorious to change each time I look at them, requiring even more research -- that is there’s the issue that I’d have to learn the “idiomatic kotlin” and the “idiomatic gdoc API” at the same time.

So instead, what about Bearing? It could be a good Kotlin candidate:

  • No new API learning curve. The usual Android stuff, just done as Kotlin.
  • Can focus on Kotlin syntax & such.
  • One option would be to rewrite the whole app in Kotlin, however… what’s the benefit?
  • Can just mix with the current version and add new stuff in Kotlin.

That is the addition would be a new fragment or activity for a mark list management, which is neatly self-contained.


2021-08-05 - Looking back at Bearing B3

Category DEV

When I (re)created Bearing B3, I tried a few things:

  • The “new” ABB (Android Bundle) mode.
    • Not a big fan but this is the way to go since Play will eventually make AAB mandatory in 2021 or 2022.
    • It was a good test and useful, and I shall keep it that way for distrib.
  • The new “instant vs installed” modes.
    • That was good learning to realize that instant creates some limitations, e.g. can’t bundle analytics stats with it.
    • Other than that, it makes the build config a bit more complicated by having 2 variants.
    • Overall it doesn’t bring much in terms of visibility. E.g. how many apps are installed vs run as instant?
  • FirebaseAnalytics instead of GA.
    • Same difference?
    • Need to constantly update the library… it’s obsolete again IIRC.

Work suggestions:

  • Remove the “instant” variant. Only keep the installed one.
    • What about google play? Can I remove the instant version there too?
    • ⇒ update the “installed” version first and check if the “instant” can be removed from Play. If it does, then cleanup the “instant” build script + code.
  • Check updating of the Firebase library.
    • ⇒ That’s enough update needed to create the new installed variant.


2021-08-02 - Summer Project: Bearing

Category DEV

Guess what… I’m in PA and I already want to add a couple features to Bearing:

  • Create a marked location list + auto save/load.
  • When marking a location:
    • Add it to the list. Names a “Location 1…” + auto-inc (use list length).
      • TBD later ⇒ dialog to edit name before adding it + cancel.
      • But to get started, generate name automatically.
    • Display name in small font below marked location.
  • Add a little “3-dot menu” on the “Marked Loc” line. Popup a menu:
    • Recall / Edit…         ⇒ goes to marked loc fragment (see below).                  [done]
    • Share…                 ⇒ share location as text/etc                                        [done]
    • V2: Rename…         ⇒ dialog with one text edit field.
    • V2: Save                 ⇒ enabled/visible if marked loc is not in current list (e.g. upgrade or deleted).
  • Share bearing (as text, to google maps).                                                        [done]
  • Marked locs fragment:
    • Reuse the current pattern (fragments in a single activity).                        [done]
    • Simple text list. Select an item : [Delete] / [Recall] / [Rename (v2)].        [done]
    • List items: GPS loc + date/time + name on 2nd line.        [done]
      • V1: Not listing the time
    • Delete with confirmation ⇒ does not remove current marked loc.                 [done]
    • Recall: honor the pref setting “ask before override marked loc”.                [done]
      • Recall would erase the current mark loc,
      • Then go directly to the compass view.
    • V2: Share selected mark.
    • V2: Export all marks as text.
    • V2 or +: reorder, rename.
  • Consider renaming “marked locations” to “waypoints”?
  • Split screen:
    • Bottom is list view
    • V2: top is map view of selected list item.
    • V2: top is detail info for item. Name edit field to rename. Trash icon for delete with confirmation. Eye or compass icon to make it the mark in compass.


2021-02-17 - ESP32 Learning: MQTT

Category Esp32

This is something I need to look into at some point: MQTT to send messages between ESP32 nodes on a local network.

There’s a group (MQTT4MR) that uses that to control sensors via JMRI (instead of C/MRI over RS485 wires).

MQTT is also used typically with LoRa and such for larger distance networks, I believe using brokers/hubs. However that’s not really my first usage.

https://learn.adafruit.com/mqtt-adafruit-io-and-you?view=all MQTT very high overview:

  • Designed for sensors … small payloads, infrequent data, not heavy streams.
    • Which is why it works well with LoRa (bandwidth vs distance, pick one).
  • It’s a N-to-1 design: one server somewhere, multiple clients.
  • Either one device acts as a server, or a “broker” app/script runs on a network computer.
    • JMRI uses the latter design for obvious reasons.
    • There are internet-wide brokers like adafruit.io
  • To connect to a broker, need server/ip, port, username, and a key.
  • The whole concept is a pub-sub:
    • Devices publish to the server.
    • Devices subscribe to the server.
  • Subscribers need to send a ping (e.g. every 5 minutes).
    • Failing to ping disconnects the device.
  • Adafruit_MQTT is such a lib for arduino.
    • They warn it’s single-duplex: a subscription message would be lost if the device is transmitting (ping or publication) at the same time.
  • Quality-of-service:
    • QOS 0 = send publication message without checking they arrived.
    • QOS 1 = send publication message with an OK / ack.
  • A “will” is a message defined such that the broker sends it when the client disconnects.


2021-02-07 - Conductor2… Kotlin vs Groovy again

Category DEV

It’s been 2 years now that I started the rewrite of Conductor 2. Back then I chose Groovy, after trying Kotlin and deciding it wasn’t mature enough. In between, Kotlin usage has expanded a lot, so time to revisit.

(N.D.L.R.: the goal of the Conductor 2 project is to replace the custom language from Conductor 1 by a new DSL based on top of Groovy, or Kotlin. That would allow the script to have more flexibility.)

Overall Conductor2 with Groovy would work. Although the engine isn’t 100% operational, I rewrote most of the main automation script using Groovy and I updated it to a few new concepts that I miss in my current custom language.

The Conductor 2 design doc has more details on the new syntax.

Through the implementation, I evolved the syntax.

In conductor 1, we have basically a “global” namespace of “conditions --> actions”.

These can be expressed in the Groovy script using:

On { closure expression return a boolean } --> { actions block }

However I later rewrote the script to be more oriented for each route / block.

A route is defined as a sequence of blocks that must be traversed, and there are actions for each block. This avoids the soup of global state variables that must be maintained in Conductor 1 to achieve the same thing (e.g. “passenger train on this block going forward”). The new syntax looks like this:

Name = route {

        Route = [

                BlockNumber.forward {

                        onStart { actions }

                        onEnter { actions } then_after delay { actions }

        after delay { actions } then_after delay { actions }

} ] }

This scheme basically encodes most of the complexity in Conductor 1’s script, which is using timers and global state to limit actions to certain routes/blocks/directions.

Click here to continue reading...


2020-12-18 - Kotlin and Rust

Category DEV

I keep circling back to these and I think it’s time I consider some “real” project for it.

I tried Rust for rig4, and I wasn’t impressed. I think of C and Rust as “embedded” development languages, not server ones.

In fact the main reason I’ve never been impressed by neither Kotlin nor Rust is the debilitating amount of hype around them. Rust, like Go, has a lot of idiosyncrasies, not to mention arbitrary conventions on what should go where. It seems to be the new trend to endocrine the structure at the compiler level.

I see Kotlin as pure hype. There’s nothing Kotlin seems to add that can’t be done in plain ol’ Java. Software engineers are kids, they always look at shiny new toys and disregard the perfectly valid ones they already have.

So anyhow, are there serious projects I can try to slowly accomplish on both? Ideally they would not be long-term projects, quick yet good enough to get some real sense of the languages and move on?

Wannabe projects I have around:

  • ESP32 grade crossing. Would be ideal for Rust, except I don’t see good ESP32 support.
  • Conductor 2… Currently Groovy + Java. Could use Kotlin as a DSL instead of Groovy.
    • I did try Kotlin back then but its DSL was not enough for my needs.
  • Rig4… Currently Java, with a (failed?) attempt at Rust. Could be using Kotlin.

One of the new directions for Rig4 is to have 2 tools (fetch + produce) so it’s possible for each to be in their own language. Seems a bit messy and quite undesirable though. If anything, it means dealing with two toolchains.

On the Android side, I have no immediate small project. Otherwise Kotlin would be a good choice there. I have some small game idea, and those would be in Godot / GDScript likely.

There seems to be something for ESP32 with Rust:

  • https://github.com/esp-rs
  • https://github.com/MabezDev/rust-xtensa

But one thing to remember is that I don’t just want “Rust on ESP32” (via llvmc, why not). What I really want is the Espressif SDK w/  FreeRTOS API, and e.g. access to the camera, hardware, etc. As the project author says “I've laid the compiler ground work, it's simply a case of writing the drivers and HAL's for it”, but really that’s the most important part of the project, there’s nothing of a “simple case” here. Without that, there’s an obvious chicken-and-egg problem.

The other side of the coin is that the whole point of the grade crossing project is to use OpenCV, which means I need OpenCV Rust bindings. There are some, but who knows how good they are on ESP32 (I don’t care if Rust + OpenCV works on desktop).

So conclusion:

  • Rust: No candidate.
  • Kotlin: Maybe Rig 4.3 reboot or Conductor 2.1 ?


2020-11-30 - Blinking LED - PIR approach

Category DEV

So here’s yet another approach: use a small PIR module, like the tiny “arduino” ones I use at Randall. This thing has a 1k Ω resistor on the output, and we can already trigger repeats & duration, so it’s essentially mirroring what a 555 timer would do and at the same time it would only blink the LED when presence is detected in the garage.

That would save on the battery by not blinking it when there’s no one around.

The sensor still needs to be powered.

Links from when I used that kind of sensor at Randall:

Sensor is a HC-SR501. Datasheet link via Aliexpress.

  • The SR501 uses a 7133 voltage regulator. We can feed it with the 5V from the AIU’s 7805.
  • The BISS001 drives the OUT pin directly via a 1kΩ resistor.

Main component is a BISS0001, datasheet link from Ladyada.

Of note:

  • Input voltage: 5-20 V; and on another page it says 4.5-20 V..
  • Power consumption: 65 mA.
  • Quiescent current: < 50 uA.
  • Output TTL 3.3 V.
  • Jumper L = single trigger, H = repeat trigger.
  • Pot on the jumper side = sensitivity.
  • Pot farther from the jumper = time delay (5-300 s).
  • Must be mounted horizontal for a variation left/right (e.g. pins at top or bottom).

One thing I had noticed at Randall is that these do not work when powered by 3 V. The unit “blinks” the output repeatedly. My guess is it fails to initialize (they go through a 1-min stabilization phase when first powered).

In my case, that means I need a 3-AA battery holder instead of my current 2-AA battery holder. It does work well with a 3-AAA holder.

On the output side, I got the illumination I want using a 1k Ω resistor on the output and a green LED. Red one was a bit weak for the value, although I could remove the extra 1kΩ.

I installed that and it works nicely as I want.

Update: I got about 1-2 years out of 3 AAA batteries powering this with moderate daily usage.


  Generated on 2025-10-07 by Rig4j 0.1-Exp-f3ee0b3