Home AMX User Forum NetLinx Studio

Dynamically adding items to a DEV array

I'm working on rolling my own AMX monitoring system since from what I've seen of RMS it's over kill for what my needs are (and I don't like the thought of running a Windows server for a web app). Anyway, for my first tests I was just trying to monitor the power state of a display. Now if I use a CHANNEL_EVENT to monitor [33001, 255] directly, I see the ON and OFF events like I would expect. This of course isn't very modular, so my ultimate goal is to have an array of devices and monitor 255 on that array ie:
CHANNEL_EVENT[dvMonitoredDevices, 255]
{
  ON: 
  {
    // Report device on
  }

  OFF:
  {
    // Report device off
  }
}

The problem is that this doesn't do anything, the code in ON and OFF never gets called. dvMonitoredDevices is a VOLATILE DEV array. I'm wondering if part of the problem may be how I'm adding devices to the array. My code is as follows:
DEFINE_FUNCTION registerMonitoredDevice(CHAR sDev[])
{
    STACK_VAR INTEGER nArraySize
    STACK_VAR DEV dvDev
    
    dvDev.NUMBER = ATOI(sDev)
    REMOVE_STRING(sDev, ':', 1)
    dvDev.PORT = ATOI(sDev)
    REMOVE_STRING(sDev, ':', 1)
    dvDev.SYSTEM = ATOI(sDev)
    
    nArraySize = LENGTH_ARRAY(dvMonitoredDevices)
    dvMonitoredDevices[nArraySize + 1] = dvDev
    SET_LENGTH_ARRAY(dvMonitoredDevices, nArraySize + 1)
}

I've also tried all of this using a DEVCHAN array just in the off chance that a CHANNEL_EVENT required it and I got the same results.

Anyone have any ideas?

Thanks,
Matt

Comments

  • mpullinmpullin Posts: 949
    1) Why are you passing in a string to your function and then parsing out the Number, Port, and System? Why not just pass a DEV? e.g. DEFINE_FUNCTION registerMonitoredDevice(DEV newDEV)

    2) SET_LENGTH_ARRAY can't make an array longer than it was originally declared, it can only change the size within that range. Try to guess how many devices you'll ever want to monitor and make your array that size. We're not dealing with vectors here.
  • mstocummstocum Posts: 120
    mpullin wrote:
    1) Why are you passing in a string to your function and then parsing out the Number, Port, and System? Why not just pass a DEV? e.g. DEFINE_FUNCTION registerMonitoredDevice(DEV newDEV)

    Because the device to be managed is coming in through a SEND_COMMAND to a module, so it has to come over as text.
    mpullin wrote:
    2) SET_LENGTH_ARRAY can't make an array longer than it was originally declared, it can only change the size within that range. Try to guess how many devices you'll ever want to monitor and make your array that size. We're not dealing with vectors here.

    That's what I'm doing (I think). I declare a 64 element empty array, so it's length should be 0, each time I add something to the array I get the length, and then add an item to length + 1. I have no idea if the call to set_length_array is needed or not, but it seems like it shouldn't hurt.
  • mpullinmpullin Posts: 949
    mstocum wrote:
    I declare a 64 element empty array, so it's length should be 0, each time I add something to the array I get the length, and then add an item to length + 1. I have no idea if the call to set_length_array is needed or not, but it seems like it shouldn't hurt.
    I'd change the last three lines so they read thusly:
    nArraySize = LENGTH_ARRAY(dvMonitoredDevices)
        SET_LENGTH_ARRAY(dvMonitoredDevices, nArraySize + 1)
        dvMonitoredDevices[nArraySize] = dvDev
    
    So that you're increasing the size of the array and THEN assigning a new device.

    Also, have you tried manually defining the array and seeing if you get the desired feedback then? That would be my first step. Then you're sure to narrow down the problem to your procedure for adding devices.
  • dbradydbrady Posts: 30
    Try using the rebuild_event function. Details can be found in netlinx studio help files.
  • mstocummstocum Posts: 120
    mpullin wrote:
    I'd change the last three lines so they read thusly:
    nArraySize = LENGTH_ARRAY(dvMonitoredDevices)
        SET_LENGTH_ARRAY(dvMonitoredDevices, nArraySize + 1)
        dvMonitoredDevices[nArraySize] = dvDev
    
    So that you're increasing the size of the array and THEN assigning a new device.

    Also, have you tried manually defining the array and seeing if you get the desired feedback then? That would be my first step. Then you're sure to narrow down the problem to your procedure for adding devices.

    I'll try both later today. The room is in use right now and I think people would notice the system rebooting itself. I really don't know why I didn't think of adding the entries by hand earlier. Guess after a couple hours of banging your head against a problem you start missing obvious things.
  • mstocummstocum Posts: 120
    dbrady wrote:
    Try using the rebuild_event function. Details can be found in netlinx studio help files.

    I'm not sure how REBUILD_EVENT() would help with the CHANNEL_EVENT not being called. It does look like something I should probably call at the end of the event though.
  • dbradydbrady Posts: 30
    Calling rebuild_event() at the end of your registerMonitoredDevice() function should rebuild the channel event using dvMonitoredDevices which has just been modified.

    The event table for the channel event will only contain the devices in dvMonitoredDevices that were there at compile time(and hence only triggered by these devices) unless you call rebuild_event() to rebuild the event table using the new devices added by your registerMonitoredDevice() function.

    Hope that makes sense.
  • mstocummstocum Posts: 120
    dbrady wrote:
    Calling rebuild_event() at the end of your registerMonitoredDevice() function should rebuild the channel event using dvMonitoredDevices which has just been modified.

    The event table for the channel event will only contain the devices in dvMonitoredDevices that were there at compile time(and hence only triggered by these devices) unless you call rebuild_event() to rebuild the event table using the new devices added by your registerMonitoredDevice() function.

    Hope that makes sense.

    Ahh, yes that does make sense. And it also fixed the problem and made everything work perfectly.
  • NMarkRobertsNMarkRoberts Posts: 455
    mstocum wrote:
    This of course isn't very modular, so my ultimate goal is to have an array of devices and monitor 255 on that array ie:
    CHANNEL_EVENT[dvMonitoredDevices, 255]
    }
    

    The problem is that this doesn't do anything, the code in ON and OFF never gets called.

    Could you explain the 255 bit please? Are you sure you shouldn't be using 0 instead, to collect all channels? I believe that specifying 255 means you only get channel 255.
    nArraySize = LENGTH_ARRAY(dvMonitoredDevices)
    dvMonitoredDevices[nArraySize + 1] = dvDev
    SET_LENGTH_ARRAY(dvMonitoredDevices, nArraySize + 1)
    

    After taking into account the other comments posted here, the code above appears to be good, and it is the way that AMX expects you to do this kind of thing. However anyone who has coded in a couple of dozen other languages will find it appalling - and unnecessarily complicated.

    Here is how I would instinctively do it:
    nArrayCount++
    dvMonitoredDevices[nArrayCount] = dvDev
    

    And here is the routine I call for all arrays during startup:
    (******************************************************************************)
    (*
    The effective length of an array can vary, who knows why...
    This ensures that it never does.
    *)
    define_function IntegerArrayLengthSet  (
    	integer nArgArray[]                  )
    (******************************************************************************)
    {
    set_length_array(nArgArray,max_length_array(nArgArray))
    } (* IntegerArrayLengthSet *)
    
  • Sorry, I was offline since wednesday. otherwise I would have told you to call the famous REBUILD_EVENT, that we all like very much.

    In AMX, understanding REBUILD_EVENT is the working at the level of deepest wisdom
  • mpullinmpullin Posts: 949
    In AMX, understanding REBUILD_EVENT is the working at the level of deepest wisdom
    Yes but the problem with REBUILD_EVENT is not all the feedback makes sense...
  • adysadys Posts: 395
    !!!

    This is the reason that my code didn't work?

    I wanted to call to a function that getting a list of DEV with a single DEV. ( in short, I wanted to made lots of updates in the local TP and only when done (release event) to send update to all the rest)

    I done something like this:


    BUTTON_EVENT[BUTTON,tpList]
    {

    DEV tempList[1]



    Panel = get_last(tpList)

    tempList[1] = Panel

    Function(tempList)

    ......
    ......

    Function(tpList)

    }

    The first call did nothing... even that I saw with the debuger that the temp list holds the values of the Panel.
    From what I reading here I needed to do a rebuild event?

    I don't see why, but its the same problem (only my code is from button event and not channel)
Sign In or Register to comment.