MOST bus integration into SAAB 9-3 II

Lots to cover!

I think the addressing is tripping you up, when in reality (Once the documentation makes sense, as it is written quite poorly! It is quite simple) The chip itself handles all receiving of the addresses, there are multiple ways to address a device

  • Logical address, this is the most common, and this is the value that is stored within the chip itself, in the case of the pimost this is the address that you set within the settings page in most-explorer. These start with 0x0140 to 0x02FF, .
  • node position, this is just 0x400 + the node position after the master. This makes it easy to message the master, since you know it is always going to be 0x0400.
  • the dynamic mode, I haven’t really seen this used, and you are correct in that the default address of the pimost is 0x110, in hindsight this should really be something in the 0x140 - 0x2ff range, however I don’t believe it affects anything it being within the 0x100 - 0x013f range. However perhaps Saab are an outlier and use the dynamic addressing rather than logical which is what all other systems so far seem to use.
  • group address, this can be sent to all slaves within a group.
  • broadcast, two types, blocking an unblocking. These are sent to every slave on the network, typically shutdown and start up messages etc.

Now when it comes to how this works in practice, think of most-explorer as a sub service to the chip itself. Most-explorer or socketmost for that matter doesn’t care about the address. The chip itself is what handles whether a message should be received. If the message deviceId (which can be any of the above messaging types) matches inside the chip, then the message is passed to the host (most-explorer).

For the next part you are talking about instanceID. This where things now get different. The addressing mentioned above is all to do with the chip itself, so that is at the lowest level. However Fblock and instanceID are more at the software level. The host itself implements these, they are not stored in the chip in anyway. So out of the box the pimost has no fblocks and in turn no instanceIDs. This is why you usually get spammed with messages from the master of “getFblocks” type. This is the master querying what fblocks are present. The idea is the software then handles these messages and responds appropriately with any fblocks present, along with their instanceIDs.

For group addresses, the first thing to mention is you can send a message to a slave requesting what the currrent set groupID of that device is. It is handy to to be able match the pimost to them. Group address is set as just a byte, the chip automatically appends 0x3 as the upper byte. I have found no use so far as to group addresses, and they don’t seem to be used in my experience.

The default address is only used out of the box, so if you have changed it, then it will no longer be used. The address is stored in persistent memory so does not get wiped etc.

For the power, yes apologies that is probably not clear, if using in auto shutdown mode it needs to be on permanent power. It does give the benefit of booting the pi when you unlock the doors too! I have also broken the ring multiple times, infact on my test bench I do it constantly, it has never caused and issue and seems to be very fault tolerant!

I realized, that in my current setup after ignition OFF and ON there actually is a short interruption in the music, but if the PiMOST is removed from the ring there is no interruption. The interruption is visible in the above log “most-dump first 10 sec”:

This is interesting! If the audio is just a blip, then I am guessing something else is overwriting the pimosts “forced switch” I call this a forced switch because it is really doing that. It is bypassing any kind of connection master and connecting an amplifier direct to the pimost. I suspect in your case the connection master is picking up on that and switching it back to where it wants to be.

If you can do a get functions to the connection master, we can look to create a proper connection master way of doing the auto switch. I would just need to see what fblocks are present in your connection master. I also suspect that where there are multiple amplifiers in your set up, perhaps one of the shadow devices are actually the ones the need the classic “forced switch”

Hey Rhys,

Thanks a lot for your addressing summary and your answers!
OK, so for the sniffing part I do not have to care about replying with present FBlocks and InstanceID’s, if I would use the PiMost in Standalone Mode and force switch the amplifiers to it I guess I won’t need to deal with this either. I think replying correctly will be relevant if I want to replicate an existing node or “create” a new node (e.g. an additional AudioDiskPlayer) - if that’s what you mean with the idea that the software responds appropriately.

Thanks for the hint for checking the group address. A “Get” in Netblock 0x01 FktID 0x004 should work for that.

The connection master only has three FktID’s: 0x0, 0xc12, 0xc13
I guess that correlates with the message in the most-dump, but I realized, that I don’t know how the RLE-coded BitField works:

most-dump getFunctions ConnectionMaster
{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x3",
		"instanceID": "0x1",
		"fktID": "0x0",
		"opType": "0xc",
		"telID": "0x0",
		"telLen": "0x5",
		"data": [
			"0x0",
			"0x1c",
			"0x12",
			"0xc1",
			"0x40",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	}

In my opinion, only 0x0 the “FktIDs” are specified in the GeneralFBlock. 0xc12 and 0xc13 seem to be manufacturer specific if I’m correct. It confuses me, since the book says 0x200 BuildSyncConnection and 0x201 RemoveSyncConnection should be mandatory. Probably they did something similar, just not according to the book?

I have not yet managed to change the power setup, but I guess (or I hope) it should not affect this result.

Today, only a small update of the mapping, including node position and group addresses. It’s in a slightly different format than my previous version:

RxTxLog - NodeName			// NodePosition 0x04xx, GroupAddress 0x03yy
	FBlockID(dec)	-	FBlockID(hex)	-	Description 	*	InstID
updated MOST mapping
0x100 - ICM					// NodePosition 0x0400, GroupAddress 0x03bf
	2	-	0x02	-	NetworkMaster		*	0x1
	3	-	0x03	-	ConnectionMaster	*	0x1
	5	-	0x05	-	Vehicle				*	0x1
	6	-	0x06	-	Diagnosis			*	0x47
	7	-	0x07	-	DebugMessages		*	0x1
	16	-	0x10	-	?Sources?			*	0x1
	82	-	0x52	-	?					*	0x1
	248	-	0xf8	-	?					* 	0x1
	252	-	0xfd	-	?					*	0x2
	253	-	0xfd	-	?					*	0x2

0x140 - CU/PU				// NodePosition 0x0401, GroupAddress 0x03f4
	6	-	0x06	-	Diagnosis			*	0x57
	38	-	0x26	-	MicrophoneInput		*	0x1
	244	-	0xf4	-	?					*	0x1
	247	-	0xf7	-	?					*	0x57


0x122 - DVD					// NodePosition 0x0402, GroupAddress 0x34f2
	6	-	0x06	-	Diagnosis			*	0x56
	247	-	0xf7	-	?					*	0x56
	250	-	0xfa	-	?					*	0x1

0x112 - AMP2				// NodePosition 0x0403, GroupAddress 0x0322
	6	-	0x06	-	Diagnosis			*	0x54
	34	-	0x22	-	AudioAmplifier		*	0x3
	247	-	0xf7	-	?					*	0x54

0x111 - AMP1				// NodePosition 0x0404, GroupAddress 0x0322
	6	-	0x06	-	Diagnosis			*	0x53
	34	-	0x22	-	AudioAmplifier		*	0x2
	247	-	0xf7	-	?					*	0x53

0x110 - EHU					// NodePosition 0x0405, GroupAddress 0x0110
	6	-	0x06	-	Diagnosis			*	0x51
	32	-	0x20	-	?					*	0x1
	34	-	0x22	-	AudioAmplifier		*	0x1
	36	-	0x24	-	AuxIn				*	0x1
	64	-	0x40	-	AmFmTuner			*	0x1
	65	-	0x41	-	TMCTuner			*	0x1
	80	-	0x50	-	Telephone			*	0x2
	242	-	0xf2	-	?					*	0x1
	243	-	0xf3	-	?					*	0x1
	247	-	0xf7	-	?					*	0x51

0x120 - CDCF				// NodePosition 0x0406, GroupAddress 0x0322
	6	-	0x06	-	Diagnosis			*	0x52
	49	-	0x31	-	AudioDiskPlayer		*	0x4
	247	-	0xf7	-	?					*	0x52

What is the reason for the mix between decimal and hexadecimal fields in the MostExplorer btw, I guess you had your reasons?

I was wondering, if the sniffing also could work via notification instead of duplicating a node (what did not work on some nodes until now), or do you miss certain traffic?

Today, I had a look at AMP2 when I switched from the AmFmTuner (EHU) to AudioDiskPlayer (CDCF) and back. The EHU incorporates a physical amplifier too - probably the master amplifier? The lowest level of sound system only has this physical amplifier from the EHU)

AmFmTuner > CD:

  1. The EHU sends a Mute “ON” for SinkNr “0x01”
  2. ICM sends a DisConnect of SinkNr 0x01
  3. ICM sends a Connect of SinkNr “0x01” with a SrcDelay of “0x04” and a ChannelList with “Channel 0-3”
  4. EHU unmutes by a Mute “OFF” for sink “0x01”
most-dump AmFmTuner > CD
[

	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// 0x110 EHU
		"fBlockID": "0x22",
		"instanceID": "0x3",			// 0x112 AMP2
		"fktID": "0x113",			// mute
		"opType": "0x0",			// set (not available anymore?, but maybe "SinkNr" & "Status"?)
		"telID": "0x0",
		"telLen": "0x2",			// 2 bytes
		"data": [
			"0x1",				// SinkNr? 0x01
			"0x1",				// Status? Bit 0 = 1 => mute on
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",			// 0x100 ICM
		"fBlockID": "0x22",
		"instanceID": "0x3",			// 0x112 AMP2
		"fktID": "0x112",			// DisConnect
		"opType": "0x2",			// StartResult
		"telID": "0x0",
		"telLen": "0x1",			// 1 byte
		"data": [
			"0x1",				// SinkNr 0x01
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",			// 0x100 ICM
		"fBlockID": "0x22",
		"instanceID": "0x3",			// 0x112 AMP2
		"fktID": "0x111",			// Connect
		"opType": "0x2",			// StartResult
		"telID": "0x0",
		"telLen": "0x6",			// 6 bytes
		"data": [
			"0x1",				// SinkNr 0x01
			"0x4",				// SrcDelay 0x04
			"0x0",				// Channel 0
			"0x1",				// Channel 1
			"0x2",				// Channel 2
			"0x3",				// Channel 3
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// 0x110 EHU
		"fBlockID": "0x22",
		"instanceID": "0x3",			// 0x112 AMP2
		"fktID": "0x113",			// mute
		"opType": "0x0",			// set (not available anymore?, but maybe "SinkNr" & "Status"?)
		"telID": "0x0",
		"telLen": "0x2",			// 2 bytes
		"data": [
			"0x1",				// SinkNr? 0x01
			"0x0",				// Status? Bit 0 = 0 => mute off
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	}
]

CD > AmFmTuner:

  1. The EHU sends a Mute “ON” for SinkNr “0x01”
  2. ICM sends a DisConnect of SinkNr 0x01
  3. ICM sends a Connect of SinkNr “0x01” with a SrcDelay of “0x03” and a ChannelList with “Channel 0-3”
  4. EHU unmutes by a Mute “OFF” for sink “0x01”
most-dump CD > AmFmTuner
[
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// 0x110 EHU
		"fBlockID": "0x22",
		"instanceID": "0x3",			// 0x112 AMP2
		"fktID": "0x113",			// mute
		"opType": "0x0",			// set (not available anymore?, but maybe "SinkNr" & "Status"?)
		"telID": "0x0",
		"telLen": "0x2",			// 2 bytes
		"data": [
			"0x1",				// SinkNr? 0x01
			"0x1",				// Status? Bit 0 = 1 => mute on
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",			// 0x100 ICM
		"fBlockID": "0x22",
		"instanceID": "0x3",			// 0x112 AMP2
		"fktID": "0x112",			// DisConnect
		"opType": "0x2",			// StartResult
		"telID": "0x0",
		"telLen": "0x1",			// 1 byte
		"data": [
			"0x1",				// SinkNr 0x01
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",			// 0x100 ICM
		"fBlockID": "0x22",
		"instanceID": "0x3",			// 0x112 AMP2
		"fktID": "0x111",			// Connect
		"opType": "0x2",			// StartResult
		"telID": "0x0",
		"telLen": "0x6",			// 6 bytes
		"data": [
			"0x1",				// SinkNr 0x01
			"0x3",				// SrcDelay 0x03
			"0x0",				// Channel 0
			"0x1",				// Channel 1
			"0x2",				// Channel 2
			"0x3",				// Channel 3
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// 0x110 EHU
		"fBlockID": "0x22",
		"instanceID": "0x3",			// 0x112 AMP2
		"fktID": "0x113",			// mute
		"opType": "0x0",			// set (not available anymore?, but maybe "SinkNr" & "Status"?)
		"telID": "0x0",
		"telLen": "0x2",			// 2 bytes
		"data": [
			"0x1",				// SinkNr? 0x01
			"0x0",				// Status? Bit 0 = 0 => mute off
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	}
]

I’m not sure if my interpretation of SrcDelay is correct, since the book says “Delay of streaming data related to the TimingMaster.” The TimingMaster should be part of the ICM. We have:
ICM > CU/PU > DVD > AMP2 > AMP1 > EHU > CDCF (> PiMost) > ICM
The only way for a 0x04 for the CDCF and a 0x03 for the EHU seems to be if AMP2 and AMP1 are counted as sinks only, whereas the other nodes are counted as sources. Is that what the SrcDelay means? Somehow I doubt it… And I guess that’s not all information you need to create a sync connection between a source and a sink, or is it? The ConnectionMaster in the ICM should start a BuildSyncConnection I guess, but it doesn’t seem to be available…

At some point in time we will find out how it works :crossed_fingers:

This is good!

The src delay is just node position. The pimost handles this by itself. It is the delay of the amount of nodes between the device and the master. In reality I have had the srcDelay wrong many times and it seems to make no difference!

In theory if you just set AMP2 parameters as the amplifier settings in most-explorer you should be able to get the audio to switch. I remember you saying there was an audio blip before, perhaps the connection master knows of the forced switch and switches the amplifier back?

It would be great to get a log of messages if you can replicate the ICM when you do those audio switches.

You can’t really sniff all traffic via notifications. Notifications would be something like the cd player saying I am now playing track 5. The sniffing is more useful to see what message was sent to the cd player to begin playing track 5 (just using the cd audio player as an example here)

Hey Rhys,

It might not be important, but if SrcDelay would be node position, 0x03 would be AMP2, and 0x04 would be AMP1. I’m still confused here.

I tried the force switch with the AMP2 setting as you proposed. Two issues occured (and an old one):

  1. With most-explorer v3.0.0-beta.3 which I installed on my mac it’s not possible to change the “amplifier” and “microphone” settings in “Standalone” mode. I can only select a preset for “JLR/Land Rover” for example and “send to dongle”. But if I want to set my car specific settings, once I click on “send to dongle” all fields get replaced by a “0”, except for one. Seems to be a bug, at least in my setup. I can only change the settings with the older v.3.0.0-beta.2

  2. Unfortunately I never managed to duplicate the ICM until now. Complete system crash every 10sec.
    Did you ever use “spy mode” which is mentioned in the book? As a a analysis tool it should be possible to be invisible in the network, but listen into the entire bus communication. Would that might be an opportunity to “duplicate” the ICM?
    For the above mentioned reason, I cannot provide a log, but I duplicated the corresponding amp instead, without much information:

most-dump force switch 0x110 0x22 0x1
[
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x12",
		"fBlockID": "0x22",
		"instanceID": "0x3",
		"fktID": "0x112",			// DisConnect
		"opType": "0xc",
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x1",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x12",
		"fBlockID": "0x22",
		"instanceID": "0x3",
		"fktID": "0x111",			// Connect
		"opType": "0xc",
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x1",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	}
]
  1. I tried all three amplifiers with a very comparable result: The audio does not stop or switch, but the affected amplifer stops working. So if I set AMP1 for example for standalone mode and then I press “force switch”, the door speakers stop working and it sounds really bad with the tweeters only from the dashboard and the bass from the trunk. The same applies if I just wait a few secs after startup. I guess thats what the standalone mode does: After a few secs (roughly 10sec or so?) it tries to force connect the amplifiers without any interaction. When I press on “force connect” an error occurs:

    I assume that the error is in decimal, which would be 0x103 in hex. In the GeneralFBlock this would be “Source Activity” which would be missing. Which functions do you call, when you perform a force switch? Do you use the ConnectTo 0x115?

Finally, I can provide a most-dump from AMP1 for the first seconds after startup until the force switch (audible loss of AMP1) happens:

most-dump AMP1 from startup to force switch
[
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x113",			// mute
		"opType": "0x1",			// get
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x0",				// SinkNr 0 (wildcard?)
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",			// ICM
		"fBlockID": "0x6",			// diagnosis, no spec sheet available?
		"instanceID": "0x53",
		"fktID": "0x1",
		"opType": "0x0",
		"telID": "0x0",
		"telLen": "0x5",
		"data": [
			"0x1",
			"0x1",
			"0x0",
			"0xc",
			"0x33",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",			// ICM
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x111",			// Connect
		"opType": "0x2",			// StartResult
		"telID": "0x0",
		"telLen": "0x6",
		"data": [
			"0x1",				// SinkNr 0x01
			"0x4",				// SrcDelay 0x04
			"0x0",				// Channel 0
			"0x1",				// Channel 1
			"0x2",				// Channel 2
			"0x3",				// Channel 3
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0xd02",			// saab specific?
		"opType": "0x0",			// set/start
		"telID": "0x0",
		"telLen": "0x2",
		"data": [
			"0x7",				// ?
			"0x1",				// ?
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x113",			// mute
		"opType": "0x0",			// set
		"telID": "0x0",
		"telLen": "0x2",
		"data": [
			"0x0",				// SinkNr 0x0 (wildcard "any instance"?)
			"0x0",				// mute Off
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x202",			// Bass
		"opType": "0x0",			// set
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0xff",				// Bass 0xff ? (Explicit values ranges are specified in the application)
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x203",			// Treble
		"opType": "0x0",			// set
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x1",				// Treble 1 (?)
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x200",			// Balance
		"opType": "0x0",			// set
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x0",				// Balance 0 = left-right equal
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x204",			// Fader
		"opType": "0x0",			// set
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x0",				// Fader 0 = front-back equal
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0xd05",			// saab specific?
		"opType": "0x0",
		"telID": "0x0",
		"telLen": "0x2",
		"data": [
			"0x1",				// ?
			"0x12",				// ? -> eventually something with AMP2 0x112?
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP2
		"fktID": "0x113",			// Mute
		"opType": "0x1",			// get
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x0",				// SinkNr 0x0 (wildcard "any instance"?)
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0xd02",			// saab specific? (used 2nd time)
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x1",				// ?
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x113",			// Mute
		"opType": "0x0",			// set
		"telID": "0x0",
		"telLen": "0x2",
		"data": [
			"0x1",				// SinkNr 0x01
			"0x0",				// Mute Off
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",			// ICM
		"fBlockID": "0xf7",			// ? AMP1, 247 present in almost every node
		"instanceID": "0x53",			// InstID 0x53
		"fktID": "0xe50",			// ? saab specific
		"opType": "0x2",			// SetGet / StartResult
		"telID": "0x0",
		"telLen": "0x2",
		"data": [
			"0xbd",				// ?
			"0x44",				// ?
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x11",		// AMP1 ?! -> guess thats the PiMost?
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x112",			// DisConnect
		"opType": "0xc",			// Result
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x1",				// SinkNr 0x01
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x11",		// AMP1 ?! -> guess thats the PiMost?
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x111",			// Connect
		"opType": "0xc",			// Result
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x1",				// SinkNr 0x01
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	}
]

There are a few saab specific functions involved, as far as I can see and FBlock 0xf7 (247) gets addressed once. This FBlock exists in every node, except for the ICM. I remember you saying, that every node usually has its shadow FBlock for the amplifier. I only have the 0x22 FBlock in every node with an AMP. What if the 0xf7 would be some kind of shadow FBlock to handle all three physical amplifiers at once? It’s only weird, that every amplifier would also have this shadow FBlock - but there might be a reason for that…

Btw, somehow I could not recreate the audio blip as described earlier, as I’m writing this now - maybe that only happend after the ignition off and on, I will need to try it again next time I’m in the car!

This is a frustrating bug, let me look back into it and resolve it

The spy mode I believe is extra hardware, there is an old MOST debugging unit that physically splits the MOST signal, it is on my list to investigate to see if it is possible to do something similar

The pimost uses this sequence

  • runs an internal allocate to get give 4 bytes to stream to
  • runs a sink disconnect to the specified amplifier (0x112)
  • runs a sink connect to the specified amplifer (0x111) message includes [sink number, node posistion, byte0, byte1, byte2, byte3] which are the bytes allocated to it from the first step

It does appear that the ICM sends standard requests to the amplifier which is great, and it also does sound like the auto switching is happening however just on one amplifier. If when that one amplifier disconnects and it stops playing audio, have you tried to play audio via the pimost? I would expect it to start playing out of the speakers that went silent. If not perhaps it needs an unmute sent to it, that would be fairly easy to do by sending a manual message, and if needed I can implement to the firmware. The error you saw on the force switch is for the microphone, I think BMW needs a source activity on for it to work. Receiving that error is not an issue, just that it is not implemented on that fblock. If an manual switch needs to be sent to all amplifiers I can also get that into the firmware, I guess we just need to check it. When the system allocates, I think there is a log in the command line of the bytes that shows which bytes get allocated, you could use these to send manual disconnect/connect messages to each amplifier.

Frustrating that the system won’t let you take the address of the ICM, however to get this streaming working I really don’t think we need it.

Hey Rhys,

Thanks for looking into this bug! Ok, I did not realize that spy mode requires an extra hardware, I did not search a lot, only whats written in the book and thats not much.

OK, so basically the PiMost performs a regular source switch, like the connection master would do I assume. So if I would run 3 connect commands with all 3 amplifiers in a row, eventually with a mute upfront and an unmute afterwards that should work as well if I understood it correctly.

Thats what I expected as well, but I guess I just tried it the wrong way: Although I wanted to check if I can select the PiMost as an audio device on my mac, I forgot to do that when I was in the car. I just let the music play on the mac and tried to force connect via most-explorer - I guess thats not enough :crazy_face:

Well, for the music only it might not be necessary to duplicate the ICM. As you probably remember I wanted to integrate it completely, as if it was original. I found the steering wheel controls like skip or volume which are sent to the CD player for example, respectively to the amplifiers. I never tried until now, but I think I could also change the audio settings (bass, balance,…) that I don’t have to set them blind once I remove the original screen (which is part of the ICM). What I didn’t find yet are other settings like brightness of the whole dashboard illumination (and screen brightness), as well as the “nightpanel” button (a nice saab feature to drive in the dark: The whole cockpit turns black except for a few things like speedometer). I know that both signals come from the I-Bus to the ICM and I was hoping that they’re also translated into a MOST signal (probably Saab specific in the 0x05 “vehicle” FBlock?), such that I don’t have to connect to the CAN network as well. I guess once the basic functionality works I could do a lot if I would want to (onboard error messages or displaying the cooling fluid temperature e.g.). But let’s focus on the sound part first!

Hey hey,

Almost two weeks ago Rhys helped us to do a manual switch of all three amplifiers! Streaming music over the PiMost for the first time was amazing :star_struck: Thanks again for your help Rhys!

I managed to replicate the same procedure several times since then and it works quite well:
First we did a “force switch” on the PiMost with the settings of one amplifier. Then we manually disconnected (FktID 0x112) both other amplifiers and then connected (TktID 0x111) with a guessed SrcDelay of 0x03 and the correct assumption that the PiMost switched to Channel 4 to 7 as the car already occupied Channel 0 to 3. The FktID 0x111 requires an OpType “StartResult” (0x02) but you cannot select that in the MostExplorer from the list - but you can select “SetGet” which is 0x02 as well. I think that might be good to know for others as well!

When I do switch the amplifiers from the active CD player to the PiMost, the CD player obviously continues to play its track and changes the CD once the last track has been played. I guess thats what you do with the force switch - you just steal the sound. Since my CD changer does not follow the book strictly I guess I will need to find out how to stop the CD at its current position if I would like to continue with the “force switch”. I tested the blinker sound when the PiMost was streaming music and that worked - the car sounds seem to be on different channels which is good :sunglasses:

What I did not manage yet to accomplish was a complete manual switch of the amplifiers (without the initial force switch of the PiMost). I tried to allocate (FktID 0x101) it myself: I just tried to reply with a “result” (SourceNr, SrcDelay, ChannelList), but I guess I inserted the wrong SourceNr. Is this basically the InstID, or the node position or again something else?

I also want to investigate the SrcDelay a little bit more: It might not be that important to set it to the correct value, but with 3 amplifiers instead of 1 in theory there should be a slight difference if you do it correctly. The question might be if you could actually hear that. Let’s see if I can find out more about that.

I will also need to investigate why we did not manage to get the microphone working, but I guess we will sort that out as well at some point :crossed_fingers:

This weekend I will investigate more on how to connect the PiMost to the permanent plus (+30) in a nice way. Additionally I want to check if I can power the new screen directly from the old electronics for the screen inside the ICM and maybe even control it’s backlight over it, but thats a different story :face_with_monocle:

I’ll let you know once I made more progress :v:

2 Likes

Hey @rhys_m

Hope you’re doing well? It has been quite a while since my last post, although I did not make much progress on the MOST side, I wasn’t inactive in the project: As announced, I solved the power management for the PiMost and then I started working on a PCB to control the LED-Backlight directly from the existing ICM signals (should cover the brightness setting, night panel and adaptive sunlight adaption). Since I’ve never done this before, it took a little bit longer compared to an expert, but I hope it will work as intended :crossed_fingers: It’s ordered now and today I had time to go back to the PiMOST.

We installed the repo from Github and now we have the terminal for debugging as you suggested. I saw that you resolved the manual typing issue for the settings and that you fixed some mic issues as well. I did not test them yet, but I will certainly do that.

We had a look into the UI of the most explorer, as well as the driver section. We think, we might be able to change the settings page accordingly, to have the possibility to fill in the information for all 3 amplifiers. we might be able to change the amplifier type to an array as well, but after that we’re still a little bit lost: For the “force switch” e.g. you see the message “sending position request <Buffer 55 01 74 00>” if you uncomment the console log in the client section for the most explorer (with the same data partially in decimal).

forceSwitch
forceSwitch = () => {
        const buf = Buffer.alloc(4);
        buf.writeUInt8(0x55, 0);
        buf.writeUint8(1, 1);
        buf.writeUint8(116, 2);
        //console.log('sending position request', buf)
        this.port.write(buf);
    };

If we interpret it correctly, we end up on the PiMOST side with “this.port.” → you send some commands and the firmware of the PiMOST follows a predefined procedure (allocate, disconnect, connect)? We did not find the code to look into it - is it publicly available somewhere?
I was wondering about the firmware version: In the settings page (and in the terminal) it shows “0.0.1”. In the DFU section it starts at “0.0.3” and the latest released version is “0.1.0”. Is it even possible that I’m on the first released version, or is this a different numbering system?
I don’t know if you would have time to support us again via discord - I hope everything went well with the birth of your baby, everyone is healthy and you’re a happy father now? In any case - your or anyone else’s input would be more than welcome :sunglasses:

1 Like

Hi Dino, great to see your progress on this! Just jumping in to answer your question about the pimost versioning, there was an issue where the 0.0.10 release would show up as 0.0.1. I would just reflash it with the latest version which you can find at Releases · rhysmorgan134/pimost-usb · GitHub. When updating through most-explorer, it fetches the latest version from that url too.

1 Like

Hi @Tigo,
Thank you very much for the hint regarding the versioning issue in release 0.0.10! We updated it to 0.1.0 - and guess what, the microphone started working as announced in the changelog :star_struck:

The force switch would be the most basic option I would like to implement, but I will keep on investigating if I manage to duplicate the ICM or find a different FktID which works to switch the audio source!
Today, we found some code in the JLR HU/src/main/PiMost.ts on Github, where it seems that the Jaguar has/could have three amplifiers as well:

1st, 2nd & 3rd amplifier
this.subscriptions = []
    const audioDiskPlayer = new AudioDiskPlayer(0x02, this.sendMessage, 0x01, 0x80, 0x01, 0x6e)
    const u240 = new U240(0x01, this.sendMessage, 0x01, 0x61, 0x01, 0x6e)
    const amFmTuner = new AmFmTuner(0x01, this.sendMessage, 0x01, 0x80, 0x01, 0x6e)
    const amplifier = new Amplifier(0xa1, this.sendMessage, 0x01, 0x61, 0x01, 0x6e)
    const secAmplifier = new Amplifier(0x05, this.sendMessage, 0x01, 0x86, 0x01, 0x6e)
    const tertiaryAmplifier = new Amplifier(0xa1, this.sendMessage, 0x01, 0x61, 0x01, 0x6e)
    const canGateway = new CanGateway(0x01, this.sendMessage, 0x01, 0x61, 0x01, 0x6e)
    const climate = new Climate(0xa1, this.sendMessage, 0x01, 0x61, 0x01, 0x6e)
    // const sources = new Source(0xa3, this.sendMessage, 0x01, 0x6e, 0x01, 0x10)
    // this.interfaces.secAmplifier = new Amplifier(0x20, this.sendMessage, 0x01, 0x86, 0x01, 0x10)
    this.interfaces = {
      AudioDiskPlayer: audioDiskPlayer,
      u240: u240,
      AmFmTuner: amFmTuner,
      Amplifier: amplifier,
      SecAmplifier: secAmplifier,
      TertiaryAmplifier: tertiaryAmplifier,
      CanGateway: canGateway,
      Climate: climate
      // Sources: sources
    }

I don’t know if it uses the “force switch” as well, but I think Rhys duplicated a node, so probably not. If we could add three amplifiers to the firmware (if this assumption is correct) of the PiMost we most likely could implement the basic functionality. Maybe I’ll end up to write something similar (but I guess not as extensively) as Rhys did for the JLR. So any input is welcome :partying_face:

2 Likes

Hey Dino! Apologies I have my hands full at the moment with a new born! @Tigo is correct, I only allowed one character for the version so version 0.0.10 became 0.0.1 :joy:

There’s only one amplifier in JLR the other two are just shadow devices, I did begin writing the firmware to allow a triple Saab auto switch, I’ll do my best to finish it off for you!

2 Likes

Hey Rhys,

Yeah I can imagine and I did not expect you to reply so fast! So no worries at all, take your time and enjoy - I still have a lot of work to do! :sweat_smile: funny bug indeed!
I’ll keep you posted about the progress on my side :v:

Hi @rhys_m
I’m @dino’s brother, we talked before a few months ago.
Congrats on the new born!

We were trying to find the forceSwitch recently and ended up figuring out it had to be in the firmware.
Is there any chance to make the source code of it available?
I did find this in the forums:

I think it would help anyone that is willing to look into it closer to understand whats going on since it is a missing piece of the puzzle, but only if you feel comfortable with it.
Additionally i could try and help with the triple amp setup.

Hi,

all that’s happening in the firmware level is the same as what is in the socketmost drivers, just implemented in C instead, if you take a look at this function it is the exact same process

With the 3 amp setup, it i will just need to the connect source function for all 3 amplifiers

Hey @rhys_m

Thanks! I started looking at the socketmost drivers - if I’m correct, it uses the function ID’s Allocate (0x101), DisConnect (0x112) and Connect (0x111) as discussed before, but I will need to go into more detail. In the meantime I can give an update on the project progress:

  • Electrical integration:
    The PiMost gets powered from the permanent plus (+30). As intended, the optical signal wakes up the PiMost. The RPI gets powered from the PiMost’s “AUX Power” and starts up as soon as the optical ring starts its operation. The CarlinKit Dongle obviously receives power from the RPI.
    The ICM (head unit) powers my self-designed PCB and delivers the signals for the screen brightness. My PCB controls the LED backlight for the new touch screen (with original stock behavior including nightpanel, manual brightness adjustment, automatic brightness control according to existing sensors :partying_face:) and powers the screen PCBs for HDMI input and touch.
    TODO: Check shutdown process of AUX Power (RPI restarts every few seconds after shutdown). Additionally check (and improve) boot time of the RPI.
    TODO: Find best parameters for startup and shutdown delay (btw does React Carplay provide the functionality to shutdown the RPI once the PiMost received the shutdown message?)

  • Mechanical integration
    The old screen will be removed from the ICM and replaced by the new touch screen once I’m sure I don’t need the old UI anymore. The dashboard will have 100% stock look, except for the screen content of course. One screen PCB will be inside the ICM, as well as my self-designed PCB. The second screen PCB will most likely sit on top of the ICM, if there is enough space below the air passage. The latter contains the HDMI and touch jacks. The RPI and PiMost will need to be placed deeper in the dashboard on the left side from the air passage (driver side).
    TODO: Remove old screen (once I don’t need the ICM’s UI anymore) and integrate the new one
    TODO: Integration of all PCB’s inside/on top of the ICM and check thermal management
    TODO: Integration of RPI and PiMost and check thermal management and check if vent noises need to be reduced

  • MOST sniffing:
    I somehow managed to duplicate the EHU once (with loss of music and also missing data on the ICM screen) but I found the command to switch between the available audio sources🥳 It means we have a connection master in the ICM, but additionally we do have a proprietary connection master in the EHU. With a single command I can switch between AmFmTuner, AUX and CD changer as if I would do it on the ICM or the steering wheel💪 Unfortunately, I did not manage yet to switch to the PiMost with this command until now, but maybe only known audio sources can be handled. If I switch to an unknown souce the currently streaming audio source gets interrupted/paused e.g. the CD changer.
    I sniffed all the commands in the “AUDIO” section: bass, treble, fader, balance and all settings in the advanced section. Additionally I do have the steering wheel controls for skip forward/backward, SRC, volume up/down on the MOST side.
    As we managed to do the force switch, followed by manual disconnection & connection of the remaining amplifiers I think, that if I want the audio to be streamed via PiMost I can send the command to the proprietary connection master to switch to an unknown audio source and then force switch to the PiMost. If I switch back to CD e.g. the audio switch happens automatically. I think it should even be possible to pause the audio streamed via the phone with the existing functionality of React Carplay, if I’m correct. Alternatively, if I manage the proprietary connection master to switch to the PiMost directly it might be even more straight forward, we will see!
    TODO investigate the proprietary connection master and check if its possible to switch to the PiMost directly
    TODO investigate the SrcDelay and it’s impact on the audio quality if possible
    TODO test a complete manual audio switch with an allocate, disconnect and connect
    TODO additional optional sniffing of available data on the MOST ring (probably once everything else is working and I still do have energy for it😅)

  • Software:
    The most basic functionality should be implemented in React Carplay already and with the upcoming firmware for the PiMost the standalone force switch should work as intended. As you know, I’m thinking about a little bit deeper integration, where we could do something similar as you did for the JLR (maybe not on such a detailed level as you did :wink:). I need to talk to my brother, but I think it might be worth to build the raw framework and get it to work, before I actually start with the “final” mechanical integration as described above.

As @Tigo suggested, we updated the firmware on the PiMost to v0.1.0 and the microphone started working, but we thought it has poor quality - in the meantime I realized, that we updated to the only available released firmware of v0.1.0 without noticing that it is for 48kHz → The result is stuttering music via the PiMost (and I assume as well for the mic input). Therefore, I downgraded now to v0.0.11 (3 byte feedback version → Or should I go to the 4 byte version for some reason? Btw which feedback are we talking about here?:sweat_smile:). v0.1.0 had a “reset” of the PiMost after “send to dongle”, which comes in very handy to switch between duplicating devices - nice job Rhys! Idk if it would be easy to release v0.1.0 for 44kHz as well, but I think I can wait for v0.1.1​:blush:
Something that crossed my mind regarding this topic: If I remember correctly, the PiMost can work on 44kHz and 48kHz with the same firmware, as long as he’s a slave (please correct me if I’m wrong - If he would be the master it requires the correct crystal on the board). I assume that the frequency information must be available on the PiMost and I was wondering if the “soundcard” could adapt automatically as well, or if that might be too complicated? Just a thought and I have no clue of whats going on in the firmware😜

You see, there’s a big progress on my project and I’ll keep you posted! Everyone please feel free to comment… it always helps a lot!

1 Like

Hi dino

This is not currently part of react-carplay, however the usb board does send a custom message requesting a shut down of the pi, so having a basic implementation of the drivers running will automatically shutdown the pi

This is super cool! Are you able to share the message details for the proprietary switch? JLR do similar and I have figured that out, I also found the same as you did that I can’t switch to an unknown source, so to get around that I removed my ipod player from the MOST ring and took that address, as far as the car is concerned my pi is now the ipod audio player and fully integrated to the OEM set up.

The new firmware is up for 44.1khz now, the issue of the frequency more comes down the the crystal for the STM processor and the dividers that are required on 48khz vs 44.1khz

Hey @rhys_m

Yaay, that sounds great - I will test the new firmware and I’ll let you know if the force switch and the microphone works as intended🤞 And I’ll test the shutdown functionality!

Good to know that it is similar in JLR. These are the required messages to switch to the related audio source:

			bNAH	bNAL	FBlockID	InstID	FktID	OPType	Byte 0	Byte 1	Byte 2	Byte 3
CDCF		0x01	0x10	0x20		0x01	0xc10	SetGet	0x0d	0x01	0x31	0x04
AUX			0x01	0x10	0x20		0x01	0xc10	SetGet	0x0d	0x01	0x24	0x01
AmFmTuner	0x01	0x10	0x20		0x01	0xc10	SetGet	0x01	0x01	0x40	0x01

Byte 0 is the same for CDCF and AUX → They’re not in the same node, but you can press the “CD” button twice on the ICM to switch to AUX, maybe it’s some kind of group? At the same time Byte 1 is different for AmFmTuner and AUX, which are FBlocks of the same node.
I currently have no clue about Byte 1, but Byte 2 is the FBlockID and Byte 3 is the InstID.

FBlock 0x20 is the proprietary connection master and 0xc10 the function to switch the source. A Get with the function 0xd21 returns the currently connected audio source. Additionally, I want to investigate function 0xd20 with OPType 0x01 (Get/Abort) with 5 bytes and similar data content, but not in the same order + 1 byte. I’ll let you know if I find out more about that🤞

Heya,

I updated the firmware and the microphone is working well, but on a low volume. It might be possible to increase the gain level somehow - at least on the mac I do not have the opportunity to adjust the input volume for the PiMost as it has for other sources. The handle on the bar for the output volume has no effect on the volume played in the car, but I guess also this could be adjusted if necessary.
→ One issue I had during testing was, that the car somehow changed the audio channels once, such that the “microphone input” actually was the CD player playing without any amp connected… So I could hear what the other person was saying, but instead of hearing me, the current CD track has been streamed. Idk how it happend, but after a few restarts of the MOST ring and the PiMost I got it repaired itself. I must have done something to cause the connection master to switch to other channels than usually.

I assume, that the automated force switch of the 3 amplifiers will be part of the next FW release, but the automated force switch of one amplifier and the manual switch of the remaining amps still works. Btw, I updated to 0.1.0, but in the settings page it displays 0.1.1

Regarding the proprietary connection master I made some progress, but I’m still not there yet. I finally saw the need to investigate how to reply correctly to the heartbeat-like request for FBlocks by the ICM. After a while I managed to reply with the same 3 FBlocks as the CDCF (I only selected a different InstID for the AudioDiskPlayer). I had to find out that the reply message needs to be shortly after a request message → After MOST ring startup the request comes in every second or so and after a while it changes to the 10sec rhythm, thats how I manually achieved to reply within the timeframe.
After that I tried to connect via proprietary connection master to the “new” FBlock AudioDiskPlayer and promplty I received an allocate message by the ICM and 3 times a “processing” message from the EHU which initiated the source switch (of course caused by my manual input message).

most-dump source switch attempt
[
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",
		"fBlockID": "0x20",
		"instanceID": "0x1",
		"fktID": "0xc10",
		"opType": "0xb",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x31",
		"instanceID": "0x1",
		"fktID": "0x101",
		"opType": "0x2",
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x1",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",
		"fBlockID": "0x20",
		"instanceID": "0x1",
		"fktID": "0xc10",
		"opType": "0xb",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",
		"fBlockID": "0x20",
		"instanceID": "0x1",
		"fktID": "0xc10",
		"opType": "0xb",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",
		"fBlockID": "0x20",
		"instanceID": "0x1",
		"fktID": "0xc10",
		"opType": "0xb",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x31",
		"instanceID": "0x1",
		"fktID": "0x101",
		"opType": "0x2",
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x1",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",
		"fBlockID": "0x20",
		"instanceID": "0x1",
		"fktID": "0xc10",
		"opType": "0xb",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",
		"fBlockID": "0x20",
		"instanceID": "0x1",
		"fktID": "0xc10",
		"opType": "0xb",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",
		"fBlockID": "0x20",
		"instanceID": "0x1",
		"fktID": "0xc10",
		"opType": "0xb",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	}
]

This sequence gets repeated once and then a massage appears in the most-explorer that the function would be implemented but that it is not available at the moment (or similar). I interpret this, that the EHU is waiting for my reply - and I do have an idea of what I have to reply, but I’m far too slow to change the manual message. Therefore, I will have a look at the printf from @ajazva or solve it with a scrip before I dive deeper on the software level. Keep your fingers crossed🤞

Thanks again for the latest firmware and a s usual any input is welcome!