Interact with Serial Bus

This lambda demonstrates use of a serial bus by cycling the power of a node mounted on a BitScope Cluster Blade.

BitScope CB04B

Cycling the power is done using the BMC from a 2nd node. In this diagram, Device 0 is shown being used to manage the power of Devices 1, 2, or 3.

graph LR;

cli --> control_plane;
control_plane <-- tunnel --> agent0;
agent0 --> bmc;
bmc --> device0;
bmc --> device1;
bmc --> device2;
bmc --> device3;

subgraph user_edge[User Edge]
cli[CLI];
end

subgraph cloud[Cloud <small>api.on-prem.net</small>]
control_plane[Control Plane];
end

subgraph device_edge[Device Edge]
blade;
end

subgraph blade[CB04B Cluster Blade]
bmc;
device0;
device1;
device2;
device3;
end

subgraph device0[Device 0, station 124]
agent0[Agent];
end

subgraph device1[Device 1, station 125]
agent1[Agent];
end

subgraph device2[Device 2, station 126]
agent2[Agent];
end

subgraph device3[Device 3, station 127]
agent3[Agent];
end

Register the lambda

$ onprem generate xid
cj7db73erad7pt31vcng
# bitscope_cycle_power.yaml
id: cj7db73erad7pt31vcng
kind: Lambda
name: bitscope_cycle_power
description: >
  Cycle the power of a node mounted on a BitScope Cluster Blade.
runAt:
  # Run at Device 0 (station 124)
  deviceId: ci2fabp32ckvhk1g9qe0
scriptContentType: text/x-lua
script: >
  local socket = require('socket')
  local Serial = require('periphery.Serial')
  
  function write_command(serial, command, timeout_ms)
    for i = 1, #command do
      local c = command:sub(i, i)
      serial:write(c)
      assert(serial:read(1, timeout_ms) == c)
    end
  end

  function set_remote_power(serial, station, value, timeout_ms)
    assert(type(station) == 'number')
    assert(type(value) == 'boolean')
    local command = string.format("[%2x]{", station) .. (value and '/' or '\\') .. '}'
    write_command(serial, command, timeout_ms)
  end

  local M={}
  
  function M.handler(event, context)
    assert(type(event.device) == 'string')
    assert(type(event.baudrate) == 'number')
    local serial = Serial(event.device, event.baudrate)
    local timeout_ms = event.timeout or 50
  
    -- send remote power off command
    set_remote_power(serial, event.station, false, timeout_ms)
  
    -- wait a bit
    socket.sleep(0.25)

    -- send remote power on command
    set_remote_power(serial, event.station, true, timeout_ms)
  
    -- respond
    return {station=event.station, ok=true}
  end
  
  return M
$ onprem apply bitscope_cycle_power.yaml

It will now show up in the cloud console.

Cloud Console

Run it

$ onprem run lambda cj7db73erad7pt31vcng --event '{"station":126,"device":"/dev/serial0","baudrate":115200}'
{"station":126,"ok":true}