Question about slice meters and conversion to s-units

  • 1
  • Question
  • Updated 4 years ago
To the gurus that have already figured this out...  Thanks in advance for your hard work.

In my project I'm subscribing to all meters and as expected bunches of them come down and I generally understand them.

I'm curious about signal level meters for slices.  In looking at the data sent for the meter I see a line like this:

S8D2F0DB8|meter 27.src=SLC#27.num=1#27.nam=LEVEL#27.low=-150.0#27.hi=20.0#27.desc=Signal strength of signals in the filter passband#27.unit=dBm#27.fps=10#

In parsing this out I can see that it is sourced from a slice "SLC" and the name is LEVEL.  The description also supports that this is a signal strength meter.

The question is... from the data above how do I know which slice this goes with?  I don't see any kind of slice ID in the meter packet?

I'm guessing that I just have to infer it using the logic that the first set of SLC meters would go to the first slice.  I'd then expect to see a repeat new set of SLC meters and assign them to the next slice.  Is that correct?

Secondly as pointed out in some other threads the Vita meter packets return the meterId as a uint16 and the meter data as an int16.

In  looking at the example meter above the low will be -150.0 to a high of 20.0 and the unit is dBm.  So the int16 value for the meter needs to be converted to dBm for use.  I'm no expert on dBm but I did notice in the FlexAPI the following function:

        public static float convertVITAtodB(int vita)       
       {
          short db = (short)(vita & 0xFFFF);
          return ((float)db / 128.0f);
        }

Does this do the job?

Thanks in advance guys!
Photo of Mark - WS7M

Mark - WS7M

  • 1370 Posts
  • 510 Reply Likes

Posted 4 years ago

  • 1
Photo of Stu Phillips - K6TU

Stu Phillips - K6TU, Elmer

  • 642 Posts
  • 256 Reply Likes
Ok - lets tease this apart

You get a string telling you of the creation of a meter - be aware that meters are added and removed based on events on the radio so be sure you are able to handle the creation/deletion logic:

The fields in the status message are separated by # charatcers

S8D2F0DB8|meter  - client handle and meter keyword
27.src=SLC - source of meter is a slice
27.num=1 - slice number 
27.nam=LEVEL - meter short name
27.low=-150.0 - meter min value
27.hi=20.0 - meter high value
27.desc=Signal strength of signals in the filter passband - meter long name/description
27.unit=dBm - units
27.fps=10 - updates per second

The raw values in the VITA packet need to be scaled based on the unit type - you found the code that scales for dBm - divide the value supplied by 128.0 and now you have dBm.

To map into S units you will need to apply the standard conversion;  See

https://en.wikipedia.org/wiki/S_meter

Stu K6TU
Photo of Mark - WS7M

Mark - WS7M

  • 1366 Posts
  • 507 Reply Likes
Hey Stu,

Thanks!  Somehow I completely missed the 23.num=1...  I guess I've been staring at the code too long!!!

That is the part I needed to be able to associate the meter with a slice.

Thanks for the dBm info.  I did find the S_meter wiki page and a few others.  I think I can figure that out.

My logic should handle meter deletion the way I have it written.  I need to test that however.  I think I can easily trigger it by removing a pan.  It seems to me I remember seeing some meter removed messages.
Photo of Walt - KZ1F

Walt - KZ1F

  • 3040 Posts
  • 645 Reply Likes
Well, when you subscribe to that even, it would be in your slice instance object. You are seeing that in a status message, correct? There is a one-to-one correlation between dbm and s-unit.
Photo of Mark - WS7M

Mark - WS7M

  • 1366 Posts
  • 507 Reply Likes
Well no... I currently have a map of meter objects.  I have yet to attach any of these to my slice objects and that was what this post was about, to figure out how to know which meter goes with which slice.  Stu to the rescue!
Photo of Walt - KZ1F

Walt - KZ1F

  • 3040 Posts
  • 645 Reply Likes
why didn't it take my last???
https://en.wikipedia.org/wiki/S_meter

            DataReadyEventHandler meterDataReady = (float data) -> onMeterDataReady(data);
            activeRadio.addSWRDataReadyListeners(meterDataReady);
 
 Your slice class will have it's own addSMeterDataReady and
addSMeterListener methods. If they don't they should.

In my Slice class

    public void addSMeterDataReadyHandler(SMeterDataReadyEventHandler listener) {
        smeterDataReadyEventListeners.add(listener);
    }
   
    private void onSMeterDataReady(float data) {
        for (SMeterDataReadyEventHandler listener : smeterDataReadyEventListeners) {
            listener.invoke(data);
        }
    }

Stu to the rescue? et tu Brutae?
(Edited)
Photo of Mark - WS7M

Mark - WS7M

  • 1366 Posts
  • 507 Reply Likes
Well... sort of.  I'm going about it a little differently using signals.  This might change but currently I have the following:

A thread that receives all UDP data packets, looks at the PacketClassCode and sends the packet off to a processor based on type.

In that processor the packet is decoded as much as is required and signals are sent to cause dependent code to update.  For example my meter packet decoder:

void FlexRadio::processMeterPacket( vitaPacket *packet )
{
  if( (packet!=nullptr) && (packet->m_arrayspacefailure==false) )
  {
    QMapIterator<quint16,qint16> i(packet->m_meter);
    while (i.hasNext())
    {
      i.next();
      quint16 mID   = i.key();
      qint16  mVal  = i.value();
      FlexMeter *meter = m_meter[mID];
      if( meter!=nullptr )
        meter->SetProperty( "MeterValue", mVal );
    }
  }
}

So the result of this is each incoming meter gets it's "MeterValue" property set to the value from the packet.

The process of calling meter->SetProperty emits a signal in this case "MeterValueChanged".

Other code, such as my slice makes a connection to the "MeterValueChanged" signal and when received it can update anything it needs to and even send another signal.

So my slice isn't really listening for meter changes, it is notified of them.

This design is working for 4 pans (all I can create with my lowly 6500) and all the stuff in between.

As you asked earlier I've baked in TONS of logging which is handled by a thread now.  Before this morning the logging could kind of bog things down.  I moved it into a thread.  Now I can enable all the logging I want and it just blasts it to the disk file in the background.

Here is some of the logging:

2016-03-23 17:18:42.187UTC -> parseDisplay2016-03-23 17:18:42.187UTC ->   pan
2016-03-23 17:18:42.187UTC ->   0x40000000
2016-03-23 17:18:42.187UTC ->   min_dbm=-127.44
2016-03-23 17:18:42.187UTC ->   max_dbm=-57.438
2016-03-23 17:18:42.187UTC ->   rfgain=10
2016-03-23 17:18:42.187UTC ->   pre=+10dB
2016-03-23 17:21:25.815UTC -> Radio WS7M - FLEX-6500 - 10.2.10.190 send command: C22|slice remove 1
2016-03-23 17:21:25.870UTC -> TCP readline data:R22|0| hex:52 32 32 7C 30 7C
2016-03-23 17:21:25.870UTC -> FlexRadio::parseReply message: R22|0|
2016-03-23 17:21:25.870UTC -> Response: R22 tidx: 55 code: 0 cmd: C22|slice remove 1
2016-03-23 17:21:25.870UTC -> TCP readline data:S8DA111DA|meter 28 removed hex:53 38 44 41 31 31 31 44 41 7C 6D 65 74 65 72 20 32 38 20 72 65 6D 6F 76 65 64
2016-03-23 17:21:25.870UTC -> TCP readline data:S8DA111DA|meter 27 removed hex:53 38 44 41 31 31 31 44 41 7C 6D 65 74 65 72 20 32 37 20 72 65 6D 6F 76 65 64
2016-03-23 17:21:25.872UTC -> TCP readline data:S8DA111DA|meter 26 removed hex:53 38 44 41 31 31 31 44 41 7C 6D 65 74 65 72 20 32 36 20 72 65 6D 6F 76 65 64
2016-03-23 17:21:25.872UTC -> TCP readline data:S8DA111DA|meter 25 removed hex:53 38 44 41 31 31 31 44 41 7C 6D 65 74 65 72 20 32 35 20 72 65 6D 6F 76 65 64
2016-03-23 17:21:25.872UTC -> TCP readline data:S8DA111DA|slice 0 active=1 hex:53 38 44 41 31 31 31 44 41 7C 73 6C 69 63 65 20 30 20 61 63 74 69 76 65 3D 31
2016-03-23 17:21:25.872UTC -> 
2016-03-23 17:21:25.872UTC -> parseSlice
2016-03-23 17:21:25.872UTC ->   0
2016-03-23 17:21:25.872UTC ->   active=1
2016-03-23 17:21:25.873UTC -> DEBUG @radio slice 0 property "active" changed to: "1"
2016-03-23 17:21:25.873UTC -> DEBUG @ display slice 0 property "active" changed to: "1"
 
You can see I captured meter removed messages in this case and I also show the slice properties being changed.

One benefit of how I've done this is that I'm not dependent directly upon properties.  I noticed when I run some tests using the C# flex api I get some "status not parsed" messages which I think mean that there is some new field or missing field expected in the list that was fed to the API.

I have very few dependencies.  In fact if the next Flex firmware added a brand new radio property called "WS7MDropDead" my code would pick that up and store it with the radio.

Of course unless I link some code to that new probably it is not really going to do anything but the properties are all stored in dictionaries.

Anway when I get a little further along I'm going to find one of those rich guys on here that has a 6700 and ask them to run it and give me some feed back.

The signal/slot system is blindingly fast.  The dictionary property storage is extremely quick.  As a test I banked up about 100 packets of FFT info for my pan and flipped the switch and it was like a pan adapter on a high caffeine diet!  I didn't bench mark the rate but I will repeat that test again.  All I can say is it was very fast.
Photo of Mark - WS7M

Mark - WS7M

  • 1366 Posts
  • 507 Reply Likes
God that came over as a mess... We really need a code formatting option here in the forum!
Photo of Walt - KZ1F

Walt - KZ1F

  • 3040 Posts
  • 645 Reply Likes
https://community.flexradio.com/flexradio/topics/metering-question

Alledgedly getSatisfaction knows about <code>...</code> but it appears to me not to work.
Photo of Stu Phillips - K6TU

Stu Phillips - K6TU, Elmer

  • 642 Posts
  • 256 Reply Likes
Use the pre option in the tool bar.

It lets you create mono-spaced content like this.
Stu K6TU
Photo of Mark - WS7M

Mark - WS7M

  • 1366 Posts
  • 507 Reply Likes
pre is what I did use but it did what you see above to a simple method.
Photo of Walt - KZ1F

Walt - KZ1F

  • 3040 Posts
  • 645 Reply Likes
No, either you misinterpreted me or I did a crap job of explaining. The slice doesn't listen to squat. It registers interest in events and they flow asynchronously to the given slice object. Similar to the pan, it registers interest in events and the events flow asynchronously to it.

I did likely an incomplete job of masking out 6700 things from 6500 things. I don't know much about 6300 controls so that is tbd. So I put up a slider, for instance, for the rfgain. It has 5 stops, -10,0,10,20,30. Works great for 6700, which I don't have. But I do know that is a difference so, if it is a 6500 in the model description, part of the radio object, I go into the slider and remove that last stop so on my machine it has stops at (-10, 0, 10, 20). Ditto for loopB, which is part of that hiddenPane...OH, this is cool, I eliminated a mouse click by doing a proximity pane for the pan options, when the mouse gets close to the left wall of spectrum that pan's control the hidden options pane slides out and when the mouse moves away from it the pane slides back...too cool. Similarly, for rf power, in my case I have 0-700w. For power under 100w I set the linear in stdy. If its talking to a different linear, the range might be 0-2000w. Or, maybe I'll be a tad 'nanny' (in Howard's terminology) and limit total output power to 1500w. If over 100w I set the linear in oper and reduce power to exciter power only. What I try to do is add enough things like that to whet the prospect's appetite for the subscription version. In the teaser version it does 0-100 only.

Photo of Walt - KZ1F

Walt - KZ1F

  • 3040 Posts
  • 645 Reply Likes
yep, pre is short for preserve spacing.There is a hidden option that, as I recall, you get by clicking on </> that shows all the options for text layout available or, intended to be eventually available, like <code</code>

So I am adding a lot of 'Easter eggs' for people to comment on. Frankly that may have drive look and feel stuff done in Austin. Maybe not but...
(Edited)