Home AMX User Forum NetLinx Studio

Channels ("real" and virtual) Vs. Variables

So I've been having this problem creep up every so often and was wondering if anyone has experience the same thing, and if so what your fix was.

On occasion I'll use device channels as a ready / busy / online / offline flag. They're global across everything (modules, master-to-master, etc.) so they're, IMHO, rather strong. On two particular modules I've written that use channels as a notification flag, the channels will get into a major tissy and flip on / off about 1,000 / second, and won't stop until the system is rebooted. The system continues to run fine, it's just whatever depends on those channels ceases to work anymore. On these two modules, they're both IP devices, and I used the 'actual' device's channel rather than the virtual, i.e. [0:40:0,251].

Has anyone ran into this? I've considered using a variable as a flag, but you don't get the 'notification' like a when a channel goes on / off. Thoughts?

Comments

  • a_riot42a_riot42 Posts: 1,624
    jjames wrote: »
    So I've been having this problem creep up every so often and was wondering if anyone has experience the same thing, and if so what your fix was.

    On occasion I'll use device channels as a ready / busy / online / offline flag. They're global across everything (modules, master-to-master, etc.) so they're, IMHO, rather strong. On two particular modules I've written that use channels as a notification flag, the channels will get into a major tissy and flip on / off about 1,000 / second, and won't stop until the system is rebooted. The system continues to run fine, it's just whatever depends on those channels ceases to work anymore. On these two modules, they're both IP devices, and I used the 'actual' device's channel rather than the virtual, i.e. [0:40:0,251].

    Has anyone ran into this? I've considered using a variable as a flag, but you don't get the 'notification' like a when a channel goes on / off. Thoughts?

    Interesting. I have been seeing something similar when using the Kaleidescape module. For no reason that I can think of, a channel will start to toggle on/off hundreds of times a second, slowing the system to a crawl. A reboot fixes it usually, but I've even seen it start up again immediately after a reboot. Its always a channel used by the Kaleidescape system so I figured it was the Kaleidescape module code, but now I am wondering. The KServer is an IP device as well. In this case, its a devchan that toggles and the device is the port ie: 0:4:0. Could there be an issue using the real port on IP devices where channels will get toggled incessantly? Hmmm.
    Paul
  • ericmedleyericmedley Posts: 4,177
    I've had trouble with this kind of thing which used to work...
    if(![vdv_device,1] )
      { on[vdv_device,1] }
    
    

    The idea being only turn on the channel if it's off but don't try if it's on. Also, in olden times, a subsequent channel on would not fire if the channel was already on.

    The fix was to track the channel state with a valuable.
  • champchamp Posts: 261
    I suspect the issue is a bug related to the online / offline status of the device, if so then using a virtual device channel instead should make the problem go away. It is worth a try.
  • jjamesjjames Posts: 2,908
    Indeed - I started thinking this myself, and was actually in the process of turning on a channel in the online event and NOT turn it off in the offline, just to see if it turns off automatically. Oddly, the channel won't turn on in the offline event - though it's a very fast connection ( < .002)

    I *know*, I *know*, I KNOW! that we were told to never rely on a 'real' device's channel for anything, including feedback . . . I just never ran into a problem with it until now. Going to move to virtual to see if it helps. (I suspect it will.)
  • a_riot42a_riot42 Posts: 1,624
    jjames wrote: »
    Indeed - I started thinking this myself, and was actually in the process of turning on a channel in the online event and NOT turn it off in the offline, just to see if it turns off automatically. Oddly, the channel won't turn on in the offline event - though it's a very fast connection ( < .002)

    I *know*, I *know*, I KNOW! that we were told to never rely on a 'real' device's channel for anything, including feedback . . . I just never ran into a problem with it until now. Going to move to virtual to see if it helps. (I suspect it will.)


    I use real devices all the time without issue, except not IP ports. My guess is that there is something special about the port device that gets these channels toggling incessantly. I just logged into the system I was seeing this with and I turned the channel off in control a device and this stopped it cold. Guess I get to dig into the Kaleidescape module once again :)
    Paul
  • jjamesjjames Posts: 2,908
    a_riot42 wrote: »
    I use real devices all the time without issue, except not IP ports. My guess is that there is something special about the port device that gets these channels toggling incessantly. I just logged into the system I was seeing this with and I turned the channel off in control a device and this stopped it cold. Guess I get to dig into the Kaleidescape module once again :)
    Paul
    Well, the reason why they (being trainers, Jedi Programmers, etc.) say it is a bad idea to use a real device is that real devices are never guaranteed to be online while a virtual device is.
  • a_riot42a_riot42 Posts: 1,624
    jjames wrote: »
    Well, the reason why they (being trainers, Jedi Programmers, etc.) say it is a bad idea to use a real device is that real devices are never guaranteed to be online while a virtual device is.

    If you need that guarantee I guess, but I don't find I ever do. Is that for when you use define_combine and those features?
    Paul
  • jjamesjjames Posts: 2,908
    a_riot42 wrote: »
    If you need that guarantee I guess, but I don't find I ever do. Is that for when you use define_combine and those features?
    Paul
    I think the scenario they typically provide is something like this:
    if([dvTP,1])
    {
      off[dvTP,1];
    }
    
    ... meaning don't rely on the status of a real device's channel to do something else.

    I don't use define_combine or anything like that, but I believe that's what that 'feature' was intended for.
  • a_riot42a_riot42 Posts: 1,624
    jjames wrote: »
    if([dvTP,1])
    {
      off[dvTP,1];
    }
    

    This code should run fine no? If the panel is offline [dvTP,1] is off, so no need to turn it off, and if its online it should work fine too. I'm not seeing the issue there.
    Paul
  • champchamp Posts: 261
    I use real devices all the time without issue, except not IP ports
    Once serial and IR ports come online they never go offline so they don't behave like IP ports.
    I don't use define_combine or anything like that, but I believe that's what that 'feature' was intended for.
    I don't use define_combine as i prefer to create arrays of devices then address them individually or as a group at will.
  • jjamesjjames Posts: 2,908
    a_riot42 wrote: »
    This code should run fine no? If the panel is offline [dvTP,1] is off, so no need to turn it off, and if its online it should work fine too. I'm not seeing the issue there.
    Paul

    Think something mission critical, it was just an example; mission critical like this:
    if([dvTP,911]) // alarm feedback
    {
       Send_command vdvLights, 'ALL=ON' // turn all the lights on if a burglar has broken into the house and might be planning to go all Norman Bates
    }
    

    I'll toy around with IP devices and their channel properties.
  • TurnipTruckTurnipTruck Posts: 1,485
    jjames wrote: »
    On occasion I'll use device channels as a ready / busy / online / offline flag. They're global across everything (modules, master-to-master, etc.) so they're, IMHO, rather strong. On two particular modules I've written that use channels as a notification flag, the channels will get into a major tissy and flip on / off about 1,000 / second, and won't stop until the system is rebooted. The system continues to run fine, it's just whatever depends on those channels ceases to work anymore. On these two modules, they're both IP devices, and I used the 'actual' device's channel rather than the virtual, i.e. [0:40:0,251].

    I've seen this.

    I have added a second port to virtual devices as a channel feedback mechanism. Worked just fine. Be sure to set_virtual_port_count=2 in the module code.

    dvDevice= 33001:1:0
    dvDeviceStatus=33001:2:0
  • the8thstthe8thst Posts: 470
    I always assumed the 'real' IP devices were offline and not available when they are not connected to the host device (unless it is for a server).

    How can the online/offline events for the device trigger if they are always available? I think this is where you guys are running into problems.

    I will have to take a look at the KScape module when I have a chance because I use it all the time and have never had an issue with it (other than excessive CPU usage).
  • jjamesjjames Posts: 2,908
    the8thst wrote: »
    How can the online/offline events for the device trigger if they are always available? I think this is where you guys are running into problems.
    They're not. You cannot send a string to an IP device when it's not connected. How do you know it's connected? With ONLINE / OFFLINE.

    The device is always available (device zero), yes, but that port isn't always available.
  • a_riot42a_riot42 Posts: 1,624
    jjames wrote: »
    Think something mission critical, it was just an example; mission critical like this:
    [code]

    I wouldn't rely on a channel state on a touch panel for that. The only thing I ever use that for is to provide feedback to the panel, so if its offline, then it doesn't matter.
    Paul
  • AuserAuser Posts: 506
    jjames wrote: »
    On two particular modules I've written that use channels as a notification flag, the channels will get into a major tissy and flip on / off about 1,000 / second, and won't stop until the system is rebooted.

    Sounds like classic duelling channels to me.
    DEFINE_EVENT
    channel_event[dvSomeDevice,CH_SOMETHINGOR_OTHER]
    {
      on:
      {
        [Data.Device,Channel.Channel] = ![Data.Device,Channel.Channel]
      }
      off:
      {
        [Data.Device,Channel.Channel] = ![Data.Device,Channel.Channel]
      }
    }
    

    There are lots of ways the behaviour can inadvertently be embedded in code without ever being obvious until you run into the problem. Effectively there's a feedback loop causing the channel to toggle which could be initiated in an event, timeline event or define_program and the problem code could be a long way downstream hidden in functions that have been called by functions that have been called by functions.

    The same sort of thing can cause levels to constantly jump about too.

    As you stated devchans are globally accessible, so code anywhere in the system could be causing the behaviour. The problem code doesn't necessarily have to be in the module you're expecting to find it in, it could be in the main program or potentially even another module.

    As a tip, TRANSLATE_DEVICE can help to break these sorts of feedback loops and stop the main program being able to affect the channels and levels being used as an interface to a module.
  • a_riot42a_riot42 Posts: 1,624
    Auser wrote: »
    Sounds like classic duelling channels to me.
    DEFINE_EVENT
    channel_event[dvSomeDevice,CH_SOMETHINGOR_OTHER]
    {
      on:
      {
        [Data.Device,Channel.Channel] = ![Data.Device,Channel.Channel]
      }
      off:
      {
        [Data.Device,Channel.Channel] = ![Data.Device,Channel.Channel]
      }
    }
    

    That's one nasty bit of code. You have to possess a truly evil mind to come up with that one.
    Auser wrote: »
    There are lots of ways the behaviour can inadvertently be embedded in code without ever being obvious until you run into the problem. Effectively there's a feedback loop causing the channel to toggle which could be initiated in an event, timeline event or define_program and the problem code could be a long way downstream hidden in functions that have been called by functions that have been called by functions.

    The same sort of thing can cause levels to constantly jump about too.

    As you stated devchans are globally accessible, so code anywhere in the system could be causing the behaviour. The problem code doesn't necessarily have to be in the module you're expecting to find it in, it could be in the main program or potentially even another module.

    As a tip, TRANSLATE_DEVICE can help to break these sorts of feedback loops and stop the main program being able to affect the channels and levels being used as an interface to a module.

    This is true and the Kaleidescape module has all sorts of that going on. They even use a recursive function for message parsing which just seems to be asking for trouble. Flipping channels in channel events that then flip other channels that depend on a variable in mainline, etc so its pretty ugly. Very difficult to trace if a problem like this pops up. I don't use devchans, combines or define_program for this reason, as it makes tshooting a nightmare.

    I've never come across translate_device before and don't see any documentation on it. Is there anything in the docs about this keyword?
    Paul
  • AuserAuser Posts: 506
    a_riot42 wrote: »
    That's one nasty bit of code. You have to possess a truly evil mind to come up with that one.

    Why thank you *blushes*. You should see what I can do with a bit of recursion.

    a_riot42 wrote: »
    I've never come across translate_device before and don't see any documentation on it. Is there anything in the docs about this keyword?

    There's not much documentation of it anywhere. The example source for a module posted by John Michener in the following post is probably the best demonstration.

    http://www.amxforums.com/showthread.php?1926-The-not-documentary-function

    Effectively translate_device is used inside modules to create an event wormhole between two devices. One device is likely to be a parameter passed to a module (let's call it vdvParameter), the other is likely to be a DYNAMIC_VIRTUAL_DEVICE (I'll refer to it as vdvInternalToTheModule - we don't care about the device outside the module as it is only ever referenced inside the module and may as well not exist as far as the rest of the program is concerned).

    When an event is initiated on one device, the event that is fired will occur on the second device only.

    ie. on[vdvParameter, CH_SOMETHING] will result in CH_SOMETHING being turned on on vdvInternalToTheModule and vice versa.

    It is therefore not possible for code outside the module to set the state of any channels on vdvParameter (or generate level events, or data_events, etc.). The events are still generated, but they are fired for vdvInternalToTheModule and the programmer can handle them as required inside the module.

    If the programmer wants a channel to go on on vdvParameter in order to provide feedback to the main program, they need to turn on that channel on vdvInternalToTheModule.

    Bit to get your head around, but very useful and a very powerful way to stop code external to a module influencing the operation of the module by altering the state of the interface vDev. Effectively you're making the interface device read only.
Sign In or Register to comment.