How do you modify the Read Holding Registers inside the Modbus RTU Server of the pyModbus RTU Server (Slave) application - pymodbus

I have the example pyModbus Server application working, but I am not sure how to adjust/modify the Input registers after the server has been started. Address range #30000-#39999
What I would like to do is to dynamically change the Input Registers inside my Server so that as my test Client reading system reads these registers, I can modify the behavior of the reading system.
Thanks
This server code is working:
#!/usr/bin/env python
"""
Pymodbus Asynchronous Server Example
--------------------------------------------------------------------------
The asynchronous server is a high performance implementation using the
twisted library as its backend. This allows it to scale to many thousands
of nodes which can be helpful for testing monitoring software.
"""
# --------------------------------------------------------------------------- #
# import the various server implementations
# --------------------------------------------------------------------------- #
from pymodbus.version import version
from pymodbus.server.asynchronous import StartTcpServer
from pymodbus.server.asynchronous import StartUdpServer
from pymodbus.server.asynchronous import StartSerialServer
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
from pymodbus.transaction import (ModbusRtuFramer,
ModbusAsciiFramer,
ModbusBinaryFramer)
#from custom_message import CustomModbusRequest
# --------------------------------------------------------------------------- #
# configure the service logging
# --------------------------------------------------------------------------- #
import logging
FORMAT = ('%(asctime)-15s %(threadName)-15s'
' %(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger()
log.setLevel(logging.DEBUG)
def run_async_server():
# ----------------------------------------------------------------------- #
# initialize your data store
# ----------------------------------------------------------------------- #
# The datastores only respond to the addresses that they are initialized to
# Therefore, if you initialize a DataBlock to addresses from 0x00 to 0xFF,
# a request to 0x100 will respond with an invalid address exception.
# This is because many devices exhibit this kind of behavior (but not all)
#
# block = ModbusSequentialDataBlock(0x00, [0]*0xff)
#
# Continuing, you can choose to use a sequential or a sparse DataBlock in
# your data context. The difference is that the sequential has no gaps in
# the data while the sparse can. Once again, there are devices that exhibit
# both forms of behavior::
#
# block = ModbusSparseDataBlock({0x00: 0, 0x05: 1})
# block = ModbusSequentialDataBlock(0x00, [0]*5)
#
# Alternately, you can use the factory methods to initialize the DataBlocks
# or simply do not pass them to have them initialized to 0x00 on the full
# address range::
#
# store = ModbusSlaveContext(di = ModbusSequentialDataBlock.create())
# store = ModbusSlaveContext()
#
# Finally, you are allowed to use the same DataBlock reference for every
# table or you you may use a seperate DataBlock for each table.
# This depends if you would like functions to be able to access and modify
# the same data or not::
#
# block = ModbusSequentialDataBlock(0x00, [0]*0xff)
# store = ModbusSlaveContext(di=block, co=block, hr=block, ir=block)
#
# The server then makes use of a server context that allows the server to
# respond with different slave contexts for different unit ids. By default
# it will return the same context for every unit id supplied (broadcast
# mode).
# However, this can be overloaded by setting the single flag to False
# and then supplying a dictionary of unit id to context mapping::
#
# slaves = {
# 0x01: ModbusSlaveContext(...),
# 0x02: ModbusSlaveContext(...),
# 0x03: ModbusSlaveContext(...),
# }
# context = ModbusServerContext(slaves=slaves, single=False)
#
# The slave context can also be initialized in zero_mode which means that a
# request to address(0-7) will map to the address (0-7). The default is
# False which is based on section 4.4 of the specification, so address(0-7)
# will map to (1-8)::
#
# store = ModbusSlaveContext(..., zero_mode=True)
# ----------------------------------------------------------------------- #
store = ModbusSlaveContext(
di=ModbusSequentialDataBlock(0, [17]*100),
co=ModbusSequentialDataBlock(0, [17]*100),
hr=ModbusSequentialDataBlock(0, [17]*100),
ir=ModbusSequentialDataBlock(0, [17]*100))
#store.register(CustomModbusRequest.function_code, 'cm',
# ModbusSequentialDataBlock(0, [17] * 100))
context = ModbusServerContext(slaves=store, single=True)
# ----------------------------------------------------------------------- #
# initialize the server information
# ----------------------------------------------------------------------- #
# If you don't set this or any fields, they are defaulted to empty strings.
# ----------------------------------------------------------------------- #
identity = ModbusDeviceIdentification()
identity.VendorName = 'Pymodbus'
identity.ProductCode = 'PM'
identity.VendorUrl = 'http://github.com/riptideio/pymodbus/'
identity.ProductName = 'Pymodbus Server'
identity.ModelName = 'Pymodbus Server'
identity.MajorMinorRevision = version.short()
# ----------------------------------------------------------------------- #
# run the server you want
# ----------------------------------------------------------------------- #
# TCP Server
#StartTcpServer(context, identity=identity, address=("localhost", 5020),
# custom_functions=[CustomModbusRequest])
# TCP Server with deferred reactor run
# from twisted.internet import reactor
# StartTcpServer(context, identity=identity, address=("localhost", 5020),
# defer_reactor_run=True)
# reactor.run()
# Server with RTU framer
# StartTcpServer(context, identity=identity, address=("localhost", 5020),
# framer=ModbusRtuFramer)
# UDP Server
# StartUdpServer(context, identity=identity, address=("127.0.0.1", 5020))
# RTU Server
StartSerialServer(context, identity=identity, port='com9', framer=ModbusRtuFramer)#,unit=5)
# ASCII Server
# StartSerialServer(context, identity=identity,
# port='/dev/ttyp0', framer=ModbusAsciiFramer)
# Binary Server
# StartSerialServer(context, identity=identity,
# port='/dev/ttyp0', framer=ModbusBinaryFramer)
if __name__ == "__main__":
run_async_server()
================================
and when I run the Client code shown below, I know I'm reading the FC04
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
#fro pymodbus.register_read_message import ReadInputRegisterResponse
client = ModbusClient(method='rtu', port='com19',stopbits=1,bytesize=8,parity='N',baudrate=19200,timeout=.03)
client.connect()
read=client.read_input_registers(address = 0x00, count =10, unit=1)
#data=read.registers[int(2)]
#print(read)
print(read.getRegister(1))

Should the port be uppercase 'COM'? and in your examples the COM ports do not match.
Server shows 'com9' and Client shows 'com19'
are you able read the registers?
cant you just write to them in the usual way?
client.write_registers(address=0, count=10, unit=1, values=(1,2,3,4,5,6,7,8,9,10))

Related

How can I create an animated plot from incoming serial port data

I want to live plot incoming data from a serial port without writing and reading data from a file. I understand that it's necessary to run a thread where the serial data is coming in on the fly. While the thread is running the animation.FuncAnimation should grab the serial data and render the plot each time.
That's where I can't figure out how to code the handover to get the animation to work.
import serial
import threading
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import itertools
def thread_data_gen():
i = 0
counter = itertools.count()
ser = serial.Serial('/dev/tty.SLAB_USBtoUART', 1000000, timeout=1) # Open port and read data.
ser.reset_input_buffer() # Flush input buffer, discarding all its contents.
while True:
ser_bytes = ser.readline() # Read serial data line by line
# Incoming lines in Format -> b'$ 32079 32079 32079 32079 32079 32079 32079 32079;\r\n'
# Each value represents a data channel which can measure torque, temperatur,...
# Right now all values are set to torque which is why they have the same values.
# 8 data channels available
decoded_bytes = ser_bytes.decode('utf-8')
decoded_bytes = decoded_bytes.lstrip('$').rstrip().split()
# Re-format to ['32274', '32274', '32274', '32274', '32274', '32274', '32274', '32274;']
if i == 0:
i += 1
continue
# Skip first read-out because the first transmitted line is empty. Don't know the reason.
t = next(counter) # Create values for x-axis
y = decoded_bytes[0] # Read channel 1 values for y-axis
yield t, y # Was thinking about a generator type of return but that's not working
def run(data): # Handing over yield data from thread_data_gen()
t, y = data # TypeError:"cannot unpack non-iterable int object" I don't know how to fix this.
# I have to convert the while loop in the running thread to something where I get iterable int data.
# That's where I don't see the solution
xdata.append(t) # Adding data to list for x-values
ydata.append(y) # Adding data to list for y-values
line.set_data(xdata, ydata) # Creating data for hand-over to plt
return line,
if __name__ == '__main__':
dgen = threading.Thread(target=thread_data_gen)
dgen.start()
fig, ax = plt.subplots()
line, = ax.plot([], [], lw=2)
ax.grid()
xdata, ydata = [], []
ani = animation.FuncAnimation(fig, run, interval=100)
plt.show()
Update
I just solved my own problem with:
# A sensor upgraded coupling in a power transmission system provides data per bluetooth.
# Data: Torque, force, temperature and acceleration (x-y-z-axis).
# A hardware gateway receives the data with an antenna.
# The purpose of this code is to read and plot out serial data from that hardware gateway
# which is linked via USB-C to the laptop. A USB-C to UART software bride,
# makes the data as serial port on MacOS or Windows available.
import time
import serial
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import itertools
def data_gen():
i = 0
counter = itertools.count() # Create counter
ser = serial.Serial('/dev/tty.SLAB_USBtoUART', 1000000, timeout=1) # Open port and read data.
ser.reset_input_buffer() # Flush input buffer, discarding all its contents.
while True:
# Read serial data line by line.
# Incoming lines in Format -> b'$ 32079 32079 32079 32079 32079 32079 32079 32079;\r\n'
# Each value represents a data channel which can measure torque, temperatur, ...
# Right now all values are set to torque which is why they have the same values.
# 8 data channels are available
ser_bytes = ser.readline()
decoded_bytes = ser_bytes.decode('utf-8')
# Re-format to list ['32274', '32274', '32274', '32274', '32274', '32274', '32274', '32274;']
decoded_bytes = decoded_bytes.lstrip('$').rstrip().split()
# Skip first read-out because the first transmitted line is empty. Don't know the reason.
if i == 0:
i += 1
continue
t = next(counter) # Create values for x-axis
y = decoded_bytes[0] # Read channel 1 values for y-axis
yield t, float(y) # Yield back x and y values for plot
def run(data):
x, y = data
y_cal = round(y * 0.00166, 1) #
xdata.append(x) # Adding data to list for x-values
ydata.append(y_cal) # Adding data to list for y-values
line.set_data(xdata, ydata) # Creating a data set for hand-over to plot
return line,
if __name__ == '__main__':
fig, ax = plt.subplots() # Setup figure and axis
line, = ax.plot([], [], lw=2) # Setup line
ax.set_ylim(40, 80) # Set limitation in y
ax.set_xlim(0, 1000) # Set limitation in x
ax.grid() # Create grid
xdata, ydata = [], [] # Create empty lists
# Frames: Receives the generated data from the serial connection
# Run: Provides the line data
ani = animation.FuncAnimation(fig, run, frames=data_gen, blit=True, interval=10)
plt.show()

reading a s3 file with s3a format using pyspark - High

#
# Some constants
#
aws_profile = "your_profile"
aws_region = "your_region"
s3_bucket = "your_bucket"
#
# Reading environment variables from aws credential file
#
import os
import configparser
config = configparser.ConfigParser()
config.read(os.path.expanduser("~/.aws/credentials"))
access_id = config.get(aws_profile, "aws_access_key_id")
access_key = config.get(aws_profile, "aws_secret_access_key")
#
# Configuring pyspark
#
# see https://github.com/jupyter/docker-stacks/issues/127#issuecomment-214594895
# and https://github.com/radanalyticsio/pyspark-s3-notebook/blob/master/s3-source-example.ipynb
os.environ['PYSPARK_SUBMIT_ARGS'] = "--packages=org.apache.hadoop:hadoop-aws:2.7.3 pyspark-shell"
# If this doesn't work you might have to delete your ~/.ivy2 directory to reset your package cache.
# (see https://github.com/databricks/spark-redshift/issues/244#issuecomment-239950148)
import pyspark
sc=pyspark.SparkContext()
# see https://github.com/databricks/spark-redshift/issues/298#issuecomment-271834485
sc.setSystemProperty("com.amazonaws.services.s3.enableV4", "true")
# see https://stackoverflow.com/questions/28844631/how-to-set-hadoop-configuration-values-from-pyspark
hadoop_conf=sc._jsc.hadoopConfiguration()
# see https://stackoverflow.com/questions/43454117/how-do-you-use-s3a-with-spark-2-1-0-on-aws-us-east-2
hadoop_conf.set("fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem")
hadoop_conf.set("com.amazonaws.services.s3.enableV4", "true")
hadoop_conf.set("fs.s3a.access.key", access_id)
hadoop_conf.set("fs.s3a.secret.key", access_key)
# see http://blog.encomiabile.it/2015/10/29/apache-spark-amazon-s3-and-apache-mesos/
hadoop_conf.set("fs.s3a.connection.maximum", "100000")
# see https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
hadoop_conf.set("fs.s3a.endpoint", "s3." + aws_region + ".amazonaws.com")
#
# Downloading the parquet file
#
sql=pyspark.sql.SparkSession(sc)
path = s3_bucket + "your_path"
dataS3=sql.read.parquet("s3://" + path)
Even have tried to write a file thinking that my directory pointing was not correct and if the file write is successful, could pin point the path where it is pointing now but still no progress and say no path exists.
If you please could guide us in this regard, it would really be helpful. Thanks in advance.

Grove I2C display not working on Raspberry Pi 3B

I only have my RPi 3B and a I²C display, I don't own any GrovePi hat and I want to show some text to the said display. Is there a way to make it work?
My display.
i2cdetect -y 1 shows this result, meaning the RPi is detecting the I²C display and it should work. But nothing seemed to be showing on the display, except for the full block on the first row.
I've tried literally everything on the internet, some library worked (as in throwing no errors) but the display still stays the same, full block on the first row.
I've installed python3, smbus, smbus2 and i2c-tools. I've changed the address to 3e.
My most recent *.py file. It does write 'LCD printing' yet nothing else works.
I don't find a way to change the contrast of the LCD (no potentiometer or whatsoever)
#!/usr/bin/python3
import smbus2 as smbus
import time
# Define some device parameters
I2C_ADDR = 0x3e # I2C device address, if any error, change this address to 0x3f
LCD_WIDTH = 16 # Maximum characters per line
# Define some device constants
LCD_CHR = 1 # Mode - Sending data
LCD_CMD = 0 # Mode - Sending command
LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line
LCD_LINE_3 = 0x94 # LCD RAM address for the 3rd line
LCD_LINE_4 = 0xD4 # LCD RAM address for the 4th line
LCD_BACKLIGHT = 0x08 # On
ENABLE = 0b00000100 # Enable bit
# Timing constants
E_PULSE = 0.0005
E_DELAY = 0.0005
# Open I2C interface
# bus = smbus.SMBus(0) # Rev 1 Pi uses 0
bus = smbus.SMBus(1) # Rev 2 Pi uses 1
def lcd_init():
# Initialise display
lcd_byte(0x33, LCD_CMD) # 110011 Initialise
lcd_byte(0x32, LCD_CMD) # 110010 Initialise
lcd_byte(0x06, LCD_CMD) # 000110 Cursor move direction
lcd_byte(0x0C, LCD_CMD) # 001100 Display On,Cursor Off, Blink Off
lcd_byte(0x28, LCD_CMD) # 101000 Data length, number of lines, font size
lcd_byte(0x01, LCD_CMD) # 000001 Clear display
time.sleep(E_DELAY)
def lcd_byte(bits, mode):
# Send byte to data pins
# bits = the data
# mode = 1 for data
# 0 for command
bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT
bits_low = mode | ((bits << 4) & 0xF0) | LCD_BACKLIGHT
# High bits
bus.write_byte(I2C_ADDR, bits_high)
lcd_toggle_enable(bits_high)
# Low bits
bus.write_byte(I2C_ADDR, bits_low)
lcd_toggle_enable(bits_low)
def lcd_toggle_enable(bits):
# Toggle enable
time.sleep(E_DELAY)
bus.write_byte(I2C_ADDR, (bits | ENABLE))
time.sleep(E_PULSE)
bus.write_byte(I2C_ADDR, (bits & ~ENABLE))
time.sleep(E_DELAY)
def lcd_string(message, line):
# Send string to display
message = message.ljust(LCD_WIDTH, " ")
lcd_byte(line, LCD_CMD)
for i in range(LCD_WIDTH):
lcd_byte(ord(message[i]), LCD_CHR)
if __name__ == '__main__':
lcd_init()
while True:
# Send some test
lcd_string("Hello ", LCD_LINE_1)
lcd_string(" World", LCD_LINE_2)
print('LCD printing!')
time.sleep(3)

How to convert Holoviews graph to Bokeh 'model' in order to utilize more Bokeh features such as bokeh.models.GraphRenderer and node_renderer?

I'm trying to create a directed graph using networkx and bokeh, however, I also want to show the arrows for each out-edge. I found that the Holoviews library has the ability to add a 'directed=true' parameter to its graph constructor. However, I also want to utilize Bokeh's design features such as adjusting node color/size based on previously set node-attributes. The latter only works if I use Bokeh's from_networkx() to get a bokeh.models.renderers.GraphRender object, and then use its attributes node_renderer and edge_renderer.
The issue is when using Holoviews' renderer to specify Bokeh as the backend, it returns a bokeh.plotting.figure.Figure instead of the GraphRenderer. Ultimately, I want to be know how to be able to control the node size/color based on some attributes possible through Bokeh, and simultaneously use Holoviews to display the arrowheads on each edge.
import networkx as nx
import holoviews as hv
from holoviews import opts
hv.extension('bokeh')
from bokeh.io import show, output_file
# ... some code for I/O ...
G = nx.DiGraph(edgeList) # Directed networkx graph
# Set Node/Edge attributes to display upon hover
numConnections = {k:v for k,v in G.out_degree()}
nx.set_node_attributes(G, numConnections, name='numConnections')
# Returns Holoviews graph
hvGraph = hv.Graph.from_networkx(G, nx.spring_layout).opts(tools=['hover'], directed=True, arrowhead_length=0.01)
# Renders Holoviews graph into bokeh.plotting.figure.Figure
hvRendered = hv.render(hvGraph, 'bokeh')
output_file("out.html")
show(hvRendered)
# # The below code runs as expected using Bokeh only, and not Holoviews
# # to produce the directed graph (without arrowed edges):
# from bokeh.models import Plot, Range1d, MultiLine, Circle
# from bokeh.models import LinearColorMapper, ColorBar, BasicTicker
# import bokeh.models as bm
# from bokeh.models.graphs import from_networkx
# from bokeh.models.graphs import NodesAndLinkedEdges, EdgesAndLinkedNodes
# # Returns GraphRenderer from bokeh.models.renderers.DateRenderer
# graphRenderer = from_networkx(G, nx.spring_layout)
# mapper = LinearColorMapper(palette="Viridis256", low=76, high=0)
# # Node size/color when unselected / selected / hover
# graphRenderer.node_renderer.glyph = Circle(
# size='node_size',
# fill_color= {'field': "numConnections", "transform": mapper},
# fill_alpha=.8
# )
# graphRenderer.node_renderer.selection_glyph = Circle(
# size=25,
# fill_color=Inferno6[4]
# )
# graphRenderer.node_renderer.hover_glyph = Circle(
# size=20,
# fill_color=Inferno6[3]
# )
# # Edge size/color when unselected / selected / hover
# graphRenderer.edge_renderer.glyph = MultiLine(
# line_color="#CCCCCC",
# line_alpha=0.8,
# line_width=3
# )
# graphRenderer.edge_renderer.selection_glyph = MultiLine(
# line_color=Inferno6[4],
# line_width=4
# )
# graphRenderer.edge_renderer.hover_glyph = MultiLine(
# line_color=Inferno6[3],
# line_width=4
# )
# graphRenderer.node_renderer.data_source.data['numConnections'] = [v for k,v in
nx.get_node_attributes(G,'numConnections').items()]
# graphRenderer.selection_policy = NodesAndLinkedEdges()
# graphRenderer.inspection_policy = NodesAndLinkedEdges()
# bar = ColorBar(color_mapper=mapper, location=(0,0), title='#connections')
# # Create Bokeh Plot
# plot = Plot(
# plot_width=20,
# plot_height=20,
# x_range=Range1d(-1.1,1.1),
# y_range=Range1d(-1.1,1.1)
# )
# plot.add_tools(
# bm.HoverTool(tooltips=[("#connections", "#numConnections")]),
# bm.TapTool(),
# bm.BoxSelectTool()
# )
# plot.renderers.append(graphRenderer)
# output_file("bokeh.html")
# show(plot)
After rendering the Holoview graph into a Bokeh Figure (not a models.GraphRenderer), if I try to call the attribute node_renderer using the rendered Bokeh Figure object, it obviously throws an exception.
Traceback (most recent call last): File "holoview.py", line 106, in hvRenderedGraph.node_renderer.selection_glyph = Circle() AttributeError: 'BokehRenderer' object has no attribute 'node_renderer'
You can get the GraphRender object by following code:
from bokeh.models import GraphRenderer
gr = hvRendered.select_one(GraphRenderer)
then use gr.node_renderer and gr.edge_renderer to adjust the style.

TNS-12505: TNS:listener does not currently know of SID given in connect descriptor after shutting down one of the DB instance

My DB machine has three instance, I had shutdown the 'EDWDBS1' only (not the whole database) in the RMAN interface by using
shutdown immediate
But when I want to reconnect to/startup 'EDWDBS1', it throws ORA-12505 error either in sqldeveloper or sqlplus or RMAN. Alrd tried to check the tnsnames.ora and listener.ora, but I still got no idea about that.
Here is my listener.ora
# copyright (c) 1997 by the Oracle Corporation
#
# NAME
# listener.ora
# FUNCTION
# Network Listener startup parameter file example
# NOTES
# This file contains all the parameters for listener.ora,
# and could be used to configure the listener by uncommenting
# and changing values. Multiple listeners can be configured
# in one listener.ora, so listener.ora parameters take the form
# of SID_LIST_<lsnr>, where <lsnr> is the name of the listener
# this parameter refers to. All parameters and values are
# case-insensitive.
# <lsnr>
# This parameter specifies both the name of the listener, and
# it listening address(es). Other parameters for this listener
# us this name in place of <lsnr>. When not specified,
# the name for <lsnr> defaults to "LISTENER", with the default
# address value as shown below.
#
# LISTENER =
# (ADDRESS_LIST=
# (ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521))
# (ADDRESS=(PROTOCOL=ipc)(KEY=PNPKEY)))
# SID_LIST_<lsnr>
# List of services the listener knows about and can connect
# clients to. There is no default. See the Net8 Administrator's
# Guide for more information.
#
# SID_LIST_LISTENER=
# (SID_LIST=
# (SID_DESC=
# #BEQUEATH CONFIG
# (GLOBAL_DBNAME=salesdb.mycompany)
# (SID_NAME=sid1)
# (ORACLE_HOME=/private/app/oracle/product/8.0.3)
# #PRESPAWN CONFIG
# (PRESPAWN_MAX=20)
# (PRESPAWN_LIST=
# (PRESPAWN_DESC=(PROTOCOL=tcp)(POOL_SIZE=2)(TIMEOUT=1))
# )
# )
# )
# PASSWORDS_<lsnr>
# Specifies a password to authenticate stopping the listener.
# Both encrypted and plain-text values can be set. Encrypted passwords
# can be set and stored using lsnrctl.
# LSNRCTL> change_password
# Will prompt for old and new passwords, and use encryption both
# to match the old password and to set the new one.
# LSNRCTL> set password
# Will prompt for the new password, for authentication with
# the listener. The password must be set before running the next
# command.
# LSNRCTL> save_config
# Will save the changed password to listener.ora. These last two
# steps are not necessary if SAVE_CONFIG_ON_STOP_<lsnr> is ON.
# See below.
#
# Default: NONE
#
# PASSWORDS_LISTENER = 20A22647832FB454 # "foobar"
# SAVE_CONFIG_ON_STOP_<lsnr>
# Tells the listener to save configuration changes to listener.ora when
# it shuts down. Changed parameter values will be written to the file,
# while preserving formatting and comments.
# Default: OFF
# Values: ON/OFF
#
# SAVE_CONFIG_ON_STOP_LISTENER = ON
# USE_PLUG_AND_PLAY_<lsnr>
# Tells the listener to contact an Onames server and register itself
# and its services with Onames.
# Values: ON/OFF
# Default: OFF
#
# USE_PLUG_AND_PLAY_LISTENER = ON
# LOG_FILE_<lsnr>
# Sets the name of the listener's log file. The .log extension
# is added automatically.
# Default=<lsnr>
#
# LOG_FILE_LISTENER = lsnr
# LOG_DIRECTORY_<lsnr>
# Sets the directory for the listener's log file.
# Default: <oracle_home>/network/log
#
# LOG_DIRECTORY_LISTENER = /private/app/oracle/product/8.0.3/network/log
# TRACE_LEVEL_<lsnr>
# Specifies desired tracing level.
# Default: OFF
# Values: OFF/USER/ADMIN/SUPPORT/0-16
#
# TRACE_LEVEL_LISTENER = SUPPORT
# TRACE_FILE_<lsnr>
# Sets the name of the listener's trace file. The .trc extension
# is added automatically.
# Default: <lsnr>
#
# TRACE_FILE_LISTENER = lsnr
# TRACE_DIRECTORY_<lsnr>
# Sets the directory for the listener's trace file.
# Default: <oracle_home>/network/trace
#
# TRACE_DIRECTORY_LISTENER=/private/app/oracle/product/8.0.3/network/trace
# CONNECT_TIMEOUT_<lsnr>
# Sets the number of seconds that the listener waits to get a
# valid database query after it has been started.
# Default: 10
#
# CONNECT_TIMEOUT_LISTENER=10
tnsnames.ora
EDWDBD1 = (DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = HKHPEDWDBSDEV01)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = EDWDBD1)
)
)
EDWDBS1 = (DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = HKHPEDWDBSDEV01)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = EDWDBS1)
)
)
EDWDBU1 = (DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = HKHPEDWDBSDEV01)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = EDWDBU1)
)
)
EDWPDBD1 = (DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = HKHPEDWDBSDEV01)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = EDWPDBD1)
)
)
Result of lsnrctl status
LSNRCTL for Linux: Version 12.2.0.1.0 - Production on 11-FEB-2019 18:43:54
Copyright (c) 1991, 2016, Oracle. All rights reserved.
Connecting to (ADDRESS=(PROTOCOL=tcp)(HOST=)(PORT=1521))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for Linux: Version 12.2.0.1.0 - Production
Start Date 11-FEB-2019 18:09:09
Uptime 0 days 0 hr. 34 min. 45 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Listener Parameter File /u01/app/oracle/product/12.2.0/db_1/network/admin/listener.ora
Listener Log File /u01/app/oracle/diag/tnslsnr/HKHPEWDBSDEV01/listener/alert/log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=HKHPEWDBSDEV01)(PORT=1521)))
Services Summary...
Service "7a114ab24bf177a5e055315d54627e2c" has 1 instance(s).
Instance "edwdbd1", status READY, has 1 handler(s) for this service...
Service "EDWDBU1" has 1 instance(s).
Instance "EDWDBU1", status READY, has 1 handler(s) for this service...
Service "EDWDBU1XDB" has 1 instance(s).
Instance "EDWDBU1", status READY, has 1 handler(s) for this service...
Service "edwdbd1" has 1 instance(s).
Instance "edwdbd1", status READY, has 1 handler(s) for this service...
Service "edwdbd1XDB" has 1 instance(s).
Instance "edwdbd1", status READY, has 1 handler(s) for this service...
Service "edwpdbd1" has 1 instance(s).
Instance "edwdbd1", status READY, has 1 handler(s) for this service...
The command completed successfully
I am guessing you are trying to start your instance remotely. In your listener.ora you don't have a static service configured, so you can't connect remotely (via TCP/IP) to the instance as the listener doesn't know about that instance.
In order to start the instance you should be connected locally (via SSH) and set all necessary environment variables (ORACLE_HOME, ORACLE_SID, PATH) and use OS authentication (usually be member of dba group) and run:
sqlplus / as sysdba
and
startup;
Also you can use password file authentication but this is another story.