Our full technical support staff does not monitor this forum. If you need assistance from a member of our staff, please submit your question from the Ask a Question page.


Log in or register to post/reply in the forum.

Querying a TCP Socket / calling a HttpGet on a CR300 Datalogger


Alex Tower Nov 13, 2018 03:44 AM

Hi,

I'm trying to query(read from) a TCP Socket or to query a server via an HTTPRequest with no success.

 My cr300 code cof TCP socket reading:

TCPOpen (TCPServerIP,TCPServerPort,0,5000,SigfoxCheckHandle,1)
CheckMessage = "###STATUS:" + Status.StationName
SerialOut(SigfoxCheckHandle,CheckMessage,"",0,0)
NBytesAvailable = SerialInChk(SigfoxCheckHandle)
SerialInRecord (SigfoxCheckHandle,CheckResponse,43,0,33,NBytesReturned,01)

 My server Node.JS code:

 

if (stringPayload.startsWith('###')) { 
var campbellMessage = parseCampbellScientificSegment(stringPayload); JSON.stringify(campbellMessage); 
console.log("sending ack to check message"); 
socket.write('+SACK:0001!');
}); }

 

My server Node.JS logs

11/13/2018 11:25:02 AM10.42.196.98 said (string): ###STATUS:79BC31,11548,011.000,CR300-CELL200.Std.07.05,CPU:postIoT_CS475A_modbus.CR300,12.25803,28.6075411/13/2018 11:25:02 AMSuccessfully retrieved device DataLogger Campbell Scientific 79BC3111/13/2018 11:25:02 AMsending ack to check message

But I receive nothing (NAN) in the CheckResponse variable.

NBytesReturned is 0 and NBytesAvailble is -1

If I try to communicate via HttpGet I have nosuccess either:

  HGetHeader = "Content-Type:application/json" + CHR(13)+CHR(10)+ "Authorization:Basic my_password_base64_encoded" + CHR(13)+CHR(10)
  GetHttpUrl =  "https://<my domain>/campbellscientific-sigfox/checkSigfoxDevice?deviceId=" + Status.StationName
  HGetHandle = HTTPGet(GetHttpUrl,HGetResponse,HGetHeader,500)

 

The same GET requests succeeds in Postman (200OK) but on my CR300 I receive an error

failed to connect on port 443: Routing problem

The url is exacly the same...

Could you please help?

Kind regards, Alessandro


Alex Tower Nov 13, 2018 05:36 AM

In fact, calling any https address (like for instance https://api.ipify.org/) fails. Why?


GTProdMgr Nov 13, 2018 10:49 AM

If you want the CR300 to "call out" to an HTTPS (TLS-based, secure socket) URL location, then the "Max TLS Server Connections" setting needs to be non-zero. Connect to the datalogger in DevConfig, choose the TLS tab from the Deployment tab and set the "Max TLS Server Connections" setting to something like 5 (and then apply, etc.). You might be able to get it to work with a value like 3, but I would start with 5.

If external clients are going to "call in" to the CR300 using an HTTPS URL, you need to "set/check" the "HTTPS Enabled" checkbox in the Network Services tab on the Deployment tab in DevConfig. And of course, if external clients are calling in to the CR300 using HTTP, then the "HTTP Enabled" checkbox needs to be checked/set as well.

Try all of this first. If that doesn't work we can dig deeper into your socket/serial instructions.


Alex Tower Nov 14, 2018 02:32 AM

As you suggested, I changed the "Max TLS Server Connections" setting to 5.

Still getting the same Http comms Error on https:

HGetHandle = HTTPGet("https://api.ipify.org",HGetResponse,"")

 

09:30:00.00 HTTP api.ipify.org Port: 443
09:30:00.20 HTTP connected : api.ipify.org
09:30:00.20 GET / HTTP/1.1
User-Agent: CR300-CELL200.Std.07.05
Host: api.ipify.org

09:30:00.20 HTTP read_line_cmp error: -1
09:30:00.20 HTTP done
09:30:00.20 delete_socketclose
09:30:00.21 HTTP client closed.
09:30:00.37 Recv2
09:30:00.37 Closing handle 115. Connection reset.
09:30:01.23 Recv1 len 12
09:30:03.03 Recv1 len 8
09:30:05.65 Recv1 len 36
09:30:09.21 Recv1 len 12
09:31:03.65 Recv1 len 12


GaryTRoberts Nov 14, 2018 12:18 PM

Using this example program:

 

Public battery_voltage
Public http_header As String * 300
Public http_response As String * 1000
Public http_socket As Long
Public panel_temperature


'Define Data Tables.
DataTable (Test, 1, -1) 
	Sample (1, battery_voltage, FP2)
	Sample (1, panel_temperature, FP2)
EndTable

'Main Program
BeginProg
	Scan (1, Sec, 0, 0)
		PanelTemp (panel_temperature, _60Hz)
		Battery (battery_voltage)
		CallTable Test
	NextScan
	SlowSequence
	  Scan(2, Min, 0, 0)
	    http_header = ""
	    http_socket = HTTPGet("https://api.ipify.org/?format=json", http_response, http_header)
	  NextScan
	EndSequence
EndProg

 

I am able to get a response without issue from api.ipify.org. I am using OS 07.05. I am using the default setting of 0 for Max TLS Server Connections as this setting is only used when the datalogger is acting as the HTTPS server. In my example program, the datalogger is acting as a HTTPS client so the Max TLS Server Connections setting is ignored.

Can you post your entire program and tell us if you are using a CR310 or a CR300 connected to a modem? If you are using a cellular modem, is the modem in PPP mode or serial server mode or is the modem a Campbell Scientific internal modem (ie. CR300-CELL210)?


Alex Tower Nov 15, 2018 02:24 AM

Hi,

my station's OS version is CR300-CELL200.Std.07.05.

I executed your program and got the same error Http comms Error, so same behavior as I have with my program.

Here is my entire program, I'm replacing my https server call with the ipify url and masking the TCPServerIP address for confidentiality:

 

'CR300 Series
'Created by Short Cut (4.0)

'Declare Variables and Units

Const DistanceArraySize = 2
Const RainMmArraySize = 3
Const SlowScanSigfoCheckInterval = 6
Const SlowScanCS650Interval = 12
Const SlowScanCS475Interval = 6
Const SlowScanKalyxRGInterval = 4
Const SlowScanMain = SlowScanKalyxRGInterval
Const SlowScanSigfoxInterval = 12
Const TCPServerIP = "*****************"
Const TCPServerPort = 9095

Public CellularActive
Public SigfoxMode
Public HGetHeader As String * 200
Public HGetResponse As String * 200
Public GetHttpUrl As String * 200
Public HGetHandle

Public BattV
Public PTemp_C
Public CS475(4)
Public Rain_mm
Public CS650(6)
Public CS650_2(6)
Public ModbusData(7) As Long
Public Result = -1
Public Handle_Kalyx As Long
Public Handle_CS650 As Long
Public Handle_CS475 As Long
Public snd_msg_Kalyx As String * 255
Public snd_msg_2_Kalyx As String * 255
Public snd_msg_CS650 As String * 255
Public snd_msg_2_CS650 As String * 255
Public snd_msg_3_CS650 As String * 255
Public snd_msg_CS475 As String * 255
Public snd_msg_2_CS475 As String * 255
Public DistanceArray(DistanceArraySize)
Public CS475Counter = 1
Public RainMmArray(RainMmArraySize)
Public KalyxCounter = 1
Public SigfoxModeSwitchCounter = 1

Alias CS475(1)=Stage
Alias CS475(2)=Distance
Alias CS475(3)=BattV_CS475A
Alias CS475(4)=Error_Code
Alias CS650(1)=VWC
Alias CS650(2)=EC
Alias CS650(3)=T
Alias CS650(4)=P
Alias CS650(5)=PA
Alias CS650(6)=VR

Alias CS650_2(1)=VWC_2
Alias CS650_2(2)=EC_2
Alias CS650_2(3)=T_2
Alias CS650_2(4)=P_2
Alias CS650_2(5)=PA_2
Alias CS650_2(6)=VR_2

Units BattV=Volts
Units PTemp_C=Deg C
Units Rain_mm=mm
Units Stage=meter
Units Distance=meter
Units BattV_CS475A=Volts
Units Error_Code=Code
Units VWC=m^3/m^3
Units EC=dS/m
Units T=Deg C
Units P=unitless
Units PA=nSec
Units VR=unitless

'Define Data Tables
DataTable(CS475A,True,-1)
  DataInterval(0,SlowScanCS475Interval,Min,0)
  Sample(1,Stage,FP2)
  Sample(1,Distance,FP2)
  Sample(1,BattV_CS475A,FP2)
  Sample(1,Error_Code,FP2)
EndTable

DataTable(Kalyx,True,-1)
  DataInterval(0,SlowScanKalyxRGInterval,Min,10)
  Totalize(1,Rain_mm,FP2,False)
EndTable

DataTable(CS650,True,-1)
  DataInterval(0,SlowScanCS650Interval,Min,0)
  Sample(1,VWC,FP2)
  Sample(1,EC,FP2)
  Sample(1,T,FP2)
  Sample(1,P,FP2)
  Sample(1,PA,FP2)
  Sample(1,VR,FP2)
EndTable

DataTable(CS650_2,True,-1)
  DataInterval(0,SlowScanCS650Interval,Min,0)
  Sample(1,VWC_2,FP2)
  Sample(1,EC_2,FP2)
  Sample(1,T_2,FP2)
  Sample(1,P_2,FP2)
  Sample(1,PA_2,FP2)
  Sample(1,VR_2,FP2)
EndTable


DataTable(System,True,-1)
  DataInterval(0,1,Hr,0)
  Maximum(1,BattV,FP2,False,True)
  Maximum(1,PTemp_C,FP2,False,True)
  Minimum(1,BattV,FP2,False,True)
  Minimum(1,PTemp_C,FP2,False,True)
  Sample(1,Status.OSVersion,IEEE4)
  Sample(1,Status.SerialNumber,IEEE4)
  Sample(1,Status.StartTime,IEEE4)
  Sample(1,Status.StationName,IEEE4)
  Sample(1,Status.RunSignature,IEEE4)
  Sample(1,Status.ProgSignature,IEEE4)
  Sample(1,Status.LithiumBattery,IEEE4)
  Sample(1,Status.SkippedScan,IEEE4)
EndTable


'Main Program
BeginProg

  'Switch on Sigfox modem and wait 5 seconds to start main program
  SW12(1)
  Delay(0,5,Sec)

  'Main Scan (Battery, Panel Temp check and Bucket Rain Gauge reading)
  Scan (SlowScanMain,min,1,0)

    'Default CR300 Datalogger Battery Voltage measurement 'BattV'
    Battery(BattV)
    'Default CR300 Datalogger Processor Temperature measurement 'PTemp_C'
    PanelTemp(PTemp_C,50)

    'Kalyx Bucket Rain Gauge measurement 'Rain_mm'
    PulseCount(Rain_mm,1,P_SW,2,0,0.2,0)
    RainMmArray(KalyxCounter) = Rain_mm
    If KalyxCounter = RainMmArraySize Then
      KalyxCounter = 1
    Else
      KalyxCounter = KalyxCounter +1
    EndIf

    'Call Data Tables and Store Data
    CallTable System
    CallTable Kalyx

    If CellularActive Then
      TCPOpen (TCPServerIP,TCPServerPort,0,5000,Handle_Kalyx,1)
      snd_msg_Kalyx = "***STATUS:" + Status.StationName + "," + Status.SerialNumber + "," + Status.RevBoard + "," + Status.OsVersion +  "," + Status.ProgName + "," + Status.Battery + "," + Status.PanelTemp
      snd_msg_2_Kalyx = ",KALYXRG:"  + Rain_mm + "," + Kalyx.TimeStamp
      SerialOut(Handle_Kalyx,snd_msg_Kalyx + snd_msg_2_Kalyx,"",0,0)
      TCPClose(Handle_Kalyx)
    EndIf
  NextScan

  'SlowSequence (1) Radar Water Level reading
  SlowSequence
  Scan(SlowScanCS475Interval,Min,1,0)

    'CS475A Radar Water Level Sensor (stage) measurements 'Stage', 'Distance', 'BattV_CS475A' and, 'Error_Code'
    SDI12Recorder(CS475(),C1,"0","M!",1,0,-1)
    DistanceArray(CS475Counter) = Distance
    If CS475Counter = DistanceArraySize Then
      CS475Counter = 1
    Else
      CS475Counter = CS475Counter +1
    EndIf

    'Call Data Tables and Store Data
    CallTable CS475A
    If BattV_CS475A > 0 Then
      If CellularActive Then
        TCPOpen (TCPServerIP,TCPServerPort,0,5000,Handle_CS475,1)
        snd_msg_CS475 = "***STATUS:" + Status.StationName + "," + Status.SerialNumber + "," + Status.RevBoard + "," + Status.OsVersion +  "," + Status.ProgName + "," + Status.Battery + "," + Status.PanelTemp
        snd_msg_2_CS475 = ",CS475A:"  + BattV_CS475A + "," + Distance + "," + Stage + "," + Error_Code  + "," + CS475A.TimeStamp
        SerialOut(Handle_CS475,snd_msg_CS475 + snd_msg_2_CS475,"",0,0)
        TCPClose(Handle_CS475)
      EndIf
    EndIf
  NextScan

  'SlowSequence (2) Sigfox transmission
  SlowSequence
  Scan (SlowScanSigfoxInterval,min,1,0)
    If NOT CellularActive Then
      If BattV_CS475A > 0 Then
        SigfoxMode = &B00
        ModbusData(1)= Round(DistanceArray(1),2) * 100
        ModbusData(2)= Round(DistanceArray(2),2) * 100
        ModbusData(3)= Error_Code
        ModbusData(4)= Round(BattV_CS475A,2) * 100
        ModbusData(5)= Round(PTemp_C,2) * 100
        ModbusData(6)= Round(BattV,2) * 100 * 4 + SigfoxMode
      Else
        ModbusData(1)= Round(RainMmArray(1),2) * 100
        ModbusData(2)= Round(RainMmArray(2),2) * 100
        ModbusData(3)= Round(RainMmArray(3),2) * 100
        ModbusData(4)= Round(EC,3) * 1000
        ModbusData(5)= Round(EC_2,3) * 1000

        If SigfoxModeSwitchCounter = 2 Then
          SigfoxMode = &B10
          ModbusData(6)= Round(BattV,2) * 100 * 4 + SigfoxMode
          SigfoxModeSwitchCounter = 1
        Else
          SigfoxMode = &B01
          ModbusData(6)= Round(PTemp_C,2) * 100 * 4 + SigfoxMode
          SigfoxModeSwitchCounter = SigfoxModeSwitchCounter +1
        EndIf
      EndIf

      ModbusData(7)= 1 'Send to Sigfox
      ModbusMaster (Result,COMRS232,19200,1,16,ModbusData(),60001,7,3,120,3)
    EndIf
  NextScan

  'SlowSequence (3) Sigfox check today transmissions
  SlowSequence
  Scan (SlowScanSigfoCheckInterval,min,1,0)
    HGetHeader = "Authorization:Basic ***********************" + CHR(13)+CHR(10)
    GetHttpUrl =  "*********************?deviceId=" + Status.StationName
    HGetHandle = HTTPGet("https://api.ipify.org",HGetResponse,"")
    If HGetResponse = "KO" Then
      CellularActive = True
      SW12(0) 'Switch Modem sigfox off
    ElseIf HGetResponse  = "OK" Then
      CellularActive = False
      SW12(1) 'Switch Modem sigfox on
    EndIf
  NextScan

  'SlowSequence (4) Water Content Reflectometer reading
  SlowSequence
  Scan (SlowScanCS650Interval,min,1,0)
    'CS650/655 Water Content Reflectometer measurements 'VWC', 'EC', 'T','P', 'PA', and 'VR'
    SDI12Recorder(CS650(),C2,"0","M4!",1,0,-1)
    SDI12Recorder(CS650_2(),C2,"1","M4!",1,0,-1) 'second sensor
    CallTable CS650
    CallTable CS650_2

    If CellularActive Then
      TCPOpen (TCPServerIP,TCPServerPort,0,5000,Handle_CS650,1)
      snd_msg_CS650 = "***STATUS:" + Status.StationName + "," + Status.SerialNumber + "," + Status.RevBoard + "," + Status.OsVersion +  "," + Status.ProgName + "," + Status.Battery + "," + Status.PanelTemp
      snd_msg_2_CS650 = ",CS650:"  + VWC  + "," + EC + "," + T + "," + P +  "," + PA +  "," + VR  + "," + CS650.TimeStamp
      snd_msg_3_CS650 = ",CS650_2:" + VWC_2  + "," + EC_2 + "," + T_2 + "," + P_2 +  "," + PA_2 +  "," + VR_2 + "," + CS650_2.TimeStamp
      SerialOut(Handle_CS650,snd_msg_CS650 + snd_msg_2_CS650 + snd_msg_3_CS650,"",0,0)
      TCPClose(Handle_CS650)
    EndIf
  NextScan
EndProg

 

Log in or register to post/reply in the forum.