Module Integration Guides
Linux
Receiving Actions
3 min
this guide shows you how to receive docid 2on vzrfinigokbl7yn7b (commands) from the cloud and execute them let us have a look at how to create a "reboot" action that restarts the device to do this we need to first register this action with uplink using its configuration file config toml if you have followed the guide this file will be present in /usr/local/share/bytebeam folder edit this file to add the line actions=\[{name="reboot"}] under \[tcpapps 1] section config toml persistence path = "/tmp/uplink" action redirections={update firmware="install firmware"} \[tcpapps 1] port=5050 actions=\[{name="reboot"}] \[downloader] path="/tmp/uplink/download" actions=\[{name="update firmware", timeout=610}, {name="send file"}] \[apis] enabled=true port=3333 \[ota installer] path="/tmp/uplink/installer" actions=\[{name="install firmware", timeout=610}] uplink port=5050 \[logging] tags=\["sshd", "systemd"] stream size=1 min level=7 restart the uplink using the following commands sudo systemctl restart uplink create a new action type called "reboot" by following the docid\ qpcsie hkxdpje0aj8z1j guide the reboot action should now be visible on the device management page do not trigger the action yet we need to first integrate the action into our application below you can find a sample application code for receiving actions demo py import socket import json import time import os import threading s = socket socket(socket af inet, socket sock stream) s connect(("localhost", 5050)) \# converts json data received over tcp into a python dictionary def receive action(s) return json loads(s recv(2048)) \# constructs a payload and sends it over tcp to uplink def send data(s, payload) send = json dumps(payload) + "\n" s sendall(bytes(send, encoding="utf 8")) \# constructs a json `action status` as a response to received action on completion def action complete(id) return { "stream" "action status", "sequence" 0, "timestamp" int(time time() 1000000), "action id" id, "state" "completed", "progress" 100, "errors" \[], } \# reboots the device def reboot(action) payload = json loads(action\["payload"]) print(payload) resp = action complete(action\["action id"]) print(resp) send data(s, resp) os system("sudo reboot") def receive actions() while true action = receive action(s) print(action) if action\["name"] == "reboot" print("reboot action received") reboot(action) print("starting uplink bridge app") threading thread(target=receive actions) start() demo js const net = require("net"); const client = new net socket(); client connect(5050, "localhost", () => { console log("connected to server"); }); // converts json data received over tcp into a javascript object function receiveaction() { return new promise((resolve, reject) => { client once("data", (data) => { try { resolve(json parse(data)); } catch (e) { reject(e); } }); }); } // constructs a payload and sends it over tcp to uplink function senddata(payload) { const send = json stringify(payload) + "\n"; client write(send, "utf 8"); } // constructs a json `action status` as a response to received action on completion function actioncomplete(id) { return { stream "action status", sequence 0, timestamp date now() 1000, action id id, state "completed", progress 100, errors \[], }; } // reboots the device function reboot(action) { const payload = json parse(action payload); console log(payload); const resp = actioncomplete(action action id); console log(resp); senddata(resp); exec("sudo reboot", (error, stdout, stderr) => { if (error) { console error(`exec error ${error}`); return; } console log(`stdout ${stdout}`); console error(`stderr ${stderr}`); }); } async function receiveactions() { while (true) { const action = await receiveaction(); console log(action); if (action name === "reboot") { console log("reboot action received"); reboot(action); } } } console log("starting uplink bridge app"); receiveactions(); demo rs use serde json {json, value}; use std io {read, write}; use std net tcpstream; use std process command; use std {thread, time}; fn main() { let mut stream = tcpstream connect("localhost 5050") expect("could not connect to server"); // start a thread to receive actions let mut stream clone = stream try clone() expect("failed to clone stream"); thread spawn(move || { receive actions(\&mut stream clone); }); } fn receive action(stream \&mut tcpstream) > value { let mut buffer = \[0; 2048]; stream read(\&mut buffer) expect("failed to read from stream"); serde json from slice(\&buffer) expect("failed to parse json") } fn send data(stream \&mut tcpstream, payload value) { let send = payload to string() + "\n"; stream write all(send as bytes()) expect("failed to write to stream"); } fn action complete(id i64) > value { json!({ "stream" "action status", "sequence" 0, "timestamp" time systemtime now() duration since(time unix epoch) expect("time went backwards") as micros() as i64, "action id" id, "state" "completed", "progress" 100, "errors" \[] }) } fn reboot(action \&value) { let payload = \&action\["payload"]; println!("{ ?}", payload); let resp = action complete(action\["action id"] as i64() unwrap()); println!("{ ?}", resp); send data(\&mut stream, resp); command new("sudo") arg("reboot") output() expect("failed to execute process"); } fn receive actions(stream \&mut tcpstream) { loop { let action = receive action(stream); println!("{ ?}", action); if action\["name"] == "reboot" { println!("reboot action received"); reboot(\&action); } } } demo go package main import ( 	"encoding/json" 	"fmt" 	"net" 	"os" 	"os/exec" 	"strconv" 	"time" ) func main() { 	conn, err = net dial("tcp", "localhost 5050") 	if err != nil { 	 fmt println("error connecting ", err error()) 	 os exit(1) 	} 	// start a goroutine for receiving actions 	go receiveactions(conn) 	fmt println("starting uplink bridge app") } // receiveaction reads and decodes json data from the connection func receiveaction(conn net conn) map\[string]interface{} { 	buffer = make(\[]byte, 2048) 	length, = conn read(buffer) 	var data map\[string]interface{} 	json unmarshal(buffer\[ length], \&data) 	return data } // senddata encodes the payload to json and sends it over the connection func senddata(conn net conn, payload map\[string]interface{}) { 	send, = json marshal(payload) 	conn write(append(send, '\n')) } // actioncomplete constructs a json action status response func actioncomplete(id interface{}) map\[string]interface{} { 	return map\[string]interface{}{ 	 "stream" "action status", 	 "sequence" 0, 	 "timestamp" time now() unixnano() / int64(time microsecond), 	 "action id" id, 	 "state" "completed", 	 "progress" 100, 	 "errors" \[]string{}, 	} } // reboot performs a system reboot func reboot(action map\[string]interface{}) { 	payload = action\["payload"] (map\[string]interface{}) 	fmt println(payload) 	resp = actioncomplete(action\["action id"]) 	fmt println(resp) 	senddata(conn, resp) 	cmd = exec command("sudo", "reboot") 	cmd run() } // receiveactions listens for actions and processes them func receiveactions(conn net conn) { 	for { 	 action = receiveaction(conn) 	 fmt println(action) 	 if action\["name"] == "reboot" { 	 fmt println("reboot action received") 	 reboot(action) 	 } 	} } once your app has been modified and is running, you can go to bytebeam cloud and click on the reboot action button to trigger the action next, you will see the following message click on yes next, on the action panel, you can monitor the status of your last triggered action after completion of an action, the action status changes to completed, and you should see your device reboot
