diff --git a/src/simple_pv/simple_epics.hh b/src/simple_pv/simple_epics.hh
index 2830457d85ade894cf65bac4b3b1f28325f528ac..f48ef0979312ffde545ddf5de44a1f060c2fef95 100644
--- a/src/simple_pv/simple_epics.hh
+++ b/src/simple_pv/simple_epics.hh
@@ -36,6 +36,12 @@ namespace simple_epics
 
     class Server;
 
+    enum class PVMode
+    {
+        ReadOnly = 0,
+        ReadWrite = 1,
+    };
+
     /*!
      * @brief A description of a PV, used to describe an int PV to the server.
      * @note this is given a pointer to the data.  This value is only read
@@ -47,48 +53,55 @@ namespace simple_epics
         pvIntAttributes( std::string           pv_name,
                          int*                  value,
                          std::pair< int, int > alarm_range,
-                         std::pair< int, int > warn_range )
+                         std::pair< int, int > warn_range,
+                         PVMode                mode = PVMode::ReadOnly )
             : name_{ std::move( pv_name ) },
 
               alarm_low_{ alarm_range.first },
               alarm_high_{ alarm_range.second }, warn_low_{ warn_range.first },
-              warn_high_{ warn_range.second }, src_{ value }
+              warn_high_{ warn_range.second }, mode_{ mode }, src_{ value }
         {
         }
 
         const std::string&
-        name( ) const
+        name( ) const noexcept
         {
             return name_;
         }
 
         int
-        alarm_high( ) const
+        alarm_high( ) const noexcept
         {
             return alarm_high_;
         }
         int
-        alarm_low( ) const
+        alarm_low( ) const noexcept
         {
             return alarm_low_;
         }
         int
-        warn_high( ) const
+        warn_high( ) const noexcept
         {
             return warn_high_;
         }
         int
-        warn_low( ) const
+        warn_low( ) const noexcept
         {
             return warn_low_;
         }
 
         const int*
-        src( ) const
+        src( ) const noexcept
         {
             return src_;
         }
 
+        PVMode
+        mode( ) const noexcept
+        {
+            return mode_;
+        }
+
     private:
         std::string name_;
 
@@ -97,7 +110,8 @@ namespace simple_epics
         int warn_high_;
         int warn_low_;
 
-        int* src_;
+        PVMode mode_;
+        int*   src_{ nullptr };
     };
 
     /*!
@@ -108,27 +122,50 @@ namespace simple_epics
     class pvStringAttributes
     {
     public:
-        pvStringAttributes( std::string pv_name, const char* value )
-            : name_{ std::move( pv_name ) }, src_{ value }
+        pvStringAttributes( std::string pv_name,
+                            const char* value,
+                            PVMode      mode = PVMode::ReadOnly,
+                            std::size_t buffer_size = 0 )
+            : name_{ std::move( pv_name ) }, mode_{ mode }, src_{ value },
+              src_size_{ buffer_size }
         {
         }
 
         const std::string&
-        name( ) const
+        name( ) const noexcept
         {
             return name_;
         }
 
         const char*
-        src( ) const
+        src( ) const noexcept
         {
             return src_;
         }
 
+        char*
+        src( ) noexcept
+        {
+            return (char*)src_;
+        }
+
+        std::size_t
+        src_size( ) const noexcept
+        {
+            return src_size_;
+        }
+
+        PVMode
+        mode( ) const noexcept
+        {
+            return mode_;
+        }
+
     private:
         std::string name_;
-
+        PVMode      mode_;
         const char* src_;
+        std::size_t src_size_;
     };
 
     /*!
@@ -142,48 +179,55 @@ namespace simple_epics
         pvDoubleAttributes( std::string                 pv_name,
                             double*                     value,
                             std::pair< double, double > alarm_range,
-                            std::pair< double, double > warn_range )
+                            std::pair< double, double > warn_range,
+                            PVMode mode = PVMode::ReadOnly )
             : name_{ std::move( pv_name ) },
 
               alarm_low_{ alarm_range.first },
               alarm_high_{ alarm_range.second }, warn_low_{ warn_range.first },
-              warn_high_{ warn_range.second }, src_{ value }
+              warn_high_{ warn_range.second }, mode_{ mode }, src_{ value }
         {
         }
 
         const std::string&
-        name( ) const
+        name( ) const noexcept
         {
             return name_;
         }
 
         double
-        alarm_high( ) const
+        alarm_high( ) const noexcept
         {
             return alarm_high_;
         }
         double
-        alarm_low( ) const
+        alarm_low( ) const noexcept
         {
             return alarm_low_;
         }
         double
-        warn_high( ) const
+        warn_high( ) const noexcept
         {
             return warn_high_;
         }
         double
-        warn_low( ) const
+        warn_low( ) const noexcept
         {
             return warn_low_;
         }
 
         const double*
-        src( ) const
+        src( ) const noexcept
         {
             return src_;
         }
 
+        PVMode
+        mode( ) const noexcept
+        {
+            return mode_;
+        }
+
     private:
         std::string name_;
 
@@ -192,7 +236,9 @@ namespace simple_epics
         double warn_high_;
         double warn_low_;
 
-        double* src_;
+        PVMode mode_;
+
+        double* src_{ nullptr };
     };
 
     /*!
@@ -201,7 +247,7 @@ namespace simple_epics
     class Server : public caServer
     {
     public:
-        Server( ) : caServer( ), pvs_{}
+        Server( ) : caServer( ), pvs_{ }
         {
         }
         ~Server( ) override;
diff --git a/src/simple_pv/simple_epics_internal.cc b/src/simple_pv/simple_epics_internal.cc
index 2bf9c4a17636319d2df670ce52d9c6d346dbe474..07e46f92a07158fad97894a7b3f5c6259cfe9b53 100644
--- a/src/simple_pv/simple_epics_internal.cc
+++ b/src/simple_pv/simple_epics_internal.cc
@@ -160,7 +160,14 @@ namespace simple_epics
         caStatus
         simpleIntPV::write( const casCtx& ctx, const gdd& value )
         {
-            return S_casApp_noSupport;
+            if ( attr_.mode( ) != PVMode::ReadWrite )
+            {
+                return S_casApp_noSupport;
+            }
+            aitInt32 newValue;
+            value.get( &newValue, aitEnumInt32 );
+            set_value( newValue );
+            return S_casApp_success;
         }
 
         aitEnum
@@ -334,7 +341,21 @@ namespace simple_epics
         caStatus
         simpleStringPV::write( const casCtx& ctx, const gdd& value )
         {
-            return S_casApp_noSupport;
+            if ( attr_.mode( ) != PVMode::ReadWrite || attr_.src_size( ) < 1 )
+            {
+                return S_casApp_noSupport;
+            }
+            aitString newValue;
+            value.get( &newValue, aitEnumString );
+            if ( newValue.string( ) == nullptr )
+            {
+                return S_casApp_noSupport;
+            }
+            std::strncpy( attr_.src( ), newValue.string( ), attr_.src_size( ) );
+            attr_.src( )[ attr_.src_size( ) - 1 ] == '\0';
+
+            set_value( newValue.string( ) );
+            return S_casApp_success;
         }
 
         aitEnum
@@ -505,7 +526,14 @@ namespace simple_epics
         caStatus
         simpleDoublePV::write( const casCtx& ctx, const gdd& value )
         {
-            return S_casApp_noSupport;
+            if ( attr_.mode( ) != PVMode::ReadWrite )
+            {
+                return S_casApp_noSupport;
+            }
+            aitFloat64 newValue;
+            value.get( &newValue, aitEnumFloat64 );
+            set_value( newValue );
+            return S_casApp_success;
         }
 
         aitEnum
diff --git a/src/simple_pv/simple_epics_internal.hh b/src/simple_pv/simple_epics_internal.hh
index f3adeb4eedfa9b400918c8788f349c35e45a1e29..630a7663874cfaeeb33b93e11fc02738844a0d85 100644
--- a/src/simple_pv/simple_epics_internal.hh
+++ b/src/simple_pv/simple_epics_internal.hh
@@ -60,7 +60,7 @@ namespace simple_epics
             caStatus read( const casCtx& ctx, gdd& prototype ) override;
             caStatus write( const casCtx& ctx, const gdd& value ) override;
 
-            void destroy( ) override{};
+            void destroy( ) override{ };
 
             aitEnum bestExternalType( ) const override;
 
@@ -133,7 +133,7 @@ namespace simple_epics
             caStatus read( const casCtx& ctx, gdd& prototype ) override;
             caStatus write( const casCtx& ctx, const gdd& value ) override;
 
-            void destroy( ) override{};
+            void destroy( ) override{ };
 
             aitEnum bestExternalType( ) const override;
 
@@ -199,7 +199,7 @@ namespace simple_epics
             caStatus read( const casCtx& ctx, gdd& prototype ) override;
             caStatus write( const casCtx& ctx, const gdd& value ) override;
 
-            void destroy( ) override{};
+            void destroy( ) override{ };
 
             aitEnum bestExternalType( ) const override;