require'protocols/websocket'classWebsocketClientinclude::Orchestrator::Constantsinclude::Orchestrator::Transcoder generic_name :Websocket descriptive_name 'Websocket example' tcp_port 80 wait_response falsedefconnected new_websocket_clientenddefdisconnected# clear the keepalive ping schedule.clearend# Send a text messagedefsome_request @ws.text "hello"# or json format etc @ws.text({ some: "message", count: 234 }.to_json)end# send a binary messagedefbinary_send @ws.binary("binstring".bytes)# or @ws.binary hex_to_byte("0xdeadbeef")endprotecteddefnew_websocket_client# NOTE:: you must use wss:// when using port 443 (TLS connection) @ws =Protocols::Websocket.new(self,"ws://#{remote_address}/path/to/ws/endpoint")# @ws.add_extension # https://github.com/faye/websocket-extensions-ruby# @ws.set_header(name, value) # Sets a custom header to be sent as part of the handshake @ws.startenddefreceived(data, resolve, command) @ws.parse(data) :successend# ====================# Websocket callbacks:# ====================# websocket readydefon_open logger.debug { "Websocket connected" } schedule.every('30s') do @ws.ping('keepalive')endenddefon_message(raw_string) logger.debug { "received: #{raw_string}" }# Process request here# request = JSON.parse(raw_string)# ...enddefon_ping(payload) logger.debug { "received ping: #{payload}" }# optionalenddefon_pong(payload) logger.debug { "received pong: #{payload}" }# optionalend# connection is closingdefon_close(event) logger.debug { "closing... #{event.code}#{event.reason}" }end# connection is closingdefon_error(error) logger.debug { "ERROR! #{error.message}" }end# ====================end
Telnet
Implements the telnet standard so that it is easy to communicate with devices that implement control codes or require negotiation.
require'protocols/telnet'classTelnetClientdefon_load new_telnet_client# Telnet client returns only relevant data for buffering config before_buffering: proc { |data| @telnet.buffer data }enddefdisconnected# Ensures the buffer is cleared new_telnet_clientenddefsome_request# Telnet deals with end of line characters# (may have been negotiated on initial connection) send @telnet.prepare('some request')endprotecteddefnew_telnet_client# Telnet client needs access to IO stream @telnet =Protocols::Telnet.newdo|data| send dataendendend
KNX
Constructs KNX standard datagrams that make it easy to communicate with devices on KNX networks.
require'protocols/oauth'classHttpClient# =====================================# Hook into HTTP request via middleware# All requests will be sent with OAuth# =====================================defon_update connectedend# This is called directly after on_load.# Middleware is not available until connecteddefconnected @oauth =Protocols::OAuth.new({ key: setting(:consumer_key), secret: setting(:consumer_secret), site: remote_address }) update_middlewareendprotecteddefupdate_middleware# middleware is service helper function mid = middleware mid.clear mid << @oauthendend
require'protocols/snmp'classSnmpClientinclude::Orchestrator::Constants udp_port 161defon_unload @client.closeend# This is called directly after on_load.# Middleware is not available until connecteddefconnected proxy =Protocols::Snmp.new(self) @client =NETSNMP::Client.new({ proxy: proxy, version: "2c", community: "public" })enddefquery_something self[:status] = @client.get(oid: '1.3.6.1.2.1.1.1.0')enddefset_something(val) @client.set('1.3.6.1.2.1.1.3.0', value: val) self[:something] = valendprotecteddefreceived(data, resolve, command)# return the data which resolves the request promise.# the proxy uses fibers to provide this to the NETSNMP client dataendend
SOAP Services
Probably the easiest way to use these services at the moment via a Logic module. There are a number of supported ruby gems:
# Ensure we are not blocking the IO reactor looprequire'httpi/adapter/libuv'require'savon'HTTPI.adapter = :libuv# Make requests as per the savon documentationclient =Savon.client(wsdl: 'https://aca.im/service.wsdl')logger.debug { "Available operations: #{client.operations}" }
Handsoap usage:
# Ensure we are not blocking the IO reactor looprequire'handsoap/http/drivers/libuv_driver'Handsoap.http_driver = :libuv# Make requests as per the handsoap documentation
Wake on LAN
Wake on LAN is available to drivers of all types
# Supports any string with the correct number of hex digits# as well as common formats (these are some examples)mac_address_string ='0x62f81d4b6f00'mac_address_string ='62:f8:1d:4b:6f:00'mac_address_string ='62-f8-1d-4b-6f-00'# Defaults to broadcast address `'255.255.255.255'`wake_device(mac_address_string)# You can define a VLan gateway for a directed broadcast (most common in enterprise)wake_device(mac_address_string,'192.168.3.1')
ICMP (ping)
Uses the operating systems ping utility to perform a connectivity check.
# perform the pingping =::UV::Ping.new(remote_address)ping.ping # true / false to indicate success / failure# check out the ping resultsping.pingable # true / false to indicate success / failureping.ip # IP pinged (remote_address can be a domain name)ping.exception # any error messagesping.warning # any warning messages