diff --git a/tests/test_urscript_commands.py b/tests/test_urscript_commands.py
index b6da9a815ce41694bd2dc247345b6cb30a8b1876..84cf742b8007fa9343fbdcd8b1ff377d99bc0190 100644
--- a/tests/test_urscript_commands.py
+++ b/tests/test_urscript_commands.py
@@ -3,7 +3,16 @@ from random import random
 
 import pytest
 
-from ur_py_ctl.urscript_commands import _get_conf, _get_func, _get_pose, move_to_conf
+from ur_py_ctl.urscript_commands import (
+    _get_conf,
+    _get_func,
+    _get_pose,
+    _quote_string_if_needed,
+    move_to_conf,
+    socket_close,
+    socket_open,
+    socket_send_string,
+)
 
 
 @pytest.fixture()
@@ -45,7 +54,20 @@ def kwargs_input_output():
     return input_, output
 
 
-def test_get_func():
+def test__quote_string_if_needed():
+    # no added quotes needed
+    assert (_quote_string_if_needed("'String'")) == "'String'"
+    # add quotes
+    assert (_quote_string_if_needed("String")) == "'String'"
+    # already quoted but with "" instead of ''
+    assert (_quote_string_if_needed('"String"')) == '"String"'
+    # unbalanced
+    assert (_quote_string_if_needed('"String')) == "'\"String'"
+    # different quote marks
+    assert (_quote_string_if_needed("'String\"")) == "''String\"'"
+
+
+def test__get_func():
     func_name = "func"
     urscript_args = "args"
     urscript_kwargs = "kwargs"
@@ -80,3 +102,27 @@ def test_move_to_conf_kwargs(conf_list, conf_str, kwargs_input_output):
     ur_func = move_to_conf(conf_list, v=input_kwargs["v"], t=input_kwargs["t"])
 
     assert ur_func == f"movej({conf_str}, {output_kwargs['v']}, {output_kwargs['t']})"
+
+
+def test_socket_open():
+    ret_val = socket_open("192.168.1.2", 3003)
+    assert ret_val == "socket_open('192.168.1.2', 3003)"
+
+    ret_val = socket_open("'192.168.1.2'", 3003, socket_name="socket_1")
+    assert ret_val == "socket_open('192.168.1.2', 3003, socket_name='socket_1')"
+
+
+def test_socket_close():
+    assert socket_close() == "socket_close()"
+    assert (
+        socket_close(socket_name="socket_other")
+        == "socket_close(socket_name='socket_other')"
+    )
+
+
+def test_socket_send_string():
+    assert socket_send_string("'c'") == "socket_send_string('c')"
+    assert (
+        socket_send_string("pose", socket_name="socket_other")
+        == "socket_send_string(pose, socket_name='socket_other')"
+    )
diff --git a/ur_py_ctl/urscript_commands.py b/ur_py_ctl/urscript_commands.py
index a53e29ef4c64d90996b87525671122cf383ca059..b3b0c83f280158c24805062d3c68fa79d9935811 100644
--- a/ur_py_ctl/urscript_commands.py
+++ b/ur_py_ctl/urscript_commands.py
@@ -1,10 +1,33 @@
 from collections.abc import Sequence
 
 
-def _get_func(func_name, urscript_args, urscript_kwargs=None):
-    args = urscript_args
-    if urscript_kwargs:
-        args += f", {urscript_kwargs}"
+def _quote_string_if_needed(string):
+    """Add enclosing quotation marks if string not already enclosed with
+    quotation marks.
+
+    Prefers single quote marks since that's what's used in URScript
+    documentation.
+
+    No smart parsing or tokenizing, only checks the start and end of string.
+    """
+    if string[0] in ('"', "'"):
+        if string[-1] == string[0]:
+            # already quoted
+            return string
+
+    return "'" + string + "'"
+
+
+def _get_func(
+    func_name: str, urscript_args: str = None, urscript_kwargs: str = None
+) -> str:
+    # if both args and kwargs, join with ", "
+    if urscript_args and urscript_kwargs:
+        args = ", ".join([urscript_args, urscript_kwargs])
+    else:
+        # either or both args and kwargs are none
+        args = urscript_args or ""  # add args if args
+        args += urscript_kwargs or ""  # add kwargs if kwargs
 
     return f"{func_name}({args})"
 
@@ -224,3 +247,35 @@ def read_AO(pin: int) -> float:
 def sleep(seconds: int) -> str:
     """Construct a function call that instructs the controller to sleep."""
     return _get_func("sleep", str(seconds))
+
+
+def socket_open(address: str, port: int, socket_name=None):
+    urscript_kwargs = (
+        f"socket_name={_quote_string_if_needed(socket_name)}" if socket_name else None
+    )
+    return _get_func(
+        "socket_open",
+        urscript_args=f"{_quote_string_if_needed(address)}, {port}",
+        urscript_kwargs=urscript_kwargs,
+    )
+
+
+def socket_close(socket_name=None):
+    urscript_kwargs = (
+        f"socket_name={_quote_string_if_needed(socket_name)}" if socket_name else None
+    )
+    return _get_func(
+        "socket_close",
+        urscript_kwargs=urscript_kwargs,
+    )
+
+
+def socket_send_string(string_or_var_name: str, socket_name=None):
+    urscript_kwargs = (
+        f"socket_name={_quote_string_if_needed(socket_name)}" if socket_name else None
+    )
+    return _get_func(
+        "socket_send_string",
+        urscript_args=string_or_var_name,
+        urscript_kwargs=urscript_kwargs,
+    )