OpenBalena with Google IoT Core, NodeRed & WiFi Connect using Raspberry Pi Zero W

Hi there,

I am working to an IoT project which uses NodeRed, Google IoT and WiFi Connect.

The scope of the project is to connect the Raspberry Pi Zero W to a device which we’d interact with (using NodeRed), store the messages to Google IoT Core and be able to manage the device using OpenBalena.

Here you can find the open sourced code, hope it gives more input of the issue.

Known issues:

  1. The containers on the IoT device are not starting, here’s an output of the issue:

  2. Google IoT does not register even though I’ve followed up the documentation.

Still questions that I have:

  1. What are the requirements for development environment for customising WiFi Connect?
    (maybe a docker-compose.yml, what containers to use or what’s the starting point).

I’d like to add a customisation so that after the user gets connected to the internet and the device registers successfully to Google IoT core, then to have a url callback (e.g. myapp://1231323 and there to have the id of the device from Google IoT).

  1. Is there a way to lock in a certain version of all dependencies? I’d like to make sure that the build of the image works all the time.

I had the surprise that after sometime the project no longer works, I just run the build command after couple of months.

Happy to contribute with the Balena GitHub official repos as soon as I’d have those issues solved / clarified.

Thank you!

1 Like

Hello @elsevero first of all apologizes for the late reply on your message. Would you like to share the current situation of your project?

it depends on what you would like to lock. Is this a debian package? node package?

Did you manage to hack the WiFi-connect application? GitHub - balena-os/wifi-connect: Easy WiFi setup for Linux devices from your mobile phone or laptop On the other hand there is the WiFi-connect block but then you can’t do what you would like to do (i guess) → GitHub - balenablocks/wifi-connect: Easy WiFi setup for Linux devices from your mobile phone or laptop

Let me know how we can help you more!

Hi there @mpous ,

Thank you for your response!

Status of the project:

I have managed to solve the previous issue with the /bin/busybox no such file or directory, I have decided to use the already build docker image and pull that in my docker template file.

Now what I’m facing is the following (pasting the log output):

[Google IoT] Connecting to Google IoT Core ...
[Google IoT] Device ID: balena-0p6hjw2f1cizer8yacntj809xtsdew74
[Google IoT] Project: project-id-XXXXXX
[Google IoT] Region: europe-west1
[Google IoT] Registry: project-registry
[Google IoT] Device with name balena-0p6hjw2f1cizer8yacntj809xtsdew74 not registered. Attempting to register...
Generating a RSA private key
..............+++++
.....+++++
writing new private key to 'rsa-priv.pem'
-----
read EC key
writing EC key
[MQTT] Refreshing jwt token ...
[MQTT] Opening connection ...
(node:654) UnhandledPromiseRejectionWarning: Error: 3 INVALID_ARGUMENT: The device credential in position 0 contains an invalid key format.
    at Object.callErrorFromStatus (/app/node_modules/@grpc/grpc-js/build/src/call.js:31:26)
    at Object.onReceiveStatus (/app/node_modules/@grpc/grpc-js/build/src/client.js:179:52)
    at Object.onReceiveStatus (/app/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:336:141)
    at Object.onReceiveStatus (/app/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:299:181)
    at process.nextTick (/app/node_modules/@grpc/grpc-js/build/src/call-stream.js:145:78)
    at processTicksAndRejections (internal/process/task_queues.js:79:9)
(node:654) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:654) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
[MQTT] MQTT error { Error: Connection refused: Not authorized
    at MqttClient._handleConnack (/app/node_modules/mqtt/lib/client.js:1190:15)
    at MqttClient._handlePacket (/app/node_modules/mqtt/lib/client.js:424:12)
    at work (/app/node_modules/mqtt/lib/client.js:321:12)
    at Writable.writable._write (/app/node_modules/mqtt/lib/client.js:335:5)
    at doWrite (/app/node_modules/readable-stream/lib/_stream_writable.js:409:139)
    at writeOrBuffer (/app/node_modules/readable-stream/lib/_stream_writable.js:398:5)
    at Writable.write (/app/node_modules/readable-stream/lib/_stream_writable.js:307:11)
    at TLSSocket.ondata (_stream_readable.js:705:22)
    at TLSSocket.emit (events.js:193:13)
    at addChunk (_stream_readable.js:295:12) code: 5 }
(node:654) UnhandledPromiseRejectionWarning: Error: Connection refused: Not authorized
    at MqttClient._handleConnack (/app/node_modules/mqtt/lib/client.js:1190:15)
    at MqttClient._handlePacket (/app/node_modules/mqtt/lib/client.js:424:12)
    at work (/app/node_modules/mqtt/lib/client.js:321:12)
    at Writable.writable._write (/app/node_modules/mqtt/lib/client.js:335:5)
    at doWrite (/app/node_modules/readable-stream/lib/_stream_writable.js:409:139)
    at writeOrBuffer (/app/node_modules/readable-stream/lib/_stream_writable.js:398:5)
    at Writable.write (/app/node_modules/readable-stream/lib/_stream_writable.js:307:11)
    at TLSSocket.ondata (_stream_readable.js:705:22)
    at TLSSocket.emit (events.js:193:13)
    at addChunk (_stream_readable.js:295:12)
(node:654) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
[MQTT] MQTT Connection closed.
[MQTT] MQTT error { Error: Connection refused: Not authorized
    at MqttClient._handleConnack (/app/node_modules/mqtt/lib/client.js:1190:15)
    at MqttClient._handlePacket (/app/node_modules/mqtt/lib/client.js:424:12)
    at work (/app/node_modules/mqtt/lib/client.js:321:12)
    at Writable.writable._write (/app/node_modules/mqtt/lib/client.js:335:5)
    at doWrite (/app/node_modules/readable-stream/lib/_stream_writable.js:409:139)
    at writeOrBuffer (/app/node_modules/readable-stream/lib/_stream_writable.js:398:5)
    at Writable.write (/app/node_modules/readable-stream/lib/_stream_writable.js:307:11)
    at TLSSocket.ondata (_stream_readable.js:705:22)
    at TLSSocket.emit (events.js:193:13)
    at addChunk (_stream_readable.js:295:12) code: 5 }
[MQTT] MQTT Connection closed.

You can find the content of the MQTTBridge.js and GoogleIoT.js

it depends on what you would like to lock. Is this a debian package? node package?

Everything that can be locked, would like to lock to specific version.

Did you manage to hack the WiFi-connect application?

Nope, can you offer me more input regarding to development setup of WiFi Connect? If you can share with me a quick start project maybe from GitHub I would highly appreciate!

And the last question regarding to the live streams which you do on your YouTube channel, where I can register my questions in order to get answer within your stream (last one was 1 month ago).

Thank you & looking forward!

Hello,

you can raise your questions for the IoT project clinic here: Submit your questions for the IoT Project Clinic
You also can raise the question during the Live-Stream via the Youtube comments.

For the other issue I’m going to dig deeper and let you know.

Best Regards
Harald

Hello!

I have checked the information you provided.

You can find the content of MQTTBridge.js and GoogleIoT.js.

I understand that your MQTTBridge.js and GoogleIoT.js are forks of our GitHub - balena-io-examples/google-iot: Google Cloud IoT integration. Are there any changes you have made compared to our solution?
At first glance, I don’t see any major issues in your code, but I haven’t fully reviewed or tried your code.
I would start by testing this particular code in a Docker container on your development machine and see if the device registration works.
I have a feeling that maybe the rsa-priv.pem you wrote and the one you used are different?
Also, can you check if the registered public key in the Google IoT Core Console is set correctly for this device?

No, can you give me more information about the WiFi Connect development setup…?

Please tell us what information you are missing on the wifi-connect/README.md at master · balena-os/wifi-connect · GitHub to set up the wifi-connect block in your multi-container app.

Best Regards
Harald

Hello!

Iam also facing the same issue , code runs for two three days smoothly after that its going to error mentioned above by @elsevero , also some times error changes to code:4 , the fun fact is that if we change the os then it will start working , after some days it will again go back to error. along with the error mentioned above , iam getting this error to.

28.12.21 12:47:11 (+0530) main [MQTT] MQTT Connection closed.
28.12.21 12:47:13 (+0530) main [MQTT] MQTT error { Error: Connection refused: Bad username or password
28.12.21 12:47:13 (+0530) main at MqttClient._handleConnack (/app/node_modules/mqtt/lib/client.js:1076:15)
28.12.21 12:47:13 (+0530) main at MqttClient._handlePacket (/app/node_modules/mqtt/lib/client.js:365:12)
28.12.21 12:47:13 (+0530) main at work (/app/node_modules/mqtt/lib/client.js:283:12)
28.12.21 12:47:13 (+0530) main at Writable.writable._write (/app/node_modules/mqtt/lib/client.js:294:5)
28.12.21 12:47:13 (+0530) main at doWrite (/app/node_modules/readable-stream/lib/_stream_writable.js:428:64)
28.12.21 12:47:13 (+0530) main at writeOrBuffer (/app/node_modules/readable-stream/lib/_stream_writable.js:417:5)
28.12.21 12:47:13 (+0530) main at Writable.write (/app/node_modules/readable-stream/lib/_stream_writable.js:334:11)
28.12.21 12:47:13 (+0530) main at TLSSocket.ondata (_stream_readable.js:705:22)
28.12.21 12:47:13 (+0530) main at TLSSocket.emit (events.js:193:13)
28.12.21 12:47:13 (+0530) main at addChunk (_stream_readable.js:295:12) code: 4 }
28.12.21 12:47:13 (+0530) main [MQTT] MQTT Connection closed.

Hello @fisehara ,

Thank you for your reply!

Managed to solve the Google IoT connection, the issue was with the format of the keys, here are the outlines, thanks for point out!

It was: RSA-X509-PEM but it needed to be RSA_X509_PEM (wrong documentation, couple of months ago I have modified and forgot, only after checking the diff with initial repo).

@mpous , @fisehara : What still I’m interested is:

  1. How to customise WiFi Connect (a getting started guide for development).

I’d like to add a customisation so that after the user gets connected to the internet and the device registers successfully to Google IoT core, then to have a url callback (e.g. myapp://1231323 and there to have the id of the device from Google IoT).

  1. Related to the locking version I am referring to this part from the OpenBalenaVPS.
    So its just adding to the terminal session and when using balena cli would pick the right version? How does that takes in account versions mentioned in that part of the video?

  2. Managed to successfully connect to Google IoT core using balena Google IoT, what would be the procedure to connect a node-red container to the balena Google IoT container and afte that Google IoT core backend.

So I’m thinking something like: Node red (MQTT) <–> Google IoT Balena Container <—> Google IoT Core (back-end).
I have exposed 8883, I understand that the MQTTBridge.js library is connected to the Google IoT Core but how would I publish ()a new message to the Google IoT back-end ?

1 Like

Hello @elsevero

Did you try to modify this wifi-connect/network.rs at 9d8b773e3bb4e6448ea39e46e4d7c0b7f7f63f77 · balena-os/wifi-connect · GitHub ?

sounds like a good solution! did you try the NodeRed block?

Hi @mpous ,

Thank you for your reply!
I have seen the callback but I am not sure if that informs the browser or can redirect the URL of the browser.

Yes, I have tried the NodeRed block but currently facing some issues with the credentials (certificate + private key generated within the GoogleIoTCore container. I am trying to use the generated credentials (see image above), I will fork and try to extend to be able to use the nodered block with a json service account for proper login.

@elsevero today i just discovered that i didn’t reply this message! apologizes for that! did you solve this issue?

@mpous :pleading_face:

I have managed to solve it the other way around for the callback thing, I am limited to the mobile operating system and it does not redirect to any url.

The only solution for me was to add a code to the client and scan the local network and check against a port, via socket.

Now currently facing back (or again) after a while this error:

[Google IoT] Connecting to Google IoT Core ...
[Google IoT] Device ID: id-00000000000000000000000000000000
[Google IoT] Project: google-iot-project-id
[Google IoT] Region: google-iot-region
[Google IoT] Registry: google-iot-registry
[Google IoT] Device with name id-00000000000000000000000000000000 not registered. Attempting to register...
Generating a RSA private key
........................+++++
................................................................................................................................................................................................................+++++
writing new private key to 'rsa-priv.pem'
-----
read EC key
writing EC key
[MQTT] Refreshing jwt token ...
{ host: 'mqtt.googleapis.com',
  port: 8883,
  clientId:
   'projects/google-iot-project-id/locations/google-iot-region/registries/google-iot-registry/devices/id-00000000000000000000000000000000',
  username: 'unused',
  password:
   'generated-password',
  protocol: 'mqtts',
  secureProtocol: 'TLSv1_2_method',
  project: 'google-iot-project-id' }
[MQTT] Opening connection ...
(node:156) UnhandledPromiseRejectionWarning: Error: 7 PERMISSION_DENIED: The signature of device credential in position 0 could not be verified against any registry certificate.
    at Object.callErrorFromStatus (/app/node_modules/@grpc/grpc-js/build/src/call.js:31:26)
    at Object.onReceiveStatus (/app/node_modules/@grpc/grpc-js/build/src/client.js:179:52)
    at Object.onReceiveStatus (/app/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:336:141)
    at Object.onReceiveStatus (/app/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:299:181)
    at process.nextTick (/app/node_modules/@grpc/grpc-js/build/src/call-stream.js:145:78)
    at processTicksAndRejections (internal/process/task_queues.js:79:9)
(node:156) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:156) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
[MQTT] MQTT error { Error: Connection refused: Not authorized

Anyone any idea?

1 Like

@elsevero did you solve this? it looks like you need other certificates?

@mpous : I have managed to solve it by re-creating the entire setup on Google IoT (Cloud dashboard).

1 Like

thank you @elsevero for confirming that you made it work. Is there any insight that you can share with the community so other developers with similar issues can find here a solution? :slight_smile: