or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-messaging.mdcore-operations.mddevice-discovery.mdindex.mdtag-discovery.mdtime-operations.md

time-operations.mddocs/

0

# PLC Time Management

1

2

Functions for reading and setting the PLC's internal clock, enabling time synchronization between PLCs and host systems. These operations are essential for applications requiring accurate timestamps, scheduled operations, and time-based process control.

3

4

## Capabilities

5

6

### Reading PLC Time

7

8

Retrieve the current time from the PLC's internal clock with options for different time formats.

9

10

```python { .api }

11

def GetPLCTime(raw=False):

12

"""

13

Get the PLC's current time.

14

15

Args:

16

raw (bool): If True, return raw microseconds since Unix epoch.

17

If False, return formatted datetime object (default).

18

19

Returns:

20

Response: Object containing the PLC time in Value field

21

- Value: datetime object (raw=False) or int microseconds (raw=True)

22

- Status: "Success" or error description

23

"""

24

```

25

26

**Usage Examples:**

27

28

```python

29

from pylogix import PLC

30

31

with PLC() as comm:

32

comm.IPAddress = '192.168.1.100'

33

34

# Get PLC time as datetime object

35

response = comm.GetPLCTime()

36

if response.Status == 'Success':

37

plc_time = response.Value

38

print(f"PLC Time: {plc_time}")

39

print(f"Formatted: {plc_time.strftime('%Y-%m-%d %H:%M:%S')}")

40

41

# Get raw time as microseconds since Unix epoch

42

response = comm.GetPLCTime(raw=True)

43

if response.Status == 'Success':

44

microseconds = response.Value

45

print(f"Raw PLC Time: {microseconds} microseconds")

46

47

# Convert to seconds for comparison

48

seconds = microseconds / 1_000_000

49

print(f"Seconds since epoch: {seconds}")

50

```

51

52

**Time Format Details:**

53

54

The PLC time is stored internally as microseconds since the Unix epoch (January 1, 1970, 00:00:00 UTC). When `raw=False` (default), PyLogix converts this to a Python `datetime` object for easier handling.

55

56

```python

57

# Working with datetime objects

58

response = comm.GetPLCTime()

59

if response.Status == 'Success':

60

plc_time = response.Value

61

62

# Extract time components

63

year = plc_time.year

64

month = plc_time.month

65

day = plc_time.day

66

hour = plc_time.hour

67

minute = plc_time.minute

68

second = plc_time.second

69

microsecond = plc_time.microsecond

70

71

# Compare with system time

72

import datetime

73

system_time = datetime.datetime.now()

74

time_diff = abs((plc_time - system_time).total_seconds())

75

print(f"Time difference: {time_diff:.2f} seconds")

76

```

77

78

### Setting PLC Time

79

80

Set the PLC's internal clock to synchronize with the host system or a specific time.

81

82

```python { .api }

83

def SetPLCTime(dst=None):

84

"""

85

Set the PLC's clock to the current system time.

86

87

Args:

88

dst (bool, optional): Daylight Saving Time flag

89

- True: DST is active

90

- False: Standard time

91

- None: Use system DST setting (default)

92

93

Returns:

94

Response: Object indicating success or failure

95

- Value: Timestamp that was set (in microseconds)

96

- Status: "Success" or error description

97

"""

98

```

99

100

**Usage Examples:**

101

102

```python

103

with PLC() as comm:

104

comm.IPAddress = '192.168.1.100'

105

106

# Set PLC time to current system time with automatic DST detection

107

response = comm.SetPLCTime()

108

if response.Status == 'Success':

109

set_time = response.Value

110

print(f"PLC time synchronized successfully")

111

print(f"Set time: {set_time} microseconds")

112

else:

113

print(f"Failed to set PLC time: {response.Status}")

114

115

# Explicitly set DST flag

116

response = comm.SetPLCTime(dst=True) # Force DST active

117

response = comm.SetPLCTime(dst=False) # Force standard time

118

```

119

120

**Time Synchronization Workflow:**

121

122

```python

123

def synchronize_plc_time(plc_ip):

124

"""Complete time synchronization workflow with validation."""

125

with PLC() as comm:

126

comm.IPAddress = plc_ip

127

128

# Get current PLC time

129

before_response = comm.GetPLCTime()

130

if before_response.Status != 'Success':

131

print(f"Cannot read PLC time: {before_response.Status}")

132

return False

133

134

plc_time_before = before_response.Value

135

print(f"PLC time before sync: {plc_time_before}")

136

137

# Set PLC time to system time

138

set_response = comm.SetPLCTime()

139

if set_response.Status != 'Success':

140

print(f"Failed to set PLC time: {set_response.Status}")

141

return False

142

143

print("Time synchronization command sent successfully")

144

145

# Verify the new time

146

import time

147

time.sleep(1) # Wait for PLC to process the time change

148

149

after_response = comm.GetPLCTime()

150

if after_response.Status == 'Success':

151

plc_time_after = after_response.Value

152

print(f"PLC time after sync: {plc_time_after}")

153

154

# Calculate synchronization accuracy

155

import datetime

156

system_time = datetime.datetime.now()

157

sync_error = abs((plc_time_after - system_time).total_seconds())

158

print(f"Synchronization accuracy: ±{sync_error:.3f} seconds")

159

160

return sync_error < 2.0 # Consider sync successful if within 2 seconds

161

162

return False

163

164

# Usage

165

success = synchronize_plc_time('192.168.1.100')

166

```

167

168

### Time Zone and DST Considerations

169

170

Understanding how PyLogix handles time zones and daylight saving time is important for accurate time operations.

171

172

**DST Handling:**

173

174

```python

175

import time

176

177

# Check current system DST status

178

dst_active = time.localtime().tm_isdst == 1

179

print(f"System DST active: {dst_active}")

180

181

# Set PLC time with explicit DST control

182

with PLC() as comm:

183

comm.IPAddress = '192.168.1.100'

184

185

if dst_active:

186

response = comm.SetPLCTime(dst=True)

187

print("PLC time set with DST active")

188

else:

189

response = comm.SetPLCTime(dst=False)

190

print("PLC time set with standard time")

191

```

192

193

**Time Zone Considerations:**

194

195

PyLogix works with the local system time. For applications spanning multiple time zones, consider converting to UTC:

196

197

```python

198

import datetime

199

200

def set_plc_time_utc(plc_ip):

201

"""Set PLC time to UTC regardless of system timezone."""

202

with PLC() as comm:

203

comm.IPAddress = plc_ip

204

205

# Get current UTC time

206

utc_now = datetime.datetime.utcnow()

207

print(f"Setting PLC to UTC time: {utc_now}")

208

209

# Note: SetPLCTime() uses system time, so this approach

210

# requires manual timestamp manipulation for UTC

211

response = comm.SetPLCTime(dst=False) # UTC doesn't use DST

212

213

return response.Status == 'Success'

214

```

215

216

### Periodic Time Synchronization

217

218

For applications requiring continuous time accuracy, implement periodic synchronization:

219

220

```python

221

import threading

222

import time as time_module

223

224

class PLCTimeSynchronizer:

225

"""Automatic PLC time synchronization service."""

226

227

def __init__(self, plc_ip, sync_interval=3600): # Default: sync every hour

228

self.plc_ip = plc_ip

229

self.sync_interval = sync_interval

230

self.running = False

231

self.thread = None

232

233

def start(self):

234

"""Start the synchronization service."""

235

self.running = True

236

self.thread = threading.Thread(target=self._sync_loop)

237

self.thread.daemon = True

238

self.thread.start()

239

print(f"PLC time sync started for {self.plc_ip} (interval: {self.sync_interval}s)")

240

241

def stop(self):

242

"""Stop the synchronization service."""

243

self.running = False

244

if self.thread:

245

self.thread.join()

246

print("PLC time synchronization stopped")

247

248

def _sync_loop(self):

249

"""Main synchronization loop."""

250

while self.running:

251

try:

252

with PLC() as comm:

253

comm.IPAddress = self.plc_ip

254

response = comm.SetPLCTime()

255

256

if response.Status == 'Success':

257

print(f"PLC {self.plc_ip} time synchronized")

258

else:

259

print(f"Sync failed for {self.plc_ip}: {response.Status}")

260

261

except Exception as e:

262

print(f"Sync error for {self.plc_ip}: {e}")

263

264

# Wait for next sync interval

265

for _ in range(self.sync_interval):

266

if not self.running:

267

break

268

time_module.sleep(1)

269

270

# Usage example

271

synchronizer = PLCTimeSynchronizer('192.168.1.100', sync_interval=1800) # 30 minutes

272

synchronizer.start()

273

274

# Later...

275

# synchronizer.stop()

276

```

277

278

### Error Handling for Time Operations

279

280

Time operations can fail for various reasons. Implement robust error handling:

281

282

```python

283

def robust_time_sync(plc_ip, max_retries=3, retry_delay=5):

284

"""Robust time synchronization with retry logic."""

285

286

for attempt in range(max_retries):

287

try:

288

with PLC() as comm:

289

comm.IPAddress = plc_ip

290

comm.SocketTimeout = 10.0 # Longer timeout for time operations

291

292

# Try to set time

293

response = comm.SetPLCTime()

294

295

if response.Status == 'Success':

296

print(f"Time sync successful on attempt {attempt + 1}")

297

return True

298

else:

299

print(f"Attempt {attempt + 1} failed: {response.Status}")

300

301

except Exception as e:

302

print(f"Exception on attempt {attempt + 1}: {e}")

303

304

if attempt < max_retries - 1:

305

print(f"Retrying in {retry_delay} seconds...")

306

time_module.sleep(retry_delay)

307

308

print(f"Failed to sync time after {max_retries} attempts")

309

return False

310

311

# Usage

312

success = robust_time_sync('192.168.1.100')

313

```

314

315

### MicroPython Considerations

316

317

When using PyLogix on MicroPython, time operations have some limitations:

318

319

```python

320

# On MicroPython, always use raw=True for GetPLCTime

321

response = comm.GetPLCTime(raw=True)

322

if response.Status == 'Success':

323

# MicroPython doesn't have datetime module

324

# Work with raw microseconds

325

microseconds = response.Value

326

seconds = microseconds // 1_000_000

327

print(f"PLC time in seconds: {seconds}")

328

```