Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

functions return SID value for matching the reply #24

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ceremcem
Copy link
Contributor

Functions return the header.SID value in order to correctly match the sent command with the reply.

Example code:

export class OmronFinsDriver extends DriverAbstract
    (@opts={}) ->
        super!
        @log = new Logger \OmronFinsDriver
        @target = {port: 9600, host: '192.168.250.1'} <<< @opts
        @timeout = 2000ms  # 100ms

        @log.log bg-yellow "Using #{@target.host}:#{@target.port}"
        @client = fins.FinsClient @target.port, @target.host

        @q = {} # exec queue. Key field is the sequence number (FinsClient.SID).

        @client.on \reply, (msg) ~>
            if msg.sid of @q
                # got an expected reply
                @q[msg.sid].go err=null, res=msg 
                delete @q[msg.sid]
            else 
                @log.error "Unexpected response: (none in #{Object.keys @q}):", msg

        @client.on \error, (err) ~> 
            @log.error "FINS Client error:", err 

        @client.on \timeout, (err) ~> 
            @log.error "FINS timeout:", err

        # PLC connection status 
        @connected = no 
        @on \connected, ~> 
            @log.info "Connected to PLC"
        @on \disconnected, ~> 
            @log.info "Disconnected from PLC"

        @check-heartbeating!


    check-heartbeating: ->>
        @log.log "Starting the heartbeat check with the PLC"
        while true
            try await @exec \read, "C0:0", 1
            await sleep 10_000ms
   
    exec: (command, ...args) ->> 
        # This is the key function that transforms the discrete .read/.write functions 
        # into async functions        
        SID = @client[command] ...args
        @q[SID] = new Signal!
        return new Promise (resolve, reject) ~>
            @q[SID].wait @timeout, (err, res) ~> 
                if err 
                    reject(err)
                    @trigger \disconnected if @connected
                    @connected = no 
                    sleep 0 ~> 
                        delete @q[SID] if SID of @q
                else 
                    resolve(res)
                    @trigger \connected unless @connected
                    @connected = yes

This is the current code I'm using for as a wrapper class. I use this driver as follows:

driver = new OmronFinsDriver()
try 
    value = await driver.exec 'read', 'DM0:0', 1
catch 
    console.error "Something went wrong while reading"

# or 

try
    await driver.exec 'write', 'DM0:0', 1
catch
  console.error "Something went wrong while writing"

In order to make this kind of usage possible, I need to match the sent command with the reply. Here the SID value plays a key role. Thereby, functions must return the SID value they are using in order to let us match the sent command with its reply.

Functions return the `header.SID` value in order to correctly match the sent command with the reply.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant