Compare commits

..

2 Commits

Author SHA1 Message Date
96725c1fb0 Update README 2026-03-06 17:07:25 -05:00
fdc364ef1d Update README 2026-03-06 17:04:27 -05:00
8 changed files with 200 additions and 522 deletions

10
.gitignore vendored
View File

@@ -1,10 +0,0 @@
################################################################################
# This .gitignore file was automatically created by Microsoft(R) Visual Studio.
################################################################################
/.vs
/prjOnRampAPI/.vs/prjOnRampAPI
/prjOnRampAPI/prjOnRampAPI/obj
/prjOnRampAPI/obj
/prjOnRampAPI/bin/Debug/net8.0
/prjOnRampAPI/.vs/ProjectEvaluation

200
README Normal file
View File

@@ -0,0 +1,200 @@
# OnRamp SDK
The **OnRamp SDK** provides supported libraries for integrating external applications with the OnRamp platform.
Current capabilities include:
* Accessing the **OnRamp API**
* Receiving **real-time Shop Monitor events** via WebSockets
* Running **registered OnRamp API queries**
The SDK is distributed via **NuGet** to allow deterministic versioning and updateable integrations.
This approach enables applications to interact with OnRamp **without requiring direct database access**, which is particularly important for hosted or cloud environments.
---
# Installation
Add the OnRamp SDK NuGet repository:
```bash
dotnet nuget add source https://git.onramp-solutions.com/api/packages/OnRampSDK/nuget/index.json --name onrampsdk
```
After adding the source, packages will be available under:
```
Package Source: onrampsdk
```
Packages can then be installed using standard NuGet workflows in Visual Studio or via the .NET CLI.
---
# Overview
Applications integrating with OnRamp typically perform the following steps:
1. Connect to the **OnRamp API**
2. Connect to the **OnRamp WebSocket service**
3. Register a **Socket ID**
4. Receive **Shop Monitor events**
5. Execute **API queries** to retrieve or process related data
Incoming WebSocket messages function similarly to **interrupt events**. They are delivered with minimal latency when Shop Monitor activity occurs.
Example event types include:
* Work Order Login
* Work Order Logout
* Cycle Start
* Cycle Complete
* Device button events
Applications can respond to these events by retrieving additional information through the OnRamp API.
---
# Example Architecture
A typical implementation:
* Launches an application (console app, service, or background process)
* Connects to the OnRamp API
* Establishes a WebSocket connection
* Registers a **Socket ID**
* Waits indefinitely for incoming Shop Monitor events
The application remains active and processes events until it is terminated.
Multiple deployment models are possible:
* A **single application handling all devices**
* Applications **per device**
* Applications **per event type**
---
# Shop Monitor Integration
Shop Monitor devices trigger events through a configured **Socket ID**.
To configure a device:
1. Open **S1280 Device Shop Monitor**
2. Set the **Process ID / Socket ID** to the value expected by the application
3. The application registers with this same Socket ID
Any application listening with that Socket ID will receive the event messages.
---
# API Queries
API queries must be registered in:
```
S5011 API Queries
```
Supported query types:
* `SELECT`
* `UPDATE`
In most integrations, **SELECT queries are sufficient**. UPDATE queries should be used cautiously.
---
# Query Parameters
Queries use **Handlebars-style parameters**.
Example:
```sql
SELECT woo_oper, woo_qty_rep
FROM wo_oper
WHERE woo_nbr = '{{p:wonum}}'
```
`p:wonum` is a parameter passed by the client application.
---
# Example Query Execution
Example code for executing a query through the API:
```vb
' Get all operations for a work order
Dim allOpsArgs As New Dictionary(Of String, String)
allOpsArgs.Add("wonum", woNum)
' QL-10000006
Dim rstDataAllOps = api.runQuery("QL-10000006", allOpsArgs)
If rstDataAllOps.RecordCount > 0 Then
Do Until rstDataAllOps.EOF
Console.WriteLine(rstDataAllOps("woo_oper") + " - QtyRep:" & rstDataAllOps("woo_qty_rep"))
rstDataAllOps.MoveNext()
Loop
End If
```
The returned result set exposes a familiar **recordset-style interface**, allowing iteration using:
* `RecordCount`
* `EOF`
* `MoveNext()`
* Column access via field name
---
# Query Performance Recommendations
For optimal performance:
* Avoid returning very large datasets
* Do not use `SELECT *`
* Specify explicit column names
* Limit queries to only the data required by the application
Example (recommended):
```sql
SELECT pt_part, pt_desc
FROM pt_mstr
```
Example (not recommended):
```sql
SELECT *
FROM pt_mstr
```
---
# Use Cases
Common uses for the SDK include:
* Shop Monitor automation
* Production event processing
* Device integrations
* External analytics services
* Integration with external systems
* Cloud-hosted integrations where database access is unavailable
---
# Future Expansion
The SDK is designed to support additional OnRamp platform integration capabilities over time, including:
* Additional event channels
* Extended API functionality
* Additional integration services

247
README.md
View File

@@ -1,247 +0,0 @@
# OnRamp SDK
The **OnRamp SDK** provides supported libraries for integrating external applications with the **OnRamp platform**.
The SDK allows applications to interact with OnRamp **without requiring direct database access**, enabling integrations for:
- hosted environments
- cloud deployments
- external services
- device integrations
The SDK is distributed via **NuGet** to provide deterministic versioning and controlled upgrades.
---
# Features
Current capabilities include:
- Access to the **OnRamp API**
- Real-time **Shop Monitor events** via WebSockets
- Execution of **registered API queries**
- Event-driven application integrations
Typical integration scenarios include:
- Shop Monitor automation
- Production event processing
- Device integrations
- External analytics
- Cloud-hosted services
---
# Installation
Add the OnRamp SDK NuGet feed:
```bash
dotnet nuget add source https://git.onramp-solutions.com/api/packages/OnRampSDK/nuget/index.json --name onrampsdk
```
After adding the source, packages will appear under:
```
Package Source: onrampsdk
```
Packages can then be installed using standard NuGet workflows.
Example:
```bash
dotnet add package ORPublicApiRefCore
dotnet add package ORSocketsCore
```
---
# Quick Start Example
The following console example demonstrates a basic integration pattern:
1. Connect to the OnRamp API
2. Establish a WebSocket connection
3. Register a Socket ID
4. Receive Shop Monitor events
5. Execute API queries
```vb
Imports System.Threading
Imports ORPublicApiRefCore
Imports ORSocketsCore
Module Program
Private api As OnRampAPI
Private socketClient As ORSocketClient
Private quitEvent As ManualResetEvent = New ManualResetEvent(False)
Sub Main(args As String())
' OnRamp root endpoint
Dim envUrl As String = "https://onramp.site.com/PROD"
' Register for Shop Monitor events
socketClient = New ORSocketClient(envUrl, "SHOPMONITORCLIENT", "SITE1001")
AddHandler socketClient.OnMessageReceived, AddressOf SocketMessageRec
AddHandler socketClient.OnLog, AddressOf SocketLog
api = New OnRampAPI(envUrl)
' API authentication
api.APILogin("api_user", "api_password")
WaitForConsoleExit()
End Sub
```
---
# Shop Monitor Events
Shop Monitor devices send events through a configured **Socket ID**.
To configure a device:
1. Open **S1280 Device Shop Monitor**
2. Set the **Process ID / Socket ID**
3. Use the same ID in the application
Example event types include:
- Work Order Login
- Work Order Logout
- Cycle Start
- Cycle Complete
- Device button events
Incoming WebSocket messages behave similarly to **interrupt events**, allowing applications to respond immediately to shop floor activity.
---
# API Queries
Queries must be registered in:
```
S5011 API Queries
```
Supported query types:
- `SELECT`
- `UPDATE`
In most integrations, **SELECT queries are sufficient**. UPDATE queries should be used cautiously.
---
# Query Parameters
Queries use **Handlebars-style parameters**.
Example:
```sql
SELECT woo_oper, woo_qty_rep
FROM wo_oper
WHERE woo_nbr = '{{p:wonum}}'
```
`p:wonum` is provided by the client application.
---
# Example Query Execution
```vb
Dim args As New Dictionary(Of String, String)
args.Add("wonum", woNum)
Dim rstDataAllOps = api.runQuery("Q-GET-WO-OPS", args)
If rstDataAllOps.RecordCount > 0 Then
Do Until rstDataAllOps.EOF
Console.WriteLine(rstDataAllOps("woo_oper") &
" - QtyRep:" &
rstDataAllOps("woo_qty_rep"))
rstDataAllOps.MoveNext()
Loop
End If
```
The returned result set exposes a **recordset-style interface** with:
- `RecordCount`
- `EOF`
- `MoveNext()`
- column access by name
---
# Query Performance Guidelines
For best performance:
- Avoid returning large datasets
- Do not use `SELECT *`
- Specify explicit columns
- Limit queries to only the required data
Recommended:
```sql
SELECT pt_part, pt_desc
FROM pt_mstr
```
Avoid:
```sql
SELECT *
FROM pt_mstr
```
---
# Example Architecture
Typical integrations run as:
- console applications
- background services
- device integration processes
The application:
1. Starts
2. Connects to OnRamp
3. Registers a socket
4. Waits for events
5. Processes events until shutdown
Deployment models include:
- one service handling all devices
- device-specific applications
- event-specific services
---
# Future Expansion
The SDK is designed to support additional integration capabilities including:
- additional event channels
- expanded API functionality
- additional integration services
---
# License
Refer to the repository license for usage terms.

View File

@@ -1,27 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.12.35707.178
MinimumVisualStudioVersion = 10.0.40219.1
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "prjOnRampAPI", "prjOnRampAPI\prjOnRampAPI.vbproj", "{392D651B-778A-4082-80D9-05FFFD1916A1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A95BA3CB-1B3C-4D31-8C3E-6AD39F4319EF}"
ProjectSection(SolutionItems) = preProject
README = README
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{392D651B-778A-4082-80D9-05FFFD1916A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{392D651B-778A-4082-80D9-05FFFD1916A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{392D651B-778A-4082-80D9-05FFFD1916A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{392D651B-778A-4082-80D9-05FFFD1916A1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -1,162 +0,0 @@
Imports System.Threading
Imports ORPublicApiRefCore
Imports ORSocketsCore
Module Program
Private api As OnRampAPI
Private socketClient As ORSocketClient
Private quitEvent As ManualResetEvent = New ManualResetEvent(False)
Sub Main(args As String())
'The http_root endpoint - use the MAIN webserver, not a farm
'Use ProdCopy for testing if needed
Dim envUrl As String = "https://onramp.site.com/PROD"
'create a socket connection to OnRamp Server to get interrupts of shop monitor events
'You are registering as a "CLIENT APP NUMBER" - for this instance we will put SITE1001
'SITE1001 is the ID you set in S1280 - Device Shop Monitor for the SOCKETID on the event you wish to capture on this application.
socketClient = New ORSocketClient(envUrl, "SHOPMONITORCLIENT", "SITE1001")
'This is how to bind incoming Interrupt socket messages to a subroutine - kind of like a RS232 Interrupt
AddHandler socketClient.OnMessageReceived, AddressOf SocketMessageRec
'This is so we can debug websocket debugging info (for info purposes only, socket connected, reconnected etc)
AddHandler socketClient.OnLog, AddressOf SocketLog
'Login to API to be able to query runQuery and Execute Queries in API Queries
'You can do lots of things with the API like OpenScreens, change values - everything you can do with a dataloader you can do with the API
api = New OnRampAPI(envUrl)
'Make an OnRamp user to use to login with the api and login with those credentials
api.APILogin("api_user", "api_password")
'now the App waits forever and interrupts to SocketMessageRec
WaitForConsoleExit()
End Sub
Private Sub SocketMessageRec(obj As Object, e As ORSocketMessageReceivedArgs)
'This is the interrupt when the "shop monitor event happens" - it acts like RS232 sort of.
Try
'You get msg details like who sent it and when
Dim senderGroup = e.senderGroup
Dim senderName = e.senderName
Dim msgTime = e.msgTime
Dim msg = e.msg
'you get a message array
Dim msgSplit() As String
msgSplit = Split(msg, Convert.ToChar(175))
'msg = deviceid, channelNum, eventType
Dim deviceId As String = msgSplit(0)
Dim channelNum As Integer = V_N2I(msgSplit(1))
Dim eventType As ShopMonitorChannelEvent = V_N2I(msgSplit(2))
'you can tie into event types
Select Case eventType
Case ShopMonitorChannelEvent.WorkOrderLogin
'new WO Logged in
Case ShopMonitorChannelEvent.WorkOrderLogout
'WO Logged out
Case ShopMonitorChannelEvent.CycleStart
'Cycle Start
Case ShopMonitorChannelEvent.CycleDone
'Cycle Done
End Select
'^^With this information you can get all you want to know about the work order etc
'We create a query in S5011 - API Queries to get device_channel Work Order Info, then use other queries to get operation information etc
'The queries in this example are just for example, you need to create your own.
'arguments for server query Q-1234
Dim rsChannelArgs As New Dictionary(Of String, String)
rsChannelArgs.Add("deviceid", deviceId)
rsChannelArgs.Add("devicechannel", channelNum)
'Example Q-1234 query is
'SELECT devc_cur_wo FROM device_chan WHERE devc_device_id = '{{p:deviceid}}' AND devc_channel_num = '{{p:devicechannel}}'
Dim rstDataWo = api.runQuery("Q-1234", rsChannelArgs)
If rstDataWo.RecordCount > 0 Then
Dim currentWoBarcode As String = rstDataWo("devc_cur_wo")
'get operation details
Dim rsOperArgs As New Dictionary(Of String, String)
rsOperArgs.Add("wobarcode", currentWoBarcode)
'Example Q-1235
'SELECT wom_partnum, wom_nbr, woo_oper FROM wo_oper INNER JOIN wo_mstr ON wom_nbr = woo_nbr where woo_barcode = '{{p:wobarcode}}'
Dim rstDataOp = api.runQuery("Q-1235", rsOperArgs)
If rstDataOp.RecordCount > 0 Then
Dim woNum As String = rstDataOp("wom_nbr")
Dim woOp As Integer = V_N2I(rstDataOp("woo_oper"))
Dim woPart As Integer = V_N2I(rstDataOp("wom_partnum"))
'get all operations for the WO
Dim allOpsArgs As New Dictionary(Of String, String)
allOpsArgs.Add("wonum", woNum)
'Example Q-1236
'SELECT woo_oper, woo_qty_rep FROM wo_oper WHERE woo_nbr = '{{p:wonum}}'
Dim rstDataAllOps = api.runQuery("Q-1236", allOpsArgs)
If rstDataAllOps.RecordCount > 0 Then
Do Until rstDataAllOps.EOF
Console.WriteLine(rstDataAllOps("woo_oper") + " - QtyRep:" & rstDataAllOps("woo_qty_rep"))
rstDataAllOps.MoveNext()
Loop
End If
'if we want to run an execute query
Dim argUpdate As New Dictionary(Of String, String)
argUpdate("deviceid") = deviceId
argUpdate("part") = woPart
'Example Q-1237
'UPDATE tbl_param_det SET PN = '{{p:part}}' WHERE Device = '{{p:deviceid}}'
api.runQuery("Q-1237", argUpdate)
End If
End If
Catch ex As Exception
Dim err As String = ex.Message
End Try
End Sub
Private Sub SocketLog(obj As Object, msg As String)
Console.WriteLine(msg)
End Sub
Private Sub WaitForConsoleExit()
'console app wait forevery on main thread
Console.WriteLine("Running. Press Ctrl+C to exit.")
AddHandler Console.CancelKeyPress, AddressOf ConsoleCancel
'Block here until Ctrl+C
quitEvent.WaitOne()
Console.WriteLine("Shutting down...")
Try
socketClient?.Dispose()
Catch
End Try
End Sub
Private Sub ConsoleCancel(sender, eArgs)
quitEvent.[Set]()
eArgs.Cancel = True
End Sub
End Module

View File

@@ -1,53 +0,0 @@
Imports ORPublicApiRefCore
Public Module modOHCommon
<ThreadStatic> Private _rstData As List(Of KeyValuePair(Of String, DTRecordSet))
Public Property rs(ByVal uniqueIdent As String) As DTRecordSet
Get
Return rstData(uniqueIdent)
End Get
Set(value As DTRecordSet)
rstData(uniqueIdent) = value
End Set
End Property
Public Property rstData(ByVal uniqueIdent As String) As DTRecordSet
Get
Dim localRs As List(Of KeyValuePair(Of String, DTRecordSet))
If _rstData Is Nothing Then
_rstData = New List(Of KeyValuePair(Of String, DTRecordSet))
End If
localRs = _rstData
For Each kvp As KeyValuePair(Of String, DTRecordSet) In localRs
If kvp.Key = uniqueIdent Then
Return kvp.Value
End If
Next kvp
'Throw New Exception("rstData(" & uniqueIdent & ") could not be found")
Return Nothing
End Get
Set(ByVal value As DTRecordSet)
Dim localRs As List(Of KeyValuePair(Of String, DTRecordSet))
If _rstData Is Nothing Then
_rstData = New List(Of KeyValuePair(Of String, DTRecordSet))
End If
localRs = _rstData
'remove from list if exists, then replace
For Each kvp As KeyValuePair(Of String, DTRecordSet) In localRs
If kvp.Key = uniqueIdent Then
localRs.Remove(kvp)
Exit For
End If
Next kvp
Dim wrapKVP As New KeyValuePair(Of String, DTRecordSet)(uniqueIdent, value)
localRs.Add(wrapKVP)
End Set
End Property
End Module

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="onramp"
value="https://git.onramp-solutions.com/api/packages/OnRampSDK/nuget/index.json" />
<add key="nuget.org"
value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>

View File

@@ -1,14 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<RootNamespace>prjOnRampAPI</RootNamespace>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ORPublicApiRefCore" Version="1.0.0" />
<PackageReference Include="ORSocketsCore" Version="2.0.4" />
</ItemGroup>
</Project>