Home AMX User Forum NetLinx Studio

NI-3100 + TCP/IP Client

Hello everyone,

I have some troubles with connection to TCP/IP Client by NI-3100.

The aim is to control IP-Camera (Pansonic AW-HE50SE) by sending telenet-string through NI-3100.

NI-3100's IP : 192.168.0.81
Panasonic's IP: 192.168.0.247

1. First of all I established connection with NI-3100 by Ethernet.
2. Secondly, I added this code into standart NetLinx Source File:
DEFINE_DEVICE
dvPAN = 0:3:0

~~~~~

DEFINE_START
IP_CLIENT_OPEN(3,'192.168.0.247',80,IP_TCP)
3. Thirdly, I compiled workspace, built Project and System, and transfered two files (*.tkn and *.src) to NI-3100.

But when I send command
send_string dvPAN, "'%command%'"

the telnet responce is:
Device Name dvPAN is invalid

The data-indicator on controller shows only INPUT data, but not OUTPUT.

Hope you can help me to find the solution of this problem.

Comments

  • RaphayoRaphayo Posts: 111
    If you use iP_CLIENT_OPEN(dvPan,'192.168.0.247',80,IP_TCP)

    Are you s?re your connection is open?

    Use data-event online/offline to confirm it.
  • Proper IP_CLIENT_OPEN statement: IP_CLIENT_OPEN(dvPan.port,'192.168.0.247',80,IP_TCP) I've got IP control working to those Panasonic cameras, I can share some code if you need.

  • viningvining Posts: 4,368
    Also you are opening the socket in define start for an http port. Http typical isn't a maintained open socket, you need to open the socket every time you need to send a string so when you have a command to send you call ip_client_open, in the data event online handler you'll receive notification that the connection has been made and you use that to trigger your send string.
  • It's a good idea to do online, offline and onerror events when doing IP programming:

    DATA_EVENT[dvIPDevice]
    {
    ONLINE:
    {
    SEND_STRING 0, 'IP Device ON-LINE'
    WAIT 100
    {
    <things to do when device comes on line>
    }
    }
    OFFLINE:
    {
    SEND_STRING 0, 'IP Device OFF-LINE'
    }
    ONERROR:
    {
    SEND_STRING 0, 'IP Device ERROR'
    SEND_STRING 0, "ITOA(DATA.NUMBER)"
    <IP_CLIENT_OPEN can run here to reestablish comm>
    }
    }

    Then you can get an idea what is happening.
  • DId you try to use the Jar Module, it will open the communication and keep it alive for you.
  • KennyKenny Posts: 209
    You said telnet strings. Are you sure the strings go in on port 80 of the camera?
    IP_CLIENT_OPEN(3,'192.168.0.247',80,IP_TCP)
  • viningvining Posts: 4,368
    bwestlake wrote: »
    It's a good idea to do online, offline and onerror events when doing IP programming:

    DATA_EVENT[dvIPDevice]
    {
    ONLINE:
    {
    SEND_STRING 0, 'IP Device ON-LINE'
    WAIT 100
    {
    <things to do when device comes on line>
    }
    }
    OFFLINE:
    {
    SEND_STRING 0, 'IP Device OFF-LINE'
    }
    ONERROR:
    {
    SEND_STRING 0, 'IP Device ERROR'
    SEND_STRING 0, "ITOA(DATA.NUMBER)"
    <IP_CLIENT_OPEN can run here to reestablish comm>
    }
    }

    Then you can get an idea what is happening.

    I've never used a wait before sending once getting the online notification, with http you usually have 30 seconds before the server will drop the connection so a 10 second wait should be alright just not nescassary. I'd get rid of it since the quicker you send the sooner you can send your next command and 10 seconds is a long time to hold things up.
  • vining wrote: »

    I've never used a wait before sending once getting the online notification, with http you usually have 30 seconds before the server will drop the connection so a 10 second wait should be alright just not nescassary. I'd get rid of it since the quicker you send the sooner you can send your next command and 10 seconds is a long time to hold things up.

    That wait was to "do other things" after the device comes online. This was a device specific thing I just left in my generic example.
  • Oh, guys! Thank you so much for you answers.
    I will check it in 5 mins.
  • I've got IP control working to those Panasonic cameras, I can share some code if you need.

    It would be great! Can you send me link or archive/file in PM?
    Also, you can share it here, but I don't know is it allowed or not.
  • bwestlake wrote: »

    DATA_EVENT[dvIPDevice]
    {
    ONLINE:
    {
    SEND_STRING 0, 'IP Device ON-LINE'
    WAIT 100
    {
    <things to do when device comes on line>
    }
    }
    OFFLINE:
    {
    SEND_STRING 0, 'IP Device OFF-LINE'
    }
    ONERROR:
    {
    SEND_STRING 0, 'IP Device ERROR'
    SEND_STRING 0, "ITOA(DATA.NUMBER)"
    <IP_CLIENT_OPEN can run here to reestablish comm>
    }
    }

    I tried that:
    DEFINE_DEVICE
    
    dvPan = 0:3:0
    
    DEFINE_EVENT
    DATA_EVENT[dvPan]
    {
    ONLINE:
    {
        SEND_STRING 0, 'IP Device ON-LINE'
    }
    OFFLINE:
    {
        SEND_STRING 0, 'IP Device OFF-LINE'
    }
    ONERROR:
    {
        SEND_STRING 0, 'IP Device ERROR'
        SEND_STRING 0, "ITOA(DATA.NUMBER)"
        IP_CLIENT_OPEN(3,'192.168.0.247',80,IP_TCP)
    }
    }
    

    But after master reboot there is nothing in Diagnostic and Notifications dialogs.
    Where should this messages (SEND_STRING) be showed?
  • Kenny wrote: »
    You said telnet strings. Are you sure the strings go in on port 80 of the camera?
    IP_CLIENT_OPEN(3,'192.168.0.247',80,IP_TCP)
    Honestly talking, I am absolutely not sure.
  • Telnet into the master and type "msg on" to turn on diagnostic messages.
  • Too much code under
    (0000015473) Memory Available = 41475928 <211392> 
    (0000015574) DynamicDeviceDetector 0.0.1 has been started 
    (0000016473) Memory Available = 41360424 <115504> 
    (0000016573) Memory Available = 41327288 <33136> 
    (0000016690) Memory Available = 41301400 <25888> 
    (0000016706) Memory Available = 41290104 <11296> 
    (0000016976) Memory Available = 41132712 <157392> 
    (0000017473) Memory Available = 41014824 <117888> 
    (0000018473) Memory Available = 40878976 <135848> 
    (0000018885) 15:58:24.699 EVENT  Started ServletHttpContext[/] 
    (0000019061) 15:58:25.349 EVENT  Started ServletHttpContext[/] 
    (0000019472) Memory Available = 40717168 <161808> 
    (0000019548) 15:58:25.833 EVENT  Started ServletHttpContext[/] 
    (0000019553) RootServlet 0.0.1 has been started 
    (0000019981) 15:58:26.266 EVENT  Started ServletHttpContext[/] 
    (0000019986) DeviceServlet 0.0.1 has been started 
    (0000020472) Memory Available = 40355792 <361376> 
    (0000020515) 15:58:26.799 EVENT  Started ServletHttpContext[/] 
    (0000020520) ConfigServlet 0.0.1 has been started 
    (0000021048) 15:58:27.333 EVENT  Started ServletHttpContext[/] 
    (0000021053) DVXSPConfigServlet 0.0.1 has been started 
    (0000021472) Memory Available = 40251248 <104544> 
    (0000021681) 15:58:27.966 EVENT  Started ServletHttpContext[/] 
    (0000021686) SecurityServlet 0.0.1 has been started 
    (0000022148) 15:58:28.433 EVENT  Started ServletHttpContext[/] 
    (0000022153) DynamicServlet 0.0.1 has been started 
    (0000022198) 15:58:28.483 EVENT  Starting Jetty/4.2.x 
    (0000022425) 15:58:28.716 EVENT  Started SocketListener on 0.0.0.0:80 
    (0000022472) Memory Available = 40017744 <233504> 
    (0000023190) 15:58:29.483 EVENT  Started SocketListener on 0.0.0.0:443 
    (0000023194) 15:58:29.483 EVENT  Started org.mortbay.jetty.Server@87742e 
    (0000023363) CIpInterpreter::Run - Execute Startup Code 
    (0000023364) Memory Available = 39765384 <252360> 
    (0000023706) Remote System 2 Online: Route 2 Metric 1 
    (0000023857) Connected Successfully 
    (0000023858) CIpEvent::OnLine 0:1:1 
    (0000023859) CIpEvent::OnLine 5001:1:1 
    (0000023859) CIpEvent::OnLine 5001:2:1 
    (0000023860) CIpEvent::OnLine 5001:3:1 
    (0000023860) CIpEvent::OnLine 5001:4:1 
    (0000023861) CIpEvent::OnLine 5001:5:1 
    (0000023861) CIpEvent::OnLine 5001:6:1 
    (0000023862) CIpEvent::OnLine 5001:7:1 
    (0000023862) CIpEvent::OnLine 5001:8:1 
    (0000023863) CIpEvent::OnLine 5001:9:1 
    (0000023863) CIpEvent::OnLine 5001:10:1 
    (0000023864) CIpEvent::OnLine 5001:11:1 
    (0000023864) CIpEvent::OnLine 5001:12:1 
    (0000023865) CIpEvent::OnLine 5001:13:1 
    (0000023867) CIpEvent::OnLine 5001:14:1 
    (0000023872) CIpEvent::OnLine 5001:15:1 
    (0000023874) CIpEvent::OnLine 5001:16:1 
    (0000023878) CIpEvent::OnLine 5001:17:1 
    (0000023882) CIpEvent::OnLine 0:1:2 
    (0000023886) CIpEvent::OnLine 0:2:1 
    (0000024471) Memory Available = 39713560 <51824> 
    (0000026982) IPDeviceDetector.run(): joined multicast group 
    (0000053814) IPSocketManConnectTask - connect Timed Out 
    (0000053815) CIpEvent::OnError 0:3:1 
    (0000053924) Exiting TCP Read thread - closing this socket for local port 2 
    (0000053925) CIpEvent::OffLine 0:2:1 
    

    That's all. So there is nothing about the message we send.

    Should IP-Device be showed in tree-list?

    b52c9e2f3c.png
  • viningvining Posts: 4,368
    Your last code snippet didn't show your complete onerror handler, do you have a send string like bwestlake posted in it?
    &#8203;
          SEND_STRING 0, 'IP Device ERROR'
    SEND_STRING 0, "ITOA(DATA.NUMBER)"
    
    note: that I didn't include the ip_client_open here because that will usually screw up the master, oprening, error, opening, error, etc forever, usually you can attempt to re-open after a 30+ second delay based on the error number​, most errors you just send a notifications and don't attempt to re connect.

    So in your diagnostic print out you should have seen your send_string 0 if you have one in your onerror handler and if your did you would see the error number and that would help to know what the problem is. Verify the camera port, IP and it's protocol, TCP or UDP. Also you should move the IP_CLIENT_OPEN out of define start and and put it under a button push or something so you can fire it when you're ready to observe the diagnostics.

    No, your IP devices won't show up in the tree, only AMX devices.






  • I usually do my IP_CLIENT_OPEN 10 seconds after the master comes online.
    First I will create a CALL:

    DEFINE_START

    DEFINE_CALL 'dvPan_Start'
    {
    SEND_STRING 0,'dvPan_Start CALLED'
    {
    IP_CLIENT_OPEN(dvPan.port,'192.168.0.247',80,IP_TCP)
    }
    }

    Then you can use this when master comes online to start communications and in an error event or button event to restart communications

    DEFINE_EVENT
    DATA_EVENT [dvMASTER]
    {
    ONLINE:
    {
    WAIT 100
    CALL 'dvPan_Start'
    }
    }

    Plus this will give you time to get through lots of the master booting messages.
  • viningvining Posts: 4,368
    bwestlake wrote: »
    I usually do my IP_CLIENT_OPEN 10 seconds after the master comes online.
    First I will create a CALL:

    DEFINE_START

    DEFINE_CALL 'dvPan_Start'
    {
    SEND_STRING 0,'dvPan_Start CALLED'
    {
    IP_CLIENT_OPEN(dvPan.port,'192.168.0.247',80,IP_TCP)
    }
    }

    Then you can use this when master comes online to start communications and in an error event or button event to restart communications

    DEFINE_EVENT
    DATA_EVENT [dvMASTER]
    {
    ONLINE:
    {
    WAIT 100
    CALL 'dvPan_Start'
    }
    }

    Plus this will give you time to get through lots of the master booting messages.
    I'll typically do the same if it's a telnet ish type of socket, something that maintains the connection but on occasion drops for what ever reason and for those drops I'll put a wait xx and then attempt to re-open the connection. With an HTTP though I usually wait until I add an outgoing command to my send Q which triggers my IP Open and then the online handler processes the 1st item in my Q, server responds, closes and in the offline I'll check if anything else is Q'd and is so open again and repeat the process. I'm working on an http/json device right now that also allows a cometd subscription socket that forces the http socket to maintain barring any protocal violation so there are some cases where http sockets can be maintained but typically not.

    In this instance I think the OP should make some global variable for all his values and in a button push or even after a flag variable in define_program call his IP_CLIEN_OPEN so he can change the parameters on the fly. Port number, IP address, UPD/TCP and then in the debug window change the variables and then set his flag making sure that he immediately 0's that flag. In diagnostics watch what happens. Posting a link to the camera's api might help too so we can take a gander for ourselves.
  • I haven't had a chance to look at or interact here for a couple weeks, but I will still try to post my camera control code if you still want it.
  • I haven't had a chance to look at or interact here for a couple weeks, but I will still try to post my camera control code if you still want it.

    Yeap, it would be great!

    Also, I connected all the devices to another NI-3100. And that's it. Everything is working. Thank you!
    There are some problems with first NI-3100, maybe.
  • And one more question.
    In TP4 I noticed that there is a function called "Recieve from Panel". What does it mean? So can I recieve the compiled project and recover it?
    Also, I have an old compiled project in NetLinx. Can I recover old project from NI-3100 without source code?

    Thank you
  • ericmedleyericmedley Posts: 4,177
    And one more question.
    In TP4 I noticed that there is a function called "Recieve from Panel". What does it mean? So can I recieve the compiled project and recover it?
    Also, I have an old compiled project in NetLinx. Can I recover old project from NI-3100 without source code?

    Thank you


    Well, you can recover them in the sense that you can save the file and reinstall it if need be. But, without source, you cannot open/modify it in Netlinx Studio.
  • This is an awful lot of code and it might be hard to follow because AFAICT, I code rather differently than most, and use structures pretty extensively for data storage I also use "Reverse Lookups" to re-match logical DeviceID's to the ports the devices use. After looling at this, I think there may even be a bug in the code, in that the part in DEFINE_START might be trying to open the camera connections when it does not need to. The camera connections are, or should be, stateless: it opens the connection, sends the command, lets the connection close.
    DEFINE_DEVICE
      dvcam201 = 0:26:0 //Cam 1
    dvcam202 = 0:27:0 //Cam 2
    dvcam203 = 0:28:0 //Cam 3
    dvcam204 = 0:29:0 //Cam 4
    dvcam205 = 0:30:0 //Cam 5
     
      DEFINE_START
      //NOTE: device definition values are actually in an include file in place here, this is just one sample
      rm[1].d[26].status = 1 //ONLINE
    rm[1].d[26].dbid = 0 //
    rm[1].d[26].type = 7 //Panasonic Camera
    rm[1].d[26].commtype = 2 //IP
    rm[1].d[26].kind = "'c'" //Camera
    rm[1].d[26].c = 1 //Camera ID
    rm[1].d[26].name = "'Cam1'"
    rm[1].d[26].ipcomm[1].ipaddr = "'10.1.20.16'"
    rm[1].d[26].ipcomm[1].ipport = 80
    rm[1].d[26].ipcomm[1].devid = dvcam201
     
      
    for(tmp_idx1 = 1; tmp_idx1 <= 2; tmp_idx1++ ) {
       
        for(tmp_idx2 = 1; tmp_idx2 <= 32; tmp_idx2++) { //COMM DEVICE INITIALIZATION
     call 'debug' ("'INIT FOR Loop: RM:',itoa(tmp_idx1),'-',itoa(rm[tmp_idx1].status),' DID:',itoa(tmp_idx2),'-',itoa(rm[tmp_idx1].d[tmp_idx2].status),' COMMTYPE:',itoa(rm[tmp_idx1].d[tmp_idx2].commtype)")
     rm[tmp_idx1].d[tmp_idx2].buffout = "" //clear buffers on boot
     rm[tmp_idx1].d[tmp_idx2].buffin = "" //clear buffers on boot
     if(rm[tmp_idx1].status==1 && rm[tmp_idx1].d[tmp_idx2].status==1 && rm[tmp_idx1].d[tmp_idx2].commtype==2 ) { //Room is online, Device is online, Device is IP based
         call 'debug' ("'Opening Device: Room:',itoa(tmp_idx1),' Device:',itoa(tmp_idx2),' DevPort:',itoa(rm[tmp_idx1].d[tmp_idx2].ipcomm[1].devid.port),' IP:',rm[tmp_idx1].d[tmp_idx2].ipcomm[1].ipaddr,' IPPort:',itoa(rm[tmp_idx1].d[tmp_idx2].ipcomm[1].ipport)")
         ip_client_open(rm[tmp_idx1].d[tmp_idx2].ipcomm[1].devid.port,rm[tmp_idx1].d[tmp_idx2].ipcomm[1].ipaddr,rm[tmp_idx1].d[tmp_idx2].ipcomm[1].ipport,IP_TCP)
     }
        }
    }
     
      DATA_EVENT
      data_event[d_all] { //IP Based Devices
       onerror: { //generally only IP devices will have errors
     stack_var integer this_dev
     stack_var integer this_port
     stack_var integer this_rm
     stack_var integer this_did
     stack_var integer this_a
     stack_var integer this_c
     stack_var integer this_j
     stack_var integer this_p
     stack_var integer this_s
     stack_var integer this_v
     
     this_dev = data.device.number
     if(this_dev > 40 && this_dev < 100) { //Axcent slave, move DEV to PORT
         this_port = this_dev
     } else {
         this_port = data.device.port
     }
     this_rm = rlookup[this_port].rm
     this_did = rlookup[this_port].d
     this_a = rlookup[this_port].a
     this_c = rlookup[this_port].c
     this_j = rlookup[this_port].j
     this_p = rlookup[this_port].p
     this_s = rlookup[this_port].s
     this_v = rlookup[this_port].v
     
     call 'debug' ("'DATA EVENT - ERROR - Data.Device: Raw:',itoa(data.device.number),' Managed:',ITOA(this_dev)")
     call 'debug' ("'Data.Device.Port: Raw:',itoa(data.device.port),' Managed:',ITOA(this_port)")
     call 'debug' ("'DID:',itoa(this_did),' Aud:',itoa(this_a),' Cam:',ITOA(this_c),' Joy:',ITOA(this_j),' Proj:',ITOA(this_p),' Swt:',ITOA(this_s),' VC:',ITOA(this_v)")
    
     call 'debug' ("'Port error: RM:',itoa(this_rm),' DID:',itoa(this_did),' ERROR=',ITOA(Data.Number)")
     rm[this_rm].d[this_did].errorcount++
     call 'debug' ("'Error Count: ',itoa(rm[this_rm].d[this_did].errorcount)")
    
     if(data.number!=14&&rm[this_rm].d[this_did].errorcount<10) { // 14 is "port already open"
         if(!timeline_active((this_rm*1000)+(this_did*10)+5)) {
      call 'debug' ("'Starting Delayed Port Re-Open Sequence. ErrorCount:',itoa(rm[this_rm].d[this_did].errorcount)")
      timeline_create((this_rm*1000)+(this_did*10)+5,cmd[rm[this_rm].d[this_did].type].commtimeout,1,timeline_absolute,timeline_once) // Delayed Re-Open
         }
         else {
      call 'debug' ("'Multiple Port Errors, Delay Re-Open already in progress: RM:',itoa(this_rm),' DID:',itoa(this_did),' ERRORCOUNT',itoa(rm[this_rm].d[this_did].errorcount)")
         }
     }
     else if(data.number!=14&&rm[this_rm].d[this_did].errorcount>10) {
        
         call 'debug' ("'Persistent Device Error: RM:',itoa(this_rm),' DID:',itoa(this_did)")
         call 'debug' ("'Port closed, stays closed, submit trouble ticket'")
         // ip_client_close(rm[this_rm].d[this_did].ipcomm[1].devid.port) //force close port
        
         //call 'submittroubleticket' (this_rm,"'system'")
     }
        }
        online: { //All devices come online
     stack_var integer this_dev
     stack_var integer this_port
     stack_var integer this_rm
     stack_var integer this_did
     stack_var integer this_a
     stack_var integer this_c
     stack_var integer this_j
     stack_var integer this_p
     stack_var integer this_s
     stack_var integer this_v
    
     call 'debug' ("'PRE-LOAD DATA: DID:',itoa(this_did),' Aud:',itoa(this_a),' Cam:',ITOA(this_c),' Joy:',ITOA(this_j),' Proj:',ITOA(this_p),' Swt:',ITOA(this_s),' VC:',ITOA(this_v)")
     
     this_dev = data.device.number
     if(this_dev > 40 && this_dev < 100) { //Axcent slave, move DEV to PORT
         this_port = this_dev
     } else {
         this_port = data.device.port
     }
     this_rm = rlookup[this_port].rm
     this_did = rlookup[this_port].d
     this_a = rlookup[this_port].a
     this_c = rlookup[this_port].c
     this_j = rlookup[this_port].j
     this_p = rlookup[this_port].p
     this_s = rlookup[this_port].s
     this_v = rlookup[this_port].v
     
     call 'debug' ("'DATA EVENT - ONLINE - Data.Device: Raw:',itoa(data.device.number),' Managed:',ITOA(this_dev)")
     call 'debug' ("'DATA EVENT - ONLINE - Data.Device.Port: Raw:',itoa(data.device.port),' Managed:',ITOA(this_port)")
     call 'debug' ("'RLOOKUP DATA: DID:',itoa(this_did),' Aud:',itoa(this_a),' Cam:',ITOA(this_c),' Joy:',ITOA(this_j),' Proj:',ITOA(this_p),' Swt:',ITOA(this_s),' VC:',ITOA(this_v)")
    
     rm[this_rm].d[this_did].errorcount = 0
     call 'debug' ("'Error Count: ',itoa(rm[this_rm].d[this_did].errorcount)")
    
     call 'debug' ("'DEVICE ONLINE: RM:',itoa(this_rm),' DID:',itoa(this_did)")
    
     select {
         active(rm[this_rm].d[this_did].commtype==1): { //Serial Device
      call 'debug' ("'Setting Serial Parameters for device: RM:',itoa(this_rm),' DID:',itoa(this_did)")
      send_command data.device,"rm[this_rm].d[this_did].sercomm"
         }
         active(rm[this_rm].d[this_did].commtype==2): { //IP Device
      call 'debug' ("'IP Device Online:',itoa(this_rm),' DID:',itoa(this_did),' Send appropriate initialization strings...'")
         }
         active(rm[this_rm].d[this_did].commtype==3): { //IR Device
      call 'debug' ("'Setting IR CTON/CTOFF: RM:',itoa(this_rm),' DID:',itoa(this_did)")
      SEND_COMMAND DATA.DEVICE, "'CTON',2"
      SEND_COMMAND DATA.DEVICE, "'CTOF',2"
         }
         active(1): { //UN-TRAPPED ONLINE EVENT
      call 'debug' ("'UNTRAPPED DEVICE ONLINE EVENT:',itoa(this_rm),' DID:',itoa(this_did)")
         }
     }
    
     select {
         active(this_a>0): { //Audio Device
      call 'debug' ("'Audio device online: RM:',itoa(this_rm),' DID:',itoa(this_did),' AudioID:',itoa(this_a)")
         }
         active(this_c>0): { //Camera Device 
      call 'debug' ("'Camera Control Session Established: RM:',itoa(this_rm),' DID:',itoa(this_did),' CamID:',itoa(this_c)")
      call 'debug' ("'Setting IPCONNECT Value'")
      rm[this_rm].d[this_did].ipconnect = 1
         }
         active(this_p>0&&rm[this_rm].d[this_did].type==2): { //EPSON Projector
          call 'debug' ("'Projector coming online: RM:',itoa(this_rm),' DID:',itoa(this_did),' projID:',itoa(this_p)")
          call 'debug' ("'EPSON Projector, Sending Connect Header: ','ESC/VP.net',$10,$03,$00,$00,$00,$00")
          SEND_STRING rm[this_rm].d[this_did].ipcomm[1].devid,"'ESC/VP.net',$10,$03,$00,$00,$00,$00"
          rm[this_rm].d[this_did].buffout = "''" // clear command buffer
          call 'addcmd' (this_rm,this_did,cmd_pwrq)
          timeline_create(((this_rm*1000)+(this_did*10)+1),cmd[rm[this_rm].d[this_did].type].polltime,1,timeline_absolute,timeline_repeat)  //once-per-minute display auto-power check
         }
         active(this_j>0): { //Joystick Online
      call 'debug' ("'Joystick coming online: RM:',itoa(this_rm),' DID:',itoa(this_did),' JoyID:',itoa(this_j)")
         }
         active(this_p>0): { //other display
      call 'debug' ("'Non-epson display device online: RM:',itoa(this_rm),' DID:',itoa(this_did),' ProjID:',itoa(this_p)")
         }
         active(this_s>0): { //Switch Online
      call 'debug' ("'Switch coming online: RM:',itoa(this_rm),' DID:',itoa(this_did),' SwtID:',itoa(this_s)")
         }
         active(this_v>0): { //POLYCOM Online
      call 'debug' ("'Polycom coming online: RM:',itoa(this_rm),' DID:',itoa(this_did),' PolyID:',itoa(this_v)")
         }
         active(1): { //fall-thru
      call 'debug' ("'FALL-THRU TRAP Device Online: RM:',itoa(this_rm),' DID:',itoa(this_did)")
         }
     }
        }
        offline: {
     stack_var integer this_dev
     stack_var integer this_port
     stack_var integer this_rm
     stack_var integer this_did
     stack_var integer this_a
     stack_var integer this_c
     stack_var integer this_j
     stack_var integer this_p
     stack_var integer this_s
     stack_var integer this_v
     
     this_dev = data.device.number
     if(this_dev > 40 && this_dev < 100) { //Axcent slave, move DEV to PORT
         this_port = this_dev
     } else {
         this_port = data.device.port
     }
     this_rm = rlookup[this_port].rm
     this_did = rlookup[this_port].d
     this_a = rlookup[this_port].a
     this_c = rlookup[this_port].c
     this_j = rlookup[this_port].j
     this_p = rlookup[this_port].p
     this_s = rlookup[this_port].s
     this_v = rlookup[this_port].v
    
     call 'debug' ("'DATA EVENT - OFFLINE - Data.Device: Raw:',itoa(data.device.number),' Managed:',ITOA(this_dev)")
     call 'debug' ("'Data.Device.Port: Raw:',itoa(data.device.port),' Managed:',ITOA(this_port)")
     call 'debug' ("'DID:',itoa(this_did),' Aud:',itoa(this_a),' Cam:',ITOA(this_c),' Joy:',ITOA(this_j),' Proj:',ITOA(this_p),' Swt:',ITOA(this_s),' VC:',ITOA(this_v)")
    
     call 'debug' ("'Port error: RM:',itoa(this_rm),' DID:',itoa(this_did),' ERROR=',ITOA(Data.Number)")
     rm[this_rm].d[this_did].errorcount++
     call 'debug' ("'Error Count: ',itoa(rm[this_rm].d[this_did].errorcount)")
    
     if(data.number!=14&&rm[this_rm].d[this_did].errorcount<10&&rm[this_rm].d[this_did].c==0) { // 14 is "port already open"
         if(!timeline_active((this_rm*1000)+(this_did*10)+5)) {
      call 'debug' ("'Starting Delayed Port Re-Open Sequence. ErrorCount:',itoa(rm[this_rm].d[this_did].errorcount)")
      timeline_create((this_rm*1000)+(this_did*10)+5,cmd[rm[this_rm].d[this_did].type].commtimeout,1,timeline_absolute,timeline_once) // Delayed Re-Open
         }
         else {
      call 'debug' ("'Multiple Port Errors, Delay Re-Open already in progress: RM:',itoa(this_rm),' DID:',itoa(this_did),' ERRORCOUNT',itoa(rm[this_rm].d[this_did].errorcount)")
         }
     }
     else if(rm[this_rm].d[this_did].c==1) {
         call 'debug' ("'Camera Port Closing (NORMAL): RM:',itoa(this_rm),' DID:',itoa(this_did),' Cam:',itoa(this_c)")
    //     call 'debug' ("'Port Remains Closed for Device RM:',itoa(this_rm),' DID:',itoa(this_did)")
     }
    
     else if(data.number!=14&&rm[this_rm].d[this_did].errorcount>10) {
         call 'debug' ("'Persistent Device Error: RM:',itoa(this_rm),' DID:',itoa(this_did)")
         call 'debug' ("'Port Remains Closed for Device RM:',itoa(this_rm),' DID:',itoa(this_did)")
     }
    
     select {
         active(this_c>0): { //Camera Device 
      call 'debug' ("'Camera Control Session Complete: RM:',itoa(this_rm),' DID:',itoa(this_did),' CamID:',itoa(this_c)")
      call 'debug' ("'Clearing IPCONNECT Value'")
      rm[this_rm].d[this_did].ipconnect = 0
         }
     }
        }
        string: {
     stack_var integer this_dev
     stack_var integer this_port
     stack_var integer this_rm
     stack_var integer this_did
     stack_var integer this_a
     stack_var integer this_c
     stack_var integer this_j
     stack_var integer this_p
     stack_var integer this_s
     stack_var integer this_v
     
     this_dev = data.device.number
     if(this_dev > 40 && this_dev < 100) { //Axcent slave, move DEV to PORT
         this_port = this_dev
     } else {
         this_port = data.device.port
     }
     this_rm = rlookup[this_port].rm
     this_did = rlookup[this_port].d
     this_a = rlookup[this_port].a
     this_c = rlookup[this_port].c
     this_j = rlookup[this_port].j
     this_p = rlookup[this_port].p
     this_s = rlookup[this_port].s
     this_v = rlookup[this_port].v
     
     call 'debug' ("'DATA EVENT - STRING - Data.Device: Raw:',itoa(data.device.number),' Managed:',ITOA(this_dev)")
     call 'debug' ("'Data.Device.Port: Raw:',itoa(data.device.port),' Managed:',ITOA(this_port)")
     call 'debug' ("'DID:',itoa(this_did),' Aud:',itoa(this_a),' Cam:',ITOA(this_c),' Joy:',ITOA(this_j),' Proj:',ITOA(this_p),' Swt:',ITOA(this_s),' VC:',ITOA(this_v)")
    
     call 'debug' ("'Data From Device: RM:',itoa(this_rm),' DID:',itoa(this_did),' Port:',itoa(data.device.port),' - ',data.text")
    
     call 'debug' ("'Adding Data to Buffer: RM:',itoa(this_rm),' DID:',itoa(this_did),' Data:',data.text")
     call 'debug' ("'Buffer Before:',rm[this_rm].d[this_did].buffin")
     rm[this_rm].d[this_did].buffin = "rm[this_rm].d[this_did].buffin,data.text"
     call 'debug' ("'Buffer After:',rm[this_rm].d[this_did].buffin")
        }
    }
     
      //Camera control
    button_event[dvtp_camera,btnset_cam] { //up
        push: {
     stack_var integer this_rm
     stack_var integer this_did
     stack_var integer this_btn
     stack_var integer this_c
     this_rm = tprm(button.input.device.number)
    
     this_c = rm[this_rm].p[11].feed - 8 /// gets current camera selection
     this_did = rm[this_rm].c[this_c].did /// gets current camera DID
    
     this_btn = button.input.channel
    
     call 'debug' ("'Camera Push Control: RM:',itoa(this_rm),' DID:',itoa(this_did),' CAM:',itoa(this_c),' Btn:',itoa(this_btn)")
    
     select {
         active(this_btn==1): {
      call 'debug' ("'Tilt Up (Push) RM:',itoa(this_rm),' DID:',itoa(this_did),' CAM:',itoa(this_c),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#T60&res=1'"
         }
         active(this_btn==2): {
      call 'debug' ("'Tilt Down (Push) RM:',itoa(this_rm),' CAM:',itoa(this_did),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#T40&res=1'"
         }
         active(this_btn==3): {
      call 'debug' ("'Pan Left (Push) RM:',itoa(this_rm),' DID:',itoa(this_did),' CAM:',itoa(this_c),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#P40&res=1'"
         }
         active(this_btn==4): {
      call 'debug' ("'Pan Right (Push) RM:',itoa(this_rm),' DID:',itoa(this_did),' CAM:',itoa(this_c),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#P60&res=1'"
         }
         active(this_btn==5): {
      call 'debug' ("'Zoom IN (Push) RM:',itoa(this_rm),' DID:',itoa(this_did),' CAM:',itoa(this_c),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#Z60&res=1'"
         }
         active(this_btn==6): {
      call 'debug' ("'Zoom OUT (Push) RM:',itoa(this_rm),' CAM:',itoa(this_did),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#Z40&res=1'"
         }
         active(this_btn==7): {
      call 'debug' ("'Focus IN (Push) RM:',itoa(this_rm),' CAM:',itoa(this_did),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'F40&res=1'"
         }
         active(this_btn==8): {
      call 'debug' ("'Focus OUT (Push) RM:',itoa(this_rm),' CAM:',itoa(this_did),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#F60&res=1'"
         }
         active(this_btn==9): {
      call 'debug' ("'Auto Focus (Push) RM:',itoa(this_rm),' CAM:',itoa(this_did),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#D1&res=1'"
         }
     }
        call 'debug' ("'Current Buffer: RM:',itoa(this_rm),' DID:',itoa(this_did),' CAM:',itoa(this_btn),' Buffer:',rm[this_rm].d[this_did].buffout")
        }
        hold[11]: {
     stack_var integer this_rm
     stack_var integer this_did
     stack_var integer this_btn
     stack_var integer this_c
     this_rm = tprm(button.input.device.number)
    
     this_c = rm[this_rm].p[11].feed - 8 /// gets current camera selection
     this_did = rm[this_rm].c[this_c].did /// gets current camera DID
    
     this_btn = button.input.channel
    
     call 'debug' ("'Camera Hold Control: RM:',itoa(this_rm),' DID:',itoa(this_did),' CAM:',itoa(this_c),' Btn:',itoa(this_btn)")
    
     select {
         active(this_btn==1): {
      call 'debug' ("'Tilt Up (Hold) RM:',itoa(this_rm),' CAM:',itoa(this_did),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#T90&res=1'"
         }
         active(this_btn==2): {
      call 'debug' ("'Tilt Down (Hold) RM:',itoa(this_rm),' CAM:',itoa(this_did),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#T10&res=1'"
         }
         active(this_btn==3): {
      call 'debug' ("'Pan Left (Hold) RM:',itoa(this_rm),' CAM:',itoa(this_did),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#P10&res=1'"
         }
         active(this_btn==4): {
      call 'debug' ("'Pan Right (Hold) RM:',itoa(this_rm),' CAM:',itoa(this_did),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#P90&res=1'"
         }
         active(this_btn==5): {
      call 'debug' ("'Zoom IN (Hold) RM:',itoa(this_rm),' CAM:',itoa(this_did),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#Z90&res=1'"
         }
         active(this_btn==6): {
      call 'debug' ("'Zoom OUT (Hold) RM:',itoa(this_rm),' CAM:',itoa(this_did),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#Z10&res=1'"
         }
         active(this_btn==7): {
      call 'debug' ("'Focus IN (Hold) RM:',itoa(this_rm),' CAM:',itoa(this_did),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#F10&res=1'"
         }
         active(this_btn==8): {
      call 'debug' ("'Focus OUT (Hold) RM:',itoa(this_rm),' CAM:',itoa(this_did),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#F90&res=1'"
         }
         active(this_btn==9): {
      call 'debug' ("'Auto Focus (Hold) RM:',itoa(this_rm),' CAM:',itoa(this_did),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#D1&res=1'"
         }
     }
        call 'debug' ("'Current Buffer: RM:',itoa(this_rm),' DID:',itoa(this_did),' CAM:',itoa(this_btn),' Buffer:',rm[this_rm].d[this_did].buffout")
        }
        release: {
     stack_var integer this_rm
     stack_var integer this_did
     stack_var integer this_btn
     stack_var integer this_c
     this_rm = tprm(button.input.device.number)
    
     this_c = rm[this_rm].p[11].feed - 8 /// gets current camera selection
     this_did = rm[this_rm].c[this_c].did /// gets current camera DID
    
     this_btn = button.input.channel
    
     call 'debug' ("'Camera Release Control: RM:',itoa(this_rm),' DID:',itoa(this_did),' CAM:',itoa(this_c),' Btn:',itoa(this_btn)")
    
     select {
         active(this_btn==1||this_btn==2): { //stop all tilt
      call 'debug' ("'STOP Tilt RM:',itoa(this_rm),' CAM:',itoa(this_did),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#T50&res=1'"
         }
         active(this_btn==3||this_btn==4): { //stop all pan
      call 'debug' ("'STOP Pan RM:',itoa(this_rm),' CAM:',itoa(this_did),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#P50&res=1'"
         }
         active(this_btn==5||this_btn==6): { //stop all zoom
      call 'debug' ("'STOP Zoom RM:',itoa(this_rm),' CAM:',itoa(this_did),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#Z50&res=1'"
         }
         active(this_btn==7||this_btn==8): { //stop all focus
      call 'debug' ("'STOP Focus RM:',itoa(this_rm),' CAM:',itoa(this_did),' Btn:',itoa(this_btn)")
      rm[this_rm].d[this_did].buffout = "rm[this_rm].d[this_did].buffout,'#F50&res=1'"
         }
     }
        }
    }
     
      DEFINE_PROGRAM
      //Cams RM 2
    while(find_string(rm[2].d[26].buffout,"'res=1'",1)&&!timeline_active(2263)) { //command in buffer
        timeline_create(2263,cmd[rm[2].d[26].type].commtimeout,1,timeline_absolute,timeline_once) // response limit timer144
    //    call 'debug' ("'Processing Camera Control Command RM:2 DID:26 CAM:1 Buffer:',rm[2].d[26].buffout")
        rm[2].d[26].ipdone = 0
        rm[2].d[26].lastacmd = remove_string(rm[2].d[26].buffout,"'res=1'",1)
        ip_client_open( rm[2].d[26].ipcomm[1].devid.port , rm[2].d[26].ipcomm[1].ipaddr , 80,1)//80=port,1=TCP
        call 'debug' ("'Opening Campera IP Connection...'")
        wait_until(rm[2].d[26].ipconnect==1) { //set to 1 in online data event, 0 in offline event
     send_string rm[2].d[26].ipcomm[1].devid,"'GET /cgi-bin/aw_ptz?cmd=#',rm[2].d[26].lastacmd,$0D,$0A"
    // call 'debug' ("'Cam Command Submit: ','GET /cgi-bin/aw_ptz?cmd=#',rm[2].d[26].lastacmd,$0D,$0A")
        }
    }
    while( length_string( rm[2].d[26].buffin ) > 0 && rm[2].d[26].ipconnect == 0 ) {
    //    call 'debug' ("'Cam Response Processing, Original Command: ', rm[2].d[26].lastacmd ")
        call 'camresponseparser' ( 2, 26, "rm[2].d[26].buffin" )
        rm[2].d[26].buffin = "''"
        rm[2].d[26].ipdone = 1
        timeline_kill(2263) //
    }
    
    If you've got questions about the code, I'll do my best to explain.
  • John NagyJohn Nagy Posts: 1,734
    And one more question.
    In TP4 I noticed that there is a function called "Recieve from Panel". What does it mean? So can I recieve the compiled project and recover it?
    Also, I have an old compiled project in NetLinx. Can I recover old project from NI-3100 without source code?

    That's 2...
    1. Yes. As the onboard HELP in TPDesign will explain. You connect to the panel, click that button, and pick the filename and location. And the result is completely editable.
    2. As Eric says, all you can get is what's in it... if there is no source code loaded in the NI, you can only get the TKN for reuse, not editable.

    To get the TKN, you can't use typical FTP clients, as the stored program "prog.tkn' is in a hidden folder.
    Open a command (DOS) window... here's a session: YOUR INPUT IS BOLD and explanation is in green italic (don't type the explanation into the session!)

    Microsoft Windows [Version 6.1.7601]
    Copyright (c) 2009 Microsoft Corporation. All rights reserved.

    C:\Users\John.Junior>ftp 192.168.1.201 [you type ftp and the IP of the NetLinx]
    Connected to 192.168.1.201.
    220 VxWorks (VxWorks 6.3) FTP server ready
    User (192.168.1.201 : (none)): administrator [user and password of the NI. Default is "administrator" and "password"]
    331 Password required
    Password: [password does not echo]
    230 User logged in
    ftp> binary [set mode by typing "binary"]
    200 Type set to I, binary mode
    ftp> get ../prog.tkn d:/extractedcode.tkn [this is the meat. Choose the location to write the file, here, on the root of D]
    200 Port set okay
    150 Opening BINARY mode data connection [it can take a minute here... be patient]
    226 Transfer complete
    ftp: 13874097 bytes received in 6.83Seconds 2032.54Kbytes/sec.
    ftp> quit [and.... we're out.]
    221 Bye...see you later

    C:\Users\John.Junior>
  • Maybe I missed something in the discussion, but TELNET is port 23, not port 80 - which is HTTP.


    As mentioned earlier, HTTP (port 80) should only be opened and closed with each command.


    But if you are after TELNET, you can open and maintain the port (in theory).


    Anyway, just my two cents. I keep seeing TELNET discussed, but port 80 is not TELNET.


    Lastly, this - ///
    'the telnet responce is:
    Code:

    Device Name dvPAN is invalid
    ///


    Does not make much sense. The receiving device should never see the text 'dvPAN' (and it certainly can't if you're trying the wrong port).


    The text 'dvPAN' is local to the program in Netlinx only. It never gets transmitted (unless it's part of you %command% variable).
    Therefore, it has to be Netlinx reporting that error, which would mean the reference (dvPAN) is incorrect.



    Bottomline, get on the right port first.. change 80 to 23 if TELNET is what you really want. But if it's HTTP on port 80 that you need, you have a bigger fish to fry.
Sign In or Register to comment.