Creating new device config.
Steps to update configuration: Step 1: Go to the device management section in Bytebeam cloud. Step 2: Go to the “Device Configs” section



Copy
Ask AI
persistence_path = "/tmp/uplink"
action_redirections={update_firmware="install_firmware"}
[tcpapps.1]
port=5050
actions=[{name="reboot"}, {name="update_config"}]
[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
Copy
Ask AI
sudo systemctl restart uplink
Copy
Ask AI
import socket
import json
import time
import threading
import logging
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": [],
    }
def update_config(action):
    payload = json.loads(action["payload"])
    print(payload)
    app = payload["name"]
    print(app)
    level = payload["level"]
    if app == "logging":
        set_log_level(level)
    resp = action_complete(action["action_id"])
    print(resp)
    send_data(s, resp)
def receive_actions():
    while True:
        action = receive_action(s)
        print(action)
        if action["name"] == "update_config":
            print("update_config action received")
            print(json.loads(action["payload"]))
            update_config(action)
def set_log_level(level):
    if level.lower() == "info":
        logging.getLogger().setLevel(logging.INFO)
    elif level.lower() == "error":
        logging.getLogger().setLevel(logging.ERROR)
    elif level.lower() == "verbose":
        logging.getLogger().setLevel(logging.VERBOSE)
    elif level.lower() == "debug":
        logging.getLogger().setLevel(logging.DEBUG)
print("Starting Uplink Bridge App")
threading.Thread(target=receive_actions).start()
logging.getLogger().setLevel(logging.INFO)
logging.Formatter("%(levelname)s - %(message)s")
while True:
    time.sleep(5)
    logging.debug("This is debug")
    logging.info("This is info")
Copy
Ask AI
const logger = log4js.getLogger();
const net = require("net");
const log4js = require("log4js");
const client = new net.Socket();
client.connect(5050, "localhost", () => {
  console.log("Connected to server");
});
// Configure logger
log4js.configure({
  appenders: { console: { type: "console" } },
  categories: { default: { appenders: ["console"], level: "info" } },
});
// Receive JSON data over TCP
function receiveAction(socket) {
  return new Promise((resolve, reject) => {
    socket.once("data", (data) => {
      try {
        const action = JSON.parse(data.toString());
        resolve(action);
      } catch (error) {
        reject(error);
      }
    });
  });
}
// Send JSON payload over TCP
function sendData(socket, payload) {
  const send = JSON.stringify(payload) + "\n";
  socket.write(send);
}
// Construct and send action status
function actionComplete(id) {
  return {
    stream: "action_status",
    sequence: 0,
    timestamp: Date.now(),
    action_id: id,
    state: "Completed",
    progress: 100,
    errors: [],
  };
}
async function updateConfig(action) {
  const payload = JSON.parse(action.payload);
  console.log(payload);
  const app = payload.name;
  console.log(app);
  const level = payload.level;
  if (app === "logging") {
    setLogLevel(level);
  }
  const resp = actionComplete(action.action_id);
  console.log(resp);
  sendData(client, resp);
}
// Receiving actions
async function receiveActions() {
  while (true) {
    const action = await receiveAction(client);
    console.log(action);
    if (action.name === "update_config") {
      console.log("update_config action received");
      console.log(JSON.parse(action.payload));
      await updateConfig(action);
    }
  }
}
console.log("Starting Uplink Bridge App");
receiveActions();
// Log messages at intervals
setInterval(() => {
  logger.debug("This is debug");
  logger.info("This is info");
}, 5000);
Copy
Ask AI
use chrono::Utc;
use flexi_logger::{LevelFilter, LogSpecification, Logger};
use log::{debug, error, info};
use serde_json::json;
use std::io::{BufRead, BufReader, Write};
use std::net::TcpStream;
use std::thread;
fn receive_action(stream: &mut TcpStream) -> serde_json::Result<serde_json::Value> {
    let mut reader = BufReader::new(stream);
    let mut buffer = String::new();
    reader.read_line(&mut buffer)?;
    serde_json::from_str(&buffer)
}
fn send_data(stream: &mut TcpStream, payload: serde_json::Value) {
    let serialized = serde_json::to_string(&payload).unwrap() + "\n";
    stream.write_all(serialized.as_bytes()).unwrap();
}
fn action_complete(action_id: &str) -> serde_json::Value {
    json!({
        "stream": "action_status",
        "sequence": 0,
        "timestamp": Utc::now().timestamp_millis(),
        "action_id": action_id,
        "state": "Completed",
        "progress": 100,
        "errors": []
    })
}
fn update_config(stream: &mut TcpStream, action: &serde_json::Value) {
    let payload: serde_json::Value =
        serde_json::from_str(action["payload"].as_str().unwrap()).unwrap();
    let app = payload["name"].as_str().unwrap();
    let level = payload["level"].as_str().unwrap();
    if app == "logging" {
        set_log_level(level);
    }
    let resp = action_complete(action["action_id"].as_str().unwrap());
    send_data(stream, resp);
}
fn set_log_level(level: &str) {
    let level_filter = match level.to_lowercase().as_str() {
        "info" => LevelFilter::Info,
        "error" => LevelFilter::Error,
        "verbose" => LevelFilter::Trace, // Rust doesn't have 'verbose', using 'Trace' instead
        "debug" => LevelFilter::Debug,
        _ => LevelFilter::Info,
    };
    let log_spec = LogSpecification::default().with_default(level_filter);
    Logger::with(log_spec).start().unwrap_or_else(|e| {
        eprintln!("Failed to initialize logger: {}", e);
    });
    info!("Log level set to {}", level);
}
fn receive_actions(mut stream: TcpStream) {
    loop {
        let action = receive_action(&mut stream).unwrap();
        if action["name"] == "update_config" {
            update_config(&mut stream, &action);
        }
    }
}
fn main() {
    Logger::with_env_or_str("info").start().unwrap();
    let mut stream = TcpStream::connect("localhost:5050").unwrap();
    println!("Starting Uplink Bridge App");
    let stream_clone = stream.try_clone().unwrap();
    thread::spawn(move || {
        receive_actions(stream_clone);
    });
    loop {
        thread::sleep(std::time::Duration::from_secs(5));
        debug!("This is debug");
        info!("This is info");
        error!("This is error");
    }
}
Copy
Ask AI
package main
import (
    "bufio"
    "encoding/json"
    "fmt"
    "io"
    "net"
    "os"
    "time"
    log "github.com/sirupsen/logrus"
)
func main() {
    conn, err := net.Dial("tcp", "localhost:5050")
    if err != nil {
        fmt.Println("Error connecting:", err)
        os.Exit(1)
    }
    defer conn.Close()
    log.SetLevel(log.InfoLevel)
    log.SetFormatter(&log.TextFormatter{})
    log.SetOutput(os.Stdout)
    go receiveActions(conn)
    fmt.Println("Starting Uplink Bridge App")
    for {
        time.Sleep(5 * time.Second)
        log.Debug("This is debug")
        log.Info("This is info")
        log.Error("This is error")
    }
}
// receiveAction reads and decodes a JSON message from the connection.
func receiveAction(conn net.Conn) (map[string]interface{}, error) {
    reader := bufio.NewReader(conn)
    msg, err := reader.ReadString('\n')
    if err != nil {
        return nil, err
    }
    var action map[string]interface{}
    err = json.Unmarshal([]byte(msg), &action)
    return action, err
}
// sendAction encodes a payload as JSON and sends it over the connection.
func sendAction(conn net.Conn, payload map[string]interface{}) error {
    msg, err := json.Marshal(payload)
    if err != nil {
        return err
    }
    _, err = conn.Write(append(msg, '\n'))
    return err
}
// actionComplete constructs a JSON `action_status` as a response to received action on completion.
func actionComplete(id interface{}) map[string]interface{} {
    return map[string]interface{}{
        "stream":    "action_status",
        "sequence":  0,
        "timestamp": time.Now().UnixNano() / 1000,
        "action_id": id,
        "state":     "Completed",
        "progress":  100,
        "errors":    []string{},
    }
}
// updateConfig processes the update_config action.
func updateConfig(conn net.Conn, action map[string]interface{}) {
    payloadStr := action["payload"].(string)
    var payload map[string]interface{}
    json.Unmarshal([]byte(payloadStr), &payload)
    app := payload["name"].(string)
    level := payload["level"].(string)
    if app == "logging" {
        setLogLevel(level)
    }
    resp := actionComplete(action["action_id"])
    sendAction(conn, resp)
}
func setLogLevel(level string) {
    switch level {
    case "info":
        log.SetLevel(log.InfoLevel)
    case "error":
        log.SetLevel(log.ErrorLevel)
    case "verbose":
        log.SetLevel(log.TraceLevel) // Go's logrus doesn't have 'verbose', using 'Trace' instead
    case "debug":
        log.SetLevel(log.DebugLevel)
    default:
        log.SetLevel(log.InfoLevel)
    }
    log.Infof("Log level set to %s", level)
}
// recvActions handles incoming actions in a separate goroutine.
func receiveActions(conn net.Conn) {
    for {
        action, err := receiveAction(conn)
        if err != nil {
            if err == io.EOF {
                fmt.Println("Connection closed by server")
                return
            }
            fmt.Println("Error reading:", err)
            continue
        }
        fmt.Println("Action received:", action)
        if action["name"] == "update_config" {
            fmt.Println("update_config action received")
            updateConfig(conn, action)
        }
    }
}
Triggering config update
On the device management section of Bytebeam Cloud, select the device and click on Update Configuration


