Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Hardware
  3. RCS RS485 thermostat

RCS RS485 thermostat

Scheduled Pinned Locked Moved Hardware
21 Posts 4 Posters 6.8k Views 5 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • dbemowskD Offline
    dbemowskD Offline
    dbemowsk
    wrote on last edited by
    #1

    So I did some digging and found my old code that I wrote to control my RCS TR40 thermostat when I was working with a software called Open Source Automation (OSA). The thermostat runs on an RS485 network and I just recently got my RS485 Arduino adapter. I think it may take me a little while, but I would like to port the code over to MySensors and create a MySensors RS485 gateway that will talk to the thermostat. I have some questions before I dive into this circuit though.

    My first question is, with OSA, the thermostat object had some configurable properties that I would assume that I would hard code into the sketch such as the serial port (Which I am guessing won't be needed at all), and the RS485 address. Another property that I would most likely hard code would be the "Refresh Interval" which told the system how often the information would update back to the automation software.

    My next question, which is possibly one that I my just have to figure out in testing, is will an Arduino Pro Mini have enough storage space for everything that I need to code in to the thermostat gateway.

    My last question would be, is there any reason that I would want to store any of the data values on something like an EEPROM on the gateway itself. I would guess that everything would store in the automation software.

    Anyway, here is the code that I am looking to port. I wrote it in Visual Basic.

    Imports System.AddIn
    Imports OpenSourceAutomation
    Imports System.Timers
    Imports System.IO.Ports
    Imports System.Threading.Thread
    Imports MySql.Data.MySqlClient
    
    <AddIn("RCS Thermostat", Version:="0.1.2")>
    Public Class RCSThermostatManager
        Implements IOpenSourceAutomationAddIn
    
        Structure Thermostat
            Dim OutsideAir As Integer
            Dim ZoneCode As Integer
            Dim CurrentTemp As Integer
            Dim CurrentSetpoint As Integer
            Dim CurrentSetpointHeat As Integer
            Dim CurrentSetpointCool As Integer
            Dim CurrentMode As String
            Dim CurrentFanMode As Integer
            Dim HeatStage1 As Integer
            Dim HeatStage2 As Integer
            Dim HeatStage3 As Integer
            Dim CoolStage1 As Integer
            Dim CoolStage2 As Integer
            Dim FanStatus As Integer
            Dim VentDamperStatus As Integer
            Dim ZoneDamperStatus As Integer
            Dim MOTMRT1Status As Integer
            Dim MOTMRT2Status As Integer
            Dim SystemModeStatus As String
            Dim SystemFanStatus As Integer
        End Structure
        'create the mode, fan mode, stage status and MOTMRT associations
        Dim Modes As New Dictionary(Of String, String)
        Dim FanModes As New Dictionary(Of Integer, String)
        Dim Status As New Dictionary(Of Integer, String)
        Dim MOTMRT As New Dictionary(Of Integer, String)
    
        Private Shared OSAEApi As New OSAE("RCS Thermostat")
        Private CN As MySqlConnection
        Private Shared dsObjects As DataSet
    
        Private Shared Plugin As String
        Private Shared ThermostatName As String
        Private Shared ThisObject As String
        Private Shared COMPort As String
        Private Shared SerialAddr As String
        Private Shared ControllerPort As SerialPort
        Private Shared ReceivedMessage As String
        Private Shared ReceiveTime As DateTime
        Private Shared LastSent As String
        Private Shared Tstat As New Thermostat
    
        Private Shared TstatTimer As New System.Timers.Timer
        Private Shared Refresh As Double
        Private Shared BusyFlag As Boolean
    
        Public Sub RunInterface(ByVal pluginName As String) Implements OpenSourceAutomation.IOpenSourceAutomationAddIn.RunInterface
    
            Try
                OSAEApi.AddToLog("Initializing plugin: " & pluginName, True)
                Plugin = pluginName
                ThermostatName = Plugin
    
                'Create the associative arrays for mode, fan mode, status and MOTMRT
                Modes.Add("O", "Off")
                Modes.Add("H", "Heat")
                Modes.Add("C", "Cool")
                Modes.Add("A", "Auto")
                Modes.Add("EH", "Emergency Heat")
                Modes.Add("I", "Invalid")
                FanModes.Add(0, "Auto")
                FanModes.Add(1, "On")
                Status.Add(0, "Off")
                Status.Add(1, "On")
                MOTMRT.Add(0, "Off")
                MOTMRT.Add(1, "MOT")
                MOTMRT.Add(2, "MRT")
    
                DBConnect()
                LoadObjects()
    
                'Define an event based timer to refresh the thermostat reading every 
                'number of seconds based on the "Refresh Interval" value
                If Not Double.TryParse(GetProperty("Refresh Interval"), Refresh) Then
                    Refresh = 20
                End If
                Try
                    TstatTimer.Interval = Refresh * 1000
                    TstatTimer.AutoReset = True
                    AddHandler TstatTimer.Elapsed, AddressOf TstatTimer_Elapsed
                    TstatTimer.Start()
    
                Catch ex As Exception
                    OSAEApi.AddToLog("Error setting up timer: " & ex.Message, True)
                End Try
            Catch ex As Exception
                OSAEApi.AddToLog("Error setting up plugin: " & ex.Message, True)
            End Try
    
        End Sub
    
        Public Sub ProcessCommand(ByVal CommandTable As System.Data.DataTable) Implements OpenSourceAutomation.IOpenSourceAutomationAddIn.ProcessCommand
            Dim Mode As String
            Dim Parameter1 As String
    
            Try
                For Each row In CommandTable.Rows
                    'Get the object that we are processing
                    ThermostatName = row("object_name").ToString
                    SetComPort()
    
                    'Get the first parameter value for use on heating and cooling
                    'set points and setting the thermostat mode
    
                    Parameter1 = row("parameter_1")
                    Select Case row("method_name").ToString
                        Case "GETSTATS"
                            Send("R=1")
    
                        Case "TEMPUP"
                            OSAEApi.EventLogAdd(ThermostatName, "TEMPCHANGE")
                            OSAEApi.AddToLog("Increasing temp set point", False)
                            Send("SP+ R=1")
    
                        Case "TEMPDOWN"
                            OSAEApi.EventLogAdd(ThermostatName, "TEMPCHANGE")
                            OSAEApi.AddToLog("Decreasing temp set point", False)
                            Send("SP- R=1")
    
                        Case "SETHEATSP"
                            OSAEApi.EventLogAdd(ThermostatName, "HEATSPCHANGE")
                            OSAEApi.AddToLog("Setting heating set point to " & Parameter1, False)
                            Send("SPH=" & Parameter1 & " R=1")
    
                        Case "SETCOOLSP"
                            OSAEApi.EventLogAdd(ThermostatName, "COOLSPCHANGE")
                            OSAEApi.AddToLog("Setting cooling set point to " & Parameter1, False)
                            Send("SPC=" & Parameter1 & " R=1")
    
                        Case "SETMODE"
                            OSAEApi.EventLogAdd(ThermostatName, "MODECHANGE")
                            Mode = Tstat.CurrentMode
                            OSAEApi.AddToLog("Changing mode from " & Modes(Mode) & " to " & Parameter1, False)
                            Send("M=" & Parameter1 & " R=1")
    
                        Case "FANON"
                            OSAEApi.EventLogAdd(ThermostatName, "FANON")
                            OSAEApi.AddToLog("Turning fan on", False)
                            Send("F=1 R=1")
    
                        Case "FANOFF"
                            OSAEApi.EventLogAdd(ThermostatName, "FANOFF")
                            Mode = If(Tstat.CurrentFanMode = 0, 1, 0)
                            OSAEApi.AddToLog("Turning fan off", False)
                            Send("F=0 R=1")
    
                        Case "TOGGLEFANMODE"
                            OSAEApi.EventLogAdd(ThermostatName, "FANMODECHANGE")
                            Mode = If(Tstat.CurrentFanMode = 0, 1, 0)
                            OSAEApi.AddToLog("Changing mode from " & Status(Tstat.CurrentFanMode) & " to " & Status(Mode), False)
                            Send("F=" & Mode & " R=1")
    
                        Case "ON"
                            OSAEApi.AddToLog("Starting thermostat automatic updates", False)
                            TstatTimer.Start()
    
                        Case "OFF"
                            OSAEApi.AddToLog("Stopping thermostat automatic updates", False)
                            TstatTimer.Stop()
                    End Select
                Next
            Catch ex As Exception
                OSAEApi.AddToLog("Error Processing Command: " & ex.Message, True)
            End Try
    
        End Sub
    
        Public Sub Shutdown() Implements OpenSourceAutomation.IOpenSourceAutomationAddIn.Shutdown
            OSAEApi.AddToLog("Shutting down plugin", True)
            ControllerPort.Close()
            OSAEApi.AddToLog("Finished shutting down plugin", True)
        End Sub
    
        Public Sub SetComPort()
            Dim Port As String
            Try
                Port = GetProperty("COM Port")
                'Check the port that we are currently working with and change it 
                'if it Is different
                If COMPort <> "COM" + Port Then
                    COMPort = "COM" + Port
    
                    ControllerPort = New SerialPort(COMPort, 9600, Parity.None, 8, StopBits.One)
                    OSAEApi.AddToLog("Port is set to: " & COMPort, True)
                    ControllerPort.NewLine = vbCrLf
                    ControllerPort.ReadTimeout = 5
    
                    ControllerPort.Open()
                End If
                'Get the RS-485 address
                SerialAddr = GetProperty("Serial Address")
    
                'To prevent double subscribing we'll first disassociate the event handler and then re-add it
                RemoveHandler ControllerPort.DataReceived, AddressOf UpdateReceived
                AddHandler ControllerPort.DataReceived, New SerialDataReceivedEventHandler(AddressOf UpdateReceived)
    
            Catch ex As Exception
                OSAEApi.AddToLog("Error setting com port: " & ex.Message, True)
            End Try
    
        End Sub
    
        Public Sub DBConnect()
            CN = New MySqlConnection
            CN.ConnectionString = "server=" & OSAEApi.DBConnection & ";Port=" & OSAEApi.DBPort & ";Database=" & OSAEApi.DBName & ";Password=" & OSAEApi.DBPassword & ";use procedure bodies=false;Persist Security Info=True;User ID=" & OSAEApi.DBUsername
            Try
                CN.Open()
                CN.Close()
                OSAEApi.AddToLog("Connected to Database: " & OSAEApi.DBName & " @ " & OSAEApi.DBConnection & ":" & OSAEApi.DBPort, True)
            Catch ex As Exception
                OSAEApi.AddToLog("Error Connecting to Database: " & ex.Message, True)
            End Try
        End Sub
    
        Private Sub LoadObjects()
            Dim CMD As New MySqlCommand
    
            Try
                'Connect to the database and find any RCS_THERMOSTAT object types so
                'they can all be automatically updated.
                CMD.Connection = CN
                CMD.CommandType = CommandType.Text
                CMD.CommandText = "SELECT object_name FROM osae_v_object WHERE object_type='RCS-TR40 THERMOSTAT'"
                dsObjects = OSAEApi.RunQuery(CMD)
    
                For Each Row As DataRow In dsObjects.Tables(0).Rows
                    OSAEApi.AddToLog("Found object: " & Row("object_name").ToString, True)
                Next
    
            Catch ex As Exception
                OSAEApi.AddToLog("Error loading objects: " & ex.Message, True)
            End Try
    
        End Sub
    
        Private Sub TstatTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs)
            For Each Row As DataRow In dsObjects.Tables(0).Rows
                'get the name of the object we are working on
                ThermostatName = Row("object_name").ToString
    
                'Make sure we are on the correct com port and RS-485 address for this object
                SetComPort()
    
                'Send the First status call to the thermostat
                Send("R=1")
    
                'Wait here while we process the first command
                Sleep(2000)
    
                'Send the second status call to the thermostat
                Send("R=2")
            Next
        End Sub
    
        Protected Sub UpdateReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)
            OSAEApi.AddToLog("Running serial port event handler", False)
            ProcessReceived()
    
        End Sub
    
        Protected Sub ProcessReceived()
            Dim Message As String
            Dim CrIndex As Integer
    
            Try
                Message = ControllerPort.ReadExisting()
                OSAEApi.AddToLog("Serial data received: " & Message.TrimEnd, True)
    
                If Message.Length > 0 Then
                    ReceivedMessage += Message
                    While True
                        CrIndex = ReceivedMessage.IndexOf(vbCr)
                        If CrIndex > -1 Then
                            ReceiveTime = Now()
                            ParseReceived(Left(ReceivedMessage, CrIndex))
                            ReceivedMessage = Mid(ReceivedMessage, CrIndex + 3)
                        Else
                            Exit While
                        End If
                    End While
                End If
    
                'Clear the BusyFlag
                BusyFlag = False
            Catch ex As Exception
                OSAEApi.AddToLog("Error receiving on com port: " & ex.Message, True)
            End Try
    
        End Sub
    
        Protected Sub ParseReceived(ByVal Message As String)
            Dim StatusData() As String
            Dim Count As Integer
            Dim StatusString As String
            Dim Status() As String
            Dim Type As String
            Dim Value As String
    
            Try
                OSAEApi.AddToLog("Processing: " & Message, True)
                SetProperty("Received", Message)
    
                'Split the status message into parts
                StatusData = Message.Split(" ")
    
                If StatusData(0).StartsWith("A=") Then
                    'Loop through each status data string and process it
                    Count = 0
                    While Count < StatusData.Length - 1
                        StatusString = StatusData(Count)
                        Status = StatusString.Split("=")
                        Type = Status(0)
                        Value = Status(1)
                        ParseStatus(Type, Value)
                        Count = Count + 1
                    End While
                Else
                    'The received response was not formatted properly.  Re-send the command
                    OSAEApi.AddToLog("re-sending command: " & LastSent, False)
                    Send(LastSent)
                End If
            Catch ex As Exception
                OSAEApi.AddToLog("Error parsing received message: " & ex.Message, True)
            End Try
    
        End Sub
    
        Protected Sub ParseStatus(ByVal Type As String, ByVal Value As String)
            Dim stg1 As Integer
            Dim stg2 As Integer
            'Process each kind of status type
            Try
                Select Case Type
                    'Type 1 status message types
                    Case "OA"
                        'OSAEApi.AddToLog("Outside air reading: " & Value, True)
                        Tstat.OutsideAir = Value
                        SetProperty("Outside Air", Value)
                    Case "Z"
                        'OSAEApi.AddToLog("Reading for zone: " & Value, True)
                        Tstat.ZoneCode = Value
                        SetProperty("Zone", Value)
                    Case "T"
                        'OSAEApi.AddToLog("Temperature reading: " & Value, True)
                        Tstat.CurrentTemp = Value
                        SetProperty("Temperature", Value)
                    Case "SP"
                        'OSAEApi.AddToLog("Set point: " & Value, True)
                        Tstat.CurrentSetpoint = Value
                        SetProperty("Set Point", Value)
                    Case "SPH"
                        'OSAEApi.AddToLog("Heat set point: " & Value, True)
                        Tstat.CurrentSetpointHeat = Value
                        SetProperty("Set Point Heat", Value)
                    Case "SPC"
                        'OSAEApi.AddToLog("Cold set point: " & Value, True)
                        Tstat.CurrentSetpointCool = Value
                        SetProperty("Set Point Cool", Value)
                    Case "M"
                        'OSAEApi.AddToLog("Mode: " & Value, True)
                        Tstat.CurrentMode = Value
                        SetProperty("Mode", Modes(Value))
                    Case "FM"
                        'OSAEApi.AddToLog("Fan mode: " & Value, True)
                        Tstat.CurrentFanMode = Value
                        SetProperty("Fan Mode", FanModes(Value))
                        'Type 2 status message types
                    Case "H1A"
                        'OSAEApi.AddToLog("Heat stage 1: " & Value, True)
                        If Tstat.HeatStage1 <> Value Then
                            OSAEApi.EventLogAdd(ThermostatName, "STATUSCHANGE")
                        End If
                        Tstat.HeatStage1 = Value
                        SetProperty("Heat Stage 1", Status(Value))
                    Case "H2A"
                        'OSAEApi.AddToLog("Heat stage 2: " & Value, True)
                        If Tstat.HeatStage2 <> Value Then
                            OSAEApi.EventLogAdd(ThermostatName, "STATUSCHANGE")
                        End If
                        Tstat.HeatStage2 = Value
                        SetProperty("Heat Stage 2", Status(Value))
                    Case "H3A"
                        'OSAEApi.AddToLog("Heat stage 3: " & Value, True)
                        If Tstat.HeatStage1 <> Value Then
                            OSAEApi.EventLogAdd(ThermostatName, "STATUSCHANGE")
                        End If
                        Tstat.HeatStage3 = Value
                        SetProperty("Heat Stage 3", Status(Value))
                    Case "C1A"
                        'OSAEApi.AddToLog("Cool stage 1: " & Value, True)
                        If Tstat.CoolStage1 <> Value Then
                            OSAEApi.EventLogAdd(ThermostatName, "STATUSCHANGE")
                        End If
                        Tstat.CoolStage1 = Value
                        SetProperty("Cool Stage 1", Status(Value))
                    Case "C2A"
                        'OSAEApi.AddToLog("Cool stage 2: " & Value, True)
                        If Tstat.CoolStage2 <> Value Then
                            OSAEApi.EventLogAdd(ThermostatName, "STATUSCHANGE")
                        End If
                        Tstat.CoolStage2 = Value
                        SetProperty("Cool Stage 2", Status(Value))
                    Case "FA"
                        'OSAEApi.AddToLog("Fan status: " & Value, True)
                        If Tstat.CoolStage2 <> Value Then
                            OSAEApi.EventLogAdd(ThermostatName, "FANMODECHANGE")
                        End If
                        Tstat.FanStatus = Value
                        SetProperty("Fan Status", FanModes(Value))
                    Case "VA"
                        'OSAEApi.AddToLog("Vent damper: " & Value, True)
                        Tstat.VentDamperStatus = Value
                        SetProperty("Vent Damper", Status(Value))
                    Case "D1"
                        'OSAEApi.AddToLog("Zone damper: " & Value, True)
                        Tstat.ZoneDamperStatus = Value
                        SetProperty("Zone Damper", Status(Value))
                    Case "SCP"
                        stg1 = Left(Value, 1)
                        stg2 = Right(Value, 1)
    
                        'OSAEApi.AddToLog("MOT/MRT stage 1: " & stg1, True)
                        Tstat.MOTMRT1Status = stg1
                        SetProperty("MOTMRT1", MOTMRT(stg1))
    
                        'OSAEApi.AddToLog("MOT/MRT stage 2: " & stg2, True)
                        Tstat.MOTMRT2Status = stg2
                        SetProperty("MOTMRT2", MOTMRT(stg2))
                    Case "SM"
                        'OSAEApi.AddToLog("System mode: " & Value, True)
                        Tstat.SystemModeStatus = Value
                        SetProperty("System Mode", Modes(Value))
                    Case "SF"
                        'OSAEApi.AddToLog("System fan: " & Value, True)
                        Tstat.SystemFanStatus = Value
                        SetProperty("System Fan", Status(Value))
                End Select
            Catch ex As Exception
                OSAEApi.AddToLog("Error parsing status data: " & ex.Message, True)
            End Try
        End Sub
    
        Private Sub Send(ByVal Cmd As String)
            Dim Command As String = "A=" & SerialAddr & " O=00 " & Cmd
            Try
                OSAEApi.AddToLog("Writing to serial port " & COMPort & ": " & Command, False)
                ControllerPort.Write(Command & vbCr)
                LastSent = Cmd
            Catch
                OSAEApi.AddToLog("Error sending command to serial port " & COMPort & ": " & Command, False)
            End Try
        End Sub
    
        Private Sub SetProperty(ByVal PropertyName As String, ByVal Data As String)
            Try
                OSAEApi.ObjectPropertySet(ThermostatName, PropertyName, Data)
            Catch ex As Exception
                OSAEApi.AddToLog("Error setting property value: " & ex.Message, True)
            End Try
        End Sub
    
        Private Function GetProperty(ByVal PropertyName As String) As String
            Dim val As String = ""
            Try
                val = OSAEApi.GetObjectPropertyValue(ThermostatName, PropertyName).Value()
                'OSAEApi.AddToLog("Fetched value: [" & val & "] from object [" & ThermostatName & "] and from property name[" & PropertyName & "]", False)
            Catch ex As Exception
                OSAEApi.AddToLog("Error getting property value: " & ex.Message, True)
            End Try
            Return val
        End Function
    
    End Class
    

    Vera Plus running UI7 with MySensors, Sonoffs and 1-Wire devices
    Visit my website for more Bits, Bytes and Ramblings from me: http://dan.bemowski.info/

    1 Reply Last reply
    0
    • dbemowskD Offline
      dbemowskD Offline
      dbemowsk
      wrote on last edited by
      #2

      So I have been working on my RS485 gateway/bridge for my RCS thermostat. I have the code set up no so that commands sent from the thermostat will update Domoticz, but I ran into a snag that I cannot figure out. Here is the code I have so far. Still a bit rough.

       /*
        RCS Thermostat for MySensors
      
        Arduino RCS RS485 thermostat control
      
        July 7,2016
      
        This is a gateway bridge to allow an RCS serial thermostat to be
      accessible to a MySensors
        gateway.  The thermostat being used to test this is an RCS TR40 RS485
      thermostat.  The published
        protocol for RCS thermostats can be found at the following address;
        http://www.rcstechnology.com/oldsite/docs/thermostats/serial/SERIAL%20PROTOCOL%20REV%204.3%20%20150-00225-43.pdf
      
        This sketch features the following:
      
        Add features here
       */
      
      // Import needed libraries
      #include <MySensor.h>
      #include <SPI.h>
      #include <SoftwareSerial.h>
      
      #define SKETCH_NAME "RCS Thermostat"
      #define SKETCH_VERSION "1.0"
      
      #define CHILD_ID_TEMP          0 // V_TEMP
      #define CHILD_ID_STATUS        1 // V_STATUS
      #define CHILD_ID_SETPOINT_COOL 2 // V_HVAC_SETPOINT_COOL
      #define CHILD_ID_SETPOINT_HEAT 3 // V_HVAC_SETPOINT_HEAT
      #define CHILD_ID_FLOW_STATE    4 // V_HVAC_FLOW_STATE
      #define CHILD_ID_FLOW_MODE     5 // V_HVAC_FLOW_MODE
      #define CHILD_ID_HVAC_SPEED    6 // V_HVAC_SPEED
      
      // Declare Constants and Pin Numbers
      #define SSerialRX        5  //Serial Receive pin 8
      #define SSerialTX        3  //Serial Transmit pin 7
      
      #define SSerialTxControl 4  //RS485 Direction control
      
      #define RS485Transmit    HIGH
      #define RS485Receive     LOW
      
      #define Pin12LED         12
      #define Pin13LED         13
      
      // Declare objects
      SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX
      
      MySensor gw;
      
      // Sensor values
      // V_TEMP, V_STATUS, V_HVAC_FLOW_STATE, V_HVAC_SPEED
      // V_HVAC_SETPOINT_COOL, V_HVAC_SETPOINT_HEAT, V_HVAC_FLOW_MODE
      MyMessage msgTemp( CHILD_ID_TEMP,             V_TEMP );
      MyMessage msgStatus( CHILD_ID_STATUS,         V_STATUS );
      MyMessage msgSetCool( CHILD_ID_SETPOINT_COOL, V_HVAC_SETPOINT_COOL );
      MyMessage msgSetHeat( CHILD_ID_SETPOINT_HEAT, V_HVAC_SETPOINT_HEAT );
      MyMessage msgFlowState( CHILD_ID_FLOW_STATE,  V_HVAC_FLOW_STATE );
      MyMessage msgFlowMode( CHILD_ID_FLOW_MODE,    V_HVAC_FLOW_MODE );
      MyMessage msgHvacSpeed( CHILD_ID_HVAC_SPEED,  V_HVAC_SPEED );
      
      
      // Sensor sub-type
      // S_HVAC
      
      // Declare Variables
      int byteReceived;
      int byteSend;
      String rcvString;
      String sndString;
      //This is for storing the last command that was sent
      String lastSent;
      //the last sent set point
      String setPoint;
      
      String mode;
      //This is the RS485 address of this node that gets sent to the thermostat
      String serialAddr = "1";
      //Placeholder for the last command sent
      String LastSent = "";
      
      
      void setup() {
        Serial.begin(9600);
      
        gw.begin( incomingMessage, AUTO, true );
      
        gw.sendSketchInfo( SKETCH_NAME, SKETCH_VERSION );
      
        // Register the thermostat with the gateway
        gw.present( CHILD_ID_TEMP,          S_HVAC );
        gw.present( CHILD_ID_STATUS,        S_HVAC );
        gw.present( CHILD_ID_SETPOINT_COOL, S_HVAC );
        gw.present( CHILD_ID_SETPOINT_HEAT, S_HVAC );
        gw.present( CHILD_ID_FLOW_STATE,    S_HVAC );
        gw.present( CHILD_ID_FLOW_MODE,     S_HVAC );
      
        // put your setup code here, to run once:
        pinMode(SSerialTxControl, OUTPUT);
      
        digitalWrite(SSerialTxControl, RS485Receive);  // Init Transceiver
      
        // Start the software serial port, to another device
        RS485Serial.begin(9600);   // set the data rate
      
      } //End setup
      
      void loop() {
        String dataIn;
        if (RS485Serial.available()) {
          dataIn = RS485Serial.readStringUntil('\n');
          ParseReceived(dataIn);
        }
      } //End loop
      
      void ParseReceived(String Message) {
        String StatusData;
        //int Count;
        String StatusString;
        String Status;
        String Type;
        String Value;
      
        int Index;
        int Start;
        int End;
        int StatIndex;
      
        Index = Message.indexOf(' ');
        Start = 0;
      
        Serial.println("Message: " + Message);
      
        if (Message.startsWith("A=")) {
          do {
            End =(Index == -1) ? Message.length() : Index;
            //Get the status string to process
            StatusString = Message.substring(Start, End);
            //Change our start position to 1 over the last space found
            Start = Index + 1;
            //Find the end of the next status string
            Index = Message.indexOf(' ', Start);
      
            //Now we need to process the status string into it's Type and Value
            StatIndex = StatusString.indexOf('=');
            Type = StatusString.substring(0, StatIndex);
            Value = StatusString.substring(StatIndex + 1);
            ParseStatus(Type, Value);
          } while (Index != -1);
        } else {
          SendCmd(LastSent);
        }
      } //End ParseReceived
      
      void ParseStatus(String Type, String Value) {
        //int stg1;
        //int stg2;
      
        //Serial.write("Type = " + Type + " : Value = " + Value + "\r\n");
        //Process each kind of status type
      
        if (Type == "OA") {
            //Outside Air not used
        } else if (Type == "Z") {
            //Zone not used
        } else if (Type == "T") {
            //logging.AddToLog("Temperature reading: " & Value, True)
            gw.send(msgTemp.set(Value.toInt()));
        } else if (Type == "SP") {
            //logging.AddToLog("Set point: " & Value, True)
            Serial.println("Set point: " + Value);
            gw.send(msgSetCool.set(Value.toInt()));
        } else if (Type == "SPH") {
            //logging.AddToLog("Heat set point: " & Value, True)
            Serial.println("Heat set point: " + Value);
            gw.send(msgSetHeat.set(Value.toInt)));
        } else if (Type == "SPC") {
            //logging.AddToLog("Cold set point: " & Value, True)
            Serial.println("Cold set point: " + Value);
            gw.send(msgSetCool.set(Value.toInt()));
        } else if (Type == "M") {
            //logging.AddToLog("Mode: " & Value, True)
            Serial.println("Mode: " + Value);
            gw.send(msgFlowMode.set(Value.c_str()));
        } else if (Type == "FM") {
            //logging.AddToLog("Fan mode: " & Value, True)
            Serial.println("Fan mode: " + Value);
            gw.send(msgFlowMode.set(Value.c_str()));
          //Type 2 status message types
        } else if (Type == "H1A") {
            //logging.AddToLog("Heat stage 1: " & Value, True)
            Serial.println("Heat stage 1: " + Value);
            gw.send(msgHvacSpeed.set("Min"));
        } else if (Type == "H2A") {
            //logging.AddToLog("Heat stage 2: " & Value, True)
            Serial.println("Heat stage 2: " + Value);
            gw.send(msgHvacSpeed.set("Normal"));
        } else if (Type == "H3A") {
            //logging.AddToLog("Heat stage 3: " & Value, True)
            Serial.println("Heat stage 3: " + Value);
            gw.send(msgHvacSpeed.set("Max"));
        } else if (Type == "C1A") {
            //logging.AddToLog("Cool stage 1: " & Value, True)
            Serial.println("Cool stage 1: " + Value);
            gw.send(msgHvacSpeed.set("Min"));
        } else if (Type == "C2A") {
            //logging.AddToLog("Cool stage 2: " & Value, True)
            Serial.println("Cool stage 2: " + Value);
            gw.send(msgHvacSpeed.set("Normal"));
        } else if (Type == "FA") {
            //logging.AddToLog("Fan status: " & Value, True)
            Serial.println("Mode: " + Value);
            gw.send(msgFlowMode.set("Normal"));
        } else if (Type == "VA") {
            //logging.AddToLog("Vent damper: " & Value, True)
            //Vent damper not used
        } else if (Type == "D1") {
            //logging.AddToLog("Zone damper: " & Value, True)
            //Damper #1 not used
        } else if (Type == "SCP") {
            //stg1 = Value.substring(0, 1)
            //stg2 = Value.substring(0, -1)
      
            //logging.AddToLog("MOT/MRT stage 1: " & stg1, True)
            //Deal with minimum off time and minimum run times
            //for stage 1
      
            //logging.AddToLog("MOT/MRT stage 2: " & stg2, True)
            //Deal with minimum off time and minimum run times
            //for stage 2
        } else if (Type == "SM") {
            //logging.AddToLog("System mode: " & Value, True)
            String FlowState;
      
            if (Value == "O") {
              FlowState = "Off";
            } else if (Value == "H") {
              FlowState = "HeatOn";
            } else if (Value == "C") {
              FlowState = "CoolOn";
            } else {
              FlowState = "AutoChangeOver";
            }
            Serial.println("Flow state: " + FlowState);
            gw.send(msgFlowState.set(FlowState.c_str()));
        } else if (Type == "SF") {
            //logging.AddToLog("System fan: " & Value, True)
            Serial.println("System fan : " + Value);
            gw.send(msgStatus.set(Value.toInt()));
        }
      } //End ParseStatus
      
      void SendCmd(String cmd) {
        String commandStr;
        commandStr = "A=" + serialAddr + " O=00 " + cmd;
      
        //DEBUG_PRINTLN("Writing to serial port: " + Command);
      
        // Enable RS485 Transmit only for the duration of the send
        digitalWrite(SSerialTxControl, RS485Transmit);
        RS485Serial.print(commandStr + "\r");
        LastSent = cmd;
        //Return to RS485 receive mode
        digitalWrite(SSerialTxControl, RS485Receive);
      } //End SendCmd
      
      void SetProperty(String PropertyName, String Data) {
        //
        PropertyName = "";
        Data = "";
      } //End SendCmd
      
      void incomingMessage(const MyMessage &message) {
        Serial.println(message.type);
        // We only expect one type of message from controller. But we better
      check anyway.
        if (message.isAck()) {
           Serial.println("This is an ack from gateway");
        }
      
        if (message.type == V_HVAC_SETPOINT_COOL) {
           Serial.println("Message received");
           setPoint = String(message.data).toInt();
           Serial.println("New Set Temp is : " + String(setPoint));
           SendCmd("SPC=" + setPoint + " R=1");
      
           // Write some debug info
           Serial.print("Incoming change for sensor:");
           Serial.print(message.sensor);
           Serial.print(", New status: ");
           Serial.println(message.data);
        }
      
        if (message.type == V_HVAC_SETPOINT_HEAT) {
           Serial.println("Message received");
           setPoint = String(message.data).toInt();
           Serial.println("New Set Temp is : " + String(setPoint));
           SendCmd("SPH=" + setPoint + " R=1");
      
           // Write some debug info
           Serial.print("Incoming change for sensor:");
           Serial.print(message.sensor);
           Serial.print(", New status: ");
           Serial.println(message.data);
        }
      } //End incomingMessage
      

      The problem I have is that I am trying to send a decimal or float number for my temp value and I cannot figure out how. In the code, there is the ParseStatus function which takes a Type and Value as it's arguments. For types like "SP" , "SPH", "SPC", etc... I have it converting the value to an integer ( Value.toInt() ) which works. But if I try to convert it to a floating point decimal ( Value.toFloat() ), I get an error:

      C:\Users\dbemowsk\Documents\Arduino\RCS_RS485_Thermostat\RCS_RS485_Thermostat.ino:
      In function 'void ParseStatus(String, String)':
      
      RCS_RS485_Thermostat:176: error: call of overloaded 'set(float)' is ambiguous
      
             gw.send(msgSetHeat.set(Value.toFloat()));
      
                                                   ^
      
      C:\Users\dbemowsk\Documents\Arduino\RCS_RS485_Thermostat\RCS_RS485_Thermostat.ino:176:45:
      note: candidates are:
      
      In file included from C:\Program Files
      (x86)\Arduino\libraries\MySensors/MyParser.h:23:0,
      
                       from C:\Program Files
      (x86)\Arduino\libraries\MySensors/MySensor.h:29,
      
                       from
      C:\Users\dbemowsk\Documents\Arduino\RCS_RS485_Thermostat\RCS_RS485_Thermostat.ino:19:
      
      C:\Program Files (x86)\Arduino\libraries\MySensors/MyMessage.h:262:13:
      note: MyMessage& MyMessage::set(uint8_t)
      
        MyMessage& set(uint8_t value);
      
                   ^
      
      C:\Program Files (x86)\Arduino\libraries\MySensors/MyMessage.h:264:13:
      note: MyMessage& MyMessage::set(long unsigned int)
      
        MyMessage& set(unsigned long value);
      
                   ^
      
      C:\Program Files (x86)\Arduino\libraries\MySensors/MyMessage.h:265:13:
      note: MyMessage& MyMessage::set(long int)
      
        MyMessage& set(long value);
      
                   ^
      
      C:\Program Files (x86)\Arduino\libraries\MySensors/MyMessage.h:266:13:
      note: MyMessage& MyMessage::set(unsigned int)
      
        MyMessage& set(unsigned int value);
      
                   ^
      
      C:\Program Files (x86)\Arduino\libraries\MySensors/MyMessage.h:267:13:
      note: MyMessage& MyMessage::set(int)
      
        MyMessage& set(int value);
      
                   ^
      
      exit status 1
      call of overloaded 'set(float)' is ambiguous
      

      Is it possible to send decimal numbers?

      The next issue is that when I send values for the heat or cool set points, I have to send them as metric Celsius values. When I send them in Farenheit the number shown in Dompticz is WAY too high. That I am sure is a setting somewhere in Domoticz, but I haven't found it yet.

      The last thing is that when I send an "SPC" or Set Point Cool value, Domoticz shows a value of 190.2 and it doesn't change if I send another value. I looked over the code and I am not seeing anything that looks to be wrong (other than the floating point number issue).

      Vera Plus running UI7 with MySensors, Sonoffs and 1-Wire devices
      Visit my website for more Bits, Bytes and Ramblings from me: http://dan.bemowski.info/

      mfalkviddM 1 Reply Last reply
      0
      • dbemowskD dbemowsk

        So I have been working on my RS485 gateway/bridge for my RCS thermostat. I have the code set up no so that commands sent from the thermostat will update Domoticz, but I ran into a snag that I cannot figure out. Here is the code I have so far. Still a bit rough.

         /*
          RCS Thermostat for MySensors
        
          Arduino RCS RS485 thermostat control
        
          July 7,2016
        
          This is a gateway bridge to allow an RCS serial thermostat to be
        accessible to a MySensors
          gateway.  The thermostat being used to test this is an RCS TR40 RS485
        thermostat.  The published
          protocol for RCS thermostats can be found at the following address;
          http://www.rcstechnology.com/oldsite/docs/thermostats/serial/SERIAL%20PROTOCOL%20REV%204.3%20%20150-00225-43.pdf
        
          This sketch features the following:
        
          Add features here
         */
        
        // Import needed libraries
        #include <MySensor.h>
        #include <SPI.h>
        #include <SoftwareSerial.h>
        
        #define SKETCH_NAME "RCS Thermostat"
        #define SKETCH_VERSION "1.0"
        
        #define CHILD_ID_TEMP          0 // V_TEMP
        #define CHILD_ID_STATUS        1 // V_STATUS
        #define CHILD_ID_SETPOINT_COOL 2 // V_HVAC_SETPOINT_COOL
        #define CHILD_ID_SETPOINT_HEAT 3 // V_HVAC_SETPOINT_HEAT
        #define CHILD_ID_FLOW_STATE    4 // V_HVAC_FLOW_STATE
        #define CHILD_ID_FLOW_MODE     5 // V_HVAC_FLOW_MODE
        #define CHILD_ID_HVAC_SPEED    6 // V_HVAC_SPEED
        
        // Declare Constants and Pin Numbers
        #define SSerialRX        5  //Serial Receive pin 8
        #define SSerialTX        3  //Serial Transmit pin 7
        
        #define SSerialTxControl 4  //RS485 Direction control
        
        #define RS485Transmit    HIGH
        #define RS485Receive     LOW
        
        #define Pin12LED         12
        #define Pin13LED         13
        
        // Declare objects
        SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX
        
        MySensor gw;
        
        // Sensor values
        // V_TEMP, V_STATUS, V_HVAC_FLOW_STATE, V_HVAC_SPEED
        // V_HVAC_SETPOINT_COOL, V_HVAC_SETPOINT_HEAT, V_HVAC_FLOW_MODE
        MyMessage msgTemp( CHILD_ID_TEMP,             V_TEMP );
        MyMessage msgStatus( CHILD_ID_STATUS,         V_STATUS );
        MyMessage msgSetCool( CHILD_ID_SETPOINT_COOL, V_HVAC_SETPOINT_COOL );
        MyMessage msgSetHeat( CHILD_ID_SETPOINT_HEAT, V_HVAC_SETPOINT_HEAT );
        MyMessage msgFlowState( CHILD_ID_FLOW_STATE,  V_HVAC_FLOW_STATE );
        MyMessage msgFlowMode( CHILD_ID_FLOW_MODE,    V_HVAC_FLOW_MODE );
        MyMessage msgHvacSpeed( CHILD_ID_HVAC_SPEED,  V_HVAC_SPEED );
        
        
        // Sensor sub-type
        // S_HVAC
        
        // Declare Variables
        int byteReceived;
        int byteSend;
        String rcvString;
        String sndString;
        //This is for storing the last command that was sent
        String lastSent;
        //the last sent set point
        String setPoint;
        
        String mode;
        //This is the RS485 address of this node that gets sent to the thermostat
        String serialAddr = "1";
        //Placeholder for the last command sent
        String LastSent = "";
        
        
        void setup() {
          Serial.begin(9600);
        
          gw.begin( incomingMessage, AUTO, true );
        
          gw.sendSketchInfo( SKETCH_NAME, SKETCH_VERSION );
        
          // Register the thermostat with the gateway
          gw.present( CHILD_ID_TEMP,          S_HVAC );
          gw.present( CHILD_ID_STATUS,        S_HVAC );
          gw.present( CHILD_ID_SETPOINT_COOL, S_HVAC );
          gw.present( CHILD_ID_SETPOINT_HEAT, S_HVAC );
          gw.present( CHILD_ID_FLOW_STATE,    S_HVAC );
          gw.present( CHILD_ID_FLOW_MODE,     S_HVAC );
        
          // put your setup code here, to run once:
          pinMode(SSerialTxControl, OUTPUT);
        
          digitalWrite(SSerialTxControl, RS485Receive);  // Init Transceiver
        
          // Start the software serial port, to another device
          RS485Serial.begin(9600);   // set the data rate
        
        } //End setup
        
        void loop() {
          String dataIn;
          if (RS485Serial.available()) {
            dataIn = RS485Serial.readStringUntil('\n');
            ParseReceived(dataIn);
          }
        } //End loop
        
        void ParseReceived(String Message) {
          String StatusData;
          //int Count;
          String StatusString;
          String Status;
          String Type;
          String Value;
        
          int Index;
          int Start;
          int End;
          int StatIndex;
        
          Index = Message.indexOf(' ');
          Start = 0;
        
          Serial.println("Message: " + Message);
        
          if (Message.startsWith("A=")) {
            do {
              End =(Index == -1) ? Message.length() : Index;
              //Get the status string to process
              StatusString = Message.substring(Start, End);
              //Change our start position to 1 over the last space found
              Start = Index + 1;
              //Find the end of the next status string
              Index = Message.indexOf(' ', Start);
        
              //Now we need to process the status string into it's Type and Value
              StatIndex = StatusString.indexOf('=');
              Type = StatusString.substring(0, StatIndex);
              Value = StatusString.substring(StatIndex + 1);
              ParseStatus(Type, Value);
            } while (Index != -1);
          } else {
            SendCmd(LastSent);
          }
        } //End ParseReceived
        
        void ParseStatus(String Type, String Value) {
          //int stg1;
          //int stg2;
        
          //Serial.write("Type = " + Type + " : Value = " + Value + "\r\n");
          //Process each kind of status type
        
          if (Type == "OA") {
              //Outside Air not used
          } else if (Type == "Z") {
              //Zone not used
          } else if (Type == "T") {
              //logging.AddToLog("Temperature reading: " & Value, True)
              gw.send(msgTemp.set(Value.toInt()));
          } else if (Type == "SP") {
              //logging.AddToLog("Set point: " & Value, True)
              Serial.println("Set point: " + Value);
              gw.send(msgSetCool.set(Value.toInt()));
          } else if (Type == "SPH") {
              //logging.AddToLog("Heat set point: " & Value, True)
              Serial.println("Heat set point: " + Value);
              gw.send(msgSetHeat.set(Value.toInt)));
          } else if (Type == "SPC") {
              //logging.AddToLog("Cold set point: " & Value, True)
              Serial.println("Cold set point: " + Value);
              gw.send(msgSetCool.set(Value.toInt()));
          } else if (Type == "M") {
              //logging.AddToLog("Mode: " & Value, True)
              Serial.println("Mode: " + Value);
              gw.send(msgFlowMode.set(Value.c_str()));
          } else if (Type == "FM") {
              //logging.AddToLog("Fan mode: " & Value, True)
              Serial.println("Fan mode: " + Value);
              gw.send(msgFlowMode.set(Value.c_str()));
            //Type 2 status message types
          } else if (Type == "H1A") {
              //logging.AddToLog("Heat stage 1: " & Value, True)
              Serial.println("Heat stage 1: " + Value);
              gw.send(msgHvacSpeed.set("Min"));
          } else if (Type == "H2A") {
              //logging.AddToLog("Heat stage 2: " & Value, True)
              Serial.println("Heat stage 2: " + Value);
              gw.send(msgHvacSpeed.set("Normal"));
          } else if (Type == "H3A") {
              //logging.AddToLog("Heat stage 3: " & Value, True)
              Serial.println("Heat stage 3: " + Value);
              gw.send(msgHvacSpeed.set("Max"));
          } else if (Type == "C1A") {
              //logging.AddToLog("Cool stage 1: " & Value, True)
              Serial.println("Cool stage 1: " + Value);
              gw.send(msgHvacSpeed.set("Min"));
          } else if (Type == "C2A") {
              //logging.AddToLog("Cool stage 2: " & Value, True)
              Serial.println("Cool stage 2: " + Value);
              gw.send(msgHvacSpeed.set("Normal"));
          } else if (Type == "FA") {
              //logging.AddToLog("Fan status: " & Value, True)
              Serial.println("Mode: " + Value);
              gw.send(msgFlowMode.set("Normal"));
          } else if (Type == "VA") {
              //logging.AddToLog("Vent damper: " & Value, True)
              //Vent damper not used
          } else if (Type == "D1") {
              //logging.AddToLog("Zone damper: " & Value, True)
              //Damper #1 not used
          } else if (Type == "SCP") {
              //stg1 = Value.substring(0, 1)
              //stg2 = Value.substring(0, -1)
        
              //logging.AddToLog("MOT/MRT stage 1: " & stg1, True)
              //Deal with minimum off time and minimum run times
              //for stage 1
        
              //logging.AddToLog("MOT/MRT stage 2: " & stg2, True)
              //Deal with minimum off time and minimum run times
              //for stage 2
          } else if (Type == "SM") {
              //logging.AddToLog("System mode: " & Value, True)
              String FlowState;
        
              if (Value == "O") {
                FlowState = "Off";
              } else if (Value == "H") {
                FlowState = "HeatOn";
              } else if (Value == "C") {
                FlowState = "CoolOn";
              } else {
                FlowState = "AutoChangeOver";
              }
              Serial.println("Flow state: " + FlowState);
              gw.send(msgFlowState.set(FlowState.c_str()));
          } else if (Type == "SF") {
              //logging.AddToLog("System fan: " & Value, True)
              Serial.println("System fan : " + Value);
              gw.send(msgStatus.set(Value.toInt()));
          }
        } //End ParseStatus
        
        void SendCmd(String cmd) {
          String commandStr;
          commandStr = "A=" + serialAddr + " O=00 " + cmd;
        
          //DEBUG_PRINTLN("Writing to serial port: " + Command);
        
          // Enable RS485 Transmit only for the duration of the send
          digitalWrite(SSerialTxControl, RS485Transmit);
          RS485Serial.print(commandStr + "\r");
          LastSent = cmd;
          //Return to RS485 receive mode
          digitalWrite(SSerialTxControl, RS485Receive);
        } //End SendCmd
        
        void SetProperty(String PropertyName, String Data) {
          //
          PropertyName = "";
          Data = "";
        } //End SendCmd
        
        void incomingMessage(const MyMessage &message) {
          Serial.println(message.type);
          // We only expect one type of message from controller. But we better
        check anyway.
          if (message.isAck()) {
             Serial.println("This is an ack from gateway");
          }
        
          if (message.type == V_HVAC_SETPOINT_COOL) {
             Serial.println("Message received");
             setPoint = String(message.data).toInt();
             Serial.println("New Set Temp is : " + String(setPoint));
             SendCmd("SPC=" + setPoint + " R=1");
        
             // Write some debug info
             Serial.print("Incoming change for sensor:");
             Serial.print(message.sensor);
             Serial.print(", New status: ");
             Serial.println(message.data);
          }
        
          if (message.type == V_HVAC_SETPOINT_HEAT) {
             Serial.println("Message received");
             setPoint = String(message.data).toInt();
             Serial.println("New Set Temp is : " + String(setPoint));
             SendCmd("SPH=" + setPoint + " R=1");
        
             // Write some debug info
             Serial.print("Incoming change for sensor:");
             Serial.print(message.sensor);
             Serial.print(", New status: ");
             Serial.println(message.data);
          }
        } //End incomingMessage
        

        The problem I have is that I am trying to send a decimal or float number for my temp value and I cannot figure out how. In the code, there is the ParseStatus function which takes a Type and Value as it's arguments. For types like "SP" , "SPH", "SPC", etc... I have it converting the value to an integer ( Value.toInt() ) which works. But if I try to convert it to a floating point decimal ( Value.toFloat() ), I get an error:

        C:\Users\dbemowsk\Documents\Arduino\RCS_RS485_Thermostat\RCS_RS485_Thermostat.ino:
        In function 'void ParseStatus(String, String)':
        
        RCS_RS485_Thermostat:176: error: call of overloaded 'set(float)' is ambiguous
        
               gw.send(msgSetHeat.set(Value.toFloat()));
        
                                                     ^
        
        C:\Users\dbemowsk\Documents\Arduino\RCS_RS485_Thermostat\RCS_RS485_Thermostat.ino:176:45:
        note: candidates are:
        
        In file included from C:\Program Files
        (x86)\Arduino\libraries\MySensors/MyParser.h:23:0,
        
                         from C:\Program Files
        (x86)\Arduino\libraries\MySensors/MySensor.h:29,
        
                         from
        C:\Users\dbemowsk\Documents\Arduino\RCS_RS485_Thermostat\RCS_RS485_Thermostat.ino:19:
        
        C:\Program Files (x86)\Arduino\libraries\MySensors/MyMessage.h:262:13:
        note: MyMessage& MyMessage::set(uint8_t)
        
          MyMessage& set(uint8_t value);
        
                     ^
        
        C:\Program Files (x86)\Arduino\libraries\MySensors/MyMessage.h:264:13:
        note: MyMessage& MyMessage::set(long unsigned int)
        
          MyMessage& set(unsigned long value);
        
                     ^
        
        C:\Program Files (x86)\Arduino\libraries\MySensors/MyMessage.h:265:13:
        note: MyMessage& MyMessage::set(long int)
        
          MyMessage& set(long value);
        
                     ^
        
        C:\Program Files (x86)\Arduino\libraries\MySensors/MyMessage.h:266:13:
        note: MyMessage& MyMessage::set(unsigned int)
        
          MyMessage& set(unsigned int value);
        
                     ^
        
        C:\Program Files (x86)\Arduino\libraries\MySensors/MyMessage.h:267:13:
        note: MyMessage& MyMessage::set(int)
        
          MyMessage& set(int value);
        
                     ^
        
        exit status 1
        call of overloaded 'set(float)' is ambiguous
        

        Is it possible to send decimal numbers?

        The next issue is that when I send values for the heat or cool set points, I have to send them as metric Celsius values. When I send them in Farenheit the number shown in Dompticz is WAY too high. That I am sure is a setting somewhere in Domoticz, but I haven't found it yet.

        The last thing is that when I send an "SPC" or Set Point Cool value, Domoticz shows a value of 190.2 and it doesn't change if I send another value. I looked over the code and I am not seeing anything that looks to be wrong (other than the floating point number issue).

        mfalkviddM Offline
        mfalkviddM Offline
        mfalkvidd
        Mod
        wrote on last edited by mfalkvidd
        #3

        @dbemowsk try

        gw.send(msgSetHeat.set(Value.toFloat(),1));
        

        I think that will do the conversion with 1 decimal.

        As for the fareheit setting, it is at Settings->Meters/counters
        0_1471111747076_image.png

        dbemowskD 2 Replies Last reply
        0
        • mfalkviddM mfalkvidd

          @dbemowsk try

          gw.send(msgSetHeat.set(Value.toFloat(),1));
          

          I think that will do the conversion with 1 decimal.

          As for the fareheit setting, it is at Settings->Meters/counters
          0_1471111747076_image.png

          dbemowskD Offline
          dbemowskD Offline
          dbemowsk
          wrote on last edited by
          #4

          @mfalkvidd said:

          As for the fareheit setting, it is at Settings->Meters/counters

          I have the temperature setting to display Fahrenheit, but when I send a value in Fahrenheit from the MySensors bridge, it displays a lot higher value. If I send the value in Celsius, it displays the correct Fahrenheit value. So the setting under Meters/Counters seems to ONLY tell the system to convert the stored value from Celsius to Fahrenheit prior to display. I will just add a function to do the conversion in my thermostat bridge sketch prior to sending it to the gateway.

          The other problem as I mentioned is that Domoticz is not seeing the incoming V_HVAC_SETPOINT_COOL. I send different values and it displays 190.4 every time (I said 190.2 last time, but it's 190.4). Is there something that I am doing wrong, or is this a limitation in Domoticz?

          Vera Plus running UI7 with MySensors, Sonoffs and 1-Wire devices
          Visit my website for more Bits, Bytes and Ramblings from me: http://dan.bemowski.info/

          P 1 Reply Last reply
          0
          • dbemowskD dbemowsk

            @mfalkvidd said:

            As for the fareheit setting, it is at Settings->Meters/counters

            I have the temperature setting to display Fahrenheit, but when I send a value in Fahrenheit from the MySensors bridge, it displays a lot higher value. If I send the value in Celsius, it displays the correct Fahrenheit value. So the setting under Meters/Counters seems to ONLY tell the system to convert the stored value from Celsius to Fahrenheit prior to display. I will just add a function to do the conversion in my thermostat bridge sketch prior to sending it to the gateway.

            The other problem as I mentioned is that Domoticz is not seeing the incoming V_HVAC_SETPOINT_COOL. I send different values and it displays 190.4 every time (I said 190.2 last time, but it's 190.4). Is there something that I am doing wrong, or is this a limitation in Domoticz?

            P Offline
            P Offline
            pjr
            wrote on last edited by
            #5

            @dbemowsk said:

            The other problem as I mentioned is that Domoticz is not seeing the incoming V_HVAC_SETPOINT_COOL. I send different values and it displays 190.4 every time (I said 190.2 last time, but it's 190.4). Is there something that I am doing wrong, or is this a limitation in Domoticz?

            Works for me Although I'm using celsius scale in my setup.. One direfference we have. I have only one S_HVAC child defined and in my setup it sends ON/OFF state, V_HVAC_SETPOINT_HEAT, V_HVAC_SETPOINT_COOL and V_TEMP -messges. Domoticz registers these separate node-child-sub-devices when it gots first messages from them. But I think this shouldnt be an issue..

            dbemowskD 2 Replies Last reply
            0
            • P pjr

              @dbemowsk said:

              The other problem as I mentioned is that Domoticz is not seeing the incoming V_HVAC_SETPOINT_COOL. I send different values and it displays 190.4 every time (I said 190.2 last time, but it's 190.4). Is there something that I am doing wrong, or is this a limitation in Domoticz?

              Works for me Although I'm using celsius scale in my setup.. One direfference we have. I have only one S_HVAC child defined and in my setup it sends ON/OFF state, V_HVAC_SETPOINT_HEAT, V_HVAC_SETPOINT_COOL and V_TEMP -messges. Domoticz registers these separate node-child-sub-devices when it gots first messages from them. But I think this shouldnt be an issue..

              dbemowskD Offline
              dbemowskD Offline
              dbemowsk
              wrote on last edited by
              #6

              @pjr said:

              I have only one S_HVAC child defined and in my setup it sends ON/OFF state, V_HVAC_SETPOINT_HEAT, V_HVAC_SETPOINT_COOL and V_TEMP -messges.

              I have a few questions regarding your setup.

              • First, what type of thermostat do you run?
              • How are you MySensorizing your thermostat?
              • Does your thermostat have a single set point, or does it have separate heating and cooling set points?
              • When you set your temp at the thermostat itself, be it the heating or cooling set point, does it report that back to your gateway/Domoticz. If so, How do you have your code set to report that back?

              Could I possibly see how you have your code set up to compare what I have? I am thinking that it is something in the way that I am reporting back to the gateway. My MySensors bridge that I am building just translates what my thermostat sends for data on the RS485 network and converts that to the MySensors standard that should work with Domoticz. I just can't seem to figure out what I am doing wrong with the cooling set point. Sending the temp and the heating set point values works perfect, just not the cooling set point.

              Vera Plus running UI7 with MySensors, Sonoffs and 1-Wire devices
              Visit my website for more Bits, Bytes and Ramblings from me: http://dan.bemowski.info/

              P 1 Reply Last reply
              0
              • mfalkviddM mfalkvidd

                @dbemowsk try

                gw.send(msgSetHeat.set(Value.toFloat(),1));
                

                I think that will do the conversion with 1 decimal.

                As for the fareheit setting, it is at Settings->Meters/counters
                0_1471111747076_image.png

                dbemowskD Offline
                dbemowskD Offline
                dbemowsk
                wrote on last edited by
                #7

                @mfalkvidd said:

                try

                gw.send(msgSetHeat.set(Value.toFloat(),1));

                @mfalkvidd Forgot to say thanks for that tip. That worked.

                Vera Plus running UI7 with MySensors, Sonoffs and 1-Wire devices
                Visit my website for more Bits, Bytes and Ramblings from me: http://dan.bemowski.info/

                1 Reply Last reply
                1
                • dbemowskD dbemowsk

                  @pjr said:

                  I have only one S_HVAC child defined and in my setup it sends ON/OFF state, V_HVAC_SETPOINT_HEAT, V_HVAC_SETPOINT_COOL and V_TEMP -messges.

                  I have a few questions regarding your setup.

                  • First, what type of thermostat do you run?
                  • How are you MySensorizing your thermostat?
                  • Does your thermostat have a single set point, or does it have separate heating and cooling set points?
                  • When you set your temp at the thermostat itself, be it the heating or cooling set point, does it report that back to your gateway/Domoticz. If so, How do you have your code set to report that back?

                  Could I possibly see how you have your code set up to compare what I have? I am thinking that it is something in the way that I am reporting back to the gateway. My MySensors bridge that I am building just translates what my thermostat sends for data on the RS485 network and converts that to the MySensors standard that should work with Domoticz. I just can't seem to figure out what I am doing wrong with the cooling set point. Sending the temp and the heating set point values works perfect, just not the cooling set point.

                  P Offline
                  P Offline
                  pjr
                  wrote on last edited by
                  #8

                  @dbemowsk said:

                  @pjr said:

                  I have only one S_HVAC child defined and in my setup it sends ON/OFF state, V_HVAC_SETPOINT_HEAT, V_HVAC_SETPOINT_COOL and V_TEMP -messges.

                  I have a few questions regarding your setup.

                  • First, what type of thermostat do you run?

                  So the node integrates my Amitime air source heat pump to domoticz.

                  gw.present(2, S_HVAC);
                  
                  • How are you MySensorizing your thermostat?

                  Its not actually thermostat. Its heat pump. Same way as thermostat is has set point heat, cool and current temp readings.

                  • Does your thermostat have a single set point, or does it have separate heating and cooling set points?

                  It has both

                  • When you set your temp at the thermostat itself, be it the heating or cooling set point, does it report that back to your gateway/Domoticz. If so, How do you have your code set to report that back?

                  Yes it report back.

                  Could I possibly see how you have your code set up to compare what I have? I am thinking that it is something in the way that I am reporting back to the gateway. My MySensors bridge that I am building just translates what my thermostat sends for data on the RS485 network and converts that to the MySensors standard that should work with Domoticz. I just can't seem to figure out what I am doing wrong with the cooling set point. Sending the temp and the heating set point values works perfect, just not the cooling set point.

                  Its very similar setup. Instead of raw rs485 I'm using modbus with my heat pump. I'll send you a PM about the sketch.

                  dbemowskD 1 Reply Last reply
                  0
                  • P pjr

                    @dbemowsk said:

                    @pjr said:

                    I have only one S_HVAC child defined and in my setup it sends ON/OFF state, V_HVAC_SETPOINT_HEAT, V_HVAC_SETPOINT_COOL and V_TEMP -messges.

                    I have a few questions regarding your setup.

                    • First, what type of thermostat do you run?

                    So the node integrates my Amitime air source heat pump to domoticz.

                    gw.present(2, S_HVAC);
                    
                    • How are you MySensorizing your thermostat?

                    Its not actually thermostat. Its heat pump. Same way as thermostat is has set point heat, cool and current temp readings.

                    • Does your thermostat have a single set point, or does it have separate heating and cooling set points?

                    It has both

                    • When you set your temp at the thermostat itself, be it the heating or cooling set point, does it report that back to your gateway/Domoticz. If so, How do you have your code set to report that back?

                    Yes it report back.

                    Could I possibly see how you have your code set up to compare what I have? I am thinking that it is something in the way that I am reporting back to the gateway. My MySensors bridge that I am building just translates what my thermostat sends for data on the RS485 network and converts that to the MySensors standard that should work with Domoticz. I just can't seem to figure out what I am doing wrong with the cooling set point. Sending the temp and the heating set point values works perfect, just not the cooling set point.

                    Its very similar setup. Instead of raw rs485 I'm using modbus with my heat pump. I'll send you a PM about the sketch.

                    dbemowskD Offline
                    dbemowskD Offline
                    dbemowsk
                    wrote on last edited by
                    #9

                    @pjr Thanks for the info. I got your PM and will review the code later tonight.

                    Vera Plus running UI7 with MySensors, Sonoffs and 1-Wire devices
                    Visit my website for more Bits, Bytes and Ramblings from me: http://dan.bemowski.info/

                    1 Reply Last reply
                    0
                    • P pjr

                      @dbemowsk said:

                      The other problem as I mentioned is that Domoticz is not seeing the incoming V_HVAC_SETPOINT_COOL. I send different values and it displays 190.4 every time (I said 190.2 last time, but it's 190.4). Is there something that I am doing wrong, or is this a limitation in Domoticz?

                      Works for me Although I'm using celsius scale in my setup.. One direfference we have. I have only one S_HVAC child defined and in my setup it sends ON/OFF state, V_HVAC_SETPOINT_HEAT, V_HVAC_SETPOINT_COOL and V_TEMP -messges. Domoticz registers these separate node-child-sub-devices when it gots first messages from them. But I think this shouldnt be an issue..

                      dbemowskD Offline
                      dbemowskD Offline
                      dbemowsk
                      wrote on last edited by
                      #10

                      @pjr said:

                      I have only one S_HVAC child defined and in my setup it sends ON/OFF state, V_HVAC_SETPOINT_HEAT, V_HVAC_SETPOINT_COOL and V_TEMP -messges.

                      OK, so I have a question on this. You say you have it sending ON/OFF, V_HVAC_SETPOINT_HEAT, V_HVAC_SETPOINT_COOL and V_TEMP. For ON/OFF, do you mean the V_HVAC_FLOW_STATE which is "Off", "HeatOn", "CoolOn", or "AutoChangeOver"? Can I send all of the following V_HVAC_SETPOINT_HEAT, V_HVAC_SETPOINT_COLD, V_HVAC_FLOW_STATE, V_HVAC_FLOW_MODE, V_HVAC_SPEED through the one child ID as defined in the v 1.5.x serial API docs. That may be my problem as in my code I was trying to send each through it's own child ID. Also, when you define your S_HVAC as the single child, how does Domoticz see that? The way I have mine set up, each one is seen as a separate device.

                      Thanks for letting me check out your code.

                      Vera Plus running UI7 with MySensors, Sonoffs and 1-Wire devices
                      Visit my website for more Bits, Bytes and Ramblings from me: http://dan.bemowski.info/

                      P 1 Reply Last reply
                      0
                      • dbemowskD dbemowsk

                        @pjr said:

                        I have only one S_HVAC child defined and in my setup it sends ON/OFF state, V_HVAC_SETPOINT_HEAT, V_HVAC_SETPOINT_COOL and V_TEMP -messges.

                        OK, so I have a question on this. You say you have it sending ON/OFF, V_HVAC_SETPOINT_HEAT, V_HVAC_SETPOINT_COOL and V_TEMP. For ON/OFF, do you mean the V_HVAC_FLOW_STATE which is "Off", "HeatOn", "CoolOn", or "AutoChangeOver"? Can I send all of the following V_HVAC_SETPOINT_HEAT, V_HVAC_SETPOINT_COLD, V_HVAC_FLOW_STATE, V_HVAC_FLOW_MODE, V_HVAC_SPEED through the one child ID as defined in the v 1.5.x serial API docs. That may be my problem as in my code I was trying to send each through it's own child ID. Also, when you define your S_HVAC as the single child, how does Domoticz see that? The way I have mine set up, each one is seen as a separate device.

                        Thanks for letting me check out your code.

                        P Offline
                        P Offline
                        pjr
                        wrote on last edited by pjr
                        #11

                        @dbemowsk
                        These are not supported yet by domoticz:

                        • V_HVAC_FLOW_STATE
                        • V_HVAC_FLOW_MODE
                        • V_HVAC_SPEED

                        Thats why I'm using V_LIGHT (ON/OFF) currently at the code.

                        You can check it from here: https://github.com/domoticz/domoticz/blob/master/hardware/MySensorsBase.cpp#L70
                        Those are not mentioned anywhere but the one list.

                        dbemowskD 1 Reply Last reply
                        0
                        • P pjr

                          @dbemowsk
                          These are not supported yet by domoticz:

                          • V_HVAC_FLOW_STATE
                          • V_HVAC_FLOW_MODE
                          • V_HVAC_SPEED

                          Thats why I'm using V_LIGHT (ON/OFF) currently at the code.

                          You can check it from here: https://github.com/domoticz/domoticz/blob/master/hardware/MySensorsBase.cpp#L70
                          Those are not mentioned anywhere but the one list.

                          dbemowskD Offline
                          dbemowskD Offline
                          dbemowsk
                          wrote on last edited by
                          #12

                          @pjr OK, that helps me understand your code better. I am assuming that the "onModbusProcessed" method is to process incoming messages sent by the modbus network and sending them to Domoticz, correct? Processing incoming messages from the RS485 network is where some of my problems are in my setup. I will try tonight to make some code changes to see if I can get it working. My main problem was my cooling set point was not updating in Domoticz correctly. The Heat set point and temp seemed to work. I'll post my findings.

                          Vera Plus running UI7 with MySensors, Sonoffs and 1-Wire devices
                          Visit my website for more Bits, Bytes and Ramblings from me: http://dan.bemowski.info/

                          1 Reply Last reply
                          0
                          • P Offline
                            P Offline
                            pjr
                            wrote on last edited by pjr
                            #13

                            @dbemowsk said:

                            @pjr OK, that helps me understand your code better. I am assuming that the "onModbusProcessed" method is to process incoming messages sent by the modbus network and sending them to Domoticz, correct?

                            Thats correct. There I handle the result of a modbus query.
                            I'm not handling decimals since the heat pump controller supports only full numbers..

                            1 Reply Last reply
                            0
                            • dbemowskD Offline
                              dbemowskD Offline
                              dbemowsk
                              wrote on last edited by
                              #14

                              So last night I figured out my issue with why my code was not updating the set point cool value. Turns out it was the way I was parsing the string passed from the RS485 side to it's key/value pairs. The string that it was working on was this:

                              A=0 O=01 T=73.4 SPH=72.1 SPC=70.0\r
                              

                              The code I had was only taking the key/value pairs up to the last one because I had it keying off of the space character. Since there was no trailing space in the string, the last pair got skipped which was the cooling set point.

                              I will post some updated code once I get a little more done.

                              Vera Plus running UI7 with MySensors, Sonoffs and 1-Wire devices
                              Visit my website for more Bits, Bytes and Ramblings from me: http://dan.bemowski.info/

                              1 Reply Last reply
                              0
                              • dbemowskD Offline
                                dbemowskD Offline
                                dbemowsk
                                wrote on last edited by dbemowsk
                                #15

                                OK, so I had this project on hold for a while and am getting back to it. My issue now is that for some reason I am not receiving messages from Domoticz for this node. If I send a temp set point or status from the RS485 side, it updates in Domoticz, but if I try to change a set point or status in Domoticz, the MySensors node doesn't receive it. The code is a bit messy right now, but it should work with what I have. If someone could look it over and advise, that would be a big help. The sketch is a MySensors 1.5.4 sketch.

                                 /*
                                  RCS Thermostat for MySensors
                                
                                  Arduino RCS RS485 thermostat control
                                
                                  July 7,2016
                                
                                  This is a gateway bridge to allow an RCS serial thermostat to be accessible to a MySensors
                                  gateway.  The thermostat being used to test this is an RCS TR40 RS485 thermostat.  The published
                                  protocol for RCS thermostats can be found at the following address;
                                  http://www.rcstechnology.com/oldsite/docs/thermostats/serial/SERIAL%20PROTOCOL%20REV%204.3%20%20150-00225-43.pdf
                                  
                                  This sketch features the following:
                                
                                  Add features here
                                 */
                                
                                // Import needed libraries
                                #include <SPI.h>
                                #include <MySensor.h>  
                                #include <SoftwareSerial.h>
                                
                                #define SKETCH_NAME "RCS TR40 Thermostat"
                                #define SKETCH_VERSION "1.1"
                                
                                #define CHILD_ID_HVAC    0 // S_HVAC
                                #define CHILD_ID_STATE   1 // S_LIGHT
                                
                                // Declare Constants and Pin Numbers
                                #define SSerialRX        5  //Serial Receive pin 8
                                #define SSerialTX        3  //Serial Transmit pin 7
                                
                                #define SSerialTxControl 4  //RS485 Direction control
                                
                                #define RS485Transmit    HIGH
                                #define RS485Receive     LOW
                                
                                // Declare objects
                                SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX
                                
                                MySensor gw;
                                
                                // Sensor values
                                MyMessage msgStatus ( CHILD_ID_STATE,  V_LIGHT );
                                MyMessage msgTemp   ( CHILD_ID_HVAC,   V_TEMP );
                                MyMessage msgSetCool( CHILD_ID_HVAC,   V_HVAC_SETPOINT_COOL );
                                MyMessage msgSetHeat( CHILD_ID_HVAC,   V_HVAC_SETPOINT_HEAT );
                                
                                // Declare Variables
                                int byteReceived;
                                int byteSend;
                                String rcvString;
                                String sndString;
                                //This is for storing the last command that was sent 
                                String lastSent;
                                //the last sent set point
                                String setPoint;
                                
                                String mode;
                                //This is the RS485 address of this node that gets sent to the thermostat
                                String serialAddr = "1";
                                //Placeholder for the last command sent
                                String LastSent = "";
                                
                                void setup() {
                                  Serial.begin(9600);
                                  
                                  gw.begin( incomingMessage, AUTO, false );
                                  
                                  gw.sendSketchInfo( SKETCH_NAME, SKETCH_VERSION );
                                  
                                  // Register the thermostat with the gateway
                                  gw.present( CHILD_ID_HVAC,  S_HVAC );
                                  gw.present( CHILD_ID_STATE, S_LIGHT );
                                  
                                  // put your setup code here, to run once:
                                  pinMode( SSerialTxControl, OUTPUT );
                                  digitalWrite( SSerialTxControl, RS485Receive );  // Init Transceiver
                                  
                                  // Start the software serial port, to another device
                                  RS485Serial.begin(9600);   // set the data rate
                                } //End setup
                                
                                void loop() {
                                  String dataIn;
                                  
                                  if (RS485Serial.available()) {
                                    dataIn = RS485Serial.readStringUntil('\n');
                                    ParseReceived(dataIn);
                                  }
                                } //End loop
                                
                                void ParseReceived(String Message) {
                                  String StatusData;
                                  //int Count;
                                  String StatusString;
                                  String Status;
                                  String Type;
                                  String Value;
                                
                                  int Index;
                                  int Start;
                                  int End;
                                  int StatIndex;
                                
                                  Index = Message.indexOf(' ');
                                  Start = 0;
                                  
                                  Serial.println("Message: " + Message);
                                  
                                  if (Message.startsWith("A=")) {
                                    while (End != Message.length()) {
                                      End = (Index == -1) ? Message.length() : Index;
                                      //Get the status string to process
                                      StatusString = Message.substring(Start, End);
                                      //Change our start position to 1 over the last space found
                                      Start = Index + 1;
                                      //Find the end of the next status string
                                      Index = Message.indexOf(' ', Start);
                                  
                                      //Now we need to process the status string into it's Type and Value
                                      StatIndex = StatusString.indexOf('=');
                                      Type = StatusString.substring(0, StatIndex);
                                      Value = StatusString.substring(StatIndex + 1);
                                      ParseStatus(Type, Value);
                                    } 
                                  } else {
                                    SendCmd(LastSent);
                                  }
                                } //End ParseReceived
                                
                                void ParseStatus(String Type, String Value) {
                                  //
                                  
                                  if (Type == "OA") {
                                      //Outside Air not used
                                  } else if (Type == "Z") {
                                      //Zone not used
                                  } else if (Type == "T") {
                                      Serial.println("T: " + Value);
                                      gw.send(msgTemp.set( F2C( Value.toFloat() ), 2 ));
                                  } else if (Type == "SP") {
                                      Serial.println("SP: " + Value);
                                      gw.send(msgSetCool.set( F2C( Value.toFloat() ), 2 ));
                                  } else if (Type == "SPH") {
                                      Serial.println("SPH: " + Value);
                                      gw.send(msgSetHeat.set( F2C( Value.toFloat() ), 2 ));
                                  } else if (Type == "SPC") {
                                      Serial.println("SPC: " + Value);
                                      gw.send(msgSetCool.set( F2C( Value.toFloat() ), 2 ));
                                  } else if (Type == "M") {
                                      //Serial.println("M: " + Value);
                                      //gw.send(msgFlowMode.set(Value.c_str()));
                                  } else if (Type == "FM") {
                                      //Serial.println("FM: " + Value);
                                      //gw.send(msgFlowMode.set(Value.c_str()));
                                    //Type 2 status message types
                                  } else if (Type == "H1A") {
                                      Serial.println("H1A: " + Value);
                                      if (Value == "1") {
                                        //gw.send(msgHvacSpeed.set("Min"));
                                      } else {
                                        //gw.send(msgHvacSpeed.set("Auto"));
                                      }
                                  } else if (Type == "H2A") {
                                      Serial.println("H2A: " + Value);
                                      if (Value == "1") {
                                        //gw.send(msgHvacSpeed.set("Normal"));
                                      } else {
                                        //gw.send(msgHvacSpeed.set("Auto"));
                                      }
                                  } else if (Type == "H3A") {
                                      Serial.println("H3A: " + Value);
                                      if (Value == "1") {
                                        //gw.send(msgHvacSpeed.set("Max"));
                                      } else {
                                        //gw.send(msgHvacSpeed.set("Auto"));
                                      }
                                  } else if (Type == "C1A") {
                                      Serial.println("C1A: " + Value);
                                      if (Value == "1") {
                                        //gw.send(msgHvacSpeed.set("Min"));
                                      } else {
                                        //gw.send(msgHvacSpeed.set("Auto"));
                                      }
                                  } else if (Type == "C2A") {
                                      Serial.println("C2A: " + Value);
                                      if (Value == "1") {
                                        //gw.send(msgHvacSpeed.set("Normal"));
                                      } else {
                                        //gw.send(msgHvacSpeed.set("Auto"));
                                      }
                                  } else if (Type == "FA") {
                                      Serial.println("FA: " + Value);
                                      if (Value == "1") {
                                        //gw.send(msgFlowMode.set("ContinuousOn"));
                                      } else {
                                        //gw.send(msgHvacSpeed.set("Auto"));
                                      }
                                  } else if (Type == "VA") {
                                      //Vent damper not used
                                  } else if (Type == "D1") {
                                      //Damper #1 not used
                                  } else if (Type == "SCP") {
                                      String stg1 = Value.substring(0, 1);
                                      String stg2 = Value.substring(0, Value.length() - 1);
                                
                                      //logging.AddToLog("MOT/MRT stage 1: " & stg1, True)
                                      //Deal with minimum off time and minimum run times 
                                      //for stage 1
                                
                                      //logging.AddToLog("MOT/MRT stage 2: " & stg2, True)
                                      //Deal with minimum off time and minimum run times 
                                      //for stage 2
                                  } else if (Type == "SM") {
                                      //logging.AddToLog("System mode: " & Value, True)
                                      String FlowState;
                                      
                                      if (Value == "O") {
                                        FlowState = "Off";
                                      } else if (Value == "H") {
                                        FlowState = "HeatOn";
                                      } else if (Value == "C") {
                                        FlowState = "CoolOn";
                                      } else {
                                        FlowState = "AutoChangeOver";
                                      }
                                      //Serial.println("SM: " + FlowState);
                                      //gw.send(msgFlowState.set(FlowState.c_str()));
                                  } else if (Type == "SF") {
                                      //logging.AddToLog("System fan: " & Value, True) 
                                      Serial.println("SF: " + Value);
                                      gw.send(msgStatus.set(Value.toInt()));
                                  }
                                } //End ParseStatus
                                
                                float F2C(float Fahrenheit) {
                                  return (5.0f/9.0f) * (Fahrenheit-32);
                                } //End F2C
                                
                                float C2F(float Celsius) {
                                  return (Celsius * 9.0f) / 5.0f + 32.0f;
                                } //End C2F
                                
                                void SendCmd(String cmd) {
                                  String commandStr;
                                  commandStr = "A=" + serialAddr + " O=00 " + cmd;
                                
                                  Serial.println("Writing to serial port: " + commandStr);
                                  
                                  // Enable RS485 Transmit only for the duration of the send
                                  digitalWrite(SSerialTxControl, RS485Transmit);
                                  RS485Serial.print(commandStr + "\r");
                                  LastSent = cmd;
                                  //Return to RS485 receive mode  
                                  digitalWrite(SSerialTxControl, RS485Receive);
                                } //End SendCmd
                                
                                /**
                                 * incomingMessage - Process the incoming messages.
                                 */
                                void incomingMessage(const MyMessage &message) {
                                  Serial.println("message received");//String(message.type));
                                  //Serial.println(message.data);
                                  // We only expect one type of message from controller. But we better check anyway.
                                  if (message.isAck()) {
                                     Serial.println("This is an ack from gateway");
                                  }
                                  Serial.println("Temp: " + String(message.data) + " -- " + message.type);
                                  
                                  if ( message.type == V_TEMP ) {
                                    //
                                    Serial.println("Temp: " + String(message.data)); 
                                  } //End V_TEMP
                                  
                                  if ( message.type == V_STATUS ) {
                                    //
                                    Serial.println("Status: " + String(message.data)); 
                                  } //End V_STATUS
                                  
                                  if ( message.type == V_HVAC_FLOW_STATE ) {
                                    //
                                    Serial.println("Flow State: " + String(message.data)); 
                                  } //End V_HVAC_FLOW_STATE
                                  
                                  if ( message.type == V_HVAC_SPEED ) {
                                    //
                                    Serial.println("Speed: " + String(message.data)); 
                                  } //End V_HVAC_SPEED
                                
                                  if (message.type == V_HVAC_SETPOINT_COOL) {
                                     Serial.println("Message received");
                                     String setPoint = String(C2F(atoi(message.data)));
                                     Serial.println("New Set Temp is : " + String(setPoint));
                                     SendCmd("SPC=" + setPoint + " R=1");
                                    
                                     // Write some debug info
                                     Serial.print("Incoming change for sensor:");
                                     Serial.print(message.sensor);
                                     Serial.print(", New status: ");
                                     Serial.println(message.data);
                                  } //End V_HVAC_SETPOINT_COOL
                                
                                  if (message.type == V_HVAC_SETPOINT_HEAT) {
                                     Serial.println("Message received");
                                     String setPoint = String(C2F(atoi(message.data))); //.toInt();
                                     Serial.println("New Set Temp is : " + String(setPoint));
                                     SendCmd("SPH=" + setPoint + " R=1");
                                    
                                     // Write some debug info
                                     Serial.print("Incoming change for sensor:");
                                     Serial.print(message.sensor);
                                     Serial.print(", New status: ");
                                     Serial.println(message.data);
                                  } //End V_HVAC_SETPOINT_HEAT
                                  
                                  if ( (message.type == V_HVAC_FLOW_MODE) ) {
                                    //
                                    Serial.println("Flow Mode: " + String(message.data)); 
                                  } //End V_HVAC_FLOW_MODE
                                } //End incomingMessage
                                

                                Thanks

                                Vera Plus running UI7 with MySensors, Sonoffs and 1-Wire devices
                                Visit my website for more Bits, Bytes and Ramblings from me: http://dan.bemowski.info/

                                AWIA 2 Replies Last reply
                                0
                                • dbemowskD dbemowsk

                                  OK, so I had this project on hold for a while and am getting back to it. My issue now is that for some reason I am not receiving messages from Domoticz for this node. If I send a temp set point or status from the RS485 side, it updates in Domoticz, but if I try to change a set point or status in Domoticz, the MySensors node doesn't receive it. The code is a bit messy right now, but it should work with what I have. If someone could look it over and advise, that would be a big help. The sketch is a MySensors 1.5.4 sketch.

                                   /*
                                    RCS Thermostat for MySensors
                                  
                                    Arduino RCS RS485 thermostat control
                                  
                                    July 7,2016
                                  
                                    This is a gateway bridge to allow an RCS serial thermostat to be accessible to a MySensors
                                    gateway.  The thermostat being used to test this is an RCS TR40 RS485 thermostat.  The published
                                    protocol for RCS thermostats can be found at the following address;
                                    http://www.rcstechnology.com/oldsite/docs/thermostats/serial/SERIAL%20PROTOCOL%20REV%204.3%20%20150-00225-43.pdf
                                    
                                    This sketch features the following:
                                  
                                    Add features here
                                   */
                                  
                                  // Import needed libraries
                                  #include <SPI.h>
                                  #include <MySensor.h>  
                                  #include <SoftwareSerial.h>
                                  
                                  #define SKETCH_NAME "RCS TR40 Thermostat"
                                  #define SKETCH_VERSION "1.1"
                                  
                                  #define CHILD_ID_HVAC    0 // S_HVAC
                                  #define CHILD_ID_STATE   1 // S_LIGHT
                                  
                                  // Declare Constants and Pin Numbers
                                  #define SSerialRX        5  //Serial Receive pin 8
                                  #define SSerialTX        3  //Serial Transmit pin 7
                                  
                                  #define SSerialTxControl 4  //RS485 Direction control
                                  
                                  #define RS485Transmit    HIGH
                                  #define RS485Receive     LOW
                                  
                                  // Declare objects
                                  SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX
                                  
                                  MySensor gw;
                                  
                                  // Sensor values
                                  MyMessage msgStatus ( CHILD_ID_STATE,  V_LIGHT );
                                  MyMessage msgTemp   ( CHILD_ID_HVAC,   V_TEMP );
                                  MyMessage msgSetCool( CHILD_ID_HVAC,   V_HVAC_SETPOINT_COOL );
                                  MyMessage msgSetHeat( CHILD_ID_HVAC,   V_HVAC_SETPOINT_HEAT );
                                  
                                  // Declare Variables
                                  int byteReceived;
                                  int byteSend;
                                  String rcvString;
                                  String sndString;
                                  //This is for storing the last command that was sent 
                                  String lastSent;
                                  //the last sent set point
                                  String setPoint;
                                  
                                  String mode;
                                  //This is the RS485 address of this node that gets sent to the thermostat
                                  String serialAddr = "1";
                                  //Placeholder for the last command sent
                                  String LastSent = "";
                                  
                                  void setup() {
                                    Serial.begin(9600);
                                    
                                    gw.begin( incomingMessage, AUTO, false );
                                    
                                    gw.sendSketchInfo( SKETCH_NAME, SKETCH_VERSION );
                                    
                                    // Register the thermostat with the gateway
                                    gw.present( CHILD_ID_HVAC,  S_HVAC );
                                    gw.present( CHILD_ID_STATE, S_LIGHT );
                                    
                                    // put your setup code here, to run once:
                                    pinMode( SSerialTxControl, OUTPUT );
                                    digitalWrite( SSerialTxControl, RS485Receive );  // Init Transceiver
                                    
                                    // Start the software serial port, to another device
                                    RS485Serial.begin(9600);   // set the data rate
                                  } //End setup
                                  
                                  void loop() {
                                    String dataIn;
                                    
                                    if (RS485Serial.available()) {
                                      dataIn = RS485Serial.readStringUntil('\n');
                                      ParseReceived(dataIn);
                                    }
                                  } //End loop
                                  
                                  void ParseReceived(String Message) {
                                    String StatusData;
                                    //int Count;
                                    String StatusString;
                                    String Status;
                                    String Type;
                                    String Value;
                                  
                                    int Index;
                                    int Start;
                                    int End;
                                    int StatIndex;
                                  
                                    Index = Message.indexOf(' ');
                                    Start = 0;
                                    
                                    Serial.println("Message: " + Message);
                                    
                                    if (Message.startsWith("A=")) {
                                      while (End != Message.length()) {
                                        End = (Index == -1) ? Message.length() : Index;
                                        //Get the status string to process
                                        StatusString = Message.substring(Start, End);
                                        //Change our start position to 1 over the last space found
                                        Start = Index + 1;
                                        //Find the end of the next status string
                                        Index = Message.indexOf(' ', Start);
                                    
                                        //Now we need to process the status string into it's Type and Value
                                        StatIndex = StatusString.indexOf('=');
                                        Type = StatusString.substring(0, StatIndex);
                                        Value = StatusString.substring(StatIndex + 1);
                                        ParseStatus(Type, Value);
                                      } 
                                    } else {
                                      SendCmd(LastSent);
                                    }
                                  } //End ParseReceived
                                  
                                  void ParseStatus(String Type, String Value) {
                                    //
                                    
                                    if (Type == "OA") {
                                        //Outside Air not used
                                    } else if (Type == "Z") {
                                        //Zone not used
                                    } else if (Type == "T") {
                                        Serial.println("T: " + Value);
                                        gw.send(msgTemp.set( F2C( Value.toFloat() ), 2 ));
                                    } else if (Type == "SP") {
                                        Serial.println("SP: " + Value);
                                        gw.send(msgSetCool.set( F2C( Value.toFloat() ), 2 ));
                                    } else if (Type == "SPH") {
                                        Serial.println("SPH: " + Value);
                                        gw.send(msgSetHeat.set( F2C( Value.toFloat() ), 2 ));
                                    } else if (Type == "SPC") {
                                        Serial.println("SPC: " + Value);
                                        gw.send(msgSetCool.set( F2C( Value.toFloat() ), 2 ));
                                    } else if (Type == "M") {
                                        //Serial.println("M: " + Value);
                                        //gw.send(msgFlowMode.set(Value.c_str()));
                                    } else if (Type == "FM") {
                                        //Serial.println("FM: " + Value);
                                        //gw.send(msgFlowMode.set(Value.c_str()));
                                      //Type 2 status message types
                                    } else if (Type == "H1A") {
                                        Serial.println("H1A: " + Value);
                                        if (Value == "1") {
                                          //gw.send(msgHvacSpeed.set("Min"));
                                        } else {
                                          //gw.send(msgHvacSpeed.set("Auto"));
                                        }
                                    } else if (Type == "H2A") {
                                        Serial.println("H2A: " + Value);
                                        if (Value == "1") {
                                          //gw.send(msgHvacSpeed.set("Normal"));
                                        } else {
                                          //gw.send(msgHvacSpeed.set("Auto"));
                                        }
                                    } else if (Type == "H3A") {
                                        Serial.println("H3A: " + Value);
                                        if (Value == "1") {
                                          //gw.send(msgHvacSpeed.set("Max"));
                                        } else {
                                          //gw.send(msgHvacSpeed.set("Auto"));
                                        }
                                    } else if (Type == "C1A") {
                                        Serial.println("C1A: " + Value);
                                        if (Value == "1") {
                                          //gw.send(msgHvacSpeed.set("Min"));
                                        } else {
                                          //gw.send(msgHvacSpeed.set("Auto"));
                                        }
                                    } else if (Type == "C2A") {
                                        Serial.println("C2A: " + Value);
                                        if (Value == "1") {
                                          //gw.send(msgHvacSpeed.set("Normal"));
                                        } else {
                                          //gw.send(msgHvacSpeed.set("Auto"));
                                        }
                                    } else if (Type == "FA") {
                                        Serial.println("FA: " + Value);
                                        if (Value == "1") {
                                          //gw.send(msgFlowMode.set("ContinuousOn"));
                                        } else {
                                          //gw.send(msgHvacSpeed.set("Auto"));
                                        }
                                    } else if (Type == "VA") {
                                        //Vent damper not used
                                    } else if (Type == "D1") {
                                        //Damper #1 not used
                                    } else if (Type == "SCP") {
                                        String stg1 = Value.substring(0, 1);
                                        String stg2 = Value.substring(0, Value.length() - 1);
                                  
                                        //logging.AddToLog("MOT/MRT stage 1: " & stg1, True)
                                        //Deal with minimum off time and minimum run times 
                                        //for stage 1
                                  
                                        //logging.AddToLog("MOT/MRT stage 2: " & stg2, True)
                                        //Deal with minimum off time and minimum run times 
                                        //for stage 2
                                    } else if (Type == "SM") {
                                        //logging.AddToLog("System mode: " & Value, True)
                                        String FlowState;
                                        
                                        if (Value == "O") {
                                          FlowState = "Off";
                                        } else if (Value == "H") {
                                          FlowState = "HeatOn";
                                        } else if (Value == "C") {
                                          FlowState = "CoolOn";
                                        } else {
                                          FlowState = "AutoChangeOver";
                                        }
                                        //Serial.println("SM: " + FlowState);
                                        //gw.send(msgFlowState.set(FlowState.c_str()));
                                    } else if (Type == "SF") {
                                        //logging.AddToLog("System fan: " & Value, True) 
                                        Serial.println("SF: " + Value);
                                        gw.send(msgStatus.set(Value.toInt()));
                                    }
                                  } //End ParseStatus
                                  
                                  float F2C(float Fahrenheit) {
                                    return (5.0f/9.0f) * (Fahrenheit-32);
                                  } //End F2C
                                  
                                  float C2F(float Celsius) {
                                    return (Celsius * 9.0f) / 5.0f + 32.0f;
                                  } //End C2F
                                  
                                  void SendCmd(String cmd) {
                                    String commandStr;
                                    commandStr = "A=" + serialAddr + " O=00 " + cmd;
                                  
                                    Serial.println("Writing to serial port: " + commandStr);
                                    
                                    // Enable RS485 Transmit only for the duration of the send
                                    digitalWrite(SSerialTxControl, RS485Transmit);
                                    RS485Serial.print(commandStr + "\r");
                                    LastSent = cmd;
                                    //Return to RS485 receive mode  
                                    digitalWrite(SSerialTxControl, RS485Receive);
                                  } //End SendCmd
                                  
                                  /**
                                   * incomingMessage - Process the incoming messages.
                                   */
                                  void incomingMessage(const MyMessage &message) {
                                    Serial.println("message received");//String(message.type));
                                    //Serial.println(message.data);
                                    // We only expect one type of message from controller. But we better check anyway.
                                    if (message.isAck()) {
                                       Serial.println("This is an ack from gateway");
                                    }
                                    Serial.println("Temp: " + String(message.data) + " -- " + message.type);
                                    
                                    if ( message.type == V_TEMP ) {
                                      //
                                      Serial.println("Temp: " + String(message.data)); 
                                    } //End V_TEMP
                                    
                                    if ( message.type == V_STATUS ) {
                                      //
                                      Serial.println("Status: " + String(message.data)); 
                                    } //End V_STATUS
                                    
                                    if ( message.type == V_HVAC_FLOW_STATE ) {
                                      //
                                      Serial.println("Flow State: " + String(message.data)); 
                                    } //End V_HVAC_FLOW_STATE
                                    
                                    if ( message.type == V_HVAC_SPEED ) {
                                      //
                                      Serial.println("Speed: " + String(message.data)); 
                                    } //End V_HVAC_SPEED
                                  
                                    if (message.type == V_HVAC_SETPOINT_COOL) {
                                       Serial.println("Message received");
                                       String setPoint = String(C2F(atoi(message.data)));
                                       Serial.println("New Set Temp is : " + String(setPoint));
                                       SendCmd("SPC=" + setPoint + " R=1");
                                      
                                       // Write some debug info
                                       Serial.print("Incoming change for sensor:");
                                       Serial.print(message.sensor);
                                       Serial.print(", New status: ");
                                       Serial.println(message.data);
                                    } //End V_HVAC_SETPOINT_COOL
                                  
                                    if (message.type == V_HVAC_SETPOINT_HEAT) {
                                       Serial.println("Message received");
                                       String setPoint = String(C2F(atoi(message.data))); //.toInt();
                                       Serial.println("New Set Temp is : " + String(setPoint));
                                       SendCmd("SPH=" + setPoint + " R=1");
                                      
                                       // Write some debug info
                                       Serial.print("Incoming change for sensor:");
                                       Serial.print(message.sensor);
                                       Serial.print(", New status: ");
                                       Serial.println(message.data);
                                    } //End V_HVAC_SETPOINT_HEAT
                                    
                                    if ( (message.type == V_HVAC_FLOW_MODE) ) {
                                      //
                                      Serial.println("Flow Mode: " + String(message.data)); 
                                    } //End V_HVAC_FLOW_MODE
                                  } //End incomingMessage
                                  

                                  Thanks

                                  AWIA Offline
                                  AWIA Offline
                                  AWI
                                  Hero Member
                                  wrote on last edited by
                                  #16

                                  @dbemowsk What does the serial log of the node tell you? Does it show messages coming in?

                                  dbemowskD 1 Reply Last reply
                                  0
                                  • dbemowskD dbemowsk

                                    OK, so I had this project on hold for a while and am getting back to it. My issue now is that for some reason I am not receiving messages from Domoticz for this node. If I send a temp set point or status from the RS485 side, it updates in Domoticz, but if I try to change a set point or status in Domoticz, the MySensors node doesn't receive it. The code is a bit messy right now, but it should work with what I have. If someone could look it over and advise, that would be a big help. The sketch is a MySensors 1.5.4 sketch.

                                     /*
                                      RCS Thermostat for MySensors
                                    
                                      Arduino RCS RS485 thermostat control
                                    
                                      July 7,2016
                                    
                                      This is a gateway bridge to allow an RCS serial thermostat to be accessible to a MySensors
                                      gateway.  The thermostat being used to test this is an RCS TR40 RS485 thermostat.  The published
                                      protocol for RCS thermostats can be found at the following address;
                                      http://www.rcstechnology.com/oldsite/docs/thermostats/serial/SERIAL%20PROTOCOL%20REV%204.3%20%20150-00225-43.pdf
                                      
                                      This sketch features the following:
                                    
                                      Add features here
                                     */
                                    
                                    // Import needed libraries
                                    #include <SPI.h>
                                    #include <MySensor.h>  
                                    #include <SoftwareSerial.h>
                                    
                                    #define SKETCH_NAME "RCS TR40 Thermostat"
                                    #define SKETCH_VERSION "1.1"
                                    
                                    #define CHILD_ID_HVAC    0 // S_HVAC
                                    #define CHILD_ID_STATE   1 // S_LIGHT
                                    
                                    // Declare Constants and Pin Numbers
                                    #define SSerialRX        5  //Serial Receive pin 8
                                    #define SSerialTX        3  //Serial Transmit pin 7
                                    
                                    #define SSerialTxControl 4  //RS485 Direction control
                                    
                                    #define RS485Transmit    HIGH
                                    #define RS485Receive     LOW
                                    
                                    // Declare objects
                                    SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX
                                    
                                    MySensor gw;
                                    
                                    // Sensor values
                                    MyMessage msgStatus ( CHILD_ID_STATE,  V_LIGHT );
                                    MyMessage msgTemp   ( CHILD_ID_HVAC,   V_TEMP );
                                    MyMessage msgSetCool( CHILD_ID_HVAC,   V_HVAC_SETPOINT_COOL );
                                    MyMessage msgSetHeat( CHILD_ID_HVAC,   V_HVAC_SETPOINT_HEAT );
                                    
                                    // Declare Variables
                                    int byteReceived;
                                    int byteSend;
                                    String rcvString;
                                    String sndString;
                                    //This is for storing the last command that was sent 
                                    String lastSent;
                                    //the last sent set point
                                    String setPoint;
                                    
                                    String mode;
                                    //This is the RS485 address of this node that gets sent to the thermostat
                                    String serialAddr = "1";
                                    //Placeholder for the last command sent
                                    String LastSent = "";
                                    
                                    void setup() {
                                      Serial.begin(9600);
                                      
                                      gw.begin( incomingMessage, AUTO, false );
                                      
                                      gw.sendSketchInfo( SKETCH_NAME, SKETCH_VERSION );
                                      
                                      // Register the thermostat with the gateway
                                      gw.present( CHILD_ID_HVAC,  S_HVAC );
                                      gw.present( CHILD_ID_STATE, S_LIGHT );
                                      
                                      // put your setup code here, to run once:
                                      pinMode( SSerialTxControl, OUTPUT );
                                      digitalWrite( SSerialTxControl, RS485Receive );  // Init Transceiver
                                      
                                      // Start the software serial port, to another device
                                      RS485Serial.begin(9600);   // set the data rate
                                    } //End setup
                                    
                                    void loop() {
                                      String dataIn;
                                      
                                      if (RS485Serial.available()) {
                                        dataIn = RS485Serial.readStringUntil('\n');
                                        ParseReceived(dataIn);
                                      }
                                    } //End loop
                                    
                                    void ParseReceived(String Message) {
                                      String StatusData;
                                      //int Count;
                                      String StatusString;
                                      String Status;
                                      String Type;
                                      String Value;
                                    
                                      int Index;
                                      int Start;
                                      int End;
                                      int StatIndex;
                                    
                                      Index = Message.indexOf(' ');
                                      Start = 0;
                                      
                                      Serial.println("Message: " + Message);
                                      
                                      if (Message.startsWith("A=")) {
                                        while (End != Message.length()) {
                                          End = (Index == -1) ? Message.length() : Index;
                                          //Get the status string to process
                                          StatusString = Message.substring(Start, End);
                                          //Change our start position to 1 over the last space found
                                          Start = Index + 1;
                                          //Find the end of the next status string
                                          Index = Message.indexOf(' ', Start);
                                      
                                          //Now we need to process the status string into it's Type and Value
                                          StatIndex = StatusString.indexOf('=');
                                          Type = StatusString.substring(0, StatIndex);
                                          Value = StatusString.substring(StatIndex + 1);
                                          ParseStatus(Type, Value);
                                        } 
                                      } else {
                                        SendCmd(LastSent);
                                      }
                                    } //End ParseReceived
                                    
                                    void ParseStatus(String Type, String Value) {
                                      //
                                      
                                      if (Type == "OA") {
                                          //Outside Air not used
                                      } else if (Type == "Z") {
                                          //Zone not used
                                      } else if (Type == "T") {
                                          Serial.println("T: " + Value);
                                          gw.send(msgTemp.set( F2C( Value.toFloat() ), 2 ));
                                      } else if (Type == "SP") {
                                          Serial.println("SP: " + Value);
                                          gw.send(msgSetCool.set( F2C( Value.toFloat() ), 2 ));
                                      } else if (Type == "SPH") {
                                          Serial.println("SPH: " + Value);
                                          gw.send(msgSetHeat.set( F2C( Value.toFloat() ), 2 ));
                                      } else if (Type == "SPC") {
                                          Serial.println("SPC: " + Value);
                                          gw.send(msgSetCool.set( F2C( Value.toFloat() ), 2 ));
                                      } else if (Type == "M") {
                                          //Serial.println("M: " + Value);
                                          //gw.send(msgFlowMode.set(Value.c_str()));
                                      } else if (Type == "FM") {
                                          //Serial.println("FM: " + Value);
                                          //gw.send(msgFlowMode.set(Value.c_str()));
                                        //Type 2 status message types
                                      } else if (Type == "H1A") {
                                          Serial.println("H1A: " + Value);
                                          if (Value == "1") {
                                            //gw.send(msgHvacSpeed.set("Min"));
                                          } else {
                                            //gw.send(msgHvacSpeed.set("Auto"));
                                          }
                                      } else if (Type == "H2A") {
                                          Serial.println("H2A: " + Value);
                                          if (Value == "1") {
                                            //gw.send(msgHvacSpeed.set("Normal"));
                                          } else {
                                            //gw.send(msgHvacSpeed.set("Auto"));
                                          }
                                      } else if (Type == "H3A") {
                                          Serial.println("H3A: " + Value);
                                          if (Value == "1") {
                                            //gw.send(msgHvacSpeed.set("Max"));
                                          } else {
                                            //gw.send(msgHvacSpeed.set("Auto"));
                                          }
                                      } else if (Type == "C1A") {
                                          Serial.println("C1A: " + Value);
                                          if (Value == "1") {
                                            //gw.send(msgHvacSpeed.set("Min"));
                                          } else {
                                            //gw.send(msgHvacSpeed.set("Auto"));
                                          }
                                      } else if (Type == "C2A") {
                                          Serial.println("C2A: " + Value);
                                          if (Value == "1") {
                                            //gw.send(msgHvacSpeed.set("Normal"));
                                          } else {
                                            //gw.send(msgHvacSpeed.set("Auto"));
                                          }
                                      } else if (Type == "FA") {
                                          Serial.println("FA: " + Value);
                                          if (Value == "1") {
                                            //gw.send(msgFlowMode.set("ContinuousOn"));
                                          } else {
                                            //gw.send(msgHvacSpeed.set("Auto"));
                                          }
                                      } else if (Type == "VA") {
                                          //Vent damper not used
                                      } else if (Type == "D1") {
                                          //Damper #1 not used
                                      } else if (Type == "SCP") {
                                          String stg1 = Value.substring(0, 1);
                                          String stg2 = Value.substring(0, Value.length() - 1);
                                    
                                          //logging.AddToLog("MOT/MRT stage 1: " & stg1, True)
                                          //Deal with minimum off time and minimum run times 
                                          //for stage 1
                                    
                                          //logging.AddToLog("MOT/MRT stage 2: " & stg2, True)
                                          //Deal with minimum off time and minimum run times 
                                          //for stage 2
                                      } else if (Type == "SM") {
                                          //logging.AddToLog("System mode: " & Value, True)
                                          String FlowState;
                                          
                                          if (Value == "O") {
                                            FlowState = "Off";
                                          } else if (Value == "H") {
                                            FlowState = "HeatOn";
                                          } else if (Value == "C") {
                                            FlowState = "CoolOn";
                                          } else {
                                            FlowState = "AutoChangeOver";
                                          }
                                          //Serial.println("SM: " + FlowState);
                                          //gw.send(msgFlowState.set(FlowState.c_str()));
                                      } else if (Type == "SF") {
                                          //logging.AddToLog("System fan: " & Value, True) 
                                          Serial.println("SF: " + Value);
                                          gw.send(msgStatus.set(Value.toInt()));
                                      }
                                    } //End ParseStatus
                                    
                                    float F2C(float Fahrenheit) {
                                      return (5.0f/9.0f) * (Fahrenheit-32);
                                    } //End F2C
                                    
                                    float C2F(float Celsius) {
                                      return (Celsius * 9.0f) / 5.0f + 32.0f;
                                    } //End C2F
                                    
                                    void SendCmd(String cmd) {
                                      String commandStr;
                                      commandStr = "A=" + serialAddr + " O=00 " + cmd;
                                    
                                      Serial.println("Writing to serial port: " + commandStr);
                                      
                                      // Enable RS485 Transmit only for the duration of the send
                                      digitalWrite(SSerialTxControl, RS485Transmit);
                                      RS485Serial.print(commandStr + "\r");
                                      LastSent = cmd;
                                      //Return to RS485 receive mode  
                                      digitalWrite(SSerialTxControl, RS485Receive);
                                    } //End SendCmd
                                    
                                    /**
                                     * incomingMessage - Process the incoming messages.
                                     */
                                    void incomingMessage(const MyMessage &message) {
                                      Serial.println("message received");//String(message.type));
                                      //Serial.println(message.data);
                                      // We only expect one type of message from controller. But we better check anyway.
                                      if (message.isAck()) {
                                         Serial.println("This is an ack from gateway");
                                      }
                                      Serial.println("Temp: " + String(message.data) + " -- " + message.type);
                                      
                                      if ( message.type == V_TEMP ) {
                                        //
                                        Serial.println("Temp: " + String(message.data)); 
                                      } //End V_TEMP
                                      
                                      if ( message.type == V_STATUS ) {
                                        //
                                        Serial.println("Status: " + String(message.data)); 
                                      } //End V_STATUS
                                      
                                      if ( message.type == V_HVAC_FLOW_STATE ) {
                                        //
                                        Serial.println("Flow State: " + String(message.data)); 
                                      } //End V_HVAC_FLOW_STATE
                                      
                                      if ( message.type == V_HVAC_SPEED ) {
                                        //
                                        Serial.println("Speed: " + String(message.data)); 
                                      } //End V_HVAC_SPEED
                                    
                                      if (message.type == V_HVAC_SETPOINT_COOL) {
                                         Serial.println("Message received");
                                         String setPoint = String(C2F(atoi(message.data)));
                                         Serial.println("New Set Temp is : " + String(setPoint));
                                         SendCmd("SPC=" + setPoint + " R=1");
                                        
                                         // Write some debug info
                                         Serial.print("Incoming change for sensor:");
                                         Serial.print(message.sensor);
                                         Serial.print(", New status: ");
                                         Serial.println(message.data);
                                      } //End V_HVAC_SETPOINT_COOL
                                    
                                      if (message.type == V_HVAC_SETPOINT_HEAT) {
                                         Serial.println("Message received");
                                         String setPoint = String(C2F(atoi(message.data))); //.toInt();
                                         Serial.println("New Set Temp is : " + String(setPoint));
                                         SendCmd("SPH=" + setPoint + " R=1");
                                        
                                         // Write some debug info
                                         Serial.print("Incoming change for sensor:");
                                         Serial.print(message.sensor);
                                         Serial.print(", New status: ");
                                         Serial.println(message.data);
                                      } //End V_HVAC_SETPOINT_HEAT
                                      
                                      if ( (message.type == V_HVAC_FLOW_MODE) ) {
                                        //
                                        Serial.println("Flow Mode: " + String(message.data)); 
                                      } //End V_HVAC_FLOW_MODE
                                    } //End incomingMessage
                                    

                                    Thanks

                                    AWIA Offline
                                    AWIA Offline
                                    AWI
                                    Hero Member
                                    wrote on last edited by AWI
                                    #17

                                    @dbemowsk And... (sorry to bother you with things you didn't ask for) Your sketch is loaded with String object definitions and therefore open fora lot of problems. String looks like an easy solution but not really suited for real time (MySensors) purposes.
                                    An interesting article/ opinion background on the subject...

                                    My advice: Forget about String and get back to comprehensible char arrays. (unless somebody can convince me otherwise) .

                                    dbemowskD 1 Reply Last reply
                                    1
                                    • AWIA AWI

                                      @dbemowsk What does the serial log of the node tell you? Does it show messages coming in?

                                      dbemowskD Offline
                                      dbemowskD Offline
                                      dbemowsk
                                      wrote on last edited by dbemowsk
                                      #18

                                      @AWI said:

                                      @dbemowsk What does the serial log of the node tell you? Does it show messages coming in?

                                      I put the first Serial.println in the incomingMessage function to test and see if it was even hitting that function. I am not even seeing that in the serial monitor. That was the thing that prompted me to post this.

                                      The set-up I have for testing right now is I have my node connected to the FTDI usb cable on one end (COM5). On the RS485 end (COM10) I have it looped back to my laptop through a USB to RS485 adapter. I then use a serial terminal program to transmit and receive strings similar to what would come from my thermostat. As I mentioned in my post, if I send a command on the RS485 side as if my thermostat controller sent it, it goes through ParseReceived and ParseStatus normally and the gw.send commands push it to Domoticz just fine.

                                      I just can't think of any reason why the incoming messages from Domoticz are not being seen by the node. One thing I did find strange was that in order to see the Serial.println messages in the arduino serial monitor, I have it set to a baud of 115200 bps. The thing that confused me was that I have the first line in set-up as :

                                      Serial.begin(9600);
                                      

                                      I did this because that is the baud rate that my thermostat communicates at on the RS485 side of things. I realize that this is for the RS232 serial side on the arduino which is why I was confused.

                                      Vera Plus running UI7 with MySensors, Sonoffs and 1-Wire devices
                                      Visit my website for more Bits, Bytes and Ramblings from me: http://dan.bemowski.info/

                                      1 Reply Last reply
                                      0
                                      • AWIA AWI

                                        @dbemowsk And... (sorry to bother you with things you didn't ask for) Your sketch is loaded with String object definitions and therefore open fora lot of problems. String looks like an easy solution but not really suited for real time (MySensors) purposes.
                                        An interesting article/ opinion background on the subject...

                                        My advice: Forget about String and get back to comprehensible char arrays. (unless somebody can convince me otherwise) .

                                        dbemowskD Offline
                                        dbemowskD Offline
                                        dbemowsk
                                        wrote on last edited by
                                        #19

                                        @AWI said:

                                        @dbemowsk And... (sorry to bother you with things you didn't ask for) Your sketch is loaded with String object definitions and therefore open fora lot of problems. String looks like an easy solution but not really suited for real time (MySensors) purposes.
                                        An interesting article/ opinion background on the subject...

                                        My advice: Forget about String and get back to comprehensible char arrays. (unless somebody can convince me otherwise) .

                                        No need to appologize. C and C++ are languages that I have not done much programming in. Well, a very limited amount of C++ and I have never used C (until getting into arduino which seems to be more C based). As I have been working in my arduuino stuff I have been seeing more people using char and char* definitions. That and converting to these using c_str(). As mentioned, I am new to these languages, so if you know of any good tutorials on how to use these versus String, I am open to suggestions. I have not yet looked at the link you posted, but will shortly. If this is the more proper way to do things in arduino, I would like to shift my thinking in that direction.

                                        Vera Plus running UI7 with MySensors, Sonoffs and 1-Wire devices
                                        Visit my website for more Bits, Bytes and Ramblings from me: http://dan.bemowski.info/

                                        1 Reply Last reply
                                        0
                                        • dbemowskD Offline
                                          dbemowskD Offline
                                          dbemowsk
                                          wrote on last edited by
                                          #20

                                          @awi I am part way through your article on strings describing the stack and the heap. GREAT article. I have not finished it yet, but what I have read so far is excellent info.

                                          Vera Plus running UI7 with MySensors, Sonoffs and 1-Wire devices
                                          Visit my website for more Bits, Bytes and Ramblings from me: http://dan.bemowski.info/

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          17

                                          Online

                                          11.7k

                                          Users

                                          11.2k

                                          Topics

                                          113.1k

                                          Posts


                                          Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • MySensors
                                          • OpenHardware.io
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular