Local File Read and Write with MUSE
Question:
How do I Read and Write Local File with MUSE?
Answer:
File read/write local files on MU controllers can be done using either Automator or line code (Python, JavaScript, Goovy). The important part of this is where the file is written or created. When working on an MU controller, the default location where files should be created and accessed is:
/mnt/data/mojo/mojo/program/*name of project*/*name of file*
This is where the program files are saved when uploaded to the MUSE controller. This information can be seen by connecting to the controller via SFTP. Here is an example of the file tree of an MU controller:

Notice that the full path mentioned above does not exist in that tree. This is because the ‘root’ that can be accessed on an MU begins at /mnt/data/mojo/. Whenever code is used to access files, it still requires the full path of the file.
This KB article contains an Automator flow that shows an example of reading, writing, and watching for changes to a file. The watching of files allows for changes of the file to occur outside of the script, and the Automator program can still act upon those changes. For example, if the system has a list of channels and channel numbers in a CSV file, a new CSV file could be uploaded via SFTP, and the code would update it on the fly.
[
{
"id": "02e5bc5eed95f352",
"type": "tab",
"label": "Flow 1",
"disabled": false,
"info": "",
"env": []
},
{
"id": "5b1bdfc4a6ec6ac4",
"type": "group",
"z": "02e5bc5eed95f352",
"name": "Writing Object to File and Watching File for Change",
"style": {
"label": true
},
"nodes": [
"932c67eeaf450e1e",
"d34b128388188e6a",
"179f78671643687a",
"43004642ba8e1226",
"82b8300a7b1029de",
"a8dc45fb37097a6d",
"ed9138bfdf87fcaa",
"9c972acb3a22292b",
"6122d1910046c99e",
"64138c139544bc77",
"5e46941ee09758aa",
"ce2e64f38b6816bf",
"a5caec6bca6f8186",
"8687b6ab81e1b680",
"b18edd29a5eecb44",
"1a6f7b4d58fc3ff6",
"f2fe099726316936",
"8a886b3b3d9455a1",
"85678fed1cc15da0",
"aa3f70b96733c0b3",
"729a72f5803976b8"
],
"x": 14,
"y": 159,
"w": 1172,
"h": 462
},
{
"id": "932c67eeaf450e1e",
"type": "inject",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "Write to File",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 130,
"y": 200,
"wires": [
[
"d34b128388188e6a"
]
]
},
{
"id": "d34b128388188e6a",
"type": "change",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "",
"rules": [
{
"t": "set",
"p": "device.vol",
"pt": "flow",
"to": "50",
"tot": "num"
},
{
"t": "set",
"p": "device.mute",
"pt": "flow",
"to": "true",
"tot": "bool"
},
{
"t": "set",
"p": "device.ip",
"pt": "flow",
"to": "127.0.0.1",
"tot": "str"
},
{
"t": "set",
"p": "device.pState",
"pt": "flow",
"to": "on",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 330,
"y": 240,
"wires": [
[
"9c972acb3a22292b"
]
]
},
{
"id": "179f78671643687a",
"type": "file",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "Write File",
"filename": "/mnt/data/mojo/mojo/program/File_Manipulation/obj.txt",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 790,
"y": 220,
"wires": [
[]
]
},
{
"id": "43004642ba8e1226",
"type": "inject",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "Read File",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 130,
"y": 320,
"wires": [
[
"82b8300a7b1029de"
]
]
},
{
"id": "82b8300a7b1029de",
"type": "file in",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "Read File",
"filename": "/mnt/data/mojo/mojo/program/File_Manipulation/obj.txt",
"filenameType": "str",
"format": "lines",
"chunk": false,
"sendError": false,
"encoding": "none",
"allProps": true,
"x": 330,
"y": 320,
"wires": [
[
"a8dc45fb37097a6d"
]
]
},
{
"id": "a8dc45fb37097a6d",
"type": "json",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 520,
"y": 320,
"wires": [
[
"ed9138bfdf87fcaa"
]
]
},
{
"id": "ed9138bfdf87fcaa",
"type": "debug",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "debug 130",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 670,
"y": 320,
"wires": []
},
{
"id": "9c972acb3a22292b",
"type": "change",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "device",
"tot": "flow"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 590,
"y": 220,
"wires": [
[
"179f78671643687a"
]
]
},
{
"id": "6122d1910046c99e",
"type": "inject",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "Write to File",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 130,
"y": 240,
"wires": [
[
"64138c139544bc77"
]
]
},
{
"id": "64138c139544bc77",
"type": "change",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "",
"rules": [
{
"t": "set",
"p": "device.vol",
"pt": "flow",
"to": "-10",
"tot": "num"
},
{
"t": "set",
"p": "device.mute",
"pt": "flow",
"to": "false",
"tot": "bool"
},
{
"t": "set",
"p": "device.ip",
"pt": "flow",
"to": "198.18.0.1",
"tot": "str"
},
{
"t": "set",
"p": "device.pState",
"pt": "flow",
"to": "off",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 330,
"y": 200,
"wires": [
[
"9c972acb3a22292b"
]
]
},
{
"id": "5e46941ee09758aa",
"type": "watch",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "Watch File",
"files": "/mnt/data/mojo/mojo/program/File_Manipulation/obj.txt",
"recursive": true,
"x": 100,
"y": 480,
"wires": [
[
"ce2e64f38b6816bf"
]
]
},
{
"id": "ce2e64f38b6816bf",
"type": "file in",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "Read Changes",
"filename": "/user/obj.txt",
"filenameType": "str",
"format": "lines",
"chunk": false,
"sendError": false,
"encoding": "none",
"allProps": true,
"x": 330,
"y": 480,
"wires": [
[
"a5caec6bca6f8186"
]
]
},
{
"id": "a5caec6bca6f8186",
"type": "json",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 500,
"y": 480,
"wires": [
[
"b18edd29a5eecb44"
]
]
},
{
"id": "8687b6ab81e1b680",
"type": "debug",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "debug 131",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 870,
"y": 420,
"wires": []
},
{
"id": "b18edd29a5eecb44",
"type": "rbe",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "",
"func": "rbe",
"gap": "",
"start": "",
"inout": "out",
"septopics": true,
"property": "payload",
"topi": "topic",
"x": 660,
"y": 480,
"wires": [
[
"8687b6ab81e1b680",
"1a6f7b4d58fc3ff6"
]
]
},
{
"id": "1a6f7b4d58fc3ff6",
"type": "function",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "function 3",
"func": "var vol = { payload: msg.payload.vol };\nvar mute = { payload: msg.payload.mute };\nvar ip = { payload: msg.payload.ip };\nvar pState = { payload: msg.payload.pState };\n\nreturn [vol,mute,ip,pState];",
"outputs": 4,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 870,
"y": 520,
"wires": [
[
"729a72f5803976b8"
],
[
"f2fe099726316936",
"aa3f70b96733c0b3"
],
[
"8a886b3b3d9455a1"
],
[
"85678fed1cc15da0"
]
]
},
{
"id": "f2fe099726316936",
"type": "debug",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "debug 133",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 1070,
"y": 500,
"wires": []
},
{
"id": "8a886b3b3d9455a1",
"type": "debug",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "debug 134",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 1070,
"y": 540,
"wires": []
},
{
"id": "85678fed1cc15da0",
"type": "debug",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "debug 135",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 1070,
"y": 580,
"wires": []
},
{
"id": "aa3f70b96733c0b3",
"type": "Command",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "Command",
"mojo": {
"device": "AMX-10001",
"command": "//port/1/channel/8",
"onebased": true,
"args": "",
"cmdvalue": "Message payload"
},
"x": 1090,
"y": 380,
"wires": [
[]
]
},
{
"id": "729a72f5803976b8",
"type": "debug",
"z": "02e5bc5eed95f352",
"g": "5b1bdfc4a6ec6ac4",
"name": "debug 136",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 1070,
"y": 460,
"wires": []
},
{
"id": "928217c3a5dd022c",
"type": "Controller",
"z": "02e5bc5eed95f352",
"name": "Controller",
"mojo": {
"controller": "10.35.88.110:80",
"protocol": "http",
"host": "10.35.88.110",
"port": 80,
"username": "admin",
"password": "12rms34"
},
"x": 120,
"y": 60,
"wires": []
}
]
Below is also an example Python script for reading and writing to files. The code creates the file in the specific path mentioned above. It is important to note that when using line code, it is not necessary to use the full path name. If the file is created without the full path name, the program will create the file in the same folder the code file exists in.
from mojo import context # type: ignore
context.log.info('Sample Python program')
#This variable contains the full path and file name to be used in the code
file_path = "/mnt/data/mojo/mojo/program/Py file RW Test/example.txt"
# Read the file
f = open(file_path,'r')
print(f.read()) # Reads entire file at once
f.close()
# Append to the end of a file
f = open(file_path,'a')
f.write('\nThis line of text was added by the code!!!\n')
f.close()
f = open(file_path,'r')
print(f.readlines()) # You can read the lines into an array!
f.close()
# Write over the entire file
f = open(file_path,'w')
f.write('This text has written over the existing file contents!\nPretty cool, huh?')
f.close()
f = open(file_path,'r')
for x in f: # Read the file line by line
print(x)
f.close()
# leave this as the last line in the Python script
context.run(globals())