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.binaryhex_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